diff options
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/editors/include/ED_object.h | 6 | ||||
-rw-r--r-- | source/blender/editors/object/object_edit.c | 50 | ||||
-rw-r--r-- | source/blender/editors/object/object_select.c | 39 | ||||
-rw-r--r-- | source/blender/editors/screen/screen_context.c | 4 | ||||
-rw-r--r-- | source/blender/editors/screen/workspace_edit.c | 43 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_enums.h | 3 |
6 files changed, 108 insertions, 37 deletions
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_PAINT | OB_MODE_SCULPT) + #endif /* __DNA_OBJECT_ENUMS_H__ */ |