[Bf-blender-cvs] [937731dff1a] master: Fix T61272: Undo fails to track multi-edit mode enter/exit

Campbell Barton noreply at git.blender.org
Thu Feb 7 11:23:53 CET 2019


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. @@



More information about the Bf-blender-cvs mailing list