[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [42152] branches/bmesh/blender/source/ blender/bmesh: fix [#29079] New face added with "F" has wrong winding

Campbell Barton ideasman42 at gmail.com
Fri Nov 25 02:18:57 CET 2011


Revision: 42152
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=42152
Author:   campbellbarton
Date:     2011-11-25 01:18:48 +0000 (Fri, 25 Nov 2011)
Log Message:
-----------
fix [#29079] New face added with "F" has wrong winding

now newly created faces use the best winding order based on surrounding edges.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c
    branches/bmesh/blender/source/blender/bmesh/operators/createops.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h	2011-11-25 01:10:55 UTC (rev 42151)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_queries.h	2011-11-25 01:18:48 UTC (rev 42152)
@@ -79,6 +79,9 @@
 /*returns number of faces e1 and e2 share.*/
 int BM_Edge_Share_Faces(struct BMEdge *e1, struct BMEdge *e2);
 
+/*edge verts in winding order from face*/
+void BM_Edge_OrderedVerts(struct BMEdge *edge, struct BMVert **r_v1, struct BMVert **r_v2);
+
 /*checks if a face is valid in the data structure*/
 int BM_Validate_Face(BMesh *bm, BMFace *face, FILE *err);
 

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c	2011-11-25 01:10:55 UTC (rev 42151)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c	2011-11-25 01:18:48 UTC (rev 42152)
@@ -443,7 +443,34 @@
 	return 0;
 }
 
+/**
+ *
+ *           BMESH EDGE ORDERED VERTS
+ *
+ *	Returns the verts of an edge as used in a face
+ *  if used in a face at all, otherwise just assign as used in the edge.
+ *
+ *  Useful to get a determanistic winding order when calling
+ *  BM_Make_Ngon() on an arbitrary array of verts,
+ *  though be sure to pick an edge which has a face.
+ *
+*/
 
+void BM_Edge_OrderedVerts(BMEdge *edge, BMVert **r_v1, BMVert **r_v2)
+{
+	if ( (edge->l == NULL) ||
+	     ( ((edge->l->prev->v == edge->v1) && (edge->l->v == edge->v2)) ||
+	       ((edge->l->v == edge->v1) && (edge->l->next->v == edge->v2)) )
+	     )
+	{
+		*r_v1= edge->v1;
+		*r_v2= edge->v2;
+	}
+	else {
+		*r_v1= edge->v2;
+		*r_v2= edge->v1;
+	}
+}
 
 /**
  *			BMESH FACE ANGLE

Modified: branches/bmesh/blender/source/blender/bmesh/operators/createops.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/createops.c	2011-11-25 01:10:55 UTC (rev 42151)
+++ branches/bmesh/blender/source/blender/bmesh/operators/createops.c	2011-11-25 01:18:48 UTC (rev 42152)
@@ -840,6 +840,7 @@
 	BLI_array_declare(edges);
 	int use_restrict = BMO_Get_Int(op, "use_restrict");
 	int i, j, group = 0;
+	unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
 
 	if (!bm->totvert || !bm->totedge)
 		return;
@@ -913,6 +914,8 @@
 		if (!path)
 			continue;
 		
+		winding[0]= winding[1]= 0;
+
 		BLI_array_empty(edges);
 		BLI_array_empty(verts);
 		i = 0;
@@ -926,6 +929,16 @@
 			if (!e)
 				break;
 			
+			/* check on the winding */
+			if (e->l) {
+				BMVert *test_v1, *test_v2;
+				/* we want to use the reverse winding to the existing order */
+				BM_Edge_OrderedVerts(edge, &test_v2, &test_v1);
+
+				/* edges vote on which winding wins out */
+				winding[(test_v1 == node->v)]++;
+			}
+
 			edata[BM_GetIndex(e)].ftag++;
 			BLI_array_growone(edges);
 			edges[i++] = e;
@@ -948,7 +961,24 @@
 			continue;
 		
 		if (i) {
-			f = BM_Make_Ngon(bm, edge->v1, edge->v2, edges, i, 1);
+			BMVert *v1, *v2;
+
+			/* to define the winding order must select first edge,
+			 * otherwise we could leave this as-is */
+			edge= edges[0];
+
+			/* if these are even it doesnt really matter what to do,
+			 * with consistent geometry one will be zero, the choice is clear */
+			if (winding[0] > winding[1]) {
+				v1= verts[0];
+				v2= verts[1];
+			}
+			else {
+				v1= verts[1];
+				v2= verts[0];
+			}
+
+			f = BM_Make_Ngon(bm, v1, v2, edges, i, 1);
 			if (f && !BMO_TestFlag(bm, f, ELE_ORIG)) {
 				BMO_SetFlag(bm, f, FACE_NEW);
 			}




More information about the Bf-blender-cvs mailing list