Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorPablo Dobarro <pablodp606>2020-09-18 20:32:35 +0300
committerPablo Dobarro <pablodp606@gmail.com>2020-09-18 20:40:40 +0300
commit827dfd76dddec962e67825815931d4f2953c741b (patch)
treece54fa0e64773c490a4e2b69650b127522890cf6 /source
parent6c9ec1c893f98c2349edd3aaae4b606b55b393c9 (diff)
Object: Switch Object operator
This object operator exits and frees the edit data of the current object and enters the same mode in another one in a single step, without going through object mode or keeping multiple edit object data active. It is assigned to the D key. This solves all conflicts that the right/click select keymap and the emulate 3 button mouse produces for this operation and it is independent of the state of Lock object modes. Also, as the SculptSession is freed, when using Multires objects go back to their preview resolution level, so it is possible to work on high vertex count scenes without slowing down the viewport and other performance problems. Reviewed By: #user_interface, pablovazquez Differential Revision: https://developer.blender.org/D7510
Diffstat (limited to 'source')
-rw-r--r--source/blender/editors/object/object_intern.h2
-rw-r--r--source/blender/editors/object/object_modes.c118
-rw-r--r--source/blender/editors/object/object_ops.c2
3 files changed, 122 insertions, 0 deletions
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 99e139b823e..0a243a56dee 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -89,6 +89,8 @@ void OBJECT_OT_forcefield_toggle(struct wmOperatorType *ot);
void OBJECT_OT_move_to_collection(struct wmOperatorType *ot);
void OBJECT_OT_link_to_collection(struct wmOperatorType *ot);
+void OBJECT_OT_switch_object(struct wmOperatorType *ot);
+
/* object_select.c */
void OBJECT_OT_select_all(struct wmOperatorType *ot);
void OBJECT_OT_select_random(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modes.c b/source/blender/editors/object/object_modes.c
index bc05a62759f..caba10c820b 100644
--- a/source/blender/editors/object/object_modes.c
+++ b/source/blender/editors/object/object_modes.c
@@ -26,6 +26,8 @@
#include "DNA_scene_types.h"
#include "DNA_workspace_types.h"
+#include "BLI_kdopbvh.h"
+#include "BLI_math.h"
#include "BLI_utildefines.h"
#include "BKE_context.h"
@@ -44,10 +46,15 @@
#include "RNA_access.h"
#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_query.h"
#include "ED_armature.h"
#include "ED_gpencil.h"
#include "ED_screen.h"
+#include "ED_transform_snap_object_context.h"
+#include "ED_view3d.h"
+
+#include "WM_toolsystem.h"
#include "ED_object.h" /* own include */
@@ -390,3 +397,114 @@ bool ED_object_mode_generic_has_data(struct Depsgraph *depsgraph, struct Object
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Switch Object
+ *
+ * Enters the same mode of the current active object in another object, leaving the mode of the
+ *current object.
+ *
+ * \{ */
+
+bool OBJECT_switch_object_poll(bContext *C)
+{
+ Object *ob = CTX_data_active_object(C);
+ if (!CTX_wm_region_view3d(C)) {
+ return false;
+ }
+ return ob && ELEM(ob->mode, OB_MODE_EDIT, OB_MODE_SCULPT);
+}
+
+static int object_switch_object_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+{
+
+ Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ARegion *ar = CTX_wm_region(C);
+ struct Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ struct SnapObjectContext *sctx = ED_transform_snap_object_context_create(scene, 0);
+
+ float global_normal[3], global_loc[3];
+ float r_obmat[4][4];
+
+ float mouse[2];
+ mouse[0] = event->mval[0];
+ mouse[1] = event->mval[1];
+
+ float ray_co[3], ray_no[3];
+ float ray_dist = BVH_RAYCAST_DIST_MAX;
+ int r_index;
+ ED_view3d_win_to_origin(ar, mouse, ray_co);
+ ED_view3d_win_to_vector(ar, mouse, ray_no);
+
+ Object *r_ob = NULL;
+
+ bool ret = ED_transform_snap_object_project_ray_ex(sctx,
+ depsgraph,
+ &(const struct SnapObjectParams){
+ .snap_select = SNAP_NOT_ACTIVE,
+ },
+ ray_co,
+ ray_no,
+ &ray_dist,
+ global_loc,
+ global_normal,
+ &r_index,
+ &r_ob,
+ (float(*)[4])r_obmat);
+ ED_transform_snap_object_context_destroy(sctx);
+
+ Object *c_ob = CTX_data_active_object(C);
+ if (!ret || r_ob == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+ if (r_ob == NULL || r_ob == c_ob) {
+ return OPERATOR_CANCELLED;
+ }
+
+ eObjectMode last_mode = (eObjectMode)c_ob->mode;
+ if (!ED_object_mode_compat_test(r_ob, last_mode)) {
+ return OPERATOR_CANCELLED;
+ }
+ ED_object_mode_generic_exit(bmain, depsgraph, scene, c_ob);
+
+ Object *ob_orig = DEG_get_original_object(r_ob);
+ Base *base = BKE_view_layer_base_find(view_layer, ob_orig);
+ BKE_view_layer_base_deselect_all(view_layer);
+ BKE_view_layer_base_select_and_set_active(view_layer, base);
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+
+ depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
+ ob_orig = DEG_get_original_object(r_ob);
+ ED_object_mode_set(C, last_mode);
+
+ /* Update the viewport rotation origin to the mouse cursor. */
+ UnifiedPaintSettings *ups = &CTX_data_tool_settings(C)->unified_paint_settings;
+ copy_v3_v3(ups->average_stroke_accum, global_loc);
+ ups->average_stroke_counter = 1;
+ ups->last_stroke_valid = true;
+
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ WM_toolsystem_update_from_context_view3d(C);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_switch_object(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Switch Object";
+ ot->idname = "OBJECT_OT_switch_object";
+ ot->description =
+ "Switches the active object and assigns the same mode to a new one under the mouse cursor, "
+ "leaving the active mode in the current one";
+
+ /* api callbacks */
+ ot->invoke = object_switch_object_invoke;
+ ot->poll = OBJECT_switch_object_poll;
+
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
+/** \} */
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 8b3837edce2..390770d5c5c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -71,6 +71,8 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_paths_range_update);
WM_operatortype_append(OBJECT_OT_forcefield_toggle);
+ WM_operatortype_append(OBJECT_OT_switch_object);
+
WM_operatortype_append(OBJECT_OT_parent_set);
WM_operatortype_append(OBJECT_OT_parent_no_inverse_set);
WM_operatortype_append(OBJECT_OT_parent_clear);