diff options
author | Bastien Montagne <bastien@blender.org> | 2020-12-11 20:12:29 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2020-12-11 20:46:21 +0300 |
commit | 561d9169fea7141b09100c563bc20560c760edd1 (patch) | |
tree | a611dd4d179b14ee832be0bb573e2248c2347a8f | |
parent | 85cb2388207386f14eea5f261c3e1c6f61f84012 (diff) |
Fix T83280: Crash when deleting hair collision collection.
Root of the issue was missing management of ID pointers in the cloth
modifier data stored in ParticleSystem for hair physics, in the
'foreach_id' particle system code.
Using modifier's 'foreach_id' code in psys one unfortunately requires
some ugly conversion gymnastics, but this is still better than having
dedicated code for that case.
Note that this is actually a fairly critical issue, fix should be
backported to 2.91.1 should we do it, and to 2.83 LTS as well I think.
-rw-r--r-- | source/blender/blenkernel/intern/particle_system.c | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 35265cf8b68..79ce6769160 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -4978,6 +4978,24 @@ void particle_system_update(struct Depsgraph *depsgraph, /* ID looper */ +/* unfortunately PSys and modifier ID loopers are not directly compatible, so we need this struct + * and the callback below to map the former to the latter (thanks to psys embedding a Cloth + * modifier data struct now, for Hair physics simulations). */ +typedef struct ParticleSystemIDLoopForModifier { + ParticleSystem *psys; + ParticleSystemIDFunc func; + void *userdata; +} ParticleSystemIDLoopForModifier; + +static void particlesystem_modifiersForeachIDLink(void *user_data, + Object *UNUSED(object), + ID **id_pointer, + int cb_flag) +{ + ParticleSystemIDLoopForModifier *data = (ParticleSystemIDLoopForModifier *)user_data; + data->func(data->psys, id_pointer, data->userdata, cb_flag); +} + void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func, void *userdata) { ParticleTarget *pt; @@ -4986,6 +5004,16 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func, func(psys, (ID **)&psys->target_ob, userdata, IDWALK_CB_NOP); func(psys, (ID **)&psys->parent, userdata, IDWALK_CB_NOP); + if (psys->clmd != NULL) { + const ModifierTypeInfo *mti = BKE_modifier_get_info(psys->clmd->modifier.type); + + if (mti->foreachIDLink != NULL) { + ParticleSystemIDLoopForModifier data = {.psys = psys, .func = func, .userdata = userdata}; + mti->foreachIDLink( + &psys->clmd->modifier, NULL, particlesystem_modifiersForeachIDLink, &data); + } + } + for (pt = psys->targets.first; pt; pt = pt->next) { func(psys, (ID **)&pt->ob, userdata, IDWALK_CB_NOP); } |