The root cause here is that in the VC++ runtime, randworks off a per-thread internal state. Because there's no srand call in this codepath, srand(1) occurs implicitly on the first rand call, and each worker thread will produce an identical noise profile, e.g. for machines with 20 cores, 20 or so layers will get an identical noise pattern.
Because the threads tend to work round-robin processing layers, this creates visible repetitive artifacts in the output when layers are identical (see pictures below)
Implementation note: Calling srand(time(NULL)) isn't a sufficient fix here since all the worker threads get kicked off at the same time and will observe the same time(NULL) value (its precision is only "seconds"). The thread ID will be unique, though, and we can hash it to produce a suitable input to srand.
Screenshots/Recordings/Graphs
Tests
I tested this on Linux and, while it doesn't repro there in the first place, it doesn't have any ill effects either. I tested a version that forced an srand(1) call on each polygon to verify that this is the correct codepath.
Description
Fixes https://github.com/SoftFever/OrcaSlicer/issues/5521 Fixes https://github.com/bambulab/BambuStudio/issues/4253
The root cause here is that in the VC++ runtime,
rand
works off a per-thread internal state. Because there's nosrand
call in this codepath,srand(1)
occurs implicitly on the firstrand
call, and each worker thread will produce an identical noise profile, e.g. for machines with 20 cores, 20 or so layers will get an identical noise pattern.Because the threads tend to work round-robin processing layers, this creates visible repetitive artifacts in the output when layers are identical (see pictures below)
Implementation note: Calling
srand(time(NULL))
isn't a sufficient fix here since all the worker threads get kicked off at the same time and will observe the sametime(NULL)
value (its precision is only "seconds"). The thread ID will be unique, though, and we can hash it to produce a suitable input tosrand
.Screenshots/Recordings/Graphs
Tests
I tested this on Linux and, while it doesn't repro there in the first place, it doesn't have any ill effects either. I tested a version that forced an
srand(1)
call on each polygon to verify that this is the correct codepath.