[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58453] trunk/blender: add new snap option : 'Selection to Cursor (Offset)',

Campbell Barton ideasman42 at gmail.com
Sat Jul 20 19:12:34 CEST 2013


Revision: 58453
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58453
Author:   campbellbarton
Date:     2013-07-20 17:12:33 +0000 (Sat, 20 Jul 2013)
Log Message:
-----------
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.

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
    trunk/blender/source/blender/editors/space_view3d/view3d_snap.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-07-20 15:47:53 UTC (rev 58452)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-07-20 17:12:33 UTC (rev 58453)
@@ -293,7 +293,10 @@
         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()
 

Modified: trunk/blender/source/blender/editors/space_view3d/view3d_snap.c
===================================================================
--- trunk/blender/source/blender/editors/space_view3d/view3d_snap.c	2013-07-20 15:47:53 UTC (rev 58452)
+++ trunk/blender/source/blender/editors/space_view3d/view3d_snap.c	2013-07-20 17:12:33 UTC (rev 58453)
@@ -64,8 +64,9 @@
 #include "WM_api.h"
 #include "WM_types.h"
 
+#include "RNA_access.h"
+#include "RNA_define.h"
 
-
 #include "ED_armature.h"
 #include "ED_mesh.h"
 #include "ED_keyframing.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 @@
 
 /* *************************************************** */
 
-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 @@
 	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,12 +706,26 @@
 		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,17 +743,26 @@
 				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)
 									pchan->loc[0] = cursor_pose[0];
@@ -751,9 +786,15 @@
 			}
 			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 @@
 	
 	/* flags */
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	/* rna */
+	RNA_def_boolean(ot->srna, "use_offset", 1, "Offset", "");
 }
 
 /* *************************************************** */
@@ -888,28 +932,29 @@
 	}
 }
 
-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 @@
 		
 		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,21 +1013,40 @@
 			}
 			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)
 {
 	/* identifiers */




More information about the Bf-blender-cvs mailing list