diff options
author | Bastien Montagne <bastien@blender.org> | 2021-01-19 18:02:25 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2021-01-19 20:50:32 +0300 |
commit | bc95c249a76563bffd8ce9242f7de6849cebe801 (patch) | |
tree | 0554bfb9393d7fc230e9d80460cd9fb3dff5fa0d /source/blender/editors | |
parent | bcdba7c34da05b1ab54f7ba2494fc8b93e0d3d6c (diff) |
Refactor modifier copying code.
Things like pointers to particle systems, or softbody data being stored
outside of its modifier, make it impossible for internal modifier copy
data code to be self-contained currently. It requires extra processing.
In existing code this was handled in several different places, in
several ways, and alltogether fairly inconsistently. Some cases were
even not properly handled, causing e.g. crashes as in T82945.
This commit addresses those issues by:
* Adding comments about the hackish/unsafe parts `psys` implies when
copying some modifier data (since we need to ensure particle system
copying and remapping of those pointers separately).
* Adding as-best-as-possible handling of those cases to
`BKE_object_copy_modifier` (note that it remains fragile, but is
expected to behave 'good enough' in any practical usecase).
* Remove special handling for specific editor code
(`copy_or_reuse_particle_system`). This should never have been
accepted in ED code area, and is now handled by
`BKE_object_copy_modifier`.
* Factorize copying of the whole modifier stack into new
`BKE_object_modifier_stack_copy`, now used by both `object_copy_data`
and `BKE_object_link_modifiers`.
Note that this implies that `BKE_object_copy_modifier` and
`BKE_object_copy_gpencil_modifier` are now to be used exclusively to
copy single modifiers. Full modifier stack copy should always use
`BKE_object_modifier_stack_copy` instead.
Fix T82945: Crash when dragging modifiers in Outliner.
Maniphest Tasks: T82945
Differential Revision: https://developer.blender.org/D10148
Diffstat (limited to 'source/blender/editors')
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 92 |
1 files changed, 7 insertions, 85 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index 3b0972a93ee..6350ffb9c77 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -535,7 +535,7 @@ void ED_object_modifier_copy_to_object(bContext *C, Object *ob_src, ModifierData *md) { - BKE_object_copy_modifier(ob_dst, ob_src, md); + BKE_object_copy_modifier(CTX_data_main(C), CTX_data_scene(C), ob_dst, ob_src, md); WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob_dst); DEG_id_tag_update(&ob_dst->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); @@ -1684,74 +1684,6 @@ void OBJECT_OT_modifier_set_active(wmOperatorType *ot) /** \name Copy Modifier To Selected Operator * \{ */ -/* If the modifier uses particles, copy particle system to destination object - * or reuse existing if it has the same ParticleSettings */ -static void copy_or_reuse_particle_system(bContext *C, Object *ob, ModifierData *md) -{ - ParticleSystem *psys_on_modifier = NULL; - - if (md->type == eModifierType_DynamicPaint) { - DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)md; - if (pmd->brush && pmd->brush->psys) { - psys_on_modifier = pmd->brush->psys; - } - } - else if (md->type == eModifierType_Fluid) { - FluidModifierData *fmd = (FluidModifierData *)md; - if (fmd->type == MOD_FLUID_TYPE_FLOW) { - if (fmd->flow && fmd->flow->psys) { - psys_on_modifier = fmd->flow->psys; - } - } - } - - if (!psys_on_modifier) { - return; - } - - ParticleSystem *psys_on_new_modifier = NULL; - - /* Check if a particle system with the same particle settings - * already exists on the destination object. */ - LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { - if (psys_on_modifier->part == psys->part) { - psys_on_new_modifier = psys; - break; - } - } - - /* If it does not exist, copy the particle system to the destination object. */ - if (!psys_on_new_modifier) { - Main *bmain = CTX_data_main(C); - Scene *scene = CTX_data_scene(C); - object_copy_particle_system(bmain, scene, ob, psys_on_modifier); - - LISTBASE_FOREACH (ParticleSystem *, psys, &ob->particlesystem) { - if (psys_on_modifier->part == psys->part) { - psys_on_new_modifier = psys; - } - } - } - - /* Update the modifier to point to the new/existing particle system. */ - LISTBASE_FOREACH (ModifierData *, new_md, &ob->modifiers) { - if (new_md->type == eModifierType_DynamicPaint) { - DynamicPaintModifierData *new_pmd = (DynamicPaintModifierData *)new_md; - - if (psys_on_modifier == new_pmd->brush->psys) { - new_pmd->brush->psys = psys_on_new_modifier; - } - } - else if (new_md->type == eModifierType_Fluid) { - FluidModifierData *new_fmd = (FluidModifierData *)new_md; - - if (psys_on_modifier == new_fmd->flow->psys) { - new_fmd->flow->psys = psys_on_new_modifier; - } - } - } -} - static int modifier_copy_to_selected_exec(bContext *C, wmOperator *op) { Main *bmain = CTX_data_main(C); @@ -1791,22 +1723,12 @@ static int modifier_copy_to_selected_exec(bContext *C, wmOperator *op) } } - if (md->type == eModifierType_ParticleSystem) { - ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md; - object_copy_particle_system(bmain, scene, ob, psmd->psys); - } - else { - if (!BKE_object_copy_modifier(ob, obact, md)) { - BKE_reportf(op->reports, - RPT_ERROR, - "Copying modifier '%s' to object '%s' failed", - md->name, - ob->id.name + 2); - } - } - - if (ELEM(md->type, eModifierType_DynamicPaint, eModifierType_Fluid)) { - copy_or_reuse_particle_system(C, ob, md); + if (!BKE_object_copy_modifier(bmain, scene, ob, obact, md)) { + BKE_reportf(op->reports, + RPT_ERROR, + "Copying modifier '%s' to object '%s' failed", + md->name, + ob->id.name + 2); } num_copied++; |