Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2014-02-14 15:54:42 +0400
committerLukas Tönne <lukas.toenne@gmail.com>2014-02-14 15:58:43 +0400
commit30c9fe19a31f6f92be4de2abacb9fd96179a9a04 (patch)
tree98334e36b5bc88b731eafa463055bad8768d46d3 /source/blender/blenkernel/intern
parent32b45cb4a7adeae637e02c3a8da87e28844e587f (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/cloth.c2
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c2
-rw-r--r--source/blender/blenkernel/intern/effect.c98
-rw-r--r--source/blender/blenkernel/intern/particle_system.c3
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c2
-rw-r--r--source/blender/blenkernel/intern/smoke.c2
-rw-r--r--source/blender/blenkernel/intern/softbody.c8
8 files changed, 66 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index acafa762853..3ab522ac24b 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 af84055fb50..fdeefad795b 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 817b81a6db3..997876dcd58 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 a8124c0f9c0..fc18a204526 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 71b91340721..4eaa2618e26 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 216620c351d..4b4cb054337 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 6aaf2ee4df0..61d9ea99c2f 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/blenkernel/intern/softbody.c
index 4e2f708eae4..fb5fc97fd46 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1642,7 +1642,7 @@ static void scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow)
SoftBody *sb = ob->soft;
ListBase *do_effector = NULL;
- do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights);
+ do_effector = pdInitEffectors(scene, ob, NULL, sb->effector_weights, true);
_scan_for_ext_spring_forces(scene, ob, timenow, 0, sb->totspring, do_effector);
pdEndEffectors(&do_effector);
}
@@ -1662,7 +1662,7 @@ static void sb_sfesf_threads_run(Scene *scene, struct Object *ob, float timenow,
int i, totthread, left, dec;
int lowsprings =100; /* wild guess .. may increase with better thread management 'above' or even be UI option sb->spawn_cf_threads_nopts */
- do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
+ do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true);
/* figure the number of threads while preventing pretty pointless threading overhead */
totthread= BKE_scene_num_threads(scene);
@@ -2468,7 +2468,7 @@ static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, fl
sb_sfesf_threads_run(scene, ob, timenow, sb->totspring, NULL);
/* after spring scan because it uses Effoctors too */
- do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights);
+ do_effector= pdInitEffectors(scene, ob, NULL, sb->effector_weights, true);
if (do_deflector) {
float defforce[3];
@@ -2543,7 +2543,7 @@ static void softbody_calc_forces(Scene *scene, Object *ob, float forcetime, floa
if (do_springcollision || do_aero) scan_for_ext_spring_forces(scene, ob, timenow);
/* after spring scan because it uses Effoctors too */
- do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights);
+ do_effector= pdInitEffectors(scene, ob, NULL, ob->soft->effector_weights, true);
if (do_deflector) {
float defforce[3];