conversion code now uses triangulator for fgonafication of ngons. also implemented...
authorJoseph Eagar <joeedh@gmail.com>
Wed, 21 Jan 2009 10:11:01 +0000 (10:11 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Wed, 21 Jan 2009 10:11:01 +0000 (10:11 +0000)
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators_private.h
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/intern/bmesh_to_editmesh.c
source/blender/bmesh/operators/dissolveops.c [moved from source/blender/bmesh/operators/dissolvefacesop.c with 57% similarity]
source/blender/bmesh/operators/triangulateop.c
source/blender/editors/mesh/editmesh_mods.c

index e123b9ffa5efa1351a3bd60fba1855470c3ca57d..49a8a67c6fb1fe685b205bd052e835863f3c97f5 100644 (file)
@@ -191,6 +191,7 @@ void BM_Collapse_Vert(struct BMesh *bm, struct BMEdge *ke, struct BMVert *kv, fl
 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);
 BMEdge *BM_Connect_Verts(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf);
+void BM_Dissolve_Disk(BMesh *bm, BMVert *v);
 
 /*Interpolation*/
 void BM_Data_Interp_From_Verts(struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac);
index a6985fe6e1f294d9bc91233a4829240b89a0592f..d290f5457f8face3d6afb59d655179b95a77b279 100644 (file)
@@ -141,8 +141,8 @@ enum {
 #define BMOP_TRIANGULATE               6
 
 #define BMOP_TRIANG_FACEIN             0
-#define BMOP_NEW_EDGES                 1
-#define BMOP_NEW_FACES                 2
+#define BMOP_TRIANG_NEW_EDGES  1
+#define BMOP_TRIANG_NEW_FACES  2
 #define BMOP_TRIANG_TOTSLOT            3
 
 /*dissolve faces*/
@@ -151,8 +151,17 @@ enum {
 #define BMOP_DISFACES_FACEIN   0
 #define BMOP_DISFACES_TOTSLOT  1
 
+/*dissolve verts*/
+#define BMOP_DISSOLVE_VERTS            8
+
+#define BMOP_DISVERTS_VERTIN   0
+#define BMOP_DISVERTS_TOTSLOT  1
+
+#define BMOP_MAKE_FGONS                        9
+#define BMOP_MAKE_FGONS_TOTSLOT        0
+
 /*keep this updated!*/
-#define BMOP_TOTAL_OPS                 8
+#define BMOP_TOTAL_OPS                 10
 /*-------------------------------end operator defines-------------------------------*/
 
 extern BMOpDefine *opdefines[];
index d033174b9211ac197ba82629c47430ea3dac4942..525c26e5d9aded557de0d00805c0e6870966d359 100644 (file)
  *     1 for success, 0 for failure.
  */
 
-void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
+void BM_Dissolve_Disk(BMesh *bm, BMVert *v) {
        BMFace *f, *f2;
        BMEdge *e, *keepedge=NULL, *baseedge=NULL;
+       BMLoop *loop;
        int done, len;
 
        if(BM_Nonmanifold_Vert(bm, v)) return;
@@ -50,6 +51,7 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
        if(v->edge){
                /*v->edge we keep, what else?*/
                e = v->edge;
+               len = 0;
                do{
                        e = bmesh_disk_nextedge(e,v);
                        if(!(BM_Edge_Share_Faces(e, v->edge))){
@@ -57,9 +59,30 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
                                baseedge = v->edge;
                                break;
                        }
+                       len++;
                }while(e != v->edge);
        }
        
+       /*this code for handling 2 and 3-valence verts
+         may be totally bad.*/
+       if (keepedge == NULL && len == 3) {
+               /*handle specific case for three-valence.  solve it by
+                 increasing valence to four.  this may be hackish. . .*/
+               loop = e->loop;
+               if (loop->v == v) loop = (BMLoop*) loop->head.next;
+               BM_Split_Face(bm, loop->f, v, loop->v, NULL, NULL, 0);
+
+               BM_Dissolve_Disk(bm, v);
+               return;
+       } else if (keepedge == NULL && len == 2) {
+               /*handle two-valence*/
+               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);
+       }
+
        if(keepedge){
                done = 0;
                while(!done){
@@ -74,14 +97,18 @@ void BM_Dissolve_Disk(BMesh *bm, BMVert *v){
                                        done = 0;
                                        break;
                                }
+                               e = bmesh_disk_nextedge(e, v);
                        }while(e != v->edge);
                }
 
                /*get remaining two faces*/
                f = v->edge->loop->f;
-               f2 = ((BMLoop*)f->loopbase->radial.next->data)->f;
+               f2 = ((BMLoop*)v->edge->loop->radial.next->data)->f;
                /*collapse the vertex*/
                BM_Collapse_Vert(bm, baseedge, v, 1.0, 0);
+
+               /*join two remaining faces*/
+               BM_Join_Faces(bm, f, f2, NULL, 0, 0);
        }
 }
 
index 67fd6dd8244c3af53f048955fe03c509c1cb1abe..b25cdd453372339d5239f606f471418de6eb1aa7 100644 (file)
@@ -3,6 +3,20 @@
 
 #include <stdio.h>
 
+BMOpDefine def_makefgonsop = {
+       {0},
+       bmesh_make_fgons_exec,
+       BMOP_MAKE_FGONS_TOTSLOT,
+       0
+};
+
+BMOpDefine def_dissolvevertsop = {
+       {BMOP_OPSLOT_PNT_BUF},
+       dissolveverts_exec,
+       BMOP_DISVERTS_TOTSLOT,
+       0
+};
+
 BMOpDefine def_dissolvefacesop = {
        {BMOP_OPSLOT_PNT_BUF},
        dissolvefaces_exec,
@@ -70,6 +84,8 @@ BMOpDefine *opdefines[] = {
        &def_subdop,
        &def_triangop,
        &def_dissolvefacesop,
+       &def_dissolvevertsop,
+       &def_makefgonsop,
 };
 
 int bmesh_total_ops = (sizeof(opdefines) / sizeof(void*));
index 31a9bf1387e1ecff0f45c9eba15a17c27d76111d..ccdfd00e2e086011fcc8023f630cb8d9c0066f9e 100644 (file)
@@ -15,5 +15,7 @@ void edit2bmesh_exec(BMesh *bmesh, BMOperator *op);
 void bmesh2edit_exec(BMesh *bmesh, BMOperator *op);
 void triangulate_exec(BMesh *bmesh, BMOperator *op);
 void dissolvefaces_exec(BMesh *bmesh, BMOperator *op);
+void dissolveverts_exec(BMesh *bmesh, BMOperator *op);
+void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op);
 
 #endif
index 44e05f9b7358cd4509d2078da4f86d290bb9cc71..54286600c0bab03e9240f31666c45813a1ee7dcc 100644 (file)
@@ -431,7 +431,7 @@ int BM_Edge_Share_Faces(BMEdge *e1, BMEdge *e2)
                                return 1;
                        }
                        l = (BMLoop*)(l->radial.next->data);
-               }while(l != f->loopbase);
+               }while(l != e1->loop);
        }
        return 0;
 }
index 0f9d227f4eabbbf7c27a359fde62f8e34589de83..63a35a99fd47b5b97693abf03ee1326a5e1ad27a 100644 (file)
@@ -224,6 +224,9 @@ EditMesh *bmesh_to_editmesh_intern(BMesh *bm)
                bmeshface_to_editface(bm, em, f, evlist, numCol, numTex);
                        
        MEM_freeN(evlist);
+
+       EM_fgon_flags(em);
+
        return em;
 }
 
@@ -232,15 +235,52 @@ void bmesh2edit_exec(BMesh *bmesh, BMOperator *op)
        BMO_Set_Pnt(op, BMOP_TO_EDITMESH_EMOUT, bmesh_to_editmesh_intern(bmesh));
 }
 
+#define FACE_NGON      1
+
+void bmesh_make_fgons_exec(BMesh *bmesh, BMOperator *op)
+{
+       BMOperator triop;
+       BMFace *face;
+       BMIter iter;
+       BMEdge *edge;
+       BMOpSlot *eout;
+       int i;
+
+       BMO_Init_Op(&triop, BMOP_TRIANGULATE);
+       
+       /*HACK: I don't know if this'll conflict with other flags at all!*/
+       for (face = BMIter_New(&iter, bmesh, BM_FACES, NULL); face; face=BMIter_Step(&iter)) {
+               if (face->len > 4) {
+                       BMO_SetFlag(bmesh, face, FACE_NGON);
+               }
+       }
+
+       BMO_Flag_To_Slot(bmesh, &triop, BMOP_TRIANG_FACEIN, FACE_NGON, BM_FACE);
+       BMO_Exec_Op(bmesh, &triop);
+
+       eout = BMO_GetSlot(&triop, BMOP_TRIANG_NEW_EDGES);
+       for (i=0; i<eout->len; i++) {
+               edge = ((BMEdge**)eout->data.buf)[i];
+               edge->head.flag |= BM_FGON;
+       }
+
+       BMO_Finish_Op(bmesh, &triop);
+}
+
 EditMesh *bmesh_to_editmesh(BMesh *bmesh)
 {
-       BMOperator conv;
+       BMOperator conv, makefgon;
        EditMesh *em;
+       
+       /*first fgon-afy the mesh*/
+       BMO_Init_Op(&makefgon, BMOP_MAKE_FGONS);
+       BMO_Exec_Op(bmesh, &makefgon);
+       BMO_Finish_Op(bmesh, &makefgon);
 
        BMO_Init_Op(&conv, BMOP_TO_EDITMESH);
        BMO_Exec_Op(bmesh, &conv);
        em = conv.slots[BMOP_TO_EDITMESH_EMOUT].data.p;
        BMO_Finish_Op(bmesh, &conv);
-
+       
        return em;
 }
\ No newline at end of file
similarity index 57%
rename from source/blender/bmesh/operators/dissolvefacesop.c
rename to source/blender/bmesh/operators/dissolveops.c
index c51b9294de10c1ad697303f0d75a1c2082887421..805531cf9ddef698d8d940226d8d21e0ce91b994 100644 (file)
@@ -23,4 +23,28 @@ void dissolvefaces_exec(BMesh *bmesh, BMOperator *op)
          a great time to use the walker api, get it up to snuff.  perhaps have a walker
          that goes over inner vertices of a contiguously-flagged region?  then you
          could just use dissolve disk on them.*/
+}
+
+void dissolveverts_exec(BMesh *bmesh, BMOperator *op)
+{
+       BMOpSlot *vinput;
+       BMVert *vert;
+       int i;
+       
+       vinput = BMO_GetSlot(op, BMOP_DISVERTS_VERTIN);
+
+       /*
+       BMO_Flag_Buffer(bmesh, op, BMOP_DISVERTS_VERTIN, VERT_MARK);
+
+       for (vert=BMIter_New(&iter, bmesh, BM_VERTS, NULL); vert; vert=BMIter_Step(&iter)) {
+               if (BMO_TestFlag(bmesh, vert, VERT_MARK)) {
+                       BM_Dissolve_Disk(bmesh, vert);
+               }
+       }
+       */
+
+       for (i=0; i<vinput->len; i++) {
+               vert = ((BMVert**)vinput->data.p)[i];
+               BM_Dissolve_Disk(bmesh, vert);
+       }
 }
\ No newline at end of file
index fb51cc68254aa2361c2785cf6e500f6fd8830b05..875fc79d2adb9cd59116ec3c2a57048581e27c65 100644 (file)
@@ -33,6 +33,6 @@ void triangulate_exec(BMesh *bmesh, BMOperator *op)
                if (projverts != projectverts) MEM_freeN(projverts);
        }
        
-       BMO_Flag_To_Slot(bmesh, op, BMOP_NEW_EDGES, EDGE_NEW, BM_EDGE);
-       BMO_Flag_To_Slot(bmesh, op, BMOP_NEW_FACES, FACE_NEW, BM_FACE);
+       BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_EDGES, EDGE_NEW, BM_EDGE);
+       BMO_Flag_To_Slot(bmesh, op, BMOP_TRIANG_NEW_FACES, FACE_NEW, BM_FACE);
 }
\ No newline at end of file
index e8c632122be915330d7b32a089952e0cc3f4e460..bf03ada51b37edffc8825bb6981d222e38e251bf 100644 (file)
@@ -3329,18 +3329,48 @@ static int bmesh_test_exec(bContext *C, wmOperator *op)
 
        bm = editmesh_to_bmesh(em);
 
-       /*do stuff here, call bmop's.*/
-       //BMOP_DupeFromFlag(bm, BM_ALL, BM_SELECT);
+#if 1
+       /*dissolve vert test*/
        {
                        BMOperator op;
+                       BMOpSlot *eoutput, *foutput;
+                       int i;
+                       
+                       BMO_Init_Op(&op, BMOP_DISSOLVE_VERTS);
+                       BMO_HeaderFlag_To_Slot(bm, &op, BMOP_DISVERTS_VERTIN, BM_SELECT, BM_VERT);
+                       BMO_Exec_Op(bm, &op);
+                       
+                       BMO_Finish_Op(bm, &op);                 
+       }
+#endif
 
+#if 0
+       /*triangulator test code*/
+       {
+                       BMOperator op;
+                       BMOpSlot *eoutput, *foutput;
+                       int i;
+                       
                        BMO_Init_Op(&op, BMOP_TRIANGULATE);
                        BMO_HeaderFlag_To_Slot(bm, &op, BMOP_TRIANG_FACEIN, BM_SELECT, BM_FACE);
-
                        BMO_Exec_Op(bm, &op);
+                       
+                       eoutput = BMO_GetSlot(&op, BMOP_TRIANG_NEW_EDGES);
+                       foutput = BMO_GetSlot(&op, BMOP_TRIANG_NEW_FACES);
+                       
+                       /*select new faces/edges*/
+                       for (i=0; i<eoutput->len; i++) {
+                               BM_Select(bm, ((void**)eoutput->data.buf)[i], 1);
+                       }
+                       
+                       for (i=0; i<foutput->len; i++) {
+                               BM_Select(bm, ((void**)foutput->data.buf)[i], 1);
+                       }
+                       
                        BMO_Finish_Op(bm, &op);
                        
        }
+#endif
        em2 = bmesh_to_editmesh(bm);
        
        /*free em's data, then copy the contents of the em2 struct