[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [19238] branches/bmesh/blender/source/ blender: dissolve faces: errors-out on holes, preserves winding, and doesn' t delete original face if no dissolving happened.

Joseph Eagar joeedh at gmail.com
Mon Mar 9 10:52:32 CET 2009


Revision: 19238
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=19238
Author:   joeedh
Date:     2009-03-09 10:52:32 +0100 (Mon, 09 Mar 2009)

Log Message:
-----------
dissolve faces: errors-out on holes, preserves winding, and doesn't delete original face if no dissolving happened.  the conversion from/to editmesh now counts selected elements properly.

Modified Paths:
--------------
    branches/bmesh/blender/source/blender/bmesh/bmesh.h
    branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_construct.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c
    branches/bmesh/blender/source/blender/bmesh/intern/bmesh_to_editmesh.c
    branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c
    branches/bmesh/blender/source/blender/bmesh/operators/dissolveops.c
    branches/bmesh/blender/source/blender/editors/mesh/editmesh_add.c

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh.h	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh.h	2009-03-09 09:52:32 UTC (rev 19238)
@@ -76,6 +76,7 @@
 #define BM_HIDDEN	(1<<3)
 #define BM_SHARP	(1<<4)
 #define BM_SMOOTH	(1<<5)
+#define BM_ACTIVE	(1<<6)
 
 typedef struct BMHeader {
 	struct BMHeader *next, *prev;

Modified: branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/bmesh_operators.h	2009-03-09 09:52:32 UTC (rev 19238)
@@ -86,6 +86,8 @@
 void BMO_Set_Vec(struct BMOperator *op, int slotcode, float *vec);
 void BMO_SetFlag(struct BMesh *bm, void *element, int flag);
 void BMO_ClearFlag(struct BMesh *bm, void *element, int flag);
+
+/*flags 15 and 16 (1<<14 and 1<<15) are reserved for bmesh api use*/
 int BMO_TestFlag(struct BMesh *bm, void *element, int flag);
 int BMO_CountFlag(struct BMesh *bm, int flag, int type);
 void BMO_Flag_To_Slot(struct BMesh *bm, struct BMOperator *op, int slotcode, int flag, int type);
@@ -340,10 +342,9 @@
 	       int flag, int numcuts, int seltype);
 void BM_extrudefaceflag(BMesh *bm, int flag);
 
-/*these next two return 1 if they did anything, or zero otherwise.
+/*this next one return 1 if they did anything, or zero otherwise.
   they're kindof a hackish way to integrate with fkey, until
   such time as fkey is completely bmeshafied.*/
-int BM_DissolveFaces(struct EditMesh *em, int flag);
 /*this doesn't display errors to the user, btw*/
 int BM_ConnectVerts(struct EditMesh *em, int flag);
 

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_construct.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_construct.c	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_construct.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -210,20 +210,33 @@
 BMFace *BM_Make_Ngon(BMesh *bm, BMVert *v1, BMVert *v2, BMEdge **edges, int len, int nodouble)
 {
 	BMVert *vert_buf[VERT_BUF_SIZE];
-	BMVert **verts = vert_buf;
+	BMVert **verts = vert_buf, *lastv;
 	BMFace *f = NULL;
-	int overlap = 0, i;
+	int overlap = 0, i, j;
 
 	if(nodouble){
 		if(len > VERT_BUF_SIZE)
 			verts = MEM_callocN(sizeof(BMVert *) * len, "bmesh make ngon vertex array");
-		for(i = 0; i < len; i++){
+		
+		/*if ((edges[i]->v1 == edges[i]->v1) || 
+		   (edges[i]->v1 == edges[i]->v2))
+		{
+			lastv = edges[i]->v2;
+		} else lastv = edges[i]->v1;
+		verts[0] = lastv;
+
+		for (i=1; i<len; i++) {
+			if (!BMO_TestFlag
+		}*/
+
+		for(i = 0, j=0; i < len; i++){
 			if(!BMO_TestFlag(bm, edges[i]->v1, BM_EDGEVERT)){
 				BMO_SetFlag(bm, edges[i]->v1, BM_EDGEVERT);
-				verts[i] = edges[i]->v1;
-			} else if(!BMO_TestFlag(bm, edges[i]->v2, BM_EDGEVERT)) {
+				verts[j++] = edges[i]->v1;
+			}
+			if(!BMO_TestFlag(bm, edges[i]->v2, BM_EDGEVERT)) {
 				BMO_SetFlag(bm, edges[i]->v2, BM_EDGEVERT);
-				verts[i] = edges[i]->v2;
+				verts[j++] = edges[i]->v2;
 			}
 		}
 		

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -4,7 +4,7 @@
 #include <stdio.h>
 
 BMOpDefine def_connectverts = {
-	"connectvert",
+	"connectverts",
 	{{BMOP_OPSLOT_PNT_BUF, "verts"},
 	{BMOP_OPSLOT_PNT_BUF, "edgeout"}},
 	connectverts_exec,

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_queries.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -114,7 +114,7 @@
 	curloop = f->loopbase;
 	do{
 		if(BMO_TestFlag(bm, curloop->v, BM_OVERLAP)) count++;
-		curloop = ((BMLoop*)(curloop->head.next));
+		curloop = (BMLoop*)(curloop->head.next);
 	} while(curloop != f->loopbase);
 
 	for(i=0; i < len; i++) BMO_ClearFlag(bm, varr[i], BM_OVERLAP);

Modified: branches/bmesh/blender/source/blender/bmesh/intern/bmesh_to_editmesh.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/intern/bmesh_to_editmesh.c	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/intern/bmesh_to_editmesh.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -167,7 +167,6 @@
 
 	efa->mat_nr = (unsigned char)f->mat_nr;
 
-
 	/*Copy normal*/
 	efa->n[0] = f->no[0];
 	efa->n[1] = f->no[1];
@@ -177,6 +176,7 @@
 	if (f->head.flag & BM_SELECT) efa->f |= SELECT;
 	if (f->head.flag & BM_HIDDEN) efa->h = 1;
 	if (f->head.flag & BM_SMOOTH) efa->flag |= ME_SMOOTH;
+	if (f->head.flag & BM_ACTIVE) EM_set_actFace(em, efa);
 
 	CustomData_em_copy_data(&bm->pdata, &em->fdata, f->data, &efa->data);
 	loops_to_editmesh_corners(bm, &em->fdata, efa->data, f, numCol,numTex);
@@ -231,6 +231,10 @@
 
 	EM_fgon_flags(em);
 
+	EM_nvertices_selected(em);
+	EM_nedges_selected(em);
+	EM_nfaces_selected(em);
+
 	return em;
 }
 

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-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/intern/editmesh_to_bmesh.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -189,6 +189,8 @@
 		f->mat_nr = efa->mat_nr;
 		if(efa->f & SELECT) BM_Select_Face(bm, f, 1);
 		if(efa->h) f->head.flag |= BM_HIDDEN;
+
+		if (efa == em->act_face) f->head.flag |= BM_ACTIVE;
 		
 		CustomData_bmesh_copy_data(&em->fdata, &bm->pdata, efa->data, &f->data);
 		editmesh_corners_to_loops(bm, &em->fdata, efa->data, f,numCol,numTex);
@@ -234,7 +236,7 @@
 {
 	BMFace *sf;
 	BMLoop *l;
-	int done;
+	int done, act=0;
 
 	sf = f;
 	done = 0;
@@ -242,8 +244,12 @@
 		done = 1;
 		l = sf->loopbase;
 		do{
-			if(l->e->head.flag & BM_FGON){ 
+			if(l->e->head.flag & BM_FGON) { 
+				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->head.flag |= act;
 				if(sf){
 					done = 0;
 					break;

Modified: branches/bmesh/blender/source/blender/bmesh/operators/dissolveops.c
===================================================================
--- branches/bmesh/blender/source/blender/bmesh/operators/dissolveops.c	2009-03-09 09:15:23 UTC (rev 19237)
+++ branches/bmesh/blender/source/blender/bmesh/operators/dissolveops.c	2009-03-09 09:52:32 UTC (rev 19238)
@@ -13,9 +13,39 @@
 
 #define FACE_MARK	1
 #define FACE_ORIG	2
-#define VERT_MARK	1
 #define FACE_NEW	4
+#define EDGE_MARK	1
 
+#define VERT_MARK	1
+
+static int check_hole_in_region(BMesh *bm, BMFace *f) {
+	BMWalker regwalker;
+	BMIter liter2;
+	BMLoop *l2, *l3;
+	BMFace *f2;
+	
+	/*checks if there are any unmarked boundary edges in the face region*/
+
+	BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK);
+	f2 = BMW_Begin(&regwalker, f);
+	for (; f2; f2=BMW_Step(&regwalker)) {
+		l2 = BMIter_New(&liter2, bm, BM_LOOPS_OF_FACE, f2);
+		for (; l2; l2=BMIter_Step(&liter2)) {			
+			l3 = bmesh_radial_nextloop(l2);
+			if (BMO_TestFlag(bm, l3->f, FACE_MARK) 
+			    != BMO_TestFlag(bm, l2->f, FACE_MARK))
+			{
+				if (!BMO_TestFlag(bm, l2->e, EDGE_MARK)) {
+					return 0;
+				}
+			}
+		}
+	}
+	BMW_End(&regwalker);
+
+	return 1;
+}
+
 void dissolvefaces_exec(BMesh *bm, BMOperator *op)
 {
 	BMOIter oiter;
@@ -51,6 +81,7 @@
 				for (; l; l=BMW_Step(&walker)) {
 					V_GROW(region);
 					region[V_COUNT(region)-1] = l;
+					BMO_SetFlag(bm, l->e, EDGE_MARK);
 				}
 				BMW_End(&walker);
 
@@ -62,6 +93,14 @@
 				
 				if (region == NULL) continue;
 
+				/*check for holes in boundary*/
+				if (!check_hole_in_region(bm, region[0]->f)) {
+					BMO_RaiseError(bm, op, 
+					      BMERR_DISSOLVEFACES_FAILED, 
+					      "Hole(s) in face region");
+					goto cleanup;
+				}
+				
 				BMW_Init(&regwalker, bm, BMW_ISLAND, FACE_MARK);
 				f2 = BMW_Begin(&regwalker, region[0]->f);
 				for (; f2; f2=BMW_Step(&regwalker)) {
@@ -95,22 +134,11 @@
 			edges[V_COUNT(edges)-1] = region[j]->e;
 		}
 		
-		f= BM_Make_Ngon(bm, edges[0]->v1, edges[0]->v2,  edges, j, 0);
+		f= BM_Make_Ngon(bm, region[0]->v, region[1]->v,  edges, j, 1);
 		
-		if (!f) continue;
-
-		/*
-		NOTE: sadly, make ngon's overlap checking option
-		      crashes ;/
-		make ngon can fail, if there was already an existing face.
-		this is desired behaviour, I think, so we'll just silently
-		ignore any possible other error cases.
-		if (!f) {
-			//raise error
-			BMO_RaiseError(bm, op, BMERR_DISSOLVEFACES_FAILED, NULL);
-			goto cleanup;
-		}*/
-		
+		/*if making the new face failed (e.g. overlapping test)
+		  unmark the original faces for deletion.*/
+		BMO_ClearFlag(bm, f, FACE_ORIG);
 		BMO_SetFlag(bm, f, FACE_NEW);
 
 		fcopied = 0;
@@ -155,24 +183,6 @@
 	V_FREE(regions);
 }
 
-/*returns 1 if any faces were dissolved*/
-int BM_DissolveFaces(EditMesh *em, int flag) {
-	BMesh *bm = editmesh_to_bmesh(em);
-	EditMesh *em2;
-	BMOperator op;
-
-	BMO_Init_Op(&op, BMOP_DISSOLVE_FACES);
-	BMO_HeaderFlag_To_Slot(bm, &op, BMOP_DISFACES_FACEIN, flag, BM_FACE);
-	BMO_Exec_Op(bm, &op);
-	BMO_Finish_Op(bm, &op);
-	
-	em2 = bmesh_to_editmesh(bm);
-	set_editMesh(em, em2);
-	MEM_freeN(em2);
-
-	return BMO_GetSlot(&op, BMOP_DISFACES_REGIONOUT)->len > 0;
-}
-
 void dissolveverts_exec(BMesh *bm, BMOperator *op)
 {
 	BMOpSlot *vinput;
@@ -195,8 +205,11 @@
 
 	BMO_CallOpf(bm, "dissolvefaces faces=%ff", FACE_MARK);
 	if (BMO_HasError(bm)) {
+			char *msg;
+
+			BMO_GetError(bm, &msg, NULL);
 			BMO_ClearStack(bm);
-			BMO_RaiseError(bm, op, BMERR_DISSOLVEVERTS_FAILED, NULL);
+			BMO_RaiseError(bm, op, BMERR_DISSOLVEVERTS_FAILED,msg);
 	}
 }
 

Modified: branches/bmesh/blender/source/blender/editors/mesh/editmesh_add.c

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list