[Bf-blender-cvs] [cc4dc2dce26] blender2.8: Depsgraph: cache effector relations, for performance and stability.

Brecht Van Lommel noreply at git.blender.org
Fri Jun 22 17:59:59 CEST 2018


Commit: cc4dc2dce26c724e27598e4a1878e00fdf30dcf2
Author: Brecht Van Lommel
Date:   Thu Jun 21 19:45:39 2018 +0200
Branches: blender2.8
https://developer.blender.org/rBcc4dc2dce26c724e27598e4a1878e00fdf30dcf2

Depsgraph: cache effector relations, for performance and stability.

To find all effectors in the scene, we need to loop over all objects.
Doing this during depsgraph evaluation caused crashes because not all
objects are guaranteed to be evaluated yet.

To fix this, we now cache the relations as part of the dependency graph
build. As a bonus this also makes evaluation faster for big scenes,
since looping over all objects for each particle system is slow.

Fixes T55156.

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

M	source/blender/blenkernel/BKE_effect.h
M	source/blender/blenkernel/intern/boids.c
M	source/blender/blenkernel/intern/cloth.c
M	source/blender/blenkernel/intern/dynamicpaint.c
M	source/blender/blenkernel/intern/effect.c
M	source/blender/blenkernel/intern/particle.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
M	source/blender/depsgraph/CMakeLists.txt
A	source/blender/depsgraph/DEG_depsgraph_physics.h
M	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
M	source/blender/depsgraph/intern/depsgraph.cc
M	source/blender/depsgraph/intern/depsgraph.h
M	source/blender/depsgraph/intern/depsgraph_build.cc
M	source/blender/depsgraph/intern/depsgraph_intern.h
A	source/blender/depsgraph/intern/depsgraph_physics.cc
M	source/blender/physics/intern/BPH_mass_spring.cpp

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

diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 379ab3e81b5..a0af34d59e6 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -45,6 +45,7 @@ struct ParticleSimulationData;
 struct ParticleData;
 struct ParticleKey;
 struct Depsgraph;
+struct ViewLayer;
 
 struct EffectorWeights *BKE_add_effector_weights(struct Collection *collection);
 struct PartDeflect *object_add_collision_fields(int type);
@@ -111,13 +112,36 @@ typedef struct EffectorCache {
 	int flag;
 } EffectorCache;
 
-void            free_partdeflect(struct PartDeflect *pd);
-struct ListBase *pdInitEffectors(
-        struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src,
-        struct EffectorWeights *weights, bool for_simulation);
-void            pdEndEffectors(struct ListBase **effectors);
-void            pdPrecalculateEffectors(struct Depsgraph *depsgraph, struct ListBase *effectors);
-void            pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
+typedef struct EffectorRelation {
+	struct EffectorRelation *next, *prev;
+
+	struct Object *ob;
+	struct ParticleSystem *psys;
+	struct PartDeflect *pd;
+} EffectorRelation;
+
+void free_partdeflect(struct PartDeflect *pd);
+
+struct ListBase *BKE_effector_relations_create(
+        struct Depsgraph *depsgraph,
+        struct ViewLayer *view_layer,
+        struct Collection *collection);
+void BKE_effector_relations_free(struct ListBase *lb);
+
+struct ListBase *BKE_effectors_create(
+        struct Depsgraph *depsgraph,
+        struct Scene *scene,
+        struct Object *ob_src,
+        struct ParticleSystem *psys_src,
+        struct EffectorWeights *weights);
+void BKE_effectors_apply(
+        struct ListBase *effectors,
+        struct ListBase *colliders,
+        struct EffectorWeights *weights,
+        struct EffectedPoint *point,
+        float *force,
+        float *impulse);
+void BKE_effectors_free(struct ListBase *lb);
 
 void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
 void pd_point_from_loc(struct Scene *scene, float *loc, float *vel, int index, struct EffectedPoint *point);
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index 8fdaf183b06..f47d09d7dc2 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -1265,7 +1265,7 @@ void boid_body(BoidBrainData *bbd, ParticleData *pa)
 
 	/* account for effectors */
 	pd_point_from_particle(bbd->sim, pa, &pa->state, &epoint);
-	pdDoEffectors(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
+	BKE_effectors_apply(bbd->sim->psys->effectors, bbd->sim->colliders, bbd->part->effector_weights, &epoint, force, NULL);
 
 	if (ELEM(bpa->data.mode, eBoidMode_OnLand, eBoidMode_Climbing)) {
 		float length = normalize_v3(force);
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index f8ea7e8b1d1..bfe59e5366d 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -375,7 +375,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Scene *scene, Object *ob,
 		mul_m4_v3(ob->obmat, verts->xconst);
 	}
 
-	effectors = pdInitEffectors(depsgraph, scene, ob, NULL, clmd->sim_parms->effector_weights, true);
+	effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, clmd->sim_parms->effector_weights);
 
 	if (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_DYNAMIC_BASEMESH )
 		cloth_update_verts ( ob, clmd, result );
@@ -395,7 +395,7 @@ static int do_step_cloth(struct Depsgraph *depsgraph, Scene *scene, Object *ob,
 
 	// TIMEIT_END(cloth_step)
 
-	pdEndEffectors(&effectors);
+	BKE_effectors_free(effectors);
 
 	// printf ( "%f\n", ( float ) tval() );
 
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 2b3ef91678f..173dc8050a1 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -4886,7 +4886,7 @@ static void dynamic_paint_prepare_effect_cb(
 		EffectedPoint epoint;
 		pd_point_from_loc(scene, realCoord[bData->s_pos[index]].v, vel, index, &epoint);
 		epoint.vel_to_sec = 1.0f;
-		pdDoEffectors(effectors, NULL, surface->effector_weights, &epoint, forc, NULL);
+		BKE_effectors_apply(effectors, NULL, surface->effector_weights, &epoint, forc, NULL);
 	}
 
 	/* if global gravity is enabled, add it too */
@@ -4926,7 +4926,7 @@ static int dynamicPaint_prepareEffectStep(
 
 	/* Init force data if required */
 	if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
-		ListBase *effectors = pdInitEffectors(depsgraph, scene, ob, NULL, surface->effector_weights, true);
+		ListBase *effectors = BKE_effectors_create(depsgraph, scene, ob, NULL, surface->effector_weights);
 
 		/* allocate memory for force data (dir vector + strength) */
 		*force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces");
@@ -4950,7 +4950,7 @@ static int dynamicPaint_prepareEffectStep(
 			}
 			average_force /= sData->total_points;
 		}
-		pdEndEffectors(&effectors);
+		BKE_effectors_free(effectors);
 	}
 
 	/* Get number of required steps using average point distance
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index c155fbc1d97..adf5b5da35e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -74,6 +74,7 @@
 #include "BKE_smoke.h"
 
 #include "DEG_depsgraph.h"
+#include "DEG_depsgraph_physics.h"
 #include "DEG_depsgraph_query.h"
 
 #include "RE_render_ext.h"
@@ -135,9 +136,8 @@ PartDeflect *object_add_collision_fields(int type)
 	return pd;
 }
 
-/* ***************** PARTICLES ***************** */
+/************************ PARTICLES ***************************/
 
-/* -------------------------- Effectors ------------------ */
 void free_partdeflect(PartDeflect *pd)
 {
 	if (!pd)
@@ -149,114 +149,7 @@ void free_partdeflect(PartDeflect *pd)
 	MEM_freeN(pd);
 }
 
-static EffectorCache *new_effector_cache(struct Depsgraph *depsgraph, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
-{
-	EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
-	eff->depsgraph = depsgraph;
-	eff->scene = scene;
-	eff->ob = ob;
-	eff->psys = psys;
-	eff->pd = pd;
-	eff->frame = -1;
-	return eff;
-}
-static void add_object_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
-{
-	EffectorCache *eff = NULL;
-
-	if ( ob == ob_src )
-		return;
-
-	if (for_simulation) {
-		if (weights->weight[ob->pd->forcefield] == 0.0f )
-			return;
-
-		if (ob->pd->shape == PFIELD_SHAPE_POINTS && !ob->derivedFinal )
-			return;
-	}
-
-	if (*effectors == NULL)
-		*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
-	eff = new_effector_cache(depsgraph, scene, ob, NULL, ob->pd);
-
-	/* make sure imat is up to date */
-	invert_m4_m4(ob->imat, ob->obmat);
-
-	BLI_addtail(*effectors, eff);
-}
-static void add_particles_to_effectors(ListBase **effectors, struct Depsgraph *depsgraph, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
-{
-	ParticleSettings *part= psys->part;
-	const bool for_render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
-
-	if ( !psys_check_enabled(ob, psys, for_render) )
-		return;
-
-	if ( psys == psys_src && (part->flag & PART_SELF_EFFECT) == 0)
-		return;
-
-	if ( part->pd && part->pd->forcefield && (!for_simulation || weights->weight[part->pd->forcefield] != 0.0f)) {
-		if (*effectors == NULL)
-			*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
-		BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd));
-	}
-
-	if (part->pd2 && part->pd2->forcefield && (!for_simulation || weights->weight[part->pd2->forcefield] != 0.0f)) {
-		if (*effectors == NULL)
-			*effectors = MEM_callocN(sizeof(ListBase), "effectors list");
-
-		BLI_addtail(*effectors, new_effector_cache(depsgraph, scene, ob, psys, part->pd2));
-	}
-}
-
-/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(
-        struct Depsgraph *depsgraph, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
-        EffectorWeights *weights, bool for_simulation)
-{
-	/* For dependency building, we get objects from the scene.
-	 * For simulation, we get objects from the depsgraph. */
-	Base *base = BKE_collection_or_layer_objects((for_simulation) ? depsgraph : NULL, scene, NULL, weights->group);
-	ListBase *effectors = NULL;
-
-	for (; base; base = base->next) {
-		if (base->object->pd && base->object->pd->forcefield) {
-			add_object_to_effectors(&effectors, depsgraph, scene, weights, base->object, ob_src, for_simulation);
-		}
-
-		if (base->object->particlesystem.first) {
-			ParticleSystem *psys= base->object->particlesystem.first;
-
-			for (; psys; psys=psys->next) {
-				add_particles_to_effectors(&effectors, depsgraph, scene, weights, base->object, psys, psys_src, for_simulation);
-			}
-		}
-	}
-
-	if (for_simulation) {
-		pdPrecalculateEffectors(depsgraph, effectors);
-	}
-
-	return effectors;
-}
-
-void pdEndEffectors(ListBase **effectors)
-{
-	if (*effectors) {
-		EffectorCache *eff = (*effectors)->first;
-
-		for (; eff; eff=eff->next) {
-			if (eff->guide_data)
-				MEM_freeN(eff->guide_data);
-		}
-
-		BLI_freelistN(*effectors);
-		MEM_freeN(*effectors);
-		*effectors = NULL;
-	}
-}
+/******************** EFFECTOR RELATIONS ***********************/
 
 static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *eff)
 {
@@ -299,12 +192,144 @@ static void precalculate_effector(struct Depsgraph *depsgraph, EffectorCache *ef
 	}
 }
 
-void pdPrecalculateEffectors(struct Depsgraph *depsgraph, ListBase *effectors)
+stat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list