[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56073] trunk/blender/source/blender: Random number generator: replace a bunch of usage of the global random number

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Apr 16 01:12:41 CEST 2013


Revision: 56073
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56073
Author:   blendix
Date:     2013-04-15 23:12:40 +0000 (Mon, 15 Apr 2013)
Log Message:
-----------
Random number generator: replace a bunch of usage of the global random number
generator with a local one. It's not thread safe and will not give repeatable
results, so in most cases it should not be used.

Also fixes #34992 where the noise texture of a displacement modifier was not
properly random in opengl animation render, because the seed got reset to a
fixed value by an unrelated function while for final render it changed each
frame.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_boids.h
    trunk/blender/source/blender/blenkernel/BKE_particle.h
    trunk/blender/source/blender/blenkernel/intern/anim.c
    trunk/blender/source/blender/blenkernel/intern/boids.c
    trunk/blender/source/blender/blenkernel/intern/effect.c
    trunk/blender/source/blender/blenkernel/intern/ocean.c
    trunk/blender/source/blender/blenkernel/intern/particle.c
    trunk/blender/source/blender/blenkernel/intern/particle_system.c
    trunk/blender/source/blender/blenkernel/intern/smoke.c
    trunk/blender/source/blender/blenlib/BLI_rand.h
    trunk/blender/source/blender/blenlib/intern/jitter.c
    trunk/blender/source/blender/blenlib/intern/rand.c
    trunk/blender/source/blender/bmesh/operators/bmo_edgenet.c
    trunk/blender/source/blender/bmesh/operators/bmo_subdivide.c
    trunk/blender/source/blender/editors/curve/editcurve.c
    trunk/blender/source/blender/editors/gpencil/gpencil_edit.c
    trunk/blender/source/blender/editors/mesh/editmesh_knife.c
    trunk/blender/source/blender/editors/mesh/editmesh_select.c
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c
    trunk/blender/source/blender/editors/metaball/mball_edit.c
    trunk/blender/source/blender/editors/physics/particle_edit.c
    trunk/blender/source/blender/editors/transform/transform_generics.c
    trunk/blender/source/blender/editors/uvedit/uvedit_unwrap_ops.c
    trunk/blender/source/blender/modifiers/intern/MOD_explode.c
    trunk/blender/source/blender/modifiers/intern/MOD_particleinstance.c
    trunk/blender/source/blender/modifiers/intern/MOD_weightvg_util.c
    trunk/blender/source/blender/modifiers/intern/MOD_weightvg_util.h
    trunk/blender/source/blender/modifiers/intern/MOD_weightvgedit.c
    trunk/blender/source/blender/modifiers/intern/MOD_weightvgproximity.c
    trunk/blender/source/blender/render/intern/source/convertblender.c
    trunk/blender/source/blender/render/intern/source/rayshade.c

Modified: trunk/blender/source/blender/blenkernel/BKE_boids.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_boids.h	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/BKE_boids.h	2013-04-15 23:12:40 UTC (rev 56073)
@@ -36,6 +36,8 @@
 
 #include "DNA_boid_types.h"
 
+struct RNG;
+
 typedef struct BoidBrainData {
 	struct ParticleSimulationData *sim;
 	struct ParticleSettings *part;
@@ -47,6 +49,8 @@
 	float goal_co[3];
 	float goal_nor[3];
 	float goal_priority;
+
+	struct RNG *rng;
 } BoidBrainData;
 
 void boids_precalc_rules(struct ParticleSettings *part, float cfra);

Modified: trunk/blender/source/blender/blenkernel/BKE_particle.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_particle.h	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/BKE_particle.h	2013-04-15 23:12:40 UTC (rev 56073)
@@ -61,6 +61,7 @@
 struct BVHTreeRay;
 struct BVHTreeRayHit; 
 struct EdgeHash;
+struct RNG;
 
 #define PARTICLE_P              ParticleData * pa; int p
 #define LOOP_PARTICLES  for (p = 0, pa = psys->particles; p < psys->totpart; p++, pa++)
@@ -82,6 +83,7 @@
 	struct ParticleSystem *psys;
 	struct ParticleSystemModifierData *psmd;
 	struct ListBase *colliders;
+	struct RNG *rng;
 	/* Courant number. This is used to implement an adaptive time step. Only the
 	 * maximum value per time step is important. Only sph_integrate makes use of
 	 * this at the moment. Other solvers could, too. */

Modified: trunk/blender/source/blender/blenkernel/intern/anim.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/anim.c	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/intern/anim.c	2013-04-15 23:12:40 UTC (rev 56073)
@@ -1263,6 +1263,7 @@
 	ChildParticle *cpa = NULL;
 	ParticleKey state;
 	ParticleCacheKey *cache;
+	RNG *rng = NULL;
 	float ctime, pa_time, scale = 1.0f;
 	float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
 	float (*obmat)[4], (*oldobmat)[4];
@@ -1293,14 +1294,9 @@
 	totpart = psys->totpart;
 	totchild = psys->totchild;
 
-	BLI_srandom(31415926 + psys->seed);
-
 	if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
 		ParticleSimulationData sim = {NULL};
-		sim.scene = scene;
-		sim.ob = par;
-		sim.psys = psys;
-		sim.psmd = psys_get_modifier(par, psys);
+
 		/* make sure emitter imat is in global coordinates instead of render view coordinates */
 		invert_m4_m4(par->imat, par->obmat);
 
@@ -1332,6 +1328,12 @@
 
 		psys_check_group_weights(part);
 
+		sim.scene = scene;
+		sim.ob = par;
+		sim.psys = psys;
+		sim.psmd = psys_get_modifier(par, psys);
+		sim.rng = BLI_rng_new(0);
+
 		psys->lattice = psys_get_lattice(&sim);
 
 		/* gather list of objects or single object */
@@ -1378,6 +1380,8 @@
 			obcopy = *ob;
 		}
 
+		rng = BLI_rng_new_srandom(31415926 + psys->seed);
+
 		if (totchild == 0 || part->draw & PART_DRAW_PARENT)
 			a = 0;
 		else
@@ -1417,7 +1421,7 @@
 
 				/* for groups, pick the object based on settings */
 				if (part->draw & PART_DRAW_RAND_GR)
-					b = BLI_rand() % totgroup;
+					b = BLI_rng_get_int(rng) % totgroup;
 				else
 					b = a % totgroup;
 
@@ -1561,6 +1565,8 @@
 		}
 		else
 			*ob = obcopy;
+
+		BLI_rng_free(sim.rng);
 	}
 
 	/* clean up */
@@ -1573,6 +1579,9 @@
 		end_latt_deform(psys->lattice);
 		psys->lattice = NULL;
 	}
+
+	if (rng)
+		BLI_rng_free(rng);
 }
 
 static Object *find_family_object(Object **obar, char *family, char ch)

Modified: trunk/blender/source/blender/blenkernel/intern/boids.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/boids.c	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/intern/boids.c	2013-04-15 23:12:40 UTC (rev 56073)
@@ -234,9 +234,9 @@
 			if (dot_v3v3(col.pce.nor, pa->prev_state.ave) < -0.99f) {
 				/* don't know why, but uneven range [0.0, 1.0] */
 				/* works much better than even [-1.0, 1.0] */
-				bbd->wanted_co[0] = BLI_frand();
-				bbd->wanted_co[1] = BLI_frand();
-				bbd->wanted_co[2] = BLI_frand();
+				bbd->wanted_co[0] = BLI_rng_get_float(bbd->rng);
+				bbd->wanted_co[1] = BLI_rng_get_float(bbd->rng);
+				bbd->wanted_co[2] = BLI_rng_get_float(bbd->rng);
 			}
 			else {
 				copy_v3_v3(bbd->wanted_co, col.pce.nor);
@@ -558,9 +558,9 @@
 
 	if (asbr->wander > 0.0f) {
 		/* abuse pa->r_ave for wandering */
-		bpa->wander[0] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
-		bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
-		bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_frand());
+		bpa->wander[0] += asbr->wander * (-1.0f + 2.0f * BLI_rng_get_float(bbd->rng));
+		bpa->wander[1] += asbr->wander * (-1.0f + 2.0f * BLI_rng_get_float(bbd->rng));
+		bpa->wander[2] += asbr->wander * (-1.0f + 2.0f * BLI_rng_get_float(bbd->rng));
 
 		normalize_v3(bpa->wander);
 
@@ -586,9 +586,9 @@
 
 		/* may happen at birth */
 		if (dot_v2v2(bbd->wanted_co, bbd->wanted_co)==0.0f) {
-			bbd->wanted_co[0] = 2.0f*(0.5f - BLI_frand());
-			bbd->wanted_co[1] = 2.0f*(0.5f - BLI_frand());
-			bbd->wanted_co[2] = 2.0f*(0.5f - BLI_frand());
+			bbd->wanted_co[0] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
+			bbd->wanted_co[1] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
+			bbd->wanted_co[2] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
 		}
 		
 		/* leveling */
@@ -663,7 +663,7 @@
 
 		/* attack if in range */
 		if (closest_dist <= bbd->part->boids->range + pa->size + enemy_pa->size) {
-			float damage = BLI_frand();
+			float damage = BLI_rng_get_float(bbd->rng);
 			float enemy_dir[3];
 
 			normalize_v3_v3(enemy_dir, bbd->wanted_co);
@@ -1164,9 +1164,9 @@
 			/* choose random direction to turn if wanted velocity */
 			/* is directly behind regardless of z-coordinate */
 			if (dot_v2v2(old_dir2, wanted_dir2) < -0.99f) {
-				wanted_dir[0] = 2.0f*(0.5f - BLI_frand());
-				wanted_dir[1] = 2.0f*(0.5f - BLI_frand());
-				wanted_dir[2] = 2.0f*(0.5f - BLI_frand());
+				wanted_dir[0] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
+				wanted_dir[1] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
+				wanted_dir[2] = 2.0f*(0.5f - BLI_rng_get_float(bbd->rng));
 				normalize_v3(wanted_dir);
 			}
 

Modified: trunk/blender/source/blender/blenkernel/intern/effect.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/effect.c	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/intern/effect.c	2013-04-15 23:12:40 UTC (rev 56073)
@@ -619,6 +619,7 @@
 			sim.scene= eff->scene;
 			sim.ob= eff->ob;
 			sim.psys= eff->psys;
+			sim.rng= NULL;
 
 			/* TODO: time from actual previous calculated frame (step might not be 1) */
 			state.time = cfra - 1.0f;

Modified: trunk/blender/source/blender/blenkernel/intern/ocean.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/ocean.c	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/intern/ocean.c	2013-04-15 23:12:40 UTC (rev 56073)
@@ -144,12 +144,12 @@
 
 
 
-static float nextfr(float min, float max)
+static float nextfr(RNG *rng, float min, float max)
 {
-	return BLI_frand() * (min - max) + max;
+	return BLI_rng_get_float(rng) * (min - max) + max;
 }
 
-static float gaussRand(void)
+static float gaussRand(RNG *rng)
 {
 	/* Note: to avoid numerical problems with very small numbers, we make these variables singe-precision floats,
 	 * but later we call the double-precision log() and sqrt() functions instead of logf() and sqrtf().
@@ -765,6 +765,7 @@
                     float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals,
                     short do_jacobian, int seed)
 {
+	RNG *rng;
 	int i, j, ii;
 
 	BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE);
@@ -825,12 +826,12 @@
 			o->_k[i * (1 + o->_N / 2) + j] = sqrt(o->_kx[i] * o->_kx[i] + o->_kz[j] * o->_kz[j]);
 
 	/*srand(seed);*/
-	BLI_srand(seed);
+	rng = BLI_rng_new(seed);
 
 	for (i = 0; i < o->_M; ++i) {
 		for (j = 0; j < o->_N; ++j) {
-			float r1 = gaussRand();
-			float r2 = gaussRand();
+			float r1 = gaussRand(rng);
+			float r2 = gaussRand(rng);
 
 			fftw_complex r1r2;
 			init_complex(r1r2, r1, r2);
@@ -890,6 +891,7 @@
 
 	set_height_normalize_factor(o);
 
+	BLI_rng_free(rng);
 }
 
 void BKE_free_ocean_data(struct Ocean *oc)
@@ -1188,13 +1190,14 @@
 	int res_x = och->resolution_x;
 	int res_y = och->resolution_y;
 	char string[FILE_MAX];
+	//RNG *rng;
 
 	if (!o) return;
 
 	if (o->_do_jacobian) prev_foam = MEM_callocN(res_x * res_y * sizeof(float), "previous frame foam bake data");
 	else prev_foam = NULL;
 
-	BLI_srand(0);
+	//rng = BLI_rng_new(0);
 
 	/* setup image format */
 	imf.imtype = R_IMF_IMTYPE_OPENEXR;
@@ -1232,7 +1235,7 @@
 						pr = prev_foam[res_x * y + x];
 					}
 
-					/* r = BLI_frand(); */ /* UNUSED */ /* randomly reduce foam */
+					/* r = BLI_rng_get_float(rng); */ /* UNUSED */ /* randomly reduce foam */
 
 					/* pr = pr * och->foam_fade; */		/* overall fade */
 
@@ -1311,10 +1314,12 @@
 
 		if (cancel) {
 			if (prev_foam) MEM_freeN(prev_foam);
+			//BLI_rng_free(rng);
 			return;
 		}
 	}
 
+	//BLI_rng_free(rng);
 	if (prev_foam) MEM_freeN(prev_foam);
 	och->baked = 1;
 }

Modified: trunk/blender/source/blender/blenkernel/intern/particle.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/particle.c	2013-04-15 21:38:31 UTC (rev 56072)
+++ trunk/blender/source/blender/blenkernel/intern/particle.c	2013-04-15 23:12:40 UTC (rev 56073)
@@ -264,11 +264,12 @@
 {
 	int i;
 	float *rand = psys->frand = MEM_callocN(PSYS_FRAND_COUNT * sizeof(float), "particle randoms");
+	RNG *rng = BLI_rng_new_srandom(psys->seed);
 
-	BLI_srandom(psys->seed);
+	for (i = 0; i < 1024; i++, rand++)
+		*rand = BLI_rng_get_float(rng);
 
-	for (i = 0; i < 1024; i++, rand++)
-		*rand = BLI_frand();
+	BLI_rng_free(rng);
 }
 int psys_check_enabled(Object *ob, ParticleSystem *psys)
 {
@@ -3302,8 +3303,11 @@
 		sim.ob = ob;
 		sim.psys = psys;
 		sim.psmd = psys_get_modifier(ob, psys);
+		sim.rng = BLI_rng_new(0);
 
 		psys_cache_child_paths(&sim, cfra, 1);
+
+		BLI_rng_free(sim.rng);
 	}
 
 	/* clear recalc flag if set here */

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list