[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40870] branches/bmesh/blender/source/ blender: Refactor removedoubles ( merge 3 different version of code to find doubles into one).

Andrew Wiggin ender79bl at gmail.com
Sun Oct 9 05:05:40 CEST 2011


Revision: 40870
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40870
Author:   ender79
Date:     2011-10-09 03:05:36 +0000 (Sun, 09 Oct 2011)
Log Message:
-----------
Refactor removedoubles (merge 3 different version of code to find doubles into one). Also fixes a minor bug where automerge would merge any two vertices (not just selected verts into unselected verts like trunk) and fixes the edge slide crash (bug 28688)

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c
    branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c

Modified: branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c	2011-10-09 02:24:51 UTC (rev 40869)
+++ branches/bmesh/blender/source/blender/bmesh/operators/removedoubles.c	2011-10-09 03:05:36 UTC (rev 40870)
@@ -445,76 +445,17 @@
 	}
 }
 
-void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
+void bmesh_finddoubles_common(BMesh *bm, BMOperator *op, BMOperator *optarget, const char *targetmapname)
 {
-	BMOperator weldop;
 	BMOIter oiter;
 	BMVert *v, *v2;
 	BMVert **verts=NULL;
 	BLI_array_declare(verts);
-	float dist, distsqr;
-	int i, j, len;
-
-	dist = BMO_Get_Float(op, "dist");
-	distsqr = dist*dist;
-
-	BMO_Init_Op(&weldop, "weldverts");
-	
-	i = 0;
-	BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
-		BLI_array_growone(verts);
-		verts[i++] = v;
-	}
-
-	/*sort by vertex coordinates added together*/
-	qsort(verts, BLI_array_count(verts), sizeof(void*), vergaverco);
-	
-	len = BLI_array_count(verts);
-	for (i=0; i<len; i++) {
-		v = verts[i];
-		if (BMO_TestFlag(bm, v, VERT_TESTED)) continue;
-		
-		BMO_SetFlag(bm, v, VERT_TESTED);
-		for (j=i+1; j<len; j++) {
-			float vec[3];
-			
-			v2 = verts[j];
-			//if ((v2->co[0]+v2->co[1]+v2->co[2]) - (v->co[0]+v->co[1]+v->co[2])
-			//     > dist) break;
-			if ((v2->co[0]-v->co[0]) + (v2->co[1]-v->co[1]) + (v2->co[2]-v->co[2]) > dist)
-				break;
-
-			vec[0] = v->co[0] - v2->co[0];
-			vec[1] = v->co[1] - v2->co[1];
-			vec[2] = v->co[2] - v2->co[2];
-			
-			if (INPR(vec, vec) < distsqr) {
-				BMO_SetFlag(bm, v2, VERT_TESTED);
-				BMO_SetFlag(bm, v2, VERT_DOUBLE);
-				BMO_SetFlag(bm, v, VERT_TARGET);
-			
-				BMO_Insert_MapPointer(bm, &weldop, "targetmap", v2, v);
-			}
-		}
-	}
-
-	BLI_array_free(verts);
-
-	BMO_Exec_Op(bm, &weldop);
-	BMO_Finish_Op(bm, &weldop);
-}
-
-
-void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
-{
-	BMOIter oiter;
-	BMVert *v, *v2;
-	BMVert **verts=NULL;
-	BLI_array_declare(verts);
-	float dist;
+	float dist, dist3;
 	int i, j, len, keepvert;
 
 	dist = BMO_Get_Float(op, "dist");
+	dist3 = dist * 3.0f;
 
 	i = 0;
 	BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
@@ -536,7 +477,11 @@
 		
 		for (j=i+1; j<len; j++) {
 			v2 = verts[j];
-			if ((v2->co[0]+v2->co[1]+v2->co[2]) - (v->co[0]+v->co[1]+v->co[2]) > dist)
+
+			/* Compare sort values of the verts using 3x tolerance (allowing for the tolerance
+			   on each of the three axes). This avoids the more expensive length comparison
+			   for most vertex pairs. */
+			if ((v2->co[0]+v2->co[1]+v2->co[2])-(v->co[0]+v->co[1]+v->co[2]) > dist3)
 				break;
 
 			if (keepvert) {
@@ -545,10 +490,16 @@
 			}
 
 			if (compare_len_v3v3(v->co, v2->co, dist)) {
+
+				/* If one vert is marked as keep, make sure it will be the target */
+				if (BMO_TestFlag(bm, v2, VERT_KEEP)) {
+					SWAP(BMVert *, v, v2);
+				}
+
 				BMO_SetFlag(bm, v2, VERT_DOUBLE);
 				BMO_SetFlag(bm, v, VERT_TARGET);
 			
-				BMO_Insert_MapPointer(bm, op, "targetmapout", v2, v);
+				BMO_Insert_MapPointer(bm, optarget, targetmapname, v2, v);
 			}
 		}
 	}
@@ -556,56 +507,49 @@
 	BLI_array_free(verts);
 }
 
-void bmesh_automerge_exec(BMesh *bm, BMOperator *op)
+void bmesh_removedoubles_exec(BMesh *bm, BMOperator *op)
 {
-	BMOIter oiter;
 	BMOperator weldop;
-	BMVert *v, *v2;
-	BMVert **verts=NULL;
-	BLI_array_declare(verts);
-	float dist;
-	int i, j, len /* , keepvert */;
 
-	dist = BMO_Get_Float(op, "dist");
-
-	i = 0;
-	BMO_ITER(v, &oiter, bm, op, "verts", BM_VERT) {
-		BLI_array_growone(verts);
-		verts[i++] = v;
-	}
-
 	BMO_Init_Op(&weldop, "weldverts");
+	bmesh_finddoubles_common(bm, op, &weldop, "targetmap");
+	BMO_Exec_Op(bm, &weldop);
+	BMO_Finish_Op(bm, &weldop);
+}
 
-	/*sort by vertex coordinates added together*/
-	qsort(verts, BLI_array_count(verts), sizeof(void*), vergaverco);
-	
-	BMO_Flag_Buffer(bm, op, "verts", VERT_KEEP, BM_VERT);
 
-	len = BLI_array_count(verts);
-	for (i=0; i<len; i++) {
-		v = verts[i];
-		if (BMO_TestFlag(bm, v, VERT_DOUBLE)) continue;
-		
-		for (j=i+1; j<len; j++) {
-			v2 = verts[j];
-			if ((v2->co[0]+v2->co[1]+v2->co[2]) - (v->co[0]+v->co[1]+v->co[2])
-			     > dist) break;
-			
-			/* only allow unselected -> selected */
-			if (BMO_TestFlag(bm, v2, VERT_IN))
-				continue;
+void bmesh_finddoubles_exec(BMesh *bm, BMOperator *op)
+{
+	bmesh_finddoubles_common(bm, op, op, "targetmapout");
+}
 
-			if (compare_len_v3v3(v->co, v2->co, dist)) {
-				BMO_SetFlag(bm, v2, VERT_DOUBLE);
-				BMO_SetFlag(bm, v, VERT_TARGET);
-			
-				BMO_Insert_MapPointer(bm, &weldop, "targetmap", v2, v);
-			}
+void bmesh_automerge_exec(BMesh *bm, BMOperator *op)
+{
+	BMOperator findop, weldop;
+	BMIter viter;
+	BMVert *v;
+
+	/* The "verts" input sent to this op is the set of verts that
+	   can be merged away into any other verts. Mark all other verts
+	   as VERT_KEEP. */
+	BMO_Flag_Buffer(bm, op, "verts", VERT_IN, BM_VERT);
+	BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
+		if (!BMO_TestFlag(bm, v, VERT_IN)) {
+			BMO_SetFlag(bm, v, VERT_KEEP);
 		}
 	}
 
+	/* Search for doubles among all vertices, but only merge non-VERT_KEEP
+	   vertices into VERT_KEEP vertices. */
+	BMO_InitOpf(bm, &findop, "finddoubles verts=%av keepverts=%fv", VERT_KEEP);
+	BMO_CopySlot(op, &findop, "dist", "dist");
+	BMO_Exec_Op(bm, &findop);
+
+	/* weld the vertices */
+	BMO_Init_Op(&weldop, "weldverts");
+	BMO_CopySlot(&findop, &weldop, "targetmapout", "targetmap");
 	BMO_Exec_Op(bm, &weldop);
-	BMO_Finish_Op(bm, &weldop);
 
-	BLI_array_free(verts);
+	BMO_Finish_Op(bm, &findop);
+	BMO_Finish_Op(bm, &weldop);
 }

Modified: branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c
===================================================================
--- branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2011-10-09 02:24:51 UTC (rev 40869)
+++ branches/bmesh/blender/source/blender/editors/mesh/bmesh_select.c	2011-10-09 03:05:36 UTC (rev 40870)
@@ -130,7 +130,7 @@
 		if (!em)
 			return;
 
-		BMO_CallOpf(em->bm, "automerge verts=%av dist=%f", scene->toolsettings->doublimit);
+		BMO_CallOpf(em->bm, "automerge verts=%hv dist=%f", BM_SELECT, scene->toolsettings->doublimit);
 		if (update) {
 			DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
 		}




More information about the Bf-blender-cvs mailing list