[Bf-blender-cvs] [30c9fe1] master: Fix for crash caused by effectors doing precalculation //during// DAG updates.

Lukas Tönne noreply at git.blender.org
Fri Feb 14 13:03:37 CET 2014


Commit: 30c9fe19a31f6f92be4de2abacb9fd96179a9a04
Author: Lukas Tönne
Date:   Fri Feb 14 12:54:42 2014 +0100
https://developer.blender.org/rB30c9fe19a31f6f92be4de2abacb9fd96179a9a04

Fix for crash caused by effectors doing precalculation //during// DAG
updates.

This file crashes on loading with NULL pointer access to curve_cache:
{F77132}

The pdInitEffectors function was amalgamating the simple
collection of effector objects with an automatic precalculation for
curve guides and the like. This precalculation requires object data
that may not be available until the DAG has finished.

Since for DAG dependencies only the list of effectors is required,
added an argument to disable precalculation when collecting effectors.

===================================================================

M	source/blender/blenkernel/BKE_effect.h
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/depsgraph.c
M	source/blender/blenkernel/intern/dynamicpaint.c
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/particle_system.c
M	source/blender/blenkernel/intern/rigidbody.c
M	source/blender/blenkernel/intern/smoke.c
M	source/blender/blenkernel/intern/softbody.c

===================================================================

diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 562a67f..d5e54d8 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -110,8 +110,9 @@ typedef struct EffectorCache {
 } EffectorCache;
 
 void            free_partdeflect(struct PartDeflect *pd);
-struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights);
+struct ListBase *pdInitEffectors(struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src, struct EffectorWeights *weights, bool precalc);
 void            pdEndEffectors(struct ListBase **effectors);
+void            pdPrecalculateEffectors(struct ListBase *effectors);
 void            pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
 
 void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index acafa76..3ab522a 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -376,7 +376,7 @@ static int do_step_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
 		mul_m4_v3(ob->obmat, verts->xconst);
 	}
 
-	effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights);
+	effectors = pdInitEffectors(clmd->scene, ob, NULL, clmd->sim_parms->effector_weights, true);
 
 	/* Support for dynamic vertex groups, changing from frame to frame */
 	cloth_apply_vgroup ( clmd, result );
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index af84055..fdeefad 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -761,7 +761,7 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O
 				}
 			}
 
-			effectors = pdInitEffectors(scene, ob, psys, part->effector_weights);
+			effectors = pdInitEffectors(scene, ob, psys, part->effector_weights, false);
 
 			if (effectors) {
 				for (eff = effectors->first; eff; eff = eff->next) {
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 817b81a..997876d 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -4225,7 +4225,7 @@ static int dynamicPaint_prepareEffectStep(DynamicPaintSurface *surface, Scene *s
 	/* Init force data if required */
 	if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
 		float vel[3] = {0};
-		ListBase *effectors = pdInitEffectors(scene, ob, NULL, surface->effector_weights);
+		ListBase *effectors = pdInitEffectors(scene, ob, NULL, surface->effector_weights, true);
 
 		/* allocate memory for force data (dir vector + strength) */
 		*force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces");
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index a8124c0..fc18a20 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -166,45 +166,6 @@ void free_partdeflect(PartDeflect *pd)
 	MEM_freeN(pd);
 }
 
-static void precalculate_effector(EffectorCache *eff)
-{
-	unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
-	if (!eff->pd->rng)
-		eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
-	else
-		BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
-
-	if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) {
-		Curve *cu= eff->ob->data;
-		if (cu->flag & CU_PATH) {
-			if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL)
-				BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
-
-			if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) {
-				where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
-				mul_m4_v3(eff->ob->obmat, eff->guide_loc);
-				mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
-			}
-		}
-	}
-	else if (eff->pd->shape == PFIELD_SHAPE_SURFACE) {
-		eff->surmd = (SurfaceModifierData *)modifiers_findByType( eff->ob, eModifierType_Surface );
-		if (eff->ob->type == OB_CURVE)
-			eff->flag |= PE_USE_NORMAL_DATA;
-	}
-	else if (eff->psys)
-		psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
-
-	/* Store object velocity */
-	if (eff->ob) {
-		float old_vel[3];
-
-		BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f);
-		copy_v3_v3(old_vel, eff->ob->obmat[3]);
-		BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra);
-		sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
-	}
-}
 static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
 {
 	EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
@@ -213,9 +174,6 @@ static EffectorCache *new_effector_cache(Scene *scene, Object *ob, ParticleSyste
 	eff->psys = psys;
 	eff->pd = pd;
 	eff->frame = -1;
-
-	precalculate_effector(eff);
-
 	return eff;
 }
 static void add_object_to_effectors(ListBase **effectors, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src)
@@ -264,7 +222,8 @@ static void add_particles_to_effectors(ListBase **effectors, Scene *scene, Effec
 }
 
 /* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src, EffectorWeights *weights)
+ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src,
+                          EffectorWeights *weights, bool precalc)
 {
 	Base *base;
 	unsigned int layer= ob_src->lay;
@@ -302,6 +261,10 @@ ListBase *pdInitEffectors(Scene *scene, Object *ob_src, ParticleSystem *psys_src
 			}
 		}
 	}
+	
+	if (precalc)
+		pdPrecalculateEffectors(effectors);
+	
 	return effectors;
 }
 
@@ -321,6 +284,55 @@ void pdEndEffectors(ListBase **effectors)
 	}
 }
 
+static void precalculate_effector(EffectorCache *eff)
+{
+	unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
+	if (!eff->pd->rng)
+		eff->pd->rng = BLI_rng_new(eff->pd->seed + cfra);
+	else
+		BLI_rng_srandom(eff->pd->rng, eff->pd->seed + cfra);
+
+	if (eff->pd->forcefield == PFIELD_GUIDE && eff->ob->type==OB_CURVE) {
+		Curve *cu= eff->ob->data;
+		if (cu->flag & CU_PATH) {
+			if (eff->ob->curve_cache == NULL || eff->ob->curve_cache->path==NULL || eff->ob->curve_cache->path->data==NULL)
+				BKE_displist_make_curveTypes(eff->scene, eff->ob, 0);
+
+			if (eff->ob->curve_cache->path && eff->ob->curve_cache->path->data) {
+				where_on_path(eff->ob, 0.0, eff->guide_loc, eff->guide_dir, NULL, &eff->guide_radius, NULL);
+				mul_m4_v3(eff->ob->obmat, eff->guide_loc);
+				mul_mat3_m4_v3(eff->ob->obmat, eff->guide_dir);
+			}
+		}
+	}
+	else if (eff->pd->shape == PFIELD_SHAPE_SURFACE) {
+		eff->surmd = (SurfaceModifierData *)modifiers_findByType( eff->ob, eModifierType_Surface );
+		if (eff->ob->type == OB_CURVE)
+			eff->flag |= PE_USE_NORMAL_DATA;
+	}
+	else if (eff->psys)
+		psys_update_particle_tree(eff->psys, eff->scene->r.cfra);
+
+	/* Store object velocity */
+	if (eff->ob) {
+		float old_vel[3];
+
+		BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra - 1.0f);
+		copy_v3_v3(old_vel, eff->ob->obmat[3]);
+		BKE_object_where_is_calc_time(eff->scene, eff->ob, cfra);
+		sub_v3_v3v3(eff->velocity, eff->ob->obmat[3], old_vel);
+	}
+}
+
+void pdPrecalculateEffectors(ListBase *effectors)
+{
+	if (effectors) {
+		EffectorCache *eff = effectors->first;
+		for (; eff; eff=eff->next)
+			precalculate_effector(eff);
+	}
+}
+
 
 void pd_point_from_particle(ParticleSimulationData *sim, ParticleData *pa, ParticleKey *state, EffectedPoint *point)
 {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 71b9134..4eaa261 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -2264,7 +2264,8 @@ void psys_update_particle_tree(ParticleSystem *psys, float cfra)
 static void psys_update_effectors(ParticleSimulationData *sim)
 {
 	pdEndEffectors(&sim->psys->effectors);
-	sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys, sim->psys->part->effector_weights);
+	sim->psys->effectors = pdInitEffectors(sim->scene, sim->ob, sim->psys,
+	                                       sim->psys->part->effector_weights, true);
 	precalc_guides(sim, sim->psys->effectors);
 }
 
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 216620c..4b4cb05 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -1066,7 +1066,7 @@ static void rigidbody_update_sim_ob(Scene *scene, RigidBodyWorld *rbw, Object *o
 		ListBase *effectors;
 
 		/* get effectors present in the group specified by effector_weights */
-		effectors = pdInitEffectors(scene, ob, NULL, effector_weights);
+		effectors = pdInitEffectors(scene, ob, NULL, effector_weights, true);
 		if (effectors) {
 			float eff_force[3] = {0.0f, 0.0f, 0.0f};
 			float eff_loc[3], eff_vel[3];
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 6aaf2ee..61d9ea9 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -2363,7 +2363,7 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds,
 	ListBase *effectors;
 	/* make sure smoke flow influence is 0.0f */
 	sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f;
-	effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights);
+	effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights, true);
 
 	if (effectors)
 	{
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenke

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list