extrude uses dupe/delete rather then split, and it detects when to not delete geometr...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 15 Feb 2009 00:47:19 +0000 (00:47 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 15 Feb 2009 00:47:19 +0000 (00:47 +0000)
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_iterators.h
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_iterators.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/operators/bmesh_dupeops.c
source/blender/bmesh/operators/extrudeops.c
source/blender/editors/mesh/editmesh_tools.c

index 42e41a0270f544e63485ea7dfdd53ed19ef08df9..5b1753a9902380c3044a87d9b15bacf72c280c36 100644 (file)
@@ -79,10 +79,10 @@ struct BMLoop;
 
 typedef struct BMHeader {
        struct BMHeader *next, *prev;
-       int             EID;                                                            /*Consider removing this/making it ifdeffed for debugging*/
+       int             EID;  /*Consider removing this/making it ifdeffed for debugging*/
        int             flag, type;
-       int                     eflag1, eflag2;                                         /*Flags used by eulers. Try and get rid of/minimize some of these*/
-       struct BMFlagLayer *flags;                                              /*Dynamically allocated block of flag layers for operators to use*/
+       int                     eflag1, eflag2; /*Flags used by eulers. Try and get rid of/minimize some of these*/
+       struct BMFlagLayer *flags; /*Dynamically allocated block of flag layers for operators to use*/
 } BMHeader;
 
 typedef struct BMFlagLayer {
index 7e1eef849180499ee4bbe5ea4f08a9181a9446eb..f2d2f03932f8ad40778cadf2e60f89054946ad0b 100644 (file)
 #define BM_FACEVERTS_OF_FACE           9
 #define BM_EDGES_OF_FACE                       10
 #define BM_LOOPS_OF_FACE                       11
+#define BM_LOOPS_OF_VERT               12
 
 /*Iterator Structure*/
 typedef struct BMIter{
        struct BMVert *firstvert, *nextvert, *vdata;
        struct BMEdge *firstedge, *nextedge, *edata;
-       struct BMLoop *firstloop, *nextloop, *ldata;
+       struct BMLoop *firstloop, *nextloop, *ldata, *l;
        struct BMFace *firstpoly, *nextpoly, *pdata;
        struct BMesh *bm;
        void (*begin)(struct BMIter *iter);
index 2250898290e283b9811d9e9397557534fa3e2842..48330c4604a05dc1c9b6ab15211a6a0a724427dc 100644 (file)
@@ -146,7 +146,6 @@ static char *bmop_error_messages[] = {
 
 enum {
        BMOP_SPLIT_MULTIN,
-       BMOP_SPLIT_KEEPIN, //input list of geometry to keep
        BMOP_SPLIT_MULTOUT,
        BMOP_SPLIT_BOUNDS_EDGEMAP, //bounding edges of split faces
        BMOP_SPLIT_TOTSLOT,
index e64e4c9ebc9fe277c816a722746c24069bd9fd52..11db2ba47fd86dd6a2ab9bf647f1e5f2d141d86d 100644 (file)
@@ -273,6 +273,51 @@ static void *loop_of_face_step(BMIter *iter)
        return current;
 }
 
+/*
+ * LOOPS OF VERT CALLBACKS
+ *
+ */
+/*
+       BMEdge *current = iter->nextedge;
+
+       if(iter->nextedge)
+               iter->nextedge = bmesh_disk_nextedge(iter->nextedge, iter->vdata);
+       
+       if(iter->nextedge == iter->firstedge) iter->nextedge = NULL; 
+
+       return current;
+*/
+       
+
+static void loop_of_vert_begin(BMIter *iter)
+{
+       init_iterator(iter);
+       iter->firstedge = iter->vdata->edge;
+       if (!iter->vdata->edge) return NULL;
+
+       iter->firstloop = iter->nextloop = iter->vdata->edge->loop;
+       iter->l = iter->firstloop;
+}
+
+static void *loop_of_vert_step(BMIter *iter)
+{
+       BMLoop *current = iter->nextloop;
+
+       if(iter->nextloop) {
+               iter->nextloop = bmesh_radial_nextloop(iter->nextloop);
+               if (iter->nextloop == iter->l) {
+                       iter->nextloop = bmesh_disk_nextedge(iter->nextloop->e, 
+                                                           iter->vdata)->loop;
+                       iter->l = iter->nextloop;
+
+                       if (iter->nextloop->e == iter->firstedge)
+                               iter->nextloop = NULL;
+               }
+       }
+       
+       return current;
+}
+
 /*
  * BMESH ITERATOR INIT
  *
@@ -333,6 +378,12 @@ void *BMIter_New(BMIter *iter, BMesh *bm, int type, void *data)
                        iter->begin = loop_of_face_begin;
                        iter->step = loop_of_face_step;
                        iter->pdata = data;
+                       break;
+               case BM_LOOPS_OF_VERT:
+                       iter->begin = loop_of_vert_begin;
+                       iter->step = loop_of_vert_step;
+                       iter->vdata = data;
+                       break;
                default:
                        break;
        }
index efcad39b79c8cb1ff40deb8a7d6405e8cac659c0..af56924fd2efa357e4694ea75e181f9124075891 100644 (file)
@@ -87,7 +87,7 @@ BMOpDefine def_dupeop = {
 };
 
 BMOpDefine def_splitop = {
-       {BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_PNT_BUF,
+       {BMOP_OPSLOT_PNT_BUF,
         BMOP_OPSLOT_PNT_BUF, BMOP_OPSLOT_MAPPING},
        splitop_exec,
        BMOP_SPLIT_TOTSLOT,
index 5f5a65e04283fac3d272a76a7e847f1a0c25ebad..628a9c5715729a63f4ebc87634fa50d31fbae9c9 100644 (file)
@@ -68,9 +68,10 @@ void BMO_push(BMesh *bm, BMOperator *op)
 */
 void BMO_pop(BMesh *bm)
 {
-       bm->stackdepth--;
        if(bm->stackdepth > 1)
                free_flag_layer(bm);
+
+       bm->stackdepth--;
 }
 
 /*
@@ -699,17 +700,17 @@ static void free_flag_layer(BMesh *bm)
        /*now go through and memcpy all the flags*/
        for(v = BMIter_New(&verts, bm, BM_VERTS, bm); v; v = BMIter_Step(&verts)){
                oldflags = v->head.flags;
-               v->head.flags = BLI_mempool_alloc(bm->flagpool);
+               v->head.flags = BLI_mempool_calloc(bm->flagpool);
                memcpy(v->head.flags, oldflags, sizeof(BMFlagLayer)*bm->totflags);  /*correct?*/
        }
        for(e = BMIter_New(&edges, bm, BM_EDGES, bm); e; e = BMIter_Step(&edges)){
                oldflags = e->head.flags;
-               e->head.flags = BLI_mempool_alloc(bm->flagpool);
+               e->head.flags = BLI_mempool_calloc(bm->flagpool);
                memcpy(e->head.flags, oldflags, sizeof(BMFlagLayer)*bm->totflags);
        }
        for(f = BMIter_New(&faces, bm, BM_FACES, bm); f; f = BMIter_Step(&faces)){
                oldflags = f->head.flags;
-               f->head.flags = BLI_mempool_alloc(bm->flagpool);
+               f->head.flags = BLI_mempool_calloc(bm->flagpool);
                memcpy(f->head.flags, oldflags, sizeof(BMFlagLayer)*bm->totflags);
        }
 
@@ -728,13 +729,13 @@ static void clear_flag_layer(BMesh *bm)
        
        /*now go through and memcpy all the flags*/
        for(v = BMIter_New(&verts, bm, BM_VERTS, bm); v; v = BMIter_Step(&verts)){
-               memset(v->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
+               memset(v->head.flags+bm->totflags-1, 0, sizeof(BMFlagLayer));
        }
        for(e = BMIter_New(&edges, bm, BM_EDGES, bm); e; e = BMIter_Step(&edges)){
-               memset(e->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
+               memset(e->head.flags+bm->totflags-1, 0, sizeof(BMFlagLayer));
        }
        for(f = BMIter_New(&faces, bm, BM_FACES, bm); f; f = BMIter_Step(&faces)){
-               memset(f->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
+               memset(f->head.flags+bm->totflags-1, 0, sizeof(BMFlagLayer));
        }
 }
 
index 2baf052a5593c7d6d4190e36095acc26f2cb7a4f..8c92e3b81ce2dcc9b5338c2e89260191d9ecc715 100644 (file)
@@ -381,8 +381,7 @@ void splitop_exec(BMesh *bm, BMOperator *op)
        }
 
        /*connect outputs of dupe to delete, exluding keep geometry*/
-       BMO_Set_Int(&delop, BMOP_DEL_CONTEXT, DEL_ONLYTAGGED);
-       BMO_Unflag_Buffer(bm, splitop, BMOP_SPLIT_KEEPIN, SPLIT_INPUT);
+       BMO_Set_Int(&delop, BMOP_DEL_CONTEXT, DEL_FACES);
        BMO_Flag_To_Slot(bm, &delop, BMOP_DEL_MULTIN, SPLIT_INPUT, BM_ALL);
        
        BMO_Exec_Op(bm, &delop);
index eca8332c917306eaa085eaa0a91e62c9ee1f8c3d..81776d673e7ec55354874b17d4cf654830dec2c8 100644 (file)
 
 #define EXT_INPUT      1
 #define EXT_KEEP       2
+#define EXT_DEL                4
 
 void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
 {
-       BMOperator splitop;
+       BMOperator dupeop, delop;
        BMOIter siter;
-       BMIter iter, fiter;
-       BMEdge *edge, *newedge;
+       BMIter iter, fiter, viter;
+       BMEdge *e, *newedge, *e2;
        BMLoop *l, *l2;
-       BMVert *verts[4];
+       BMVert *verts[4], *v;
        BMFace *f;
-       int totflagged, rlen;
+       int rlen, found, delorig=0, i;
 
        /*initialize our sub-operators*/
-       BMO_Init_Op(&splitop, BMOP_SPLIT);
+       BMO_Init_Op(&dupeop, BMOP_DUPE);
+       BMO_Init_Op(&delop, BMOP_DEL);
        
        BMO_Flag_Buffer(bm, op, BMOP_EXFACE_EDGEFACEIN, EXT_INPUT);
 
-       /*calculate geometry to keep*/
-       for (edge = BMIter_New(&iter, bm, BM_EDGES, NULL); edge; edge=BMIter_Step(&iter)) {
-               f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, edge);
-               rlen = 0;
-               for (; f; f=BMIter_Step(&fiter)) {
-                       if (BMO_TestFlag(bm, f, EXT_INPUT)) rlen++;
+#if 1
+       for (e=BMIter_New(&iter, bm, BM_EDGES, NULL);e;e=BMIter_Step(&iter)) {
+               found = 0;
+               f = BMIter_New(&fiter, bm, BM_FACES_OF_EDGE, e);
+               for (rlen=0; f; f=BMIter_Step(&fiter), rlen++) {
+                       if (!BMO_TestFlag(bm, f, EXT_INPUT)) {
+                               found = 1;
+                               delorig = 1;
+                               break;
+                       }
                }
+               
+               if (!found && (rlen > 1)) BMO_SetFlag(bm, e, EXT_DEL);
+       }
+
+       /*calculate verts to delete*/
+       for (v = BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
+               found = 0;
+
+               l = BMIter_New(&viter, bm, BM_LOOPS_OF_VERT, v);
+               for (; l; l=BMIter_Step(&viter)) {
+                       if (!BMO_TestFlag(bm, l->e, EXT_INPUT)) {
+                               found = 1;
+                               break;
+                       }
+                       if (!BMO_TestFlag(bm, l->f, EXT_INPUT)) {
+                               found = 1;
+                               break;
+                       }
 
-               if (rlen < 2) {
-                       BMO_SetFlag(bm, edge, EXT_KEEP);
-                       BMO_SetFlag(bm, edge->v1, EXT_KEEP);
-                       BMO_SetFlag(bm, edge->v2, EXT_KEEP);
+                       if (found) break;
                }
-       }
 
-       BMO_CopySlot(op, &splitop, BMOP_EXFACE_EDGEFACEIN, BMOP_SPLIT_MULTIN);
-       BMO_Flag_To_Slot(bm, &splitop, BMOP_SPLIT_KEEPIN, EXT_KEEP, BM_ALL);
+               if (!found) {
+                       BMO_SetFlag(bm, v, EXT_DEL);
+               }
+       }
        
-       BMO_Exec_Op(bm, &splitop);
+       for (f=BMIter_New(&fiter, bm, BM_FACES, NULL); f; f=BMIter_Step(&fiter)) {
+               if (BMO_TestFlag(bm, f, EXT_INPUT))
+                       BMO_SetFlag(bm, f, EXT_DEL);
+       }
+#endif
+       if (delorig) BMO_Flag_To_Slot(bm, &delop, BMOP_DEL_MULTIN, EXT_DEL, BM_ALL);
+       BMO_Set_Int(&delop, BMOP_DEL_CONTEXT, DEL_ONLYTAGGED);
 
-       BMO_CopySlot(&splitop, op, BMOP_SPLIT_MULTOUT, BMOP_EXFACE_MULTOUT);
+       BMO_CopySlot(op, &dupeop, BMOP_EXFACE_EDGEFACEIN, BMOP_DUPE_MULTIN);
        
-       edge = BMO_IterNew(&siter, bm, &splitop, BMOP_SPLIT_BOUNDS_EDGEMAP);
-       for (; edge; edge=BMO_IterStep(&siter)) {
-               if (BMO_InMap(bm, op, BMOP_EXFACE_EXCLUDEMAP, edge)) continue;
+       BMO_Exec_Op(bm, &dupeop);
+       if (delorig) BMO_Exec_Op(bm, &delop);
+
+       BMO_CopySlot(&dupeop, op, BMOP_DUPE_NEW, BMOP_EXFACE_MULTOUT);
+       e = BMO_IterNew(&siter, bm, &dupeop, BMOP_DUPE_BOUNDS_EDGEMAP);
+       for (; e; e=BMO_IterStep(&siter)) {
+               if (BMO_InMap(bm, op, BMOP_EXFACE_EXCLUDEMAP, e)) continue;
 
                newedge = BMO_IterMapVal(&siter);
                if (!newedge) continue;
                newedge = *(BMEdge**)newedge;
 
-               verts[0] = edge->v1;
-               verts[1] = edge->v2;
+               verts[0] = e->v1;
+               verts[1] = e->v2;
                verts[2] = newedge->v2;
                verts[3] = newedge->v1;
                
@@ -89,7 +121,9 @@ void extrude_edge_context_exec(BMesh *bm, BMOperator *op)
                        }
                }
        }
+
        
        /*cleanup*/
-       BMO_Finish_Op(bm, &splitop);
+       BMO_Finish_Op(bm, &delop);
+       BMO_Finish_Op(bm, &dupeop);
 }
index 2ac962e5d59f3ed0c808df4575f2986d53c2e4ea..591854c2811e1fb43f620419031b42b725be7c3e 100644 (file)
@@ -91,6 +91,7 @@ editmesh_tool.c: UI called tools for editmesh, geometry changes here, otherwise
 #include "UI_interface.h"
 
 #include "mesh_intern.h"
+#include "bmesh.h"
 
 /* XXX */
 static int extern_qread() {return 0;}
@@ -1024,6 +1025,22 @@ void delete_mesh(Object *obedit, EditMesh *em, int event)
                erase_faces(em, &em->faces);
                erase_vertices(em, &em->verts);
        } 
+       else if(event==7) {
+               BMesh *bm = editmesh_to_bmesh(em);
+               BMOperator op;
+               EditMesh *em2;
+               
+               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);
+               
+               em2 = bmesh_to_editmesh(bm);
+               set_editMesh(em, em2);
+               MEM_freeN(em2);
+       }
        else if(event==6) {
                if(!EdgeLoopDelete(em))
                        return;
@@ -1155,6 +1172,7 @@ static EnumPropertyItem prop_mesh_delete_types[] = {
        {4, "EDGE_FACE","Edges & Faces", ""},
        {5, "ONLY_FACE","Only Faces", ""},
        {6, "EDGE_LOOP","Edge Loop", ""},
+       {7, "COLLAPSE","Collapse", ""},
        {0, NULL, NULL, NULL}
 };