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.
This commit is contained in:
Bastien Montagne 2020-12-11 18:12:29 +01:00
parent 85cb238820
commit 561d9169fe
Notes: blender-bot 2023-02-14 03:52:45 +01:00
Referenced by issue #83280, Crash when deleting hair collision collection
Referenced by issue #83216, Potential candidates for corrective releases
Referenced by issue #77348, Blender LTS: Maintenance Task 2.83
1 changed files with 28 additions and 0 deletions

View File

@ -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);
}