[Bf-blender-cvs] [4ab002bca36] blender2.8: WorkSpace: object-mode switching support

Campbell Barton noreply at git.blender.org
Thu Feb 22 08:15:51 CET 2018


Commit: 4ab002bca36ace4d2b4b21efce622a682b99b844
Author: Campbell Barton
Date:   Thu Feb 22 18:15:34 2018 +1100
Branches: blender2.8
https://developer.blender.org/rB4ab002bca36ace4d2b4b21efce622a682b99b844

WorkSpace: object-mode switching support

When changing workspaces, existing object-mode data is freed
the new workspaces mode is entered (if possible).

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

M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/object/object_select.c
M	source/blender/editors/screen/screen_context.c
M	source/blender/editors/screen/workspace_edit.c
M	source/blender/makesdna/DNA_object_enums.h

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

diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 5df46dd26b8..ddbf3325a87 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -155,6 +155,12 @@ void ED_object_sculptmode_exit_ex(
         struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
 void ED_object_sculptmode_exit(struct bContext *C);
 
+bool ED_object_mode_generic_enter(
+        struct bContext *C, eObjectMode object_mode);
+void ED_object_mode_generic_exit(
+        const struct EvaluationContext *eval_ctx,
+        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob);
+
 void ED_object_location_from_view(struct bContext *C, float loc[3]);
 void ED_object_rotation_from_view(struct bContext *C, float rot[3], const char align_axis);
 void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]);
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index c6f9ced51a3..0da4bd1e045 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -77,6 +77,7 @@
 #include "BKE_mball.h"
 #include "BKE_mesh.h"
 #include "BKE_object.h"
+#include "BKE_paint.h"
 #include "BKE_pointcache.h"
 #include "BKE_property.h"
 #include "BKE_sca.h"
@@ -2068,6 +2069,55 @@ void OBJECT_OT_game_physics_copy(struct wmOperatorType *ot)
 
 /* generic utility function */
 
+bool ED_object_mode_generic_enter(
+        struct bContext *C, eObjectMode object_mode)
+{
+	WorkSpace *workspace = CTX_wm_workspace(C);
+	if (workspace->object_mode == object_mode) {
+		return true;
+	}
+	wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false);
+	PointerRNA ptr;
+	WM_operator_properties_create_ptr(&ptr, ot);
+	RNA_enum_set(&ptr, "mode", object_mode);
+	WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
+	WM_operator_properties_free(&ptr);
+	return (workspace->object_mode == object_mode);
+}
+
+/**
+ * Use for changing works-paces or changing active object.
+ * Caller can check #OB_MODE_ALL_MODE_DATA to test if this needs to be run.
+ */
+void ED_object_mode_generic_exit(
+        const struct EvaluationContext *eval_ctx,
+        struct WorkSpace *workspace, struct Scene *scene, struct Object *ob)
+{
+	if (eval_ctx->object_mode & OB_MODE_EDIT) {
+		if (BKE_object_is_in_editmode(ob)) {
+			ED_object_editmode_exit_ex(NULL, workspace, scene, ob, EM_FREEDATA);
+		}
+	}
+	else if (eval_ctx->object_mode & OB_MODE_VERTEX_PAINT) {
+		if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_VERTEX_PAINT)) {
+			ED_object_vpaintmode_exit_ex(workspace, ob);
+		}
+	}
+	else if (eval_ctx->object_mode & OB_MODE_WEIGHT_PAINT) {
+		if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_WEIGHT_PAINT)) {
+			ED_object_wpaintmode_exit_ex(workspace, ob);
+		}
+	}
+	else if (eval_ctx->object_mode & OB_MODE_SCULPT) {
+		if (ob->sculpt && (ob->sculpt->mode_type == OB_MODE_SCULPT)) {
+			ED_object_sculptmode_exit_ex(eval_ctx, workspace, scene, ob);
+		}
+	}
+	else {
+		BLI_assert((eval_ctx->object_mode & OB_MODE_ALL_MODE_DATA) == 0);
+	}
+}
+
 bool ED_object_editmode_calc_active_center(Object *obedit, const bool select_only, float r_center[3])
 {
 	switch (obedit->type) {
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 851a5d86d1b..620ee015724 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -146,40 +146,12 @@ void ED_object_base_activate(bContext *C, Base *base)
 		 *
 		 * Not correct because it's possible other work-spaces use these.
 		 * although that's a corner case. */
-		if (workspace->object_mode & OB_MODE_EDIT) {
-			FOREACH_OBJECT(view_layer, ob) {
-				if (ob != obact) {
-					if (BKE_object_is_in_editmode(ob)) {
-						ED_object_editmode_exit_ex(NULL, workspace, scene, ob, EM_FREEDATA);
-					}
-				}
-			}
-			FOREACH_OBJECT_END;
-		}
-		else if (workspace->object_mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_SCULPT)) {
+		if (workspace->object_mode & OB_MODE_ALL_MODE_DATA) {
 			EvaluationContext eval_ctx;
 			CTX_data_eval_ctx(C, &eval_ctx);
 			FOREACH_OBJECT(view_layer, ob) {
 				if (ob != obact) {
-					if (ob->sculpt) {
-						switch (ob->sculpt->mode_type) {
-							case OB_MODE_VERTEX_PAINT:
-							{
-								ED_object_vpaintmode_exit_ex(workspace, ob);
-								break;
-							}
-							case OB_MODE_WEIGHT_PAINT:
-							{
-								ED_object_wpaintmode_exit_ex(workspace, ob);
-								break;
-							}
-							case OB_MODE_SCULPT:
-							{
-								ED_object_sculptmode_exit_ex(&eval_ctx, workspace, scene, ob);
-								break;
-							}
-						}
-					}
+					ED_object_mode_generic_exit(&eval_ctx, workspace, scene, ob);
 				}
 			}
 			FOREACH_OBJECT_END;
@@ -191,12 +163,7 @@ void ED_object_base_activate(bContext *C, Base *base)
 	view_layer->basact = base;
 
 	if (reset == false) {
-		wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_mode_set", false);
-		PointerRNA ptr;
-		WM_operator_properties_create_ptr(&ptr, ot);
-		RNA_enum_set(&ptr, "mode", object_mode);
-		WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr);
-		WM_operator_properties_free(&ptr);
+		ED_object_mode_generic_enter(C, object_mode);
 	}
 
 	if (base) {
diff --git a/source/blender/editors/screen/screen_context.c b/source/blender/editors/screen/screen_context.c
index 2a48ae46b12..dc4dcdb4554 100644
--- a/source/blender/editors/screen/screen_context.c
+++ b/source/blender/editors/screen/screen_context.c
@@ -93,7 +93,6 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 	WorkSpace *workspace = BKE_workspace_active_get(win->workspace_hook);
 	ViewLayer *view_layer = BKE_view_layer_from_workspace_get(scene, workspace);
 	Object *obact = (view_layer && view_layer->basact) ? view_layer->basact->object : NULL;
-	Object *obedit = BKE_workspace_edit_object(workspace, scene);
 
 	if (CTX_data_dir(member)) {
 		CTX_data_dir_set(result, screen_context_dir);
@@ -204,6 +203,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 		return 1;
 	}
 	else if (CTX_data_equals(member, "visible_bones") || CTX_data_equals(member, "editable_bones")) {
+		Object *obedit = BKE_workspace_edit_object(workspace, scene);
 		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
 		EditBone *ebone, *flipbone = NULL;
 		const bool editable_bones = CTX_data_equals(member, "editable_bones");
@@ -246,6 +246,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 		}
 	}
 	else if (CTX_data_equals(member, "selected_bones") || CTX_data_equals(member, "selected_editable_bones")) {
+		Object *obedit = BKE_workspace_edit_object(workspace, scene);
 		bArmature *arm = (obedit && obedit->type == OB_ARMATURE) ? obedit->data : NULL;
 		EditBone *ebone, *flipbone = NULL;
 		const bool selected_editable_bones = CTX_data_equals(member, "selected_editable_bones");
@@ -367,6 +368,7 @@ int ed_screen_context(const bContext *C, const char *member, bContextDataResult
 	}
 	else if (CTX_data_equals(member, "edit_object")) {
 		/* convenience for now, 1 object per scene in editmode */
+		Object *obedit = BKE_workspace_edit_object(workspace, scene);
 		if (obedit)
 			CTX_data_id_pointer_set(result, &obedit->id);
 		
diff --git a/source/blender/editors/screen/workspace_edit.c b/source/blender/editors/screen/workspace_edit.c
index 1ec83ed7c08..465e30357dc 100644
--- a/source/blender/editors/screen/workspace_edit.c
+++ b/source/blender/editors/screen/workspace_edit.c
@@ -56,6 +56,8 @@
 
 #include "RNA_access.h"
 
+#include "DEG_depsgraph.h"
+
 #include "UI_interface.h"
 #include "UI_resources.h"
 
@@ -166,6 +168,41 @@ bool ED_workspace_change(
 	BLI_assert(BKE_workspace_layout_screen_get(layout_new) == screen_new);
 
 	if (screen_new) {
+		bool object_mode_set = false;
+
+		/* Handle object mode switching */
+		if ((workspace_old->object_mode != OB_MODE_OBJECT) ||
+		    (workspace_new->object_mode != OB_MODE_OBJECT))
+		{
+			Scene *scene = CTX_data_scene(C);
+			ViewLayer *view_layer_old = BKE_workspace_view_layer_get(workspace_old, scene);
+			ViewLayer *view_layer_new = BKE_workspace_view_layer_get(workspace_new, scene);
+			Object *obact_old = OBACT(view_layer_old);
+			Object *obact_new = OBACT(view_layer_new);
+
+			if ((workspace_old->object_mode == workspace_new->object_mode) &&
+			    (obact_old == obact_new))
+			{
+				/* pass */
+			}
+			else {
+				if (workspace_old->object_mode & OB_MODE_ALL_MODE_DATA) {
+					if (obact_old) {
+						eObjectMode object_mode = workspace_old->object_mode;
+						EvaluationContext eval_ctx;
+						CTX_data_eval_ctx(C, &eval_ctx);
+						ED_object_mode_generic_exit(&eval_ctx, workspace_old, scene, obact_old);
+						/* weak, set it back so it's used when activating again. */
+						workspace_old->object_mode = object_mode;
+					}
+				}
+
+				if (workspace_new->object_mode != OB_MODE_OBJECT) {
+					object_mode_set = true;
+				}
+			}
+		}
+
 		WM_window_set_active_layout(win, workspace_new, layout_new);
 		WM_window_set_active_workspace(win, workspace_new);
 
@@ -179,6 +216,12 @@ bool ED_workspace_change(
 		WM_toolsystem_unlink(C, workspace_old);
 		WM_toolsystem_link(C, workspace_new);
 
+		if (object_mode_set) {
+			eObjectMode object_mode = workspace_new->object_mode;
+			workspace_new->object_mode = OB_MODE_OBJECT;
+			ED_object_mode_generic_enter(C, object_mode);
+		}
+
 		return true;
 	}
 
diff --git a/source/blender/makesdna/DNA_object_enums.h b/source/blender/makesdna/DNA_object_enums.h
index 58f9e29297f..524c85948f3 100644
--- a/source/blender/makesdna/DNA_object_enums.h
+++ b/source/blender/makesdna/DNA_object_enums.h
@@ -46,4 +46,7 @@ typedef enum eObjectMode {
 /* Any mode that uses Object.sculpt. */
 #define OB_MODE_ALL_SCULPT (OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)
 
+/* Any mode that has data we need to free when switching modes, see: #ED_object_mode_generic_exit */
+#define OB_MODE_ALL_MODE_DATA (OB_MODE_EDIT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_P

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list