Fix T61272: Undo fails to track multi-edit mode enter/exit
[blender.git] / source / blender / editors / undo / ed_undo.c
index 69e02148ba5076b422092a470a7bb3c5877187c7..ffe752e11b18afdc84a230814011751128814d4e 100644 (file)
@@ -653,4 +653,37 @@ void ED_undo_object_set_active_or_warn(ViewLayer *view_layer, Object *ob, const
        }
 }
 
+void ED_undo_object_editmode_restore_helper(
+        struct bContext *C, Object **object_array, uint object_array_len, uint object_array_stride)
+{
+       Main *bmain = CTX_data_main(C);
+       ViewLayer *view_layer = CTX_data_view_layer(C);
+       uint bases_len = 0;
+       /* Don't request unique data because we wan't to de-select objects when exiting edit-mode
+        * for that to be done on all objects we can't skip ones that share data. */
+       Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
+               view_layer, NULL, &bases_len);
+       for (uint i = 0; i < bases_len; i++) {
+               ((ID *)bases[i]->object->data)->tag |= LIB_TAG_DOIT;
+       }
+       Scene *scene = CTX_data_scene(C);
+       Object **ob_p = object_array;
+       for (uint i = 0; i < object_array_len; i++, ob_p = POINTER_OFFSET(ob_p, object_array_stride)) {
+               Object *obedit = *ob_p;
+               ED_object_editmode_enter_ex(bmain, scene, obedit, EM_NO_CONTEXT);
+               ((ID *)obedit->data)->tag &= ~LIB_TAG_DOIT;
+       }
+       for (uint i = 0; i < bases_len; i++) {
+               ID *id = bases[i]->object->data;
+               if (id->tag & LIB_TAG_DOIT) {
+                       ED_object_editmode_exit_ex(bmain, scene, bases[i]->object, EM_FREEDATA);
+                       /* Ideally we would know the selection state it was before entering edit-mode,
+                        * for now follow the convention of having them unselected when exiting the mode. */
+                       ED_object_base_select(bases[i], BA_DESELECT);
+
+               }
+       }
+       MEM_freeN(bases);
+}
+
 /** \} */