Commit: 937731dff1af4910dc94646904106432c14b2042
Author: Campbell Barton
Date:   Thu Feb 7 20:27:11 2019 +1100
Branches: master
https://developer.blender.org/rB937731dff1af4910dc94646904106432c14b2042

Fix T61272: Undo fails to track multi-edit mode enter/exit

Objects leaving edit-mode weren't restored by edit-mode undo steps.

===================================================================

M       source/blender/editors/armature/editarmature_undo.c
M       source/blender/editors/curve/editcurve_undo.c
M       source/blender/editors/include/ED_undo.h
M       source/blender/editors/lattice/editlattice_undo.c
M       source/blender/editors/mesh/editmesh_undo.c
M       source/blender/editors/metaball/editmball_undo.c
M       source/blender/editors/undo/ed_undo.c

===================================================================

diff --git a/source/blender/editors/armature/editarmature_undo.c 
b/source/blender/editors/armature/editarmature_undo.c
index f88054f20c8..3e76a66e891 100644
--- a/source/blender/editors/armature/editarmature_undo.c
+++ b/source/blender/editors/armature/editarmature_undo.c
@@ -146,9 +146,11 @@ static bool armature_undosys_step_encode(struct bContext 
*C, struct Main *UNUSED
 {
        ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
 
+       /* Important not to use the 3D view when getting objects because all 
objects
+        * outside of this list will be moved out of edit-mode when reading 
back undo steps. */
        ViewLayer *view_layer = CTX_data_view_layer(C);
        uint objects_len = 0;
-       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, 
CTX_wm_view3d(C), &objects_len);
+       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, 
&objects_len);
 
        us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
        us->elems_len = objects_len;
@@ -168,12 +170,13 @@ static bool armature_undosys_step_encode(struct bContext 
*C, struct Main *UNUSED
 
 static void armature_undosys_step_decode(struct bContext *C, struct Main 
*UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
 {
-       /* TODO(campbell): undo_system: use low-level API to set mode. */
-       ED_object_mode_set(C, OB_MODE_EDIT);
-       BLI_assert(armature_undosys_poll(C));
-
        ArmatureUndoStep *us = (ArmatureUndoStep *)us_p;
 
+       /* Load all our objects  into edit-mode, clear everything else. */
+       ED_undo_object_editmode_restore_helper(C, &us->elems[0].obedit_ref.ptr, 
us->elems_len, sizeof(*us->elems));
+
+       BLI_assert(armature_undosys_poll(C));
+
        for (uint i = 0; i < us->elems_len; i++) {
                ArmatureUndoStep_Elem *elem = &us->elems[i];
                Object *obedit = elem->obedit_ref.ptr;
diff --git a/source/blender/editors/curve/editcurve_undo.c 
b/source/blender/editors/curve/editcurve_undo.c
index a586e94a6f9..e9586594274 100644
--- a/source/blender/editors/curve/editcurve_undo.c
+++ b/source/blender/editors/curve/editcurve_undo.c
@@ -213,9 +213,11 @@ static bool curve_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bm
 {
        CurveUndoStep *us = (CurveUndoStep *)us_p;
 
+       /* Important not to use the 3D view when getting objects because all 
objects
+        * outside of this list will be moved out of edit-mode when reading 
back undo steps. */
        ViewLayer *view_layer = CTX_data_view_layer(C);
        uint objects_len = 0;
-       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, 
CTX_wm_view3d(C), &objects_len);
+       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, 
&objects_len);
 
        us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
        us->elems_len = objects_len;
@@ -234,12 +236,14 @@ static bool curve_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bm
 
 static void curve_undosys_step_decode(struct bContext *C, struct Main 
*UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
 {
-       /* TODO(campbell): undo_system: use low-level API to set mode. */
-       ED_object_mode_set(C, OB_MODE_EDIT);
-       BLI_assert(curve_undosys_poll(C));
-
        CurveUndoStep *us = (CurveUndoStep *)us_p;
 
+       /* Load all our objects  into edit-mode, clear everything else. */
+       ED_undo_object_editmode_restore_helper(
+               C, &us->elems[0].obedit_ref.ptr, us->elems_len, 
sizeof(*us->elems));
+
+       BLI_assert(curve_undosys_poll(C));
+
        for (uint i = 0; i < us->elems_len; i++) {
                CurveUndoStep_Elem *elem = &us->elems[i];
                Object *obedit = elem->obedit_ref.ptr;
diff --git a/source/blender/editors/include/ED_undo.h 
b/source/blender/editors/include/ED_undo.h
index 3486761c19f..3a45e2c3b68 100644
--- a/source/blender/editors/include/ED_undo.h
+++ b/source/blender/editors/include/ED_undo.h
@@ -23,7 +23,9 @@
 #include "BLI_compiler_attrs.h"
 
 struct CLG_LogRef;
+struct Object;
 struct UndoStack;
+struct ViewLayer;
 struct bContext;
 struct wmOperator;
 struct wmOperatorType;
@@ -51,6 +53,10 @@ bool    ED_undo_is_valid(const struct bContext *C, const 
char *undoname);
 
 bool    ED_undo_is_memfile_compatible(const struct bContext *C);
 
+void    ED_undo_object_editmode_restore_helper(
+        struct bContext *C,
+        struct Object **object_array, uint object_array_len, uint 
object_array_stride);
+
 struct UndoStack *ED_undo_stack_get(void);
 
 /* helpers */
diff --git a/source/blender/editors/lattice/editlattice_undo.c 
b/source/blender/editors/lattice/editlattice_undo.c
index c6c0ad542d1..8dddec3ed6d 100644
--- a/source/blender/editors/lattice/editlattice_undo.c
+++ b/source/blender/editors/lattice/editlattice_undo.c
@@ -148,9 +148,11 @@ static bool lattice_undosys_step_encode(struct bContext 
*C, struct Main *UNUSED(
 {
        LatticeUndoStep *us = (LatticeUndoStep *)us_p;
 
+       /* Important not to use the 3D view when getting objects because all 
objects
+        * outside of this list will be moved out of edit-mode when reading 
back undo steps. */
        ViewLayer *view_layer = CTX_data_view_layer(C);
        uint objects_len = 0;
-       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, 
CTX_wm_view3d(C), &objects_len);
+       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, 
&objects_len);
 
        us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
        us->elems_len = objects_len;
@@ -170,12 +172,13 @@ static bool lattice_undosys_step_encode(struct bContext 
*C, struct Main *UNUSED(
 
 static void lattice_undosys_step_decode(struct bContext *C, struct Main 
*UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
 {
-       /* TODO(campbell): undo_system: use low-level API to set mode. */
-       ED_object_mode_set(C, OB_MODE_EDIT);
-       BLI_assert(lattice_undosys_poll(C));
-
        LatticeUndoStep *us = (LatticeUndoStep *)us_p;
 
+       /* Load all our objects  into edit-mode, clear everything else. */
+       ED_undo_object_editmode_restore_helper(C, &us->elems[0].obedit_ref.ptr, 
us->elems_len, sizeof(*us->elems));
+
+       BLI_assert(lattice_undosys_poll(C));
+
        for (uint i = 0; i < us->elems_len; i++) {
                LatticeUndoStep_Elem *elem = &us->elems[i];
                Object *obedit = elem->obedit_ref.ptr;
diff --git a/source/blender/editors/mesh/editmesh_undo.c 
b/source/blender/editors/mesh/editmesh_undo.c
index 7af7204deab..5ed4395a740 100644
--- a/source/blender/editors/mesh/editmesh_undo.c
+++ b/source/blender/editors/mesh/editmesh_undo.c
@@ -698,9 +698,11 @@ static bool mesh_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bma
 {
        MeshUndoStep *us = (MeshUndoStep *)us_p;
 
+       /* Important not to use the 3D view when getting objects because all 
objects
+        * outside of this list will be moved out of edit-mode when reading 
back undo steps. */
        ViewLayer *view_layer = CTX_data_view_layer(C);
        uint objects_len = 0;
-       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, 
CTX_wm_view3d(C), &objects_len);
+       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, 
&objects_len);
 
        us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
        us->elems_len = objects_len;
@@ -718,16 +720,12 @@ static bool mesh_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bma
        return true;
 }
 
-static void mesh_undosys_step_decode(struct bContext *C, struct Main *bmain, 
UndoStep *us_p, int UNUSED(dir))
+static void mesh_undosys_step_decode(struct bContext *C, struct Main 
*UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
 {
        MeshUndoStep *us = (MeshUndoStep *)us_p;
 
-       Scene *scene = CTX_data_scene(C);
-       for (uint i = 0; i < us->elems_len; i++) {
-               MeshUndoStep_Elem *elem = &us->elems[i];
-               Object *obedit = elem->obedit_ref.ptr;
-               ED_object_editmode_enter_ex(bmain, scene, obedit, 
EM_NO_CONTEXT);
-       }
+       /* Load all our objects  into edit-mode, clear everything else. */
+       ED_undo_object_editmode_restore_helper(C, &us->elems[0].obedit_ref.ptr, 
us->elems_len, sizeof(*us->elems));
 
        BLI_assert(mesh_undosys_poll(C));
 
diff --git a/source/blender/editors/metaball/editmball_undo.c 
b/source/blender/editors/metaball/editmball_undo.c
index c526edd7bd2..160b43b7065 100644
--- a/source/blender/editors/metaball/editmball_undo.c
+++ b/source/blender/editors/metaball/editmball_undo.c
@@ -156,9 +156,11 @@ static bool mball_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bm
 {
        MBallUndoStep *us = (MBallUndoStep *)us_p;
 
+       /* Important not to use the 3D view when getting objects because all 
objects
+        * outside of this list will be moved out of edit-mode when reading 
back undo steps. */
        ViewLayer *view_layer = CTX_data_view_layer(C);
        uint objects_len = 0;
-       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, 
CTX_wm_view3d(C), &objects_len);
+       Object **objects = 
BKE_view_layer_array_from_objects_in_edit_mode_unique_data(view_layer, NULL, 
&objects_len);
 
        us->elems = MEM_callocN(sizeof(*us->elems) * objects_len, __func__);
        us->elems_len = objects_len;
@@ -178,12 +180,13 @@ static bool mball_undosys_step_encode(struct bContext *C, 
struct Main *UNUSED(bm
 
 static void mball_undosys_step_decode(struct bContext *C, struct Main 
*UNUSED(bmain), UndoStep *us_p, int UNUSED(dir))
 {
-       /* TODO(campbell): undo_system: use low-level API to set mode. */
-       ED_object_mode_set(C, OB_MODE_EDIT);
-       BLI_assert(mball_undosys_poll(C));
-
        MBallUndoStep *us = (MBallUndoStep *)us_p;
 
+       /* Load all our objects  into edit-mode, clear everything else. */
+       ED_undo_object_editmode_restore_helper(C, &us->elems[0].obedit_ref.ptr, 
us->elems_len, sizeof(*us->elems));
+
+       BLI_assert(mball_undosys_poll(C));
+
        for (uint i = 0; i < us->elems_len; i++) {
                MBallUndoStep_Elem *elem = &us->elems[i];
                Object *obedit = elem->obedit_ref.ptr;
diff --git a/source/blender/editors/undo/ed_undo.c 
b/source/blender/editors/undo/ed_undo.c
index 69e02148ba5..ffe752e11b1 100644
--- a/source/blender/editors/undo/ed_undo.c
+++ b/source/blender/editors/undo/ed_undo.c
@@ -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 
o

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to