diff options
author | Campbell Barton <ideasman42@gmail.com> | 2021-01-22 07:23:34 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2021-01-22 07:43:25 +0300 |
commit | 1a30687c24be7899d0835d4c3572d7dc0f1a5656 (patch) | |
tree | e3b4ea339d33b1ff2192ba9c817826ee79a2ee6e /source/blender/editors/util/ed_util.c | |
parent | 7b528b2a3ad33b3ad7328213669d8179528e254b (diff) |
Fix undo crash on active object change without exiting edit-mode
While the previous fix for T84920 is correct, the crash could still be
triggered by changing the active object while in edit-mode.
Ensure stale data isn't used by tagging for depsgraph update when
edit-mode data is freed on undo.
While exiting edit-mode normally does this, it's possible to set the
active object to a non edit-mode mesh, skipping the mode-switch
operator and it's depsgraph tagging.
Diffstat (limited to 'source/blender/editors/util/ed_util.c')
-rw-r--r-- | source/blender/editors/util/ed_util.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/source/blender/editors/util/ed_util.c b/source/blender/editors/util/ed_util.c index 4b1335cf047..c59fbbe1646 100644 --- a/source/blender/editors/util/ed_util.c +++ b/source/blender/editors/util/ed_util.c @@ -194,6 +194,17 @@ void ED_editors_exit(Main *bmain, bool do_undo_system) } } + /* On undo, tag for update so the depsgraph doesn't use stale edit-mode data, + * this is possible when mixing edit-mode and memory-file undo. + * + * By convention, objects are not left in edit-mode - so this isn't often problem in practice, + * since exiting edit-mode will tag the objects too. + * + * However there is no guarantee the active object _never_ changes while in edit-mode. + * Python for example can do this, some callers to #ED_object_base_activate + * don't handle modes either (doing so isn't always practical). + * + * To reproduce the problem where stale data is used, see: T84920. */ for (Object *ob = bmain->objects.first; ob; ob = ob->id.next) { if (ob->type == OB_MESH) { Mesh *me = ob->data; @@ -201,12 +212,18 @@ void ED_editors_exit(Main *bmain, bool do_undo_system) EDBM_mesh_free(me->edit_mesh); MEM_freeN(me->edit_mesh); me->edit_mesh = NULL; + if (do_undo_system == false) { + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + } } } else if (ob->type == OB_ARMATURE) { bArmature *arm = ob->data; if (arm->edbo) { ED_armature_edit_free(ob->data); + if (do_undo_system == false) { + DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY); + } } } } |