Fix T64623: Freestyle procedural noise not consistent across platforms
authorBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 14 May 2019 21:36:50 +0000 (23:36 +0200)
committerBrecht Van Lommel <brechtvanlommel@gmail.com>
Tue, 14 May 2019 21:45:14 +0000 (23:45 +0200)
Use the Blender RNG instead of rand() to solve it.

source/blender/blenlib/BLI_rand.h
source/blender/freestyle/intern/geometry/Noise.cpp

index 151b02a..eec4e88 100644 (file)
  * \brief Random number functions.
  */
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /* RNG is an abstract random number generator type that avoids using globals.
  * Always use this instead of the global RNG unless you have a good reason,
  * the global RNG is not thread safe and will not give repeatable results.
@@ -106,4 +110,8 @@ void BLI_hammersley_1d(unsigned int n, double *r);
 void BLI_halton_2d_sequence(unsigned int prime[2], double offset[2], int n, double *r);
 void BLI_hammersley_2d_sequence(unsigned int n, double *r);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __BLI_RAND_H__ */
index 09c2902..8b81660 100644 (file)
@@ -24,6 +24,9 @@
 #include <stdlib.h>
 #include <time.h>
 
+#include "BLI_compiler_attrs.h"
+#include "BLI_rand.h"
+
 #include "Noise.h"
 
 namespace Freestyle {
@@ -40,9 +43,7 @@ namespace Freestyle {
     ((s) * (RTable[m] * 0.5 + RTable[m + 1] * (x) + RTable[m + 2] * (y) + RTable[m + 3] * (z)))
 
 #  define MAXSIZE 500
-#  define NRAND() ((float)rand() / (float)RAND_MAX)
 #endif
-#define SEEDNRAND(x) (srand(x * RAND_MAX))
 
 #define BM 0xff
 #define N 0x1000
@@ -236,25 +237,26 @@ float Noise::smoothNoise3(Vec3f &vec)
 
 Noise::Noise(long seed)
 {
+  /* Use Blender RNG for repeatable results across platforms. */
+  RNG *rng = BLI_rng_new(seed);
   int i, j, k;
 
-  SEEDNRAND((seed < 0) ? time(NULL) : seed);
   for (i = 0; i < _NOISE_B; i++) {
     p[i] = i;
-    g1[i] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+    g1[i] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
 
     for (j = 0; j < 2; j++)
-      g2[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+      g2[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
     normalize2(g2[i]);
 
     for (j = 0; j < 3; j++)
-      g3[i][j] = (float)((rand() % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
+      g3[i][j] = (float)((BLI_rng_get_int(rng) % (_NOISE_B + _NOISE_B)) - _NOISE_B) / _NOISE_B;
     normalize3(g3[i]);
   }
 
   while (--i) {
     k = p[i];
-    p[i] = p[j = rand() % _NOISE_B];
+    p[i] = p[j = BLI_rng_get_int(rng) % _NOISE_B];
     p[j] = k;
   }
 
@@ -268,6 +270,8 @@ Noise::Noise(long seed)
     for (j = 0; j < 3; j++)
       g3[_NOISE_B + i][j] = g3[i][j];
   }
+
+  BLI_rng_free(rng);
 }
 
 } /* namespace Freestyle */