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:
authorCampbell Barton <ideasman42@gmail.com>2013-07-20 21:12:33 +0400
committerCampbell Barton <ideasman42@gmail.com>2013-07-20 21:12:33 +0400
commit7233f22e2171d49060a21a46d5f2d2982dabc789 (patch)
tree57d28787341920cc35d041de65c2c53979e77952 /source/blender/editors/space_view3d/view3d_snap.c
parent6eb580e15c99137575efde92cceaf1a8d66f153f (diff)
add new snap option: 'Selection to Cursor (Offset)',
rather then moving everything into the cursor location, the current selection centers around the cursor, maintaining their relative distances. works for mesh, object, pose bones etc.
Diffstat (limited to 'source/blender/editors/space_view3d/view3d_snap.c')
-rw-r--r--source/blender/editors/space_view3d/view3d_snap.c130
1 files changed, 97 insertions, 33 deletions
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)