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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-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);