[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [15323] trunk/blender/source/blender/src/ transform_snap.c: Transform Snapping

Martin Poirier theeth at yahoo.com
Mon Jun 23 01:21:29 CEST 2008


Revision: 15323
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=15323
Author:   theeth
Date:     2008-06-23 01:21:29 +0200 (Mon, 23 Jun 2008)

Log Message:
-----------
Transform Snapping

Snap to edges and vertice without have to go through faces.

This means you can import floor plans and use the edges as snapping guides and other sort of fun things.

The bounding box test still needs padding though.

Modified Paths:
--------------
    trunk/blender/source/blender/src/transform_snap.c

Modified: trunk/blender/source/blender/src/transform_snap.c
===================================================================
--- trunk/blender/source/blender/src/transform_snap.c	2008-06-22 23:07:42 UTC (rev 15322)
+++ trunk/blender/source/blender/src/transform_snap.c	2008-06-22 23:21:29 UTC (rev 15323)
@@ -737,136 +737,6 @@
 }
 /*================================================================*/
 
-
-/* find snapping point on face, return 1 on success */
-int snapFace(MFace *face, EditFace *efa, MVert *verts, float *intersect, float *loc, float *no)
-{
-	MVert *v[4];
-	EditVert *eve[4];
-	int totvert;
-	int result = 0;
-	
-	v[0] = verts + face->v1;
-	v[1] = verts + face->v2;
-	v[2] = verts + face->v3;
-	
-	if (face->v4)
-	{
-		v[3] = verts + face->v4;
-		totvert = 4;
-	}
-	else
-	{
-		v[3] = NULL;
-		totvert = 3;
-	}
-	
-	if (efa)
-	{
-		eve[0] = efa->v1;
-		eve[1] = efa->v2;
-		eve[2] = efa->v3;
-		eve[3] = efa->v4;
-	}
-	
-	switch(G.scene->snap_mode)
-	{
-		case SCE_SNAP_MODE_VERTEX:
-			{
-				float min_dist = FLT_MAX;
-				int i;
-				
-				for(i = 0; i < totvert; i++)
-				{
-					
-					if (efa == NULL || (eve[i]->f1 & SELECT) == 0)
-					{
-						float vert_dist = VecLenf(v[i]->co, intersect);
-						
-						if (vert_dist < min_dist)
-						{
-							result = 1;
-							
-							min_dist = vert_dist;
-	
-							VECCOPY(loc, v[i]->co);
-							NormalShortToFloat(no, v[i]->no);						
-						}
-					}
-				}
-				break;
-			}
-		case SCE_SNAP_MODE_EDGE:
-			{
-				float min_dist = FLT_MAX;
-				int i;
-				
-				for(i = 0; i < totvert; i++)
-				{
-					MVert *v1, *v2;
-					EditVert *eve1, *eve2;
-					
-					v1 = v[i];
-					v2 = v[(i + 1) % totvert];
-					
-					eve1 = eve[i];
-					eve2 = eve[(i + 1) % totvert];
-					
-					if (efa == NULL || ((eve1->f1 & SELECT) == 0 && (eve2->f1 & SELECT) == 0))
-					{
-						float edge_loc[3];
-						float vec[3];
-						float mul;
-						float edge_dist;
-						
-						VecSubf(edge_loc, v2->co, v1->co);
-						VecSubf(vec, intersect, v1->co);
-						
-						mul = Inpf(vec, edge_loc) / Inpf(edge_loc, edge_loc);
-						
-						VecMulf(edge_loc, mul);
-						VecAddf(edge_loc, edge_loc, v1->co);
-						
-						edge_dist = VecLenf(edge_loc, intersect);
-						
-						if (edge_dist < min_dist)
-						{
-							float n1[3], n2[3];
-							result = 1;
-							
-							min_dist = edge_dist;
-	
-							VECCOPY(loc, edge_loc);
-							
-							NormalShortToFloat(n1, v1->no);						
-							NormalShortToFloat(n2, v2->no);
-							VecLerpf(no, n1, n2, mul);
-							Normalize(no);						
-						}
-					}
-				}
-				break;
-			}
-		case SCE_SNAP_MODE_FACE:
-			{
-				if (efa == NULL || ((efa->f1 & SELECT) == 0))
-				{
-					result = 1;
-	
-					VECCOPY(loc, intersect);
-					
-					if (totvert == 4)
-						CalcNormFloat4(v[0]->co, v[1]->co, v[2]->co, v[3]->co, no);
-					else
-						CalcNormFloat(v[0]->co, v[1]->co, v[2]->co, no);
-				}
-				break;
-			}
-	}
-	
-	return result;
-}
-
 int snapDerivedMesh(Object *ob, DerivedMesh *dm, float obmat[][4], float ray_start[3], float ray_normal[3], short mval[2], float *loc, float *no, int *dist, float *depth, short EditMesh)
 {
 	int retval = 0;
@@ -891,7 +761,7 @@
 		Mat4Mul3Vecfl(imat, ray_normal_local);
 		
 		
-		/* If number of vert is more than an arbitrary limit,
+		/* If number of vert is more than an arbitrary limit, 
 		 * test against boundbox first
 		 * */
 		if (totface > 16) {
@@ -900,117 +770,219 @@
 		}
 		
 		if (test == 1) {
-			MVert *verts = dm->getVertArray(dm);
-			MFace *faces = dm->getFaceArray(dm);
-			int *index_array = NULL;
-			int index = 0;
-			int i;
 			
-			if (EditMesh)
+			switch (G.scene->snap_mode)
 			{
-				index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
-				EM_init_index_arrays(0, 0, 1);
-			}
-			
-			for( i = 0; i < totface; i++) {
-				EditFace *efa = NULL;
-				MFace *f = faces + i;
-				float lambda;
-				int result;
-				
-				test = 1; /* reset for every face */
-			
-				if (EditMesh)
-				{
-					if (index_array)
+				case SCE_SNAP_MODE_FACE:
+				{ 
+					MVert *verts = dm->getVertArray(dm);
+					MFace *faces = dm->getFaceArray(dm);
+					int *index_array = NULL;
+					int index = 0;
+					int i;
+					
+					if (EditMesh)
 					{
-						index = index_array[i];
+						index_array = dm->getFaceDataArray(dm, CD_ORIGINDEX);
+						EM_init_index_arrays(0, 0, 1);
 					}
-					else
-					{
-						index = i;
-					}
 					
-					if (index == ORIGINDEX_NONE)
-					{
-						test = 0;
-					}
-					else
-					{
-						efa = EM_get_face_for_index(index);
+					for( i = 0; i < totface; i++) {
+						EditFace *efa = NULL;
+						MFace *f = faces + i;
+						float lambda;
+						int result;
 						
-						if (efa && efa->f1 & SELECT)
+						test = 1; /* reset for every face */
+					
+						if (EditMesh)
 						{
-							test = 0;
+							if (index_array)
+							{
+								index = index_array[i];
+							}
+							else
+							{
+								index = i;
+							}
+							
+							if (index == ORIGINDEX_NONE)
+							{
+								test = 0;
+							}
+							else
+							{
+								efa = EM_get_face_for_index(index);
+								
+								if (efa && efa->f & SELECT)
+								{
+									test = 0;
+								}
+							}
 						}
-					}
-				}
-				
-				
-				if (test)
-				{
-					result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
-					
-					if (result) {
-						float location[3], normal[3];
-						float intersect[3];
 						
-						VECCOPY(intersect, ray_normal_local);
-						VecMulf(intersect, lambda);
-						VecAddf(intersect, intersect, ray_start_local);
 						
-						if (snapFace(f, efa, verts, intersect, location, normal))
-						{ 
-							float new_depth;
-							int screen_loc[2];
-							int new_dist;
+						if (test)
+						{
+							result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, &lambda, NULL);
 							
-							Mat4MulVecfl(obmat, location);
-							
-							new_depth = VecLenf(location, ray_start);					
-							
-							project_int(location, screen_loc);
-							new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
-							
-							if (new_dist <= *dist && new_depth < *depth)
-							{
-								*depth = new_depth;
-								retval = 1;
+							if (result) {
+								float location[3], normal[3];
+								float intersect[3];
+								float new_depth;
+								int screen_loc[2];
+								int new_dist;
 								
-								VECCOPY(loc, location);
-								VECCOPY(no, normal);
+								VECCOPY(intersect, ray_normal_local);
+								VecMulf(intersect, lambda);
+								VecAddf(intersect, intersect, ray_start_local);
 								
-								Mat3MulVecfl(timat, no);
-								Normalize(no);
-				
-								project_int(loc, screen_loc);
+								VECCOPY(location, intersect);
 								
-								*dist = new_dist;
-							} 
+								if (f->v4)
+									CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+								else
+									CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+
+								Mat4MulVecfl(obmat, location);
+								
+								new_depth = VecLenf(location, ray_start);					
+								
+								project_int(location, screen_loc);
+								new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+								
+								if (new_dist <= *dist && new_depth < *depth)
+								{
+									*depth = new_depth;
+									retval = 1;
+									
+									VECCOPY(loc, location);
+									VECCOPY(no, normal);
+									
+									Mat3MulVecfl(timat, no);
+									Normalize(no);
+					
+									*dist = new_dist;
+								} 
+							}
+					
+							if (f->v4 && result == 0)
+							{
+								result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
+								
+								if (result) {
+									float location[3], normal[3];
+									float intersect[3];
+									float new_depth;
+									int screen_loc[2];
+									int new_dist;
+									
+									VECCOPY(intersect, ray_normal_local);
+									VecMulf(intersect, lambda);
+									VecAddf(intersect, intersect, ray_start_local);
+									
+									VECCOPY(location, intersect);
+									
+									if (f->v4)
+										CalcNormFloat4(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, verts[f->v4].co, normal);
+									else
+										CalcNormFloat(verts[f->v1].co, verts[f->v2].co, verts[f->v3].co, normal);
+	
+									Mat4MulVecfl(obmat, location);
+									
+									new_depth = VecLenf(location, ray_start);					
+									
+									project_int(location, screen_loc);
+									new_dist = abs(screen_loc[0] - mval[0]) + abs(screen_loc[1] - mval[1]);
+									
+									if (new_dist <= *dist && new_depth < *depth)
+									{
+										*depth = new_depth;
+										retval = 1;
+										
+										VECCOPY(loc, location);
+										VECCOPY(no, normal);
+										
+										Mat3MulVecfl(timat, no);
+										Normalize(no);
+						
+										*dist = new_dist;
+									}
+								} 
+							}
 						}
 					}
-			
-					if (f->v4 && result == 0)
+					
+					if (EditMesh)
 					{
-						result = RayIntersectsTriangle(ray_start_local, ray_normal_local, verts[f->v3].co, verts[f->v4].co, verts[f->v1].co, &lambda, NULL);
+						EM_free_index_arrays();
+					}
+					break;
+				}
+				case SCE_SNAP_MODE_VERTEX:
+				{
+					MVert *verts = dm->getVertArray(dm);
+					int *index_array = NULL;
+					int index = 0;
+					int i;
+					
+					if (EditMesh)
+					{
+						index_array = dm->getVertDataArray(dm, CD_ORIGINDEX);
+						EM_init_index_arrays(1, 0, 0);
+					}
+					
+					for( i = 0; i < totvert; i++) {
+						EditVert *eve = NULL;
+						MVert *v = verts + i;
 						
-						if (result) {
-							float location[3], normal[3];
-							float intersect[3];
+						test = 1; /* reset for every vert */
+					
+						if (EditMesh)
+						{
+							if (index_array)
+							{
+								index = index_array[i];
+							}
+							else
+							{
+								index = i;
+							}
 							
-							VECCOPY(intersect, ray_normal_local);
-							VecMulf(intersect, lambda);
-							VecAddf(intersect, intersect, ray_start_local);
-				
-							if (snapFace(f, efa, verts, intersect, location, normal))
-							{ 
+							if (index == ORIGINDEX_NONE)
+							{
+								test = 0;
+							}
+							else
+							{
+								eve = EM_get_vert_for_index(index);
+								
+								if (eve && eve->f & SELECT)
+								{
+									test = 0;
+								}
+							}
+						}
+						
+						
+						if (test)
+						{

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list