[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19273] branches/bmesh/blender/source/ blender/bmesh: Dissolve faces now uses a different method of finding the boundary,

Joseph Eagar joeedh at gmail.com
Fri Mar 13 14:11:50 CET 2009


Revision: 19273
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19273
Author:   joeedh
Date:     2009-03-13 14:11:50 +0100 (Fri, 13 Mar 2009)

Log Message:
-----------
Dissolve faces now uses a different method of finding the boundary,
that handles some non-manifold situations better without failing.  
Also made edge subdivide use a more specializzed internal version 
of BM_Connect_Verts, that should hopefully always split the correct face.

Dissolve verts also now has checks to not accidentally dissolve
unselected vertices.  It's not kindof a hybrid tool, using dissolve
faces where it can to dissolve verts for robustness, and using
BM_Dissolve_Verts where it cannot.

And removed some cruft from a few API functions.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c
    branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c
    branches/bmesh/blender/source/blender/bmesh/operators/connectops.c
    branches/bmesh/blender/source/blender/bmesh/operators/dissolveops.c
    branches/bmesh/blender/source/blender/bmesh/operators/subdivideop.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh.h	2009-03-13 10:22:49 UTC (rev 19272)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh.h	2009-03-13 13:11:50 UTC (rev 19273)
@@ -191,11 +191,18 @@
 
 
 /*Modification*/
-struct BMFace *BM_Join_Faces(struct BMesh *bm, struct BMFace *f1, struct BMFace *f2, struct BMEdge *e, int calcnorm, int weldUVs);
-struct BMFace *BM_Split_Face(struct BMesh *bm, struct BMFace *f, struct BMVert *v1, struct BMVert *v2, struct BMLoop **nl, struct BMEdge *example, int calcnorm);
-void BM_Collapse_Vert(struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, float fac, int calcnorm);
-struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, struct BMEdge *e, struct BMEdge **ne, float percent, int calcnorm);
-struct BMVert  *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, int numcuts);
+struct BMFace *BM_Join_Faces(struct BMesh *bm, struct BMFace *f1, 
+                             struct BMFace *f2, struct BMEdge *e);
+struct BMFace *BM_Split_Face(struct BMesh *bm, struct BMFace *f,  
+                             struct BMVert *v1, struct BMVert *v2, 
+			     struct BMLoop **nl, struct BMEdge *example);
+void BM_Collapse_Vert(struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, 
+		      float fac);
+struct BMVert *BM_Split_Edge(struct BMesh *bm, struct BMVert *v, 
+                             struct BMEdge *e, struct BMEdge **ne,
+                             float percent);
+struct BMVert  *BM_Split_Edge_Multi(struct BMesh *bm, struct BMEdge *e, 
+	                            int numcuts);
 BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
 void BM_Face_UpdateNormal(BMesh *bm, BMFace *f);
 void BM_Edge_UpdateNormals(BMesh *bm, BMEdge *e);

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c	2009-03-13 10:22:49 UTC (rev 19272)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_mods.c	2009-03-13 13:11:50 UTC (rev 19273)
@@ -103,7 +103,7 @@
 		  increasing valence to four.  this may be hackish. . .*/
 		loop = e->loop;
 		if (loop->v == v) loop = (BMLoop*) loop->head.next;
-		if (!BM_Split_Face(bm, loop->f, v, loop->v, NULL, NULL, 0))
+		if (!BM_Split_Face(bm, loop->f, v, loop->v, NULL, NULL))
 			return 0;
 
 		BM_Dissolve_Disk(bm, v);
@@ -113,8 +113,8 @@
 		f = v->edge->loop->f;
 		f2 = ((BMLoop*)v->edge->loop->radial.next->data)->f;
 		/*collapse the vertex*/
-		BM_Collapse_Vert(bm, v->edge, v, 1.0, 0);
-		BM_Join_Faces(bm, f, f2, NULL, 0, 0);
+		BM_Collapse_Vert(bm, v->edge, v, 1.0);
+		BM_Join_Faces(bm, f, f2, NULL);
 
 		return 1;
 	}
@@ -128,7 +128,7 @@
 				f = NULL;
 				len = bmesh_cycle_length(&(e->loop->radial));
 				if(len == 2 && (e!=baseedge) && (e!=keepedge)) {
-					f = BM_Join_Faces(bm, e->loop->f, ((BMLoop*)(e->loop->radial.next->data))->f, e, 0, 0); 
+					f = BM_Join_Faces(bm, e->loop->f, ((BMLoop*)(e->loop->radial.next->data))->f, e); 
 					/*return if couldn't join faces in manifold
 					  conditions.*/
 					//!disabled for testing why bad things happen
@@ -148,11 +148,11 @@
 		f2 = ((BMLoop*)v->edge->loop->radial.next->data)->f;
 
 		/*collapse the vertex*/
-		BM_Collapse_Vert(bm, baseedge, v, 1.0, 0);
+		BM_Collapse_Vert(bm, baseedge, v, 1.0);
 		
 		if (f != f2) {
 			/*join two remaining faces*/
-			if (!BM_Join_Faces(bm, f, f2, NULL, 0, 0)) return 0;
+			if (!BM_Join_Faces(bm, f, f2, NULL)) return 0;
 		}
 	}
 
@@ -178,7 +178,7 @@
 				if(len == 2){
 					f = BM_Join_Faces(bm,e->loop->f,((BMLoop*)
 					      (e->loop->radial.next->data))->f, 
-					       e, 1, 0);
+					       e);
 				}
 				if(f){ 
 					done = 0;
@@ -186,7 +186,7 @@
 				}
 			};
 		}
-		BM_Collapse_Vert(bm, v->edge, v, 1.0, 1);
+		BM_Collapse_Vert(bm, v->edge, v, 1.0);
 	}
 }
 #endif
@@ -194,16 +194,13 @@
 /**
  *			bmesh_join_faces
  *
- *  joins two adjacenct faces togather. If weldUVs == 1
- *  and the uv/vcols of the two faces are non-contigous, the
- *  per-face properties of f2 will be transformed into place
- *  around f1.
+ *  joins two adjacenct faces togather.
  * 
  *  Returns -
  *	BMFace pointer
  */
  
-BMFace *BM_Join_Faces(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e, int calcnorm, int weldUVs) {
+BMFace *BM_Join_Faces(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) {
 
 	BMLoop *l1, *l2;
 	BMEdge *jed=NULL;
@@ -229,8 +226,6 @@
 
 	f1 = bmesh_jfke(bm, f1, f2, jed);
 	
-	if (calcnorm && f1) BM_Face_UpdateNormal(bm, f1);
-	
 	return f1;
 }
 
@@ -255,7 +250,7 @@
 	for (face = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v1); face; face=BMIter_Step(&iter)) {
 		for (v=BMIter_New(&iter2, bm, BM_VERTS_OF_FACE, face); v; v=BMIter_Step(&iter2)) {
 			if (v == v2) {
-				face = BM_Split_Face(bm, face, v1, v2, &nl, NULL, 1);
+				face = BM_Split_Face(bm, face, v1, v2, &nl, NULL);
 
 				if (nf) *nf = face;
 				return nl->e;
@@ -275,18 +270,13 @@
  *	BMFace pointer
  */
  
-BMFace *BM_Split_Face(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl, BMEdge *example, int calcnorm)
+BMFace *BM_Split_Face(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, BMLoop **nl, BMEdge *example)
 {
 	BMFace *nf;
 	nf = bmesh_sfme(bm,f,v1,v2,nl);
 	
 	BM_Copy_Attributes(bm, bm, f, nf);
 
-	if (calcnorm && nf) {
-		BM_Face_UpdateNormal(bm, nf);
-		BM_Face_UpdateNormal(bm, f);
-	}
-
 	return nf;
 }
 
@@ -307,7 +297,7 @@
  *	Nothing
  */
  
-void BM_Collapse_Vert(BMesh *bm, BMEdge *ke, BMVert *kv, float fac, int calcnorm){
+void BM_Collapse_Vert(BMesh *bm, BMEdge *ke, BMVert *kv, float fac){
 	void *src[2];
 	float w[2];
 	BMLoop *l=NULL, *kvloop=NULL, *tvloop=NULL;
@@ -345,7 +335,7 @@
  *	the new vert
  */
 
-BMVert *BM_Split_Edge(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percent, int calcnorm) {
+BMVert *BM_Split_Edge(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percent) {
 	BMVert *nv, *v2;
 
 	v2 = bmesh_edge_getothervert(e,v);
@@ -371,7 +361,7 @@
 	
 	for(i=0; i < numcuts; i++){
 		percent = 1.0f / (float)(numcuts + 1 - i);
-		nv = BM_Split_Edge(bm, e->v2, e, NULL, percent, 0);
+		nv = BM_Split_Edge(bm, e->v2, e, NULL, percent);
 	}
 	return nv;
 }

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c	2009-03-13 10:22:49 UTC (rev 19272)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_polygon.c	2009-03-13 13:11:50 UTC (rev 19273)
@@ -243,6 +243,85 @@
 }
 
 /*
+  BM LEGAL EDGES
+
+  takes in a face and a list of edges, and sets to NULL any edge in
+  the list that bridges a concave region of the face or intersects
+  any of the faces's edges.
+*/
+static void shrink_edge(float *v1, float *v2, float fac)
+{
+	float mid[3];
+
+	VecAddf(mid, v1, v2);
+	VecMulf(mid, 0.5f);
+
+	VecSubf(v1, v1, mid);
+	VecSubf(v2, v2, mid);
+
+	VecMulf(v1, fac);
+	VecMulf(v2, fac);
+
+	VecAddf(v1, v1, mid);
+	VecAddf(v2, v2, mid);
+
+}
+
+#if 0
+void BM_LegalSplits(BMesh *bm, BMFace *f, BMLoop (*loops)[2], int len)
+{
+	BMIter iter;
+	BMLoop *l;
+	float v1[3], v2[3], no[3], *p1, *p2;
+	float projectverts[100][3];
+	float edgevertsstack[100][2][3];
+	float (*projverts)[3] = projectverts;
+	float (*edgeverts)[2][3] = edgevertsstack;
+	int i, nvert, j;
+
+	if (f->len > 100) projverts = MEM_mallocN(sizeof(float)*3*f->len, "projvertsb");
+	if (len > 100) edgeverts = MEM_mallocN(sizeof(float)*3*2*len, "edgevertsb");
+	
+	i = 0;
+	l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, f);
+	for (; l; l=BMIter_Step(&iter)) {
+		VECCOPY(projverts[i], l->v->co);
+		i++;
+	}
+
+	for (i=0; i<len; i++) {
+		VECCOPY(v1, loops[i][0]->v->co);
+		VECCOPY(v2, loops[i][0]->v->co);
+
+		shrink_edge(v1, v2, 0.9999f);
+
+		VECCOPY(edgeverts[i][0], v1);
+		VECCOPY(edgeverts[i][1], v2);
+	}
+	
+	compute_poly_normal(no, projverts, f->len);
+	poly_rotate_plane(no, projverts, f->len);
+	poly_rotate_plane(no, edgeverts, len);
+
+	for (i=0; i<len; i++) {
+		if (convexangle(
+	}
+
+	for (i=0; i<f->len; i++) {
+		for (j=0; j<len; j++) {
+			p1 = projverts[i];
+			p2 = projverts[(i+1)%f->len];
+			if (convexangle(
+			if (linecrosses(p1, p2, 
+		}
+	}
+	
+	if (projverts != projectverts) MEM_freeN(projverts);
+	if (edgeverts != edgevertsstack) MEM_freeN(edgeverts);
+}
+#endif
+
+/*
  * POLY ROTATE PLANE
  *
  * Rotates a polygon so that it's
@@ -308,7 +387,7 @@
 
 void BM_Edge_UpdateNormals(BMesh *bm, BMEdge *e)
 {
-	BMIter *iter;
+	BMIter iter;
 	BMFace *f;
 	
 	f = BMIter_New(&iter, bm, BM_FACES_OF_EDGE, e);
@@ -578,7 +657,7 @@
 			v = l->v;
 			f = BM_Split_Face(bm, l->f, ((BMLoop*)(l->head.prev))->v, 
 			                  ((BMLoop*)(l->head.next))->v, 
-			                  &newl, NULL, 0);
+			                  &newl, NULL);
 			VECCOPY(f->no, l->f->no);
 
 			if (!f) {
@@ -605,7 +684,7 @@
 		while (l->f->len > 3){
 			nextloop = ((BMLoop*)(l->head.next->next));
 			f = BM_Split_Face(bm, l->f, l->v, nextloop->v, 
-			                  &newl, NULL, 0);
+			                  &newl, NULL);
 			if (!f) {
 				printf("triangle fan step of triangulator failed.\n");
 				return;

Modified: branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c	2009-03-13 10:22:49 UTC (rev 19272)
+++ branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c	2009-03-13 13:11:50 UTC (rev 19273)
@@ -256,7 +256,7 @@
 				if (l->f->head.flag & BM_ACTIVE) act = BM_ACTIVE;
 				if (((BMLoop*)l->radial.next->data)->f->head.flag & BM_ACTIVE) act = BM_ACTIVE;
 
-				sf = BM_Join_Faces(bm,l->f, ((BMLoop*)l->radial.next->data)->f, l->e, 0,0);
+				sf = BM_Join_Faces(bm,l->f, ((BMLoop*)l->radial.next->data)->f, l->e);
 				if (!sf) {
 					//tesselation error
 					break;

Modified: branches/bmesh/blender/source/blender/bmesh/operators/connectops.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/connectops.c	2009-03-13 10:22:49 UTC (rev 19272)
+++ branches/bmesh/blender/source/blender/bmesh/operators/connectops.c	2009-03-13 13:11:50 UTC (rev 19273)
@@ -17,7 +17,7 @@
 	BMIter iter, liter;
 	BMFace *f, *nf;
 	BMEdge *e;
-	BMLoop *l;
+	BMLoop *l, *nl;

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list