From ca41cf7484d0d4f4159c87841c78166ea67fe38b Mon Sep 17 00:00:00 2001 From: Jam3D Date: Sat, 9 Sep 2023 01:11:05 +0330 Subject: [PATCH 1/4] snap 3dcursor rotation in pose mode and general TODO: edit mode and other snapping types --- source/blender/blenlib/BLI_math_matrix.h | 12 +++ source/blender/blenlib/intern/math_matrix.c | 30 ++++++ source/blender/editors/include/ED_object.hh | 4 + source/blender/editors/object/object_utils.cc | 94 +++++++++++++++++++ .../editors/space_view3d/view3d_snap.cc | 25 ++++- 5 files changed, 163 insertions(+), 2 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index 2846d315db4..a9e225391e2 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -455,11 +455,23 @@ void rescale_m4(float mat[4][4], const float scale[3]); */ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]); +/** + * Rotate(only) a 3x3 matrix by a 4x4 matrix, + * Useful for setting the rotation of 3dcursor + */ +void rotate_m3_m4(float mat3[3][3], const float mat4[4][4]); + /** * \param rot: A 3x3 rotation matrix, normalized never negative. */ void mat4_to_rot(float rot[3][3], const float wmat[4][4]); +/** + * \param rot: A 3x3 rotation matrix, skewness considered, + * one primary axis is conserved, normalized never negative. + */ +void mat4_to_rot_skew_check(float rot[3][3], const float wmat[4][4], int primary_axis); + /** * \param rot: A 3x3 rotation matrix, normalized never negative. * \param size: The scale, negative if `mat3` is negative. diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 6ccecfa52a1..3dd1f4aea55 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -2220,6 +2220,28 @@ void mat4_to_rot(float rot[3][3], const float wmat[4][4]) } } +/** Makes a rotation matrix, keeping an axis fixed. + ** This is useful in case of having skewness in the original matrix + **/ +void mat4_to_rot_skew_check(float rot[3][3], const float wmat[4][4], int primary_axis) +{ + if (primary_axis < 0 || primary_axis >= 3) { + return; + } + float proj[3]; + normalize_v3_v3(rot[primary_axis], wmat[primary_axis]); + for (int i = 0; i < 3; i++) { + if (i != primary_axis) { + project_v3_v3v3(proj, wmat[i], rot[primary_axis]); + sub_v3_v3v3(rot[i], wmat[i], proj); + normalize_v3(rot[i]); + } + } + if (UNLIKELY(is_negative_m3(rot))) { + negate_m3(rot); + } +} + void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]) { float mat3[3][3]; /* wmat -> 3x3 */ @@ -2373,6 +2395,14 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]) mul_m4_m4m4(mat, mat, tmat); } +void rotate_m3_m4(float mat3[3][3], const float mat4[4][4]) +{ + float rot_mat[3][3], res[3][3]; + mat4_to_rot(rot_mat, mat4); + mul_m3_m3m3(res, rot_mat, mat3); + copy_m3_m3(mat3, res); +} + void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], diff --git a/source/blender/editors/include/ED_object.hh b/source/blender/editors/include/ED_object.hh index 44cf76814a3..ccd418768c0 100644 --- a/source/blender/editors/include/ED_object.hh +++ b/source/blender/editors/include/ED_object.hh @@ -71,6 +71,10 @@ bool ED_object_calc_active_center_for_editmode(Object *obedit, bool ED_object_calc_active_center_for_posemode(Object *ob, bool select_only, float r_center[3]); bool ED_object_calc_active_center(Object *ob, bool select_only, float r_center[3]); +bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, float r_rot[3][3]); +bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float r_rot[3][3]); +bool ED_object_calc_active_rot(Object *ob, const bool select_only, float r_rot[3][3]); + /* Object Data Container helper API. */ struct XFormObjectData_Container; XFormObjectData_Container *ED_object_data_xform_container_create(); diff --git a/source/blender/editors/object/object_utils.cc b/source/blender/editors/object/object_utils.cc index 822832fa935..c7dc3a3454b 100644 --- a/source/blender/editors/object/object_utils.cc +++ b/source/blender/editors/object/object_utils.cc @@ -136,6 +136,100 @@ bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_ce return false; } +// Functions for getting the rotation of active element +bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, float r_rot[3][3]) +{ + switch (obedit->type) { + case OB_MESH: { + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMEditSelection ese; + + if (BM_select_history_active_get(em->bm, &ese)) { + // BM_editselection_center(&ese, r_center); + return true; + } + break; + } + case OB_ARMATURE: { + bArmature *arm = static_cast(obedit->data); + EditBone *ebo = arm->act_edbone; + + if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) { + // copy_v3_v3(r_center, ebo->head); + return true; + } + + break; + } + case OB_CURVES_LEGACY: + case OB_SURF: { + Curve *cu = static_cast(obedit->data); + + return true; + // if (ED_curve_active_center(cu, r_center)) { + // return true; + // } + break; + } + case OB_MBALL: { + MetaBall *mb = static_cast(obedit->data); + MetaElem *ml_act = mb->lastelem; + + if (ml_act && (!select_only || (ml_act->flag & SELECT))) { + // copy_v3_v3(r_center, &ml_act->x); + return true; + } + break; + } + case OB_LATTICE: { + BPoint *actbp = BKE_lattice_active_point_get(static_cast(obedit->data)); + + if (actbp) { + // copy_v3_v3(r_center, actbp->vec); + return true; + } + break; + } + } + + return false; +} + +bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float r_rot[3][3]) +{ + bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob); + if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) { + // keeping y axis untouched + mat4_to_rot_skew_check(r_rot, pchan->pose_mat, 1); + return true; + } + return false; +} + +bool ED_object_calc_active_rot(Object *ob, const bool select_only, float r_rot[3][3]) +{ + if (ob->mode & OB_MODE_EDIT) { + if (ED_object_calc_active_rot_for_editmode(ob, select_only, r_rot)) { + rotate_m3_m4(r_rot, ob->object_to_world); + return true; + } + return false; + } + if (ob->mode & OB_MODE_POSE) { + if (ED_object_calc_active_rot_for_posemode(ob, select_only, r_rot)) { + rotate_m3_m4(r_rot, ob->object_to_world); + return true; + } + return false; + } + if (!select_only || (ob->base_flag & BASE_SELECTED)) { + unit_m3(r_rot); + rotate_m3_m4(r_rot, ob->object_to_world); + return true; + } + return false; +} + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/editors/space_view3d/view3d_snap.cc b/source/blender/editors/space_view3d/view3d_snap.cc index 205cae7ca9e..5d1641549a5 100644 --- a/source/blender/editors/space_view3d/view3d_snap.cc +++ b/source/blender/editors/space_view3d/view3d_snap.cc @@ -885,7 +885,12 @@ static int snap_curs_to_sel_exec(bContext *C, wmOperator * /*op*/) { Scene *scene = CTX_data_scene(C); const int pivot_point = scene->toolsettings->transform_pivot_point; - if (snap_curs_to_sel_ex(C, pivot_point, scene->cursor.location)) { + bool is_align_rot_on = RNA_boolean_get(op->ptr, "is_align_rot_on"); + bool is_align_loc_on = RNA_boolean_get(op->ptr, "is_align_loc_on"); + if (!is_align_loc_on && !is_align_rot_on) { + is_align_loc_on = true; + } + if (is_align_loc_on && snap_curs_to_sel_ex(C, pivot_point, scene->cursor.location)) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); @@ -930,11 +935,27 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r return ED_object_calc_active_center(ob, select_only, r_center); } +static bool snap_cursor_to_active_rot(bContext *C, const bool select_only, View3DCursor *cursor) +{ + Object *ob = CTX_data_active_object(C); + if (ob == nullptr) { + return false; + } + float r_rot[3][3]; + if (ED_object_calc_active_rot(ob, select_only, r_rot)) { + BKE_scene_cursor_mat3_to_rot(cursor, r_rot, false); + return true; + } + return false; +} + static int snap_curs_to_active_exec(bContext *C, wmOperator * /*op*/) { Scene *scene = CTX_data_scene(C); - if (snap_calc_active_center(C, false, scene->cursor.location)) { + if (snap_calc_active_center(C, false, scene->cursor.location) && + snap_cursor_to_active_rot(C, false, &scene->cursor)) + { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); -- 2.30.2 From 64a9cc088ce7834a23e4b44476abb255b4019979 Mon Sep 17 00:00:00 2001 From: Jam3D Date: Wed, 13 Sep 2023 03:58:26 +0330 Subject: [PATCH 2/4] snap 3d cursor in edit mode --- source/blender/blenlib/BLI_math_matrix.h | 13 +-- source/blender/blenlib/intern/math_matrix.c | 87 ++++++++++++------- .../blender/editors/curve/editcurve_query.cc | 20 +++++ source/blender/editors/include/ED_curve.hh | 2 + source/blender/editors/include/ED_object.hh | 4 +- source/blender/editors/object/object_utils.cc | 42 +++++---- .../editors/space_view3d/view3d_snap.cc | 7 +- 7 files changed, 113 insertions(+), 62 deletions(-) diff --git a/source/blender/blenlib/BLI_math_matrix.h b/source/blender/blenlib/BLI_math_matrix.h index a9e225391e2..41f831f123b 100644 --- a/source/blender/blenlib/BLI_math_matrix.h +++ b/source/blender/blenlib/BLI_math_matrix.h @@ -27,6 +27,7 @@ void unit_m2(float m[2][2]); void unit_m3(float m[3][3]); void unit_m4(float m[4][4]); void unit_m4_db(double m[4][4]); +void m3_from_single_axis(float mat3[3][3], const float axis[3], const int axis_index); void copy_m2_m2(float m1[2][2], const float m2[2][2]); void copy_m3_m3(float m1[3][3], const float m2[3][3]); @@ -456,22 +457,16 @@ void rescale_m4(float mat[4][4], const float scale[3]); void transform_pivot_set_m4(float mat[4][4], const float pivot[3]); /** - * Rotate(only) a 3x3 matrix by a 4x4 matrix, - * Useful for setting the rotation of 3dcursor + * \param rot: A 3x3 rotation matrix, skewness considered, + * one primary axis is conserved, normalized never negative. */ -void rotate_m3_m4(float mat3[3][3], const float mat4[4][4]); +void remove_skew_m3_m3(float mat3[3][3], const float wmat[3][3], const int fixed_axis); /** * \param rot: A 3x3 rotation matrix, normalized never negative. */ void mat4_to_rot(float rot[3][3], const float wmat[4][4]); -/** - * \param rot: A 3x3 rotation matrix, skewness considered, - * one primary axis is conserved, normalized never negative. - */ -void mat4_to_rot_skew_check(float rot[3][3], const float wmat[4][4], int primary_axis); - /** * \param rot: A 3x3 rotation matrix, normalized never negative. * \param size: The scale, negative if `mat3` is negative. diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c index 3dd1f4aea55..98d3931c016 100644 --- a/source/blender/blenlib/intern/math_matrix.c +++ b/source/blender/blenlib/intern/math_matrix.c @@ -69,6 +69,40 @@ void unit_m4_db(double m[4][4]) m[3][0] = m[3][1] = m[3][2] = 0.0f; } +void m3_from_single_axis(float mat3[3][3], const float axis[3], const int axis_index) +{ + float len, vec[3], world_ax[3]; + int ax_i = mod_i(axis_index, 3); + zero_v3(world_ax); + world_ax[ax_i] = 1; + // 1st axis + normalize_v3_v3(mat3[ax_i], axis); + if (compare_v3v3(mat3[ax_i], world_ax, FLT_EPSILON)) { + unit_m3(mat3); + return; + } + // check not to generate zero axes + cross_v3_v3v3(vec, mat3[ax_i], world_ax); + len = len_v3(vec); + if (compare_ff(len, 0, 0.01f)) { + zero_v3(vec); + vec[mod_i((ax_i - 1), 3)] = 1; + } + else { + copy_v3_v3(vec, world_ax); + } + // remaining axes + for (int i = 0; i < 2; i++) { + ax_i = mod_i((ax_i - 1), 3); + cross_v3_v3v3(mat3[ax_i], vec, axis); + len = normalize_v3(mat3[ax_i]); + copy_v3_v3(vec, mat3[ax_i]); + } + if (UNLIKELY(is_negative_m3(mat3))) { + negate_m3(mat3); + } +} + void copy_m2_m2(float m1[2][2], const float m2[2][2]) { memcpy(m1, m2, sizeof(float[2][2])); @@ -2210,6 +2244,29 @@ void mat3_to_rot_size(float rot[3][3], float size[3], const float mat3[3][3]) } } +/* Makes a skewed rotation matrices, keeps an axis fixed, + * and orthogonalizes the other two with respect to fixed axis + */ +void remove_skew_m3_m3(float mat3[3][3], const float wmat[3][3], const int fixed_axis) +{ + int cur_axis, prev_axis, f_axis = mod_i(fixed_axis, 3); + float proj[3]; + normalize_v3_v3(mat3[f_axis], wmat[f_axis]); // Keep fixed axis as is + for (int i = 1; i <= 2; i++) { // For the two remaining axes do orthogonalization + cur_axis = mod_i((f_axis + i), 3); + copy_v3_v3(mat3[cur_axis], wmat[cur_axis]); + for (int j = f_axis; j < f_axis + i; j++) { // Make it perpendicular to previous axes + prev_axis = mod_i(j, 3); + project_v3_v3v3(proj, mat3[cur_axis], mat3[prev_axis]); + sub_v3_v3(mat3[cur_axis], proj); + } + normalize_v3(mat3[cur_axis]); + } + if (UNLIKELY(is_negative_m3(mat3))) { + negate_m3(mat3); + } +} + void mat4_to_rot(float rot[3][3], const float wmat[4][4]) { normalize_v3_v3(rot[0], wmat[0]); @@ -2220,28 +2277,6 @@ void mat4_to_rot(float rot[3][3], const float wmat[4][4]) } } -/** Makes a rotation matrix, keeping an axis fixed. - ** This is useful in case of having skewness in the original matrix - **/ -void mat4_to_rot_skew_check(float rot[3][3], const float wmat[4][4], int primary_axis) -{ - if (primary_axis < 0 || primary_axis >= 3) { - return; - } - float proj[3]; - normalize_v3_v3(rot[primary_axis], wmat[primary_axis]); - for (int i = 0; i < 3; i++) { - if (i != primary_axis) { - project_v3_v3v3(proj, wmat[i], rot[primary_axis]); - sub_v3_v3v3(rot[i], wmat[i], proj); - normalize_v3(rot[i]); - } - } - if (UNLIKELY(is_negative_m3(rot))) { - negate_m3(rot); - } -} - void mat4_to_loc_rot_size(float loc[3], float rot[3][3], float size[3], const float wmat[4][4]) { float mat3[3][3]; /* wmat -> 3x3 */ @@ -2395,14 +2430,6 @@ void transform_pivot_set_m4(float mat[4][4], const float pivot[3]) mul_m4_m4m4(mat, mat, tmat); } -void rotate_m3_m4(float mat3[3][3], const float mat4[4][4]) -{ - float rot_mat[3][3], res[3][3]; - mat4_to_rot(rot_mat, mat4); - mul_m3_m3m3(res, rot_mat, mat3); - copy_m3_m3(mat3, res); -} - void blend_m3_m3m3(float out[3][3], const float dst[3][3], const float src[3][3], diff --git a/source/blender/editors/curve/editcurve_query.cc b/source/blender/editors/curve/editcurve_query.cc index 00daa5ff844..3fa30d278af 100644 --- a/source/blender/editors/curve/editcurve_query.cc +++ b/source/blender/editors/curve/editcurve_query.cc @@ -12,6 +12,7 @@ #include "MEM_guardedalloc.h" #include "BLI_listbase.h" +#include "BLI_math_matrix.h" #include "BLI_math_vector.h" #include "BKE_curve.h" @@ -242,4 +243,23 @@ bool ED_curve_active_center(Curve *cu, float center[3]) return true; } +bool ED_curve_active_rot(Curve *cu, float rot[3][3]) +{ + float _axis[3]; + Nurb *nu = nullptr; + void *vert = nullptr; + if (!BKE_curve_nurb_vert_active_get(cu, &nu, &vert)) { + return false; + } + if (nu->type == CU_BEZIER) { + BezTriple *bezt = (BezTriple *)vert; + sub_v3_v3v3(_axis, bezt->vec[2], bezt->vec[1]); + m3_from_single_axis(rot, _axis, 1); + } + else { + unit_m3(rot); + } + return true; +} + /** \} */ diff --git a/source/blender/editors/include/ED_curve.hh b/source/blender/editors/include/ED_curve.hh index 18db65b033f..789cad8e802 100644 --- a/source/blender/editors/include/ED_curve.hh +++ b/source/blender/editors/include/ED_curve.hh @@ -100,6 +100,8 @@ int ED_curve_updateAnimPaths(Main *bmain, Curve *cu); bool ED_curve_active_center(Curve *cu, float center[3]); +bool ED_curve_active_rot(Curve *cu, float rot[3][3]); + /** * Text box selection. * diff --git a/source/blender/editors/include/ED_object.hh b/source/blender/editors/include/ED_object.hh index ccd418768c0..e71e9676934 100644 --- a/source/blender/editors/include/ED_object.hh +++ b/source/blender/editors/include/ED_object.hh @@ -71,7 +71,9 @@ bool ED_object_calc_active_center_for_editmode(Object *obedit, bool ED_object_calc_active_center_for_posemode(Object *ob, bool select_only, float r_center[3]); bool ED_object_calc_active_center(Object *ob, bool select_only, float r_center[3]); -bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, float r_rot[3][3]); +bool ED_object_calc_active_world_rot_for_editmode(Object *obedit, + bool select_only, + float r_rot[3][3]); bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float r_rot[3][3]); bool ED_object_calc_active_rot(Object *ob, const bool select_only, float r_rot[3][3]); diff --git a/source/blender/editors/object/object_utils.cc b/source/blender/editors/object/object_utils.cc index c7dc3a3454b..00158eefc95 100644 --- a/source/blender/editors/object/object_utils.cc +++ b/source/blender/editors/object/object_utils.cc @@ -137,7 +137,9 @@ bool ED_object_calc_active_center(Object *ob, const bool select_only, float r_ce } // Functions for getting the rotation of active element -bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, float r_rot[3][3]) +bool ED_object_calc_active_world_rot_for_editmode(Object *obedit, + bool select_only, + float r_rot[3][3]) { switch (obedit->type) { case OB_MESH: { @@ -145,7 +147,11 @@ bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, fl BMEditSelection ese; if (BM_select_history_active_get(em->bm, &ese)) { - // BM_editselection_center(&ese, r_center); + float _axis[3]; + BM_editselection_normal(&ese, _axis); + m3_from_single_axis(r_rot, _axis, 2); + mul_m3_m4m3(r_rot, obedit->object_to_world, r_rot); + remove_skew_m3_m3(r_rot, r_rot, 0); return true; } break; @@ -155,7 +161,9 @@ bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, fl EditBone *ebo = arm->act_edbone; if (ebo && (!select_only || (ebo->flag & (BONE_SELECTED | BONE_ROOTSEL)))) { - // copy_v3_v3(r_center, ebo->head); + copy_m3_m4(r_rot, ebo->disp_mat); + mul_m3_m4m3(r_rot, obedit->object_to_world, r_rot); + remove_skew_m3_m3(r_rot, r_rot, 1); return true; } @@ -165,10 +173,11 @@ bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, fl case OB_SURF: { Curve *cu = static_cast(obedit->data); - return true; - // if (ED_curve_active_center(cu, r_center)) { - // return true; - // } + if (ED_curve_active_rot(cu, r_rot)) { + mul_m3_m4m3(r_rot, obedit->object_to_world, r_rot); + remove_skew_m3_m3(r_rot, r_rot, 1); + return true; + } break; } case OB_MBALL: { @@ -176,7 +185,8 @@ bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, fl MetaElem *ml_act = mb->lastelem; if (ml_act && (!select_only || (ml_act->flag & SELECT))) { - // copy_v3_v3(r_center, &ml_act->x); + copy_m3_m4(r_rot, obedit->object_to_world); + remove_skew_m3_m3(r_rot, r_rot, 2); return true; } break; @@ -185,7 +195,8 @@ bool ED_object_calc_active_rot_for_editmode(Object *obedit, bool select_only, fl BPoint *actbp = BKE_lattice_active_point_get(static_cast(obedit->data)); if (actbp) { - // copy_v3_v3(r_center, actbp->vec); + copy_m3_m4(r_rot, obedit->object_to_world); + remove_skew_m3_m3(r_rot, r_rot, 2); return true; } break; @@ -199,8 +210,7 @@ bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float { bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob); if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) { - // keeping y axis untouched - mat4_to_rot_skew_check(r_rot, pchan->pose_mat, 1); + copy_m3_m4(r_rot, pchan->pose_mat); return true; } return false; @@ -209,22 +219,22 @@ bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float bool ED_object_calc_active_rot(Object *ob, const bool select_only, float r_rot[3][3]) { if (ob->mode & OB_MODE_EDIT) { - if (ED_object_calc_active_rot_for_editmode(ob, select_only, r_rot)) { - rotate_m3_m4(r_rot, ob->object_to_world); + if (ED_object_calc_active_world_rot_for_editmode(ob, select_only, r_rot)) { return true; } return false; } if (ob->mode & OB_MODE_POSE) { if (ED_object_calc_active_rot_for_posemode(ob, select_only, r_rot)) { - rotate_m3_m4(r_rot, ob->object_to_world); + mul_m3_m4m3(r_rot, ob->object_to_world, r_rot); + remove_skew_m3_m3(r_rot, r_rot, 1); return true; } return false; } if (!select_only || (ob->base_flag & BASE_SELECTED)) { - unit_m3(r_rot); - rotate_m3_m4(r_rot, ob->object_to_world); + copy_m3_m4(r_rot, ob->object_to_world); + remove_skew_m3_m3(r_rot, r_rot, 2); return true; } return false; diff --git a/source/blender/editors/space_view3d/view3d_snap.cc b/source/blender/editors/space_view3d/view3d_snap.cc index 5d1641549a5..9676dc9c329 100644 --- a/source/blender/editors/space_view3d/view3d_snap.cc +++ b/source/blender/editors/space_view3d/view3d_snap.cc @@ -885,12 +885,7 @@ static int snap_curs_to_sel_exec(bContext *C, wmOperator * /*op*/) { Scene *scene = CTX_data_scene(C); const int pivot_point = scene->toolsettings->transform_pivot_point; - bool is_align_rot_on = RNA_boolean_get(op->ptr, "is_align_rot_on"); - bool is_align_loc_on = RNA_boolean_get(op->ptr, "is_align_loc_on"); - if (!is_align_loc_on && !is_align_rot_on) { - is_align_loc_on = true; - } - if (is_align_loc_on && snap_curs_to_sel_ex(C, pivot_point, scene->cursor.location)) { + if (snap_curs_to_sel_ex(C, pivot_point, scene->cursor.location)) { WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); -- 2.30.2 From 418bea4db35877537b839161776f71bcb5d16679 Mon Sep 17 00:00:00 2001 From: Jam3D Date: Wed, 13 Sep 2023 16:28:16 +0330 Subject: [PATCH 3/4] snap mode enum added --- .../editors/space_view3d/view3d_snap.cc | 54 +++++++++++++++---- 1 file changed, 43 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/space_view3d/view3d_snap.cc b/source/blender/editors/space_view3d/view3d_snap.cc index 9676dc9c329..37d758615ec 100644 --- a/source/blender/editors/space_view3d/view3d_snap.cc +++ b/source/blender/editors/space_view3d/view3d_snap.cc @@ -600,6 +600,19 @@ bool ED_view3d_snap_selected_to_location(bContext *C, /** \name Snap Selection to Cursor Operator * \{ */ +enum { + SNAP_LOC = 0, + SNAP_ROT, + SNAP_LOC_ROT, +}; + +static const EnumPropertyItem snap_transform_mode_items[] = { + {SNAP_LOC, "LOC", 0, "Location", ""}, + {SNAP_ROT, "ROT", 0, "Rotation", ""}, + {SNAP_LOC_ROT, "LOC_ROT", 0, "Loc & Rot", ""}, + {0, nullptr, 0, nullptr, nullptr}, +}; + static int snap_selected_to_cursor_exec(bContext *C, wmOperator *op) { const bool use_offset = RNA_boolean_get(op->ptr, "use_offset"); @@ -930,27 +943,43 @@ static bool snap_calc_active_center(bContext *C, const bool select_only, float r return ED_object_calc_active_center(ob, select_only, r_center); } -static bool snap_cursor_to_active_rot(bContext *C, const bool select_only, View3DCursor *cursor) +static bool snap_calc_active_rot(bContext *C, const bool select_only, float r_rot[3][3]) { Object *ob = CTX_data_active_object(C); if (ob == nullptr) { return false; } - float r_rot[3][3]; - if (ED_object_calc_active_rot(ob, select_only, r_rot)) { - BKE_scene_cursor_mat3_to_rot(cursor, r_rot, false); - return true; - } - return false; + return ED_object_calc_active_rot(ob, select_only, r_rot); } -static int snap_curs_to_active_exec(bContext *C, wmOperator * /*op*/) +static int snap_curs_to_active_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); + const int snap_mode = RNA_enum_get(op->ptr, "snap_mode"); + bool is_snap_done = false, is_loc_done = false, is_rot_done = false; + float r_center[3], r_rot[3][3]; + switch (snap_mode) { + case SNAP_LOC: + is_loc_done = is_snap_done = snap_calc_active_center(C, false, r_center); + break; + case SNAP_ROT: + is_rot_done = is_snap_done = snap_calc_active_rot(C, false, r_rot); + break; + case SNAP_LOC_ROT: + is_loc_done = is_rot_done = is_snap_done = snap_calc_active_center(C, false, r_center) & + snap_calc_active_rot(C, false, r_rot); + break; - if (snap_calc_active_center(C, false, scene->cursor.location) && - snap_cursor_to_active_rot(C, false, &scene->cursor)) - { + default: + break; + } + if (is_snap_done) { + if (is_loc_done) { + copy_v3_v3(scene->cursor.location, r_center); + } + if (is_rot_done) { + BKE_scene_cursor_mat3_to_rot(&scene->cursor, r_rot, false); + } WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, nullptr); DEG_id_tag_update(&scene->id, ID_RECALC_COPY_ON_WRITE); @@ -972,6 +1001,9 @@ void VIEW3D_OT_snap_cursor_to_active(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "snap_mode", snap_transform_mode_items, 0, "Snap Mode", ""); } /** \} */ -- 2.30.2 From 3bf9f6a9a7e7209e8580dff964f640659d842b64 Mon Sep 17 00:00:00 2001 From: Jam3D Date: Fri, 22 Sep 2023 14:06:55 +0330 Subject: [PATCH 4/4] active bone function rename --- source/blender/editors/object/object_utils.cc | 2 +- source/blender/editors/space_view3d/view3d_snap.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/editors/object/object_utils.cc b/source/blender/editors/object/object_utils.cc index 00158eefc95..f3e3a8231cb 100644 --- a/source/blender/editors/object/object_utils.cc +++ b/source/blender/editors/object/object_utils.cc @@ -208,7 +208,7 @@ bool ED_object_calc_active_world_rot_for_editmode(Object *obedit, bool ED_object_calc_active_rot_for_posemode(Object *ob, bool select_only, float r_rot[3][3]) { - bPoseChannel *pchan = BKE_pose_channel_active_if_layer_visible(ob); + bPoseChannel *pchan = BKE_pose_channel_active_if_bonecoll_visible(ob); if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) { copy_m3_m4(r_rot, pchan->pose_mat); return true; diff --git a/source/blender/editors/space_view3d/view3d_snap.cc b/source/blender/editors/space_view3d/view3d_snap.cc index 37d758615ec..cba7600f079 100644 --- a/source/blender/editors/space_view3d/view3d_snap.cc +++ b/source/blender/editors/space_view3d/view3d_snap.cc @@ -609,7 +609,7 @@ enum { static const EnumPropertyItem snap_transform_mode_items[] = { {SNAP_LOC, "LOC", 0, "Location", ""}, {SNAP_ROT, "ROT", 0, "Rotation", ""}, - {SNAP_LOC_ROT, "LOC_ROT", 0, "Loc & Rot", ""}, + {SNAP_LOC_ROT, "LOC_ROT", 0, "Location & Rotation", ""}, {0, nullptr, 0, nullptr, nullptr}, }; -- 2.30.2