[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [13224] trunk/blender/source/blender: === Transform Snap ===

Martin Poirier theeth at yahoo.com
Sun Jan 13 23:20:18 CET 2008


Revision: 13224
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=13224
Author:   theeth
Date:     2008-01-13 23:20:18 +0100 (Sun, 13 Jan 2008)

Log Message:
-----------
=== Transform Snap ===

Snapping for object mode

Changes:
- Transform snap now working in object mode and not just mesh edit mode
- Shift-Tab can be used to toggle snap on/off inside transform too (no more Esc,toggle,restart)
- Object mode snap: Closest uses the bounding box corners of all selected objects, Median uses object center and Center uses transform center (same as edit mode).
- Object mode snap: all visible meshes can be used to get the snapping point (unlike edit mode snap which is limited to selected mesh: this might be adjusted to make edit mode snap use all visible too).

To Do:
- Add "Active" snap target method: use active object (or mesh element) as snap target
- Add snapping capabilities to Scale
- (Maybe) Add "Near pointer" snap target method: use selected element that is closest to mouse pointer as snap target. Active could probably accomplish that already in a less confusing manner, so I might skip this.

Modified Paths:
--------------
    trunk/blender/source/blender/include/BIF_transform.h
    trunk/blender/source/blender/include/transform.h
    trunk/blender/source/blender/src/header_view3d.c
    trunk/blender/source/blender/src/space.c
    trunk/blender/source/blender/src/transform_conversions.c
    trunk/blender/source/blender/src/transform_snap.c

Modified: trunk/blender/source/blender/include/BIF_transform.h
===================================================================
--- trunk/blender/source/blender/include/BIF_transform.h	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/include/BIF_transform.h	2008-01-13 22:20:18 UTC (rev 13224)
@@ -90,6 +90,8 @@
 void BIF_setLocalAxisConstraint(char axis, char *text);
 void BIF_setLocalLockConstraint(char axis, char *text);
 
+int BIF_snappingSupported(void);
+
 struct TransformOrientation;
 
 void BIF_clearTransformOrientation(void);

Modified: trunk/blender/source/blender/include/transform.h
===================================================================
--- trunk/blender/source/blender/include/transform.h	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/include/transform.h	2008-01-13 22:20:18 UTC (rev 13224)
@@ -122,7 +122,7 @@
     float  iquat[4];	 /* Initial rotation quaternion                                                    */
     float *size;         /* Size of the data to transform (Faculative)                                     */
     float  isize[3];	 /* Initial size                                                                   */
-	float  obmat[3][3];	 /* Object matrix */  
+	float  obmat[4][4];	 /* Object matrix */  
 } TransDataExtension;
 
 typedef struct TransData2D {

Modified: trunk/blender/source/blender/src/header_view3d.c
===================================================================
--- trunk/blender/source/blender/src/header_view3d.c	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/src/header_view3d.c	2008-01-13 22:20:18 UTC (rev 13224)
@@ -1818,7 +1818,7 @@
 		uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1, "Center Cursor",          0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 12, "");
 	}
 	
-	if (G.obedit != NULL && G.obedit->type==OB_MESH)
+	if (BIF_snappingSupported())
 	{
 		uiDefBut(block, SEPR, 0, "",                    0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
 	
@@ -5476,7 +5476,7 @@
 		}
 
 		/* Snap */
-		if(G.obedit && (G.obedit->type == OB_MESH)) { // Only Mesh for now
+		if (BIF_snappingSupported()) {
 			uiBlockBeginAlign(block);
 
 			if (G.scene->snap_flag & SCE_SNAP) {

Modified: trunk/blender/source/blender/src/space.c
===================================================================
--- trunk/blender/source/blender/src/space.c	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/src/space.c	2008-01-13 22:20:18 UTC (rev 13224)
@@ -1570,8 +1570,8 @@
 				/* Shift-Tabe handling (other cases are in toets) */
 				if (G.qual == LR_SHIFTKEY)
 				{
-					/* Snap toggle (only edit mesh right now) */
-					if (G.obedit && G.obedit->type==OB_MESH)
+					/* Snap toggle only when supported */
+					if (BIF_snappingSupported())
 					{
 						G.scene->snap_flag ^= SCE_SNAP;
 						allqueue(REDRAWHEADERS, 0);

Modified: trunk/blender/source/blender/src/transform_conversions.c
===================================================================
--- trunk/blender/source/blender/src/transform_conversions.c	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/src/transform_conversions.c	2008-01-13 22:20:18 UTC (rev 13224)
@@ -2861,6 +2861,8 @@
 	VECCOPY(td->ext->dsize, ob->dsize);
 
 	VECCOPY(td->center, ob->obmat[3]);
+	
+	Mat4CpyMat4(td->ext->obmat, ob->obmat);
 
 	/* is there a need to set the global<->data space conversion matrices? */
 	if (ob->parent || constinv) {

Modified: trunk/blender/source/blender/src/transform_snap.c
===================================================================
--- trunk/blender/source/blender/src/transform_snap.c	2008-01-13 18:24:09 UTC (rev 13223)
+++ trunk/blender/source/blender/src/transform_snap.c	2008-01-13 22:20:18 UTC (rev 13224)
@@ -90,10 +90,22 @@
 float TranslationBetween(TransInfo *t, float p1[3], float p2[3]);
 
 // Trickery
-int findNearestVertFromObjects(int *dist, float *loc);
+int findNearestVertFromObjects(int *dist, float *loc, int selected);
 
 /****************** IMPLEMENTATIONS *********************/
 
+int BIF_snappingSupported(void)
+{
+	int status = 0;
+	
+	if (G.obedit == NULL || G.obedit->type==OB_MESH) /* only support object or mesh */
+	{
+		status = 1;
+	}
+	
+	return status;
+}
+
 void drawSnapping(TransInfo *t)
 {
 	if ((t->tsnap.status & (SNAP_ON|POINT_INIT|TARGET_INIT)) == (SNAP_ON|POINT_INIT|TARGET_INIT) &&
@@ -168,7 +180,13 @@
 {
 	int status = 0;
 	
-	// Put keyhandling code here
+	if (BIF_snappingSupported() && event == TABKEY && (G.qual & LR_SHIFTKEY) == LR_SHIFTKEY)
+	{
+		/* toggle snap and reinit */
+		G.scene->snap_flag ^= SCE_SNAP;
+		initSnapping(t);
+		status = 1;
+	}
 	
 	return status;
 }
@@ -211,10 +229,19 @@
 	if (t->spacetype == SPACE_VIEW3D || t->spacetype == SPACE_IMAGE) { // Only 3D view or UV
 		setSnappingCallback(t);
 
+		/* Edit mode */
 		if (t->tsnap.applySnap != NULL && // A snapping function actually exist
+			(G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
 			(G.obedit != NULL && G.obedit->type==OB_MESH) && // Temporary limited to edit mode meshes
+			((t->flag & T_PROP_EDIT) == 0) ) // No PET, obviously
+		{
+			t->tsnap.status |= SNAP_ON;
+			t->tsnap.modePoint = SNAP_GEO;
+		}
+		/* Object mode */
+		else if (t->tsnap.applySnap != NULL && // A snapping function actually exist
 			(G.scene->snap_flag & SCE_SNAP) && // Only if the snap flag is on
-			(t->flag & T_PROP_EDIT) == 0) // No PET, obviously
+			(G.obedit == NULL) ) // Object Mode
 		{
 			t->tsnap.status |= SNAP_ON;
 			t->tsnap.modePoint = SNAP_GEO;
@@ -364,8 +391,29 @@
 
 void CalcSnapGeometry(TransInfo *t, float *vec)
 {
-	if (G.obedit != NULL && G.obedit->type==OB_MESH)
+	if (G.obedit == NULL)
 	{
+		if (t->spacetype == SPACE_VIEW3D)
+		{
+			float vec[3];
+			int found = 0;
+			int dist = 40; // Use a user defined value here
+			
+			found = findNearestVertFromObjects(&dist, vec, 0);
+			if (found == 1)
+			{
+				VECCOPY(t->tsnap.snapPoint, vec);
+				
+				t->tsnap.status |=  POINT_INIT;
+			}
+			else
+			{
+				t->tsnap.status &= ~POINT_INIT;
+			}
+		}
+	}
+	else if (G.obedit != NULL && G.obedit->type==OB_MESH)
+	{
 		/*if (G.scene->selectmode & B_SEL_VERT)*/
 		
 		if (t->spacetype == SPACE_VIEW3D)
@@ -378,7 +426,7 @@
 			// use findnearestverts in vert mode, others in other modes
 			nearest = findnearestvert(&dist, SELECT, 1);
 			
-			found = findNearestVertFromObjects(&dist, vec);
+			found = findNearestVertFromObjects(&dist, vec, SELECT);
 			if (found == 1)
 			{
 				VECCOPY(t->tsnap.snapPoint, vec);
@@ -479,7 +527,7 @@
 		
 		for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
 		{
-			VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->iloc);
+			VecAddf(t->tsnap.snapTarget, t->tsnap.snapTarget, td->center);
 		}
 		
 		VecMulf(t->tsnap.snapTarget, 1.0 / t->total);
@@ -500,28 +548,42 @@
 	{
 		TransData *closest = NULL, *td = NULL;
 		
-		// Base case, only one selected item
-		if (t->total == 1)
+		/* Object mode */
+		if (t->flag & T_OBJECT)
 		{
-			VECCOPY(t->tsnap.snapTarget, t->data[0].iloc);
-
-			if(t->flag & (T_EDIT|T_POSE)) {
-				Object *ob= G.obedit?G.obedit:t->poseobj;
-				Mat4MulVecfl(ob->obmat, t->tsnap.snapTarget);
+			int i;
+			for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
+			{
+				struct BoundBox *bb = object_get_boundbox(td->ob);
+				int j;
+				
+				for (j = 0; j < 8; j++) {
+					float loc[3];
+					float dist;
+					
+					VECCOPY(loc, bb->vec[j]);
+					Mat4MulVecfl(td->ext->obmat, loc);
+					
+					dist = t->tsnap.distance(t, loc, t->tsnap.snapPoint);
+					
+					if (closest == NULL || fabs(dist) < fabs(t->tsnap.dist))
+					{
+						VECCOPY(t->tsnap.snapTarget, loc);
+						closest = td;
+						t->tsnap.dist = dist; 
+					}
+				}
 			}
-
-			t->tsnap.dist = t->tsnap.distance(t, t->tsnap.snapTarget, t->tsnap.snapPoint);
 		}
-		// More than one selected item
 		else
-			{
+		{
 			int i;
 			for(td = t->data, i = 0 ; i < t->total && td->flag & TD_SELECTED ; i++, td++)
 			{
 				float loc[3];
 				float dist;
 				
-				VECCOPY(loc, td->iloc);
+				VECCOPY(loc, td->center);
 				
 				if(t->flag & (T_EDIT|T_POSE)) {
 					Object *ob= G.obedit?G.obedit:t->poseobj;
@@ -544,7 +606,7 @@
 }
 /*================================================================*/
 
-int findNearestVertFromObjects(int *dist, float *loc) {
+int findNearestVertFromObjects(int *dist, float *loc, int selected) {
 	Base *base;
 	int retval = 0;
 	short mval[2];
@@ -553,7 +615,7 @@
 	
 	base= FIRSTBASE;
 	for ( base = FIRSTBASE; base != NULL; base = base->next ) {
-		if ( TESTBASE(base) && base != BASACT ) {
+		if ( base != BASACT && BASE_SELECTABLE(base) && (base->flag & SELECT) == selected ) {
 			Object *ob = base->object;
 			
 			if (ob->type == OB_MESH) {





More information about the Bf-blender-cvs mailing list