[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [40925] branches/bmesh/blender/source/ blender/bmesh/operators/extrudeops.c: Fixes for solidify when the selection does not form a completely closed 2-manifold

Andrew Wiggin ender79bl at gmail.com
Tue Oct 11 07:18:33 CEST 2011


Revision: 40925
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=40925
Author:   ender79
Date:     2011-10-11 05:18:33 +0000 (Tue, 11 Oct 2011)
Log Message:
-----------
Fixes for solidify when the selection does not form a completely closed 2-manifold

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/operators/extrudeops.c

Modified: branches/bmesh/blender/source/blender/bmesh/operators/extrudeops.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/extrudeops.c	2011-10-11 05:02:45 UTC (rev 40924)
+++ branches/bmesh/blender/source/blender/bmesh/operators/extrudeops.c	2011-10-11 05:18:33 UTC (rev 40925)
@@ -21,9 +21,11 @@
 #define EXT_KEEP  2
 #define EXT_DEL   4
 
-#define VERT_NONMAN 1
-#define EDGE_NONMAN 1
+#define VERT_MARK 1
+#define EDGE_MARK 1
 #define FACE_MARK 1
+#define VERT_NONMAN 2
+#define EDGE_NONMAN 2
 
 void bmesh_extrude_face_indiv_exec(BMesh *bm, BMOperator *op)
 {
@@ -341,13 +343,47 @@
 	BMIter viter, eiter, fiter;
 	BMVert *v;
 	BMEdge *e;
-	BMLoop *l;
 	BMFace *f, *f1, *f2;
 	float edge_normal[3];
+	int i;
 
-	BM_ITER(e, &eiter, bm, BM_EDGES_OF_VERT, NULL) {
-		/* Mark the non-manifold edges and the vertices they connect */
-		if (BM_Nonmanifold_Edge(bm, e)) {
+	BM_Compute_Normals(bm);
+
+	/* Clear indices of verts & edges */
+	BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
+		BM_SetIndex(v, 0);
+	}
+	BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
+		BM_SetIndex(e, 0);
+	}
+
+	BM_ITER(f, &fiter, bm, BM_FACES_OF_MESH, NULL) {
+		if (!BMO_TestFlag(bm, f, FACE_MARK)) {
+			continue;
+		}
+
+		BM_ITER(e, &eiter, bm, BM_EDGES_OF_FACE, f) {
+			i = BM_GetIndex(e);
+			/* Count number of marked faces using each edge */
+			BM_SetIndex(e, i+1);
+
+			/* And mark the edges and verts around marked faces */
+			BMO_SetFlag(bm, e, EDGE_MARK);
+			BMO_SetFlag(bm, e->v1, VERT_MARK);
+			BMO_SetFlag(bm, e->v2, VERT_MARK);
+		}
+	}
+
+	BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
+		if (!BMO_TestFlag(bm, e, EDGE_MARK)) {
+			continue;
+		}
+
+		i = BM_GetIndex(e);
+
+		if (i == 0 || i > 2) {
+			/* Edge & vertices are non-manifold even when considering
+			   only marked faces */
 			BMO_SetFlag(bm, e, EDGE_NONMAN);
 			BMO_SetFlag(bm, e->v1, VERT_NONMAN);
 			BMO_SetFlag(bm, e->v2, VERT_NONMAN);
@@ -355,24 +391,41 @@
 	}
 
 	BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
-		BM_SetIndex(v, 0);
-		zero_v3(v->no);
+		if (BM_Nonmanifold_Vert(bm, v)) {
+			BMO_SetFlag(bm, v, VERT_NONMAN);
+			continue;
+		}
+
+		if (BMO_TestFlag(bm, v, VERT_MARK)) {
+			zero_v3(v->no);
+		}
 	}
 
 	BM_ITER(e, &eiter, bm, BM_EDGES_OF_MESH, NULL) {
 		float angle;
-
-		if (BMO_TestFlag(bm, e, EDGE_NONMAN)) {
+		
+		if (!BMO_TestFlag(bm, e, EDGE_MARK) || BMO_TestFlag(bm, e, EDGE_NONMAN)) {
 			continue;
 		}
 
-		l = e->l;
-		f1 = l->f;
-		f2 = bmesh_radial_nextloop(l)->f;
+		f1 = f2 = NULL;
 
-		angle = angle_normalized_v3v3(f1->no, f2->no);
+		BM_ITER(f, &fiter, bm, BM_FACES_OF_EDGE, e) {
+			if (BMO_TestFlag(bm, f, FACE_MARK)) {
+				if (f1 == NULL) {
+					f1 = f;
+				}
+				else if (f2 == NULL) {
+					f2 = f;
+				}
+			}
+		}
 
-		if (f1 != f2) {
+		BLI_assert(f1 != NULL);
+
+		if (f2 != NULL) {
+			angle = angle_normalized_v3v3(f1->no, f2->no);
+
 			if (angle > 0.0f) {
 				/* two faces using this edge, calculate the edges normal
 				 * using the angle between the faces as a weighting */
@@ -402,6 +455,10 @@
 
 	/* normalize accumulated vertex normals*/
 	BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
+		if (!BMO_TestFlag(bm, v, VERT_MARK)) {
+			continue;
+		}
+
 		if (BMO_TestFlag(bm, v, VERT_NONMAN)) {
 			/* use standard normals for vertices connected to non-manifold
 			   edges */
@@ -409,11 +466,13 @@
 		}
 		else if (normalize_v3(v->no) == 0.0f && BM_GetIndex(v) < 0) {
 			/* exceptional case, totally flat. use the normal
-			   of any face around the vertex */
-			f = BMIter_New(&fiter, bm, BM_FACES_OF_VERT, v);
-			if (f) {
-				copy_v3_v3(v->no, f->no);
+			   of any marked face around the vertex */
+			BM_ITER(f, &fiter, bm, BM_FACES_OF_VERT, v) {
+				if (BMO_TestFlag(bm, f, FACE_MARK)) {
+					break;
+				}
 			}
+			copy_v3_v3(v->no, f->no);
 		}	
 	}
 }
@@ -493,8 +552,6 @@
 	BMO_Exec_Op(bm, &reverseop);
 	BMO_Finish_Op(bm, &reverseop);
 
-	calc_solidify_normals(bm);
-
 	/* Extrude the region */
 	BMO_InitOpf(bm, &extrudeop, "extrudefaceregion alwayskeeporig=%i", 1);
 	BMO_CopySlot(op, &extrudeop, "geom", "edgefacein");
@@ -502,6 +559,7 @@
 
 	/* Push the verts of the extruded faces inward to create thickness */
 	BMO_Flag_Buffer(bm, &extrudeop, "geomout", FACE_MARK, BM_FACE);
+	calc_solidify_normals(bm);
 	solidify_add_thickness(bm, thickness);
 
 	BMO_CopySlot(&extrudeop, op, "geomout", "geomout");




More information about the Bf-blender-cvs mailing list