diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2018-12-05 20:22:18 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2018-12-05 22:54:02 +0300 |
commit | 71e2efc4ce6b760fe35edaf451e9cc803bc7c1a4 (patch) | |
tree | 2b3b2cbb31d73ca665be7f0345098dd37bc23e4b | |
parent | c0baa648dc58ca57a264be832beafc3bcb1e63da (diff) |
Fix T58210, part I: Surface Deform modifier (un)binding is broken.
Binding and unbinding *has* to happen outside of 'normal' depsgraph
evaluation of modifiers now that we have CoW, otherwise persistent data
stored in modifier data are always lost!
Note that this is only first step of the fix, modifiers code needs also
some work. Surfacedeform one is in next commit, Laplacian case is much,
much more complicated to handle, given how it uses its cached data. :(
-rw-r--r-- | source/blender/editors/object/object_modifier.c | 44 |
1 files changed, 22 insertions, 22 deletions
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index ec80ec98b21..7b4fba23551 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -2283,25 +2283,25 @@ static int laplaciandeform_bind_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); LaplacianDeformModifierData *lmd = (LaplacianDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_LaplacianDeform); - if (!lmd) + if (lmd == NULL) { return OPERATOR_CANCELLED; + } + if (lmd->flag & MOD_LAPLACIANDEFORM_BIND) { - /* Un-binding happens inside the modifier when it's evaluated. */ lmd->flag &= ~MOD_LAPLACIANDEFORM_BIND; } else { - int mode = lmd->modifier.mode; - - /* Force modifier to run, it will call binding routine. */ - lmd->modifier.mode |= eModifierMode_Realtime; lmd->flag |= MOD_LAPLACIANDEFORM_BIND; - - object_force_modifier_update_for_bind(depsgraph, scene, ob); - - lmd->modifier.mode = mode; } - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */ + const int mode = lmd->modifier.mode; + lmd->modifier.mode |= eModifierMode_Realtime; + object_force_modifier_update_for_bind(depsgraph, scene, ob); + lmd->modifier.mode = mode; + + /* We need DEG_TAG_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ + DEG_id_tag_update(&ob->id, DEG_TAG_GEOMETRY | DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; } @@ -2345,25 +2345,25 @@ static int surfacedeform_bind_exec(bContext *C, wmOperator *op) Depsgraph *depsgraph = CTX_data_depsgraph(C); SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)edit_modifier_property_get(op, ob, eModifierType_SurfaceDeform); - if (!smd) + if (smd == NULL) { return OPERATOR_CANCELLED; + } + if (smd->flags & MOD_SDEF_BIND) { - /* Un-binding happens inside the modifier when it's evaluated. */ smd->flags &= ~MOD_SDEF_BIND; } else if (smd->target) { - int mode = smd->modifier.mode; - - /* Force modifier to run, it will call binding routine. */ - smd->modifier.mode |= eModifierMode_Realtime; smd->flags |= MOD_SDEF_BIND; - - object_force_modifier_update_for_bind(depsgraph, scene, ob); - - smd->modifier.mode = mode; } - DEG_id_tag_update(&ob->id, OB_RECALC_DATA); + /* Force modifier to run, it will call binding routine (this has to happen outside of depsgraph evaluation). */ + const int mode = smd->modifier.mode; + smd->modifier.mode |= eModifierMode_Realtime; + object_force_modifier_update_for_bind(depsgraph, scene, ob); + smd->modifier.mode = mode; + + /* We need DEG_TAG_COPY_ON_WRITE to ensure (un)binding is flushed to CoW copies of the object... */ + DEG_id_tag_update(&ob->id, DEG_TAG_GEOMETRY | DEG_TAG_COPY_ON_WRITE); WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob); return OPERATOR_FINISHED; } |