[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23138] branches/bmesh/blender/source/ blender/bmesh: fkey on two broken edge loops will create an ngon now, as will fkey on one broken edge loop

Joseph Eagar joeedh at gmail.com
Sat Sep 12 10:41:39 CEST 2009


Revision: 23138
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23138
Author:   joeedh
Date:     2009-09-12 10:41:39 +0200 (Sat, 12 Sep 2009)

Log Message:
-----------
fkey on two broken edge loops will create an ngon now, as will fkey on one broken edge loop

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
    branches/bmesh/blender/source/blender/bmesh/operators/createops.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h	2009-09-12 07:08:57 UTC (rev 23137)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_operator_api.h	2009-09-12 08:41:39 UTC (rev 23138)
@@ -255,6 +255,10 @@
 int BMO_CountSlotBuf(struct BMesh *bm, struct BMOperator *op, char *slotname);
 int BMO_CountSlotMap(struct BMesh *bm, struct BMOperator *op, char *slotname);
 
+/*Counts the number of edges with tool flag toolflag around
+  v*/
+int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag);
+
 /*inserts a key/value mapping into a mapping slot.  note that it copies the
   value, it doesn't store a reference to it.*/
 //BM_INLINE void BMO_Insert_Mapping(BMesh *bm, BMOperator *op, char *slotname, 

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-09-12 07:08:57 UTC (rev 23137)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-09-12 08:41:39 UTC (rev 23138)
@@ -343,7 +343,6 @@
 	0,
 };
 
-/*this may be unimplemented*/
 BMOpDefine def_edgenet_fill= {
 	"edgenet_fill",
 	{{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
@@ -354,6 +353,25 @@
 };
 
 /*
+  Edgenet Prepare
+
+  Identifies several useful edge loop cases and modifies them so
+  they'll become a face when edgenet_fill is called.  The cases covered are:
+
+  * One single loop; an edge is added to connect the ends
+  * Two loops; two edges are added to connect the endpoints (based on the
+    shortest distance between each endpont).
+*/
+BMOpDefine def_edgenet_prepare= {
+	"edgenet_prepare",
+	{{BMOP_OPSLOT_ELEMENT_BUF, "edges"}, //input edges
+	 {BMOP_OPSLOT_ELEMENT_BUF, "edgeout"}, //new edges
+	{0, /*null-terminating sentinel*/}},
+	bmesh_edgenet_prepare,
+	0,
+};
+
+/*
   Rotate
 
   Rotate vertices around a center, using a 3x3 rotation
@@ -777,6 +795,7 @@
 	&def_meshrotateuvs,
 	&def_bmesh_to_mesh,
 	&def_meshreverseuvs,
+	&def_edgenet_prepare,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c	2009-09-12 07:08:57 UTC (rev 23137)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators.c	2009-09-12 08:41:39 UTC (rev 23138)
@@ -679,7 +679,26 @@
 	}
 }
 
+int BMO_Vert_CountEdgeFlags(BMesh *bm, BMVert *v, int toolflag)
+{
+	BMNode *diskbase;
+	BMEdge *curedge;
+	int i, len=0, count=0;
+	
+	if(v->edge){
+		diskbase = bmesh_disk_getpointer(v->edge, v);
+		len = bmesh_cycle_length(diskbase);
+		
+		for(i = 0, curedge=v->edge; i<len; i++){
+			if (BMO_TestFlag(bm, curedge, toolflag))
+				count++;
+			curedge = bmesh_disk_nextedge(curedge, v);
+		}
+	}
 
+	return count;
+}
+
 /*
  *
  * BMO_FLAG_BUFFER

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2009-09-12 07:08:57 UTC (rev 23137)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2009-09-12 08:41:39 UTC (rev 23138)
@@ -54,5 +54,6 @@
 void bmesh_rotateuvs_exec(BMesh *bm, BMOperator *op);
 void object_load_bmesh_exec(BMesh *bm, BMOperator *op);
 void bmesh_reverseuvs_exec(BMesh *bm, BMOperator *op);
+void bmesh_edgenet_prepare(BMesh *bm, BMOperator *op);
 
 #endif

Modified: branches/bmesh/blender/source/blender/bmesh/operators/createops.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/createops.c	2009-09-12 07:08:57 UTC (rev 23137)
+++ branches/bmesh/blender/source/blender/bmesh/operators/createops.c	2009-09-12 08:41:39 UTC (rev 23138)
@@ -38,8 +38,6 @@
 #define EDGE_MARK	1
 #define EDGE_VIS	2
 
-#define VERT_VIS	1
-
 #define FACE_NEW	1
 
 PathBase *edge_pathbase_new(void)
@@ -195,10 +193,9 @@
 
 void bmesh_edgenet_fill_exec(BMesh *bm, BMOperator *op)
 {
-	BMIter iter, liter;
+	BMIter iter;
 	BMOIter siter;
 	BMEdge *e, *edge;
-	BMLoop *l;
 	BMFace *f;
 	EPath *path;
 	EPathNode *node;
@@ -206,7 +203,7 @@
 	BMEdge **edges = NULL;
 	PathBase *pathbase = edge_pathbase_new();
 	V_DECLARE(edges);
-	int i, j;
+	int i;
 
 	if (!bm->totvert || !bm->totedge)
 		return;
@@ -314,16 +311,195 @@
 	return 0;
 }
 
+BMEdge *edge_next(BMesh *bm, BMEdge *e)
+{
+	BMIter iter;
+	BMEdge *e2;
+	int i;
+
+	for (i=0; i<2; i++) {
+		BM_ITER(e2, &iter, bm, BM_EDGES_OF_VERT, i?e->v2:e->v1) {
+			if (BMO_TestFlag(bm, e2, EDGE_MARK) 
+			    && !BMO_TestFlag(bm, e2, EDGE_VIS) && e2 != e)
+			{
+				return e2;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+void bmesh_edgenet_prepare(BMesh *bm, BMOperator *op)
+{
+	BMOIter siter;
+	BMIter iter;
+	BMEdge *e, *e2;
+	BMEdge **edges1 = NULL, **edges2 = NULL, **edges;
+	V_DECLARE(edges1);
+	V_DECLARE(edges2);
+	V_DECLARE(edges);
+	int ok = 1;
+	int i, count;
+
+	BMO_Flag_Buffer(bm, op, "edges", EDGE_MARK, BM_EDGE);
+	
+	/*validate that each edge has at most one other tagged edge in the
+	  disk cycle around each of it's vertices*/
+	BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+		for (i=0; i<2; i++) {
+			count = BMO_Vert_CountEdgeFlags(bm, i?e->v2:e->v1, EDGE_MARK);
+			if (count > 2) {
+				ok = 0;
+				break;
+			}
+		}
+
+		if (!ok) break;
+	}
+
+	/*we don't have valid edge layouts, return*/
+	if (!ok)
+		return;
+
+
+	/*find connected loops within the input edges*/
+	count = 0;
+	while (1) {
+		BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
+			if (!BMO_TestFlag(bm, e, EDGE_VIS)) {
+				if (BMO_Vert_CountEdgeFlags(bm, e->v1, EDGE_MARK)==1)
+					break;
+				if (BMO_Vert_CountEdgeFlags(bm, e->v2, EDGE_MARK)==1)
+					break;
+			}
+		}
+		
+		if (!e) break;
+		
+		if (!count)
+			edges = edges1;
+		else if (count==1)
+			edges = edges2;
+		else break;
+		
+		i = 0;
+		while (e) {
+			BMO_SetFlag(bm, e, EDGE_VIS);
+			V_GROW(edges);
+			edges[i] = e;
+
+			e = edge_next(bm, e);
+			i++;
+		}
+
+		if (!count) {
+			edges1 = edges;
+			V_SETCOUNT(edges1, V_COUNT(edges));
+		} else {
+			edges2 = edges;
+			V_SETCOUNT(edges2, V_COUNT(edges));
+		}
+
+		V_RESET(edges);
+		count++;
+	}
+
+#define EDGECON(e1, e2) (e1->v1 == e2->v1 || e1->v2 == e2->v2 || e1->v1 == e2->v2)
+
+	if (edges1 && V_COUNT(edges1) > 2 && EDGECON(edges1[0], edges1[V_COUNT(edges1)-1])) {
+		if (edges2 && V_COUNT(edges2) > 2 && EDGECON(edges2[0], edges2[V_COUNT(edges2)-1])) {
+			V_FREE(edges1);
+			V_FREE(edges2);
+			return;
+		} else {
+			edges1 = edges2;
+			edges2 = NULL;
+		}
+	}
+
+	if (edges2 && V_COUNT(edges2) > 2 && EDGECON(edges2[0], edges2[V_COUNT(edges2)-1])) {
+		edges2 = NULL;
+	}
+
+	/*two unconnected loops, connect them*/
+	if (edges1 && edges2) {
+		BMVert *v1, *v2, *v3, *v4;
+
+		if (V_COUNT(edges1)==1) {
+			v1 = edges1[0]->v1;
+			v2 = edges1[0]->v2;
+		} else {
+			if (BM_Vert_In_Edge(edges1[1], edges1[0]->v1))
+				v1 = edges1[0]->v2;
+			else v1 = edges1[0]->v1;
+
+			i = V_COUNT(edges1)-1;
+			if (BM_Vert_In_Edge(edges1[i-1], edges1[i]->v1))
+				v2 = edges1[i]->v2;
+			else v2 = edges1[i]->v1;
+		}
+
+		if (V_COUNT(edges2)==1) {
+			v3 = edges2[0]->v1;
+			v4 = edges2[0]->v2;
+		} else {
+			if (BM_Vert_In_Edge(edges2[1], edges2[0]->v1))
+				v3 = edges2[0]->v2;
+			else v3 = edges2[0]->v1;
+
+			i = V_COUNT(edges2)-1;
+			if (BM_Vert_In_Edge(edges2[i-1], edges2[i]->v1))
+				v4 = edges2[i]->v2;
+			else v4 = edges2[i]->v1;
+		}
+
+		if (VecLenf(v1->co, v3->co) > VecLenf(v1->co, v4->co)) {
+			BMVert *v;
+			v = v3;
+			v3 = v4;
+			v4 = v;
+		}
+
+		e = BM_Make_Edge(bm, v1, v3, NULL, 1);
+		BMO_SetFlag(bm, e, ELE_NEW);
+		e = BM_Make_Edge(bm, v2, v4, NULL, 1);
+		BMO_SetFlag(bm, e, ELE_NEW);
+	} else if (edges1) {
+		BMVert *v1, *v2;
+		
+		if (V_COUNT(edges1) > 1) {
+			if (BM_Vert_In_Edge(edges1[1], edges1[0]->v1))
+				v1 = edges1[0]->v2;
+			else v1 = edges1[0]->v1;
+
+			i = V_COUNT(edges1)-1;
+			if (BM_Vert_In_Edge(edges1[i-1], edges1[i]->v1))
+				v2 = edges1[i]->v2;
+			else v2 = edges1[i]->v1;
+
+			e = BM_Make_Edge(bm, v1, v2, NULL, 1);
+			BMO_SetFlag(bm, e, ELE_NEW);
+		}
+	}
+	
+	BMO_Flag_To_Slot(bm, op, "edgeout", ELE_NEW, BM_EDGE);
+
+	V_FREE(edges1);
+	V_FREE(edges2);
+
+#undef EDGECON
+}
+
 /*this is essentially new fkey*/
 void bmesh_contextual_create_exec(BMesh *bm, BMOperator *op)
 {
 	BMOperator op2;
 	BMOIter oiter;
-	BMIter iter, liter;
+	BMIter iter;
 	BMHeader *h;
 	BMVert *v, *verts[4];
 	BMEdge *e;
-	BMLoop *l;
 	BMFace *f;
 	int totv=0, tote=0, totf=0, amount;
 
@@ -338,20 +514,13 @@
 		BMO_SetFlag(bm, h, ELE_NEW);
 	}
 	
-	/*first call dissolve faces*/
-	BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW);
+	/*call edgenet create*/
+	/*  call edgenet prepare op so additional face creation cases work*/
+	BMO_InitOpf(bm, &op2, "edgenet_prepare edges=%fe", ELE_NEW);
 	BMO_Exec_Op(bm, &op2);
-	
-	/*if we dissolved anything, then return.*/
-	if (BMO_CountSlotBuf(bm, &op2, "regionout")) {
-		BMO_CopySlot(&op2, op, "regionout", "faceout");
-		BMO_Finish_Op(bm, &op2);
-		return;
-	}
-
+	BMO_Flag_Buffer(bm, &op2, "edgeout", ELE_NEW, BM_EDGE);
 	BMO_Finish_Op(bm, &op2);
 
-	/*call edgenet create*/
 	BMO_InitOpf(bm, &op2, "edgenet_fill edges=%fe", ELE_NEW);
 	BMO_Exec_Op(bm, &op2);
 
@@ -364,6 +533,19 @@
 
 	BMO_Finish_Op(bm, &op2);
 	
+	/*now call dissolve faces*/
+	BMO_InitOpf(bm, &op2, "dissolvefaces faces=%ff", ELE_NEW);
+	BMO_Exec_Op(bm, &op2);
+	
+	/*if we dissolved anything, then return.*/
+	if (BMO_CountSlotBuf(bm, &op2, "regionout")) {
+		BMO_CopySlot(&op2, op, "regionout", "faceout");
+		BMO_Finish_Op(bm, &op2);
+		return;
+	}
+
+	BMO_Finish_Op(bm, &op2);
+
 	/*now, count how many verts we have*/
 	amount = 0;
 	BM_ITER(v, &iter, bm, BM_VERTS_OF_MESH, NULL) {





More information about the Bf-blender-cvs mailing list