diff options
author | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-10-17 13:49:32 +0400 |
---|---|---|
committer | Lukas Toenne <lukas.toenne@googlemail.com> | 2012-10-17 13:49:32 +0400 |
commit | 7061fa7cf1f1aa3f15ce2784c2ec39d561205dad (patch) | |
tree | e1914f836eb6e4aa7e38a0ff55ea11e2ffc77f90 /source/blender/modifiers/intern/MOD_particleinstance.c | |
parent | 536d9fec80dad342ef28f2fc8a0c5b4e5de98d31 (diff) |
Fix #32887, ParticleInstance: crash with hidden particle system + children.
The issue here is that the particle instance modifier (pimd) accesses data from the linked particle system modifier (psmd). This data is only correctly generated when the psmd is enabled; here the design violates the modifier principle of providing valid object data (or rather DM) even when disabled.
The solution in this case is to make a custom isDisabled check for the pimd to see if the psmd is enabled. This means the pimd won't work for disabled psmd, but doesn't crash.
Diffstat (limited to 'source/blender/modifiers/intern/MOD_particleinstance.c')
-rw-r--r-- | source/blender/modifiers/intern/MOD_particleinstance.c | 40 |
1 files changed, 39 insertions, 1 deletions
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e64e80efde3..20b02c63605 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -81,6 +81,44 @@ static int dependsOnTime(ModifierData *UNUSED(md)) { return 0; } + +static int isDisabled(ModifierData *md, int useRenderParams) +{ + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + ParticleSystem *psys; + ModifierData *ob_md; + + if (!pimd->ob) + return TRUE; + + psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); + if (psys == NULL) + return TRUE; + + /* If the psys modifier is disabled we cannot use its data. + * First look up the psys modifier from the object, then check if it is enabled. + */ + for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { + if (ob_md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; + if (psmd->psys == psys) { + int required_mode; + + if (useRenderParams) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + + if (!modifier_isEnabled(md->scene, ob_md, required_mode)) + return TRUE; + + break; + } + } + } + + return FALSE; +} + + static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), Object *UNUSED(ob), @@ -384,7 +422,7 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* initData */ initData, /* requiredDataMask */ NULL, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepgraph */ updateDepgraph, /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, |