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:
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py5
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c130
2 files changed, 101 insertions, 34 deletions
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index a5c8e7727b2..19095df6a14 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -293,7 +293,10 @@ class VIEW3D_MT_snap(Menu):
layout = self.layout
layout.operator("view3d.snap_selected_to_grid", text="Selection to Grid")
- layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor")
+ props = layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor")
+ props.use_offset = False
+ props = layout.operator("view3d.snap_selected_to_cursor", text="Selection to Cursor (Offset)")
+ props.use_offset = True
layout.separator()
diff --git a/source/blender/editors/space_view3d/view3d_snap.c b/source/blender/editors/space_view3d/view3d_snap.c
index 28291971570..fb7bbdaa178 100644
--- a/source/blender/editors/space_view3d/view3d_snap.c
+++ b/source/blender/editors/space_view3d/view3d_snap.c
@@ -64,7 +64,8 @@
#include "WM_api.h"
#include "WM_types.h"
-
+#include "RNA_access.h"
+#include "RNA_define.h"
#include "ED_armature.h"
#include "ED_mesh.h"
@@ -79,6 +80,8 @@
/* *********** will get replaced with new transform * */
/* ************************************************** */
+static bool snap_curs_to_sel_ex(bContext *C, float cursor[3]);
+
typedef struct TransVert {
float *loc;
float oldloc[3], maploc[3];
@@ -670,7 +673,7 @@ void VIEW3D_OT_snap_selected_to_grid(wmOperatorType *ot)
/* *************************************************** */
-static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
+static int snap_sel_to_curs(bContext *C, wmOperator *op)
{
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
@@ -678,10 +681,19 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
TransVert *tv;
float imat[3][3], bmat[3][3];
const float *cursor_global;
+ float center_global[3];
+ float offset_global[3];
int a;
+ const bool use_offset = RNA_boolean_get(op->ptr, "use_offset");
+
cursor_global = give_cursor(scene, v3d);
+ if (use_offset) {
+ snap_curs_to_sel_ex(C, center_global);
+ sub_v3_v3v3(offset_global, cursor_global, center_global);
+ }
+
if (obedit) {
float cursor_local[3];
@@ -694,11 +706,25 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
copy_m3_m4(bmat, obedit->obmat);
invert_m3_m3(imat, bmat);
- tv = transvmain;
+ /* get the cursor in object space */
sub_v3_v3v3(cursor_local, cursor_global, obedit->obmat[3]);
mul_m3_v3(imat, cursor_local);
- for (a = 0; a < tottrans; a++, tv++) {
- copy_v3_v3(tv->loc, cursor_local);
+
+ if (use_offset) {
+ float offset_local[3];
+
+ mul_v3_m3v3(offset_local, imat, offset_global);
+
+ tv = transvmain;
+ for (a = 0; a < tottrans; a++, tv++) {
+ add_v3_v3(tv->loc, offset_local);
+ }
+ }
+ else {
+ tv = transvmain;
+ for (a = 0; a < tottrans; a++, tv++) {
+ copy_v3_v3(tv->loc, cursor_local);
+ }
}
special_transvert_update(obedit);
@@ -717,16 +743,25 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
float cursor_local[3];
invert_m4_m4(ob->imat, ob->obmat);
- copy_v3_v3(cursor_local, cursor_global);
- mul_m4_v3(ob->imat, cursor_local);
-
+ mul_v3_m4v3(cursor_local, ob->imat, cursor_global);
+
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (pchan->bone->flag & BONE_SELECTED) {
- if (pchan->bone->layer & arm->layer) {
+ if (PBONE_VISIBLE(arm, pchan->bone)) {
if ((pchan->bone->flag & BONE_CONNECTED) == 0) {
/* Get position in pchan (pose) space. */
float cursor_pose[3];
- BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose);
+
+ if (use_offset) {
+ mul_v3_m4v3(cursor_pose, ob->obmat, pchan->pose_mat[3]);
+ add_v3_v3(cursor_pose, offset_global);
+
+ mul_m4_v3(ob->imat, cursor_pose);
+ BKE_armature_loc_pose_to_bone(pchan, cursor_pose, cursor_pose);
+ }
+ else {
+ BKE_armature_loc_pose_to_bone(pchan, cursor_local, cursor_pose);
+ }
/* copy new position */
if ((pchan->protectflag & OB_LOCK_LOCX) == 0)
@@ -751,9 +786,15 @@ static int snap_sel_to_curs(bContext *C, wmOperator *UNUSED(op))
}
else {
float cursor_parent[3]; /* parent-relative */
- cursor_parent[0] = -ob->obmat[3][0] + cursor_global[0];
- cursor_parent[1] = -ob->obmat[3][1] + cursor_global[1];
- cursor_parent[2] = -ob->obmat[3][2] + cursor_global[2];
+
+ if (use_offset) {
+ add_v3_v3v3(cursor_parent, ob->obmat[3], offset_global);
+ }
+ else {
+ copy_v3_v3(cursor_parent, cursor_global);
+ }
+
+ sub_v3_v3(cursor_parent, ob->obmat[3]);
if (ob->parent) {
float originmat[3][3];
@@ -796,6 +837,9 @@ void VIEW3D_OT_snap_selected_to_cursor(wmOperatorType *ot)
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* rna */
+ RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", "");
}
/* *************************************************** */
@@ -888,28 +932,29 @@ static void bundle_midpoint(Scene *scene, Object *ob, float vec[3])
}
}
-static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
+static bool snap_curs_to_sel_ex(bContext *C, float cursor[3])
{
Object *obedit = CTX_data_edit_object(C);
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
TransVert *tv;
- float *curs, bmat[3][3], vec[3], min[3], max[3], centroid[3];
+ float bmat[3][3], vec[3], min[3], max[3], centroid[3];
int count, a;
- curs = give_cursor(scene, v3d);
-
count = 0;
INIT_MINMAX(min, max);
zero_v3(centroid);
if (obedit) {
tottrans = 0;
-
+
if (ELEM6(obedit->type, OB_ARMATURE, OB_LATTICE, OB_MESH, OB_SURF, OB_CURVE, OB_MBALL))
make_trans_verts(obedit, bmat[0], bmat[1], TM_ALL_JOINTS | TM_SKIP_HANDLES);
- if (tottrans == 0) return OPERATOR_CANCELLED;
-
+
+ if (tottrans == 0) {
+ return false;
+ }
+
copy_m3_m4(bmat, obedit->obmat);
tv = transvmain;
@@ -923,10 +968,10 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
if (v3d->around == V3D_CENTROID) {
mul_v3_fl(centroid, 1.0f / (float)tottrans);
- copy_v3_v3(curs, centroid);
+ copy_v3_v3(cursor, centroid);
}
else {
- mid_v3_v3v3(curs, min, max);
+ mid_v3_v3v3(cursor, min, max);
}
MEM_freeN(transvmain);
transvmain = NULL;
@@ -968,19 +1013,38 @@ static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
}
CTX_DATA_END;
}
- if (count) {
- if (v3d->around == V3D_CENTROID) {
- mul_v3_fl(centroid, 1.0f / (float)count);
- copy_v3_v3(curs, centroid);
- }
- else {
- mid_v3_v3v3(curs, min, max);
- }
+
+ if (count == 0) {
+ return false;
+ }
+
+ if (v3d->around == V3D_CENTROID) {
+ mul_v3_fl(centroid, 1.0f / (float)count);
+ copy_v3_v3(cursor, centroid);
+ }
+ else {
+ mid_v3_v3v3(cursor, min, max);
}
}
- WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
-
- return OPERATOR_FINISHED;
+ return true;
+}
+
+static int snap_curs_to_sel(bContext *C, wmOperator *UNUSED(op))
+{
+ Scene *scene = CTX_data_scene(C);
+ View3D *v3d = CTX_wm_view3d(C);
+ float *curs;
+
+ curs = give_cursor(scene, v3d);
+
+ if (snap_curs_to_sel_ex(C, curs)) {
+ WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
void VIEW3D_OT_snap_cursor_to_selected(wmOperatorType *ot)