View3D: expose snap selection as a utility funciton
This makes it convenient to position appended objects, see: T92111.
This commit is contained in:
parent
943debfab5
commit
2bcf93bbbe
Notes:
blender-bot
2023-02-14 06:45:14 +01:00
Referenced by commit4681987d92
, Fix T96156: Snap to 3D cursor can't be undone Referenced by commit6e26c615af
, Fix T92663: Snap Selected to Active not working properly Referenced by commit16f468fb14
, Fix T92514: Edit-mode bone snap to cursor uses the center of the bone Referenced by issue #96156, Selection to 3D cursor operation cannot be redone Referenced by issue #92663, Snap Selected to Active not working properly. Referenced by issue #92514, Bone snapping to cursor in edit mode snaps to middle of the bone instead of the head (regression)
|
@ -229,6 +229,11 @@ typedef enum {
|
|||
(V3D_PROJ_TEST_CLIP_CONTENT | V3D_PROJ_TEST_CLIP_NEAR | V3D_PROJ_TEST_CLIP_FAR | \
|
||||
V3D_PROJ_TEST_CLIP_WIN)
|
||||
|
||||
/* view3d_snap.c */
|
||||
bool ED_view3d_snap_selected_to_location(struct bContext *C,
|
||||
const float snap_target_global[3],
|
||||
const int pivot_point);
|
||||
|
||||
/* view3d_cursor_snap.c */
|
||||
#define USE_SNAP_DETECT_FROM_KEYMAP_HACK
|
||||
typedef enum {
|
||||
|
|
|
@ -58,7 +58,7 @@
|
|||
|
||||
#include "view3d_intern.h"
|
||||
|
||||
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]);
|
||||
static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_cursor[3]);
|
||||
static bool snap_calc_active_center(bContext *C, const bool select_only, float r_center[3]);
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -310,9 +310,11 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
|
|||
* and be snapped by the selection pivot point (median, active),
|
||||
* or if every object origin should be snapped to the given location.
|
||||
*/
|
||||
static int snap_selected_to_location(bContext *C,
|
||||
const float snap_target_global[3],
|
||||
const bool use_offset)
|
||||
static bool snap_selected_to_location(bContext *C,
|
||||
const float snap_target_global[3],
|
||||
const bool use_offset,
|
||||
const int pivot_point,
|
||||
const bool use_toolsettings)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
|
@ -326,12 +328,11 @@ static int snap_selected_to_location(bContext *C,
|
|||
int a;
|
||||
|
||||
if (use_offset) {
|
||||
if ((scene->toolsettings->transform_pivot_point == V3D_AROUND_ACTIVE) &&
|
||||
snap_calc_active_center(C, true, center_global)) {
|
||||
if ((pivot_point == V3D_AROUND_ACTIVE) && snap_calc_active_center(C, true, center_global)) {
|
||||
/* pass */
|
||||
}
|
||||
else {
|
||||
snap_curs_to_sel_ex(C, center_global);
|
||||
snap_curs_to_sel_ex(C, pivot_point, center_global);
|
||||
}
|
||||
sub_v3_v3v3(offset_global, snap_target_global, center_global);
|
||||
}
|
||||
|
@ -341,7 +342,7 @@ static int snap_selected_to_location(bContext *C,
|
|||
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);
|
||||
view_layer, v3d, &objects_len);
|
||||
for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
|
||||
obedit = objects[ob_index];
|
||||
|
||||
|
@ -435,18 +436,23 @@ static int snap_selected_to_location(bContext *C,
|
|||
}
|
||||
|
||||
/* copy new position */
|
||||
if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
|
||||
pchan->loc[0] = cursor_pose[0];
|
||||
}
|
||||
if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
|
||||
pchan->loc[1] = cursor_pose[1];
|
||||
}
|
||||
if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
|
||||
pchan->loc[2] = cursor_pose[2];
|
||||
}
|
||||
if (use_toolsettings) {
|
||||
if ((pchan->protectflag & OB_LOCK_LOCX) == 0) {
|
||||
pchan->loc[0] = cursor_pose[0];
|
||||
}
|
||||
if ((pchan->protectflag & OB_LOCK_LOCY) == 0) {
|
||||
pchan->loc[1] = cursor_pose[1];
|
||||
}
|
||||
if ((pchan->protectflag & OB_LOCK_LOCZ) == 0) {
|
||||
pchan->loc[2] = cursor_pose[2];
|
||||
}
|
||||
|
||||
/* auto-keyframing */
|
||||
ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
|
||||
/* auto-keyframing */
|
||||
ED_autokeyframe_pchan(C, scene, ob, pchan, ks);
|
||||
}
|
||||
else {
|
||||
copy_v3_v3(pchan->loc, cursor_pose);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -484,9 +490,11 @@ static int snap_selected_to_location(bContext *C,
|
|||
objects_len = BLI_array_len(objects);
|
||||
}
|
||||
|
||||
const bool use_transform_skip_children = (scene->toolsettings->transform_flag &
|
||||
const bool use_transform_skip_children = use_toolsettings &&
|
||||
(scene->toolsettings->transform_flag &
|
||||
SCE_XFORM_SKIP_CHILDREN);
|
||||
const bool use_transform_data_origin = (scene->toolsettings->transform_flag &
|
||||
const bool use_transform_data_origin = use_toolsettings &&
|
||||
(scene->toolsettings->transform_flag &
|
||||
SCE_XFORM_DATA_ORIGIN);
|
||||
struct XFormObjectSkipChild_Container *xcs = NULL;
|
||||
struct XFormObjectData_Container *xds = NULL;
|
||||
|
@ -538,18 +546,23 @@ static int snap_selected_to_location(bContext *C,
|
|||
invert_m3_m3(imat, originmat);
|
||||
mul_m3_v3(imat, cursor_parent);
|
||||
}
|
||||
if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
|
||||
ob->loc[0] += cursor_parent[0];
|
||||
}
|
||||
if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
|
||||
ob->loc[1] += cursor_parent[1];
|
||||
}
|
||||
if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
|
||||
ob->loc[2] += cursor_parent[2];
|
||||
}
|
||||
if (use_toolsettings) {
|
||||
if ((ob->protectflag & OB_LOCK_LOCX) == 0) {
|
||||
ob->loc[0] += cursor_parent[0];
|
||||
}
|
||||
if ((ob->protectflag & OB_LOCK_LOCY) == 0) {
|
||||
ob->loc[1] += cursor_parent[1];
|
||||
}
|
||||
if ((ob->protectflag & OB_LOCK_LOCZ) == 0) {
|
||||
ob->loc[2] += cursor_parent[2];
|
||||
}
|
||||
|
||||
/* auto-keyframing */
|
||||
ED_autokeyframe_object(C, scene, ob, ks);
|
||||
/* auto-keyframing */
|
||||
ED_autokeyframe_object(C, scene, ob, ks);
|
||||
}
|
||||
else {
|
||||
add_v3_v3(ob->loc, cursor_parent);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
|
||||
}
|
||||
|
@ -570,7 +583,21 @@ static int snap_selected_to_location(bContext *C,
|
|||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ED_view3d_snap_selected_to_location(bContext *C,
|
||||
const float snap_target_global[3],
|
||||
const int pivot_point)
|
||||
{
|
||||
/* These could be passed as arguments if needed. */
|
||||
/* Always use pivot point. */
|
||||
const bool use_offset = true;
|
||||
/* Disable object protected flags & auto-keyframing,
|
||||
* so this can be used as a low level function. */
|
||||
const bool use_toolsettings = false;
|
||||
return snap_selected_to_location(
|
||||
C, snap_target_global, use_offset, pivot_point, use_toolsettings);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
@ -586,8 +613,12 @@ static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
|
||||
const float *snap_target_global = scene->cursor.location;
|
||||
const int pivot_point = scene->toolsettings->transform_pivot_point;
|
||||
|
||||
return snap_selected_to_location(C, snap_target_global, use_offset);
|
||||
if (snap_selected_to_location(C, snap_target_global, pivot_point, use_offset, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
|
||||
|
@ -628,7 +659,10 @@ static int snap_selected_to_active_exec(bContext *C, wmOperator *op)
|
|||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
return snap_selected_to_location(C, snap_target_global, false);
|
||||
if (!snap_selected_to_location(C, snap_target_global, -1, false, true)) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void VIEW3D_OT_snap_selected_to_active(wmOperatorType *ot)
|
||||
|
@ -752,7 +786,7 @@ static void bundle_midpoint(Scene *scene, Object *ob, float r_vec[3])
|
|||
}
|
||||
|
||||
/** Snaps the 3D cursor location to the median point of the selection. */
|
||||
static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
|
||||
static bool snap_curs_to_sel_ex(bContext *C, const int pivot_point, float r_cursor[3])
|
||||
{
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
ViewLayer *view_layer_eval = DEG_get_evaluated_view_layer(depsgraph);
|
||||
|
@ -849,12 +883,12 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
|
|||
return false;
|
||||
}
|
||||
|
||||
if (scene->toolsettings->transform_pivot_point == V3D_AROUND_CENTER_BOUNDS) {
|
||||
mid_v3_v3v3(cursor, min, max);
|
||||
if (pivot_point == V3D_AROUND_CENTER_BOUNDS) {
|
||||
mid_v3_v3v3(r_cursor, min, max);
|
||||
}
|
||||
else {
|
||||
mul_v3_fl(centroid, 1.0f / (float)count);
|
||||
copy_v3_v3(cursor, centroid);
|
||||
copy_v3_v3(r_cursor, centroid);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -862,7 +896,8 @@ static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
|
|||
static int snap_curs_to_sel_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
if (snap_curs_to_sel_ex(C, scene->cursor.location)) {
|
||||
const int pivot_point = scene->toolsettings->transform_pivot_point;
|
||||
if (snap_curs_to_sel_ex(C, pivot_point, scene->cursor.location)) {
|
||||
WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL);
|
||||
DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
||||
|
|
Loading…
Reference in New Issue