bmesh esubdivide now supports one of the selection actions the editmesh does (so...
authorJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 11:53:14 +0000 (11:53 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sun, 8 Feb 2009 11:53:14 +0000 (11:53 +0000)
source/blender/bmesh/bmesh.h
source/blender/bmesh/intern/bmesh_operators.c
source/blender/bmesh/operators/subdivideop.c
source/blender/bmesh/operators/triangulateop.c
source/blender/editors/mesh/editmesh_mods.c

index 1ee07dd9a832240637ffd6e09af57b6420c0c71b..54ec9f321af1007904855c49f08051429d9f79dc 100644 (file)
@@ -159,10 +159,12 @@ typedef struct BMLoop  {
 typedef struct BMFace {
        struct BMHeader head;
        struct BMLoop *loopbase;
-       unsigned int len;
+       int len;
        void *data;
        float no[3];
-       unsigned short mat_nr;                                                                  /*custom data again, and get rid of the unsigned short nonsense...*/
+
+       /*custom data again*/
+       short mat_nr; 
 } BMFace;
 
 /*stub */
index f843ae173f553e277c4d3f94dc53c319a2613876..5be0ec881c0132a266f204b53bd8181720d76293 100644 (file)
@@ -13,8 +13,8 @@
 /*forward declarations*/
 static void alloc_flag_layer(BMesh *bm);
 static void free_flag_layer(BMesh *bm);
+static void clear_flag_layer(BMesh *bm);
 
-/*function pointer table*/
 typedef void (*opexec)(struct BMesh *bm, struct BMOperator *op);
 
 /*operator slot type information - size of one element of the type given.*/
@@ -47,6 +47,8 @@ void BMO_push(BMesh *bm, BMOperator *op)
        /*add flag layer, if appropriate*/
        if (bm->stackdepth > 1)
                alloc_flag_layer(bm);
+       else
+               clear_flag_layer(bm);
 }
 
 /*
@@ -246,7 +248,7 @@ void BMO_SetFlag(BMesh *bm, void *element, int flag)
 void BMO_ClearFlag(BMesh *bm, void *element, int flag)
 {
        BMHeader *head = element;
-       head->flags[bm->stackdepth].mask &= ~flag;
+       head->flags[bm->stackdepth-1].mask &= ~flag;
 }
 
 /*
@@ -516,3 +518,25 @@ static void free_flag_layer(BMesh *bm)
 
        BLI_mempool_destroy(oldpool);
 }
+
+static void clear_flag_layer(BMesh *bm)
+{
+       BMVert *v;
+       BMEdge *e;
+       BMFace *f;
+       
+       BMIter verts;
+       BMIter edges;
+       BMIter faces;
+       
+       /*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);
+       }
+       for(e = BMIter_New(&edges, bm, BM_EDGES, bm); e; e = BMIter_Step(&edges)){
+               memset(e->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
+       }
+       for(f = BMIter_New(&faces, bm, BM_FACES, bm); f; f = BMIter_Step(&faces)){
+               memset(f->head.flags, 0, sizeof(BMFlagLayer)*bm->totflags);
+       }
+}
index 4868cf37d54a3ff8b2ff4d73c52ab10a518528de..70f17e205534121b0be106098f2bb044069ab5b5 100644 (file)
 #define FACE_NEW       1
 #define MAX_FACE       800
 
+/*stuff for the flag paramter.  note that
+  what used to live in "beauty" and
+  in "seltype" live here.  still have to
+  convert the beauty flags over, which
+  is why it starts at 128 (to avoid
+  collision).*/
+#define SELTYPE_INNER  128
+
+
 /*
 NOTE: beauty has been renamed to flag!
 */
@@ -49,7 +58,6 @@ typedef struct subdpattern {
     split the edge only?
 */
 
-
 /* calculates offset for co, based on fractal, sphere or smooth settings  */
 static void alter_co(float *co, BMEdge *edge, float rad, int flag, float perc,
                     BMVert *vsta, BMVert *vend)
@@ -117,6 +125,7 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge, float rad,
 //     float co[3];
        
        ev = BM_Split_Edge(bm, edge->v1, edge, out, percent, 1);
+       if (flag & SELTYPE_INNER) BM_Select_Vert(bm, ev, 1);
 
        /* offset for smooth or sphere or fractal */
        alter_co(ev->co, edge, rad, flag, percent, vsta, vend);
@@ -165,6 +174,7 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge,
 */
                ev= bm_subdivide_edge_addvert(bm, edge, rad, flag, percent, 
                                       newe, vsta, vend);
+               
 /*             VECCOPY(ev->co, co2);
        }
 */     
@@ -210,15 +220,19 @@ static void q_1edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                add = 2;
                for (i=0; i<numcuts; i++) {
                        if (i == numcuts/2) add -= 1;
-                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], &nf);
+                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], 
+                                          &nf);
                }
        } else {
                add = 2;
                for (i=0; i<numcuts; i++) {
-                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], &nf);
+                       BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], 
+                                          &nf);
                        if (i == numcuts/2) {
                                add -= 1;
-                               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+add], &nf);
+                               BM_Connect_Verts(bm, vlist[i], 
+                                                  vlist[numcuts+add],
+                                                  &nf);
                        }
                }
 
@@ -248,7 +262,8 @@ static void q_2edge_op_split(BMesh *bm, BMFace *face, BMVert **vlist,
        int i;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[(numcuts-i-1)+numcuts+2], &nf);
+               BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i-1)+numcuts+2],
+                                  &nf);
        }
 }
 
@@ -273,7 +288,8 @@ static void q_2edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
        int i;
        
        for (i=0; i<numcuts; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+(numcuts-i)], &nf);
+               BM_Connect_Verts(bm, vlist[i], vlist[numcuts+(numcuts-i)],
+                                  &nf);
        }
        BM_Connect_Verts(bm, vlist[numcuts*2+3], vlist[numcuts*2+1], &nf);
 }
@@ -302,15 +318,18 @@ static void q_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
        for (i=0; i<numcuts; i++) {
                if (i == numcuts/2) {
                        if (numcuts % 2 != 0) {
-                               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], vlist[i+numcuts+1], &nf);
+                               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], 
+                                                vlist[i+numcuts+1], &nf);
                        }
                        add = numcuts*2+2;
                }
-               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], vlist[i+numcuts+1], &nf);
+               BM_Connect_Verts(bm, vlist[numcuts-i-1+add], 
+                                    vlist[i+numcuts+1], &nf);
        }
 
        for (i=0; i<numcuts/2+1; i++) {
-               BM_Connect_Verts(bm, vlist[i], vlist[(numcuts-i)+numcuts*2+1], &nf);
+               BM_Connect_Verts(bm, vlist[i],vlist[(numcuts-i)+numcuts*2+1],
+                                  &nf);
        }
 }
 
@@ -360,6 +379,10 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                b = numcuts + 1 + numcuts + 1 + (numcuts - i - 1);
                
                e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
+               if (flag & SELTYPE_INNER) {
+                       BM_Select_Edge(bm, e, 1);
+                       BM_Select_Face(bm, nf, 1);
+               }
                
                v1 = lines[(i+1)*s] = vlist[a];
                v2 = lines[(i+1)*s + s-1] = vlist[b];
@@ -367,6 +390,9 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                for (a=0; a<numcuts; a++) {
                        v = subdivideedgenum(bm, e, a, numcuts, rad, flag, &ne,
                                             v1, v2);
+                       if (flag & SELTYPE_INNER) {
+                               BM_Select_Edge(bm, ne, 1);
+                       }
                        lines[(i+1)*s+a+1] = v;
                }
        }
@@ -375,7 +401,11 @@ static void q_4edge_split(BMesh *bm, BMFace *face, BMVert **vlist, int numcuts,
                for (j=1; j<numcuts+1; j++) {
                        a = i*s + j;
                        b = (i-1)*s + j;
-                       BM_Connect_Verts(bm, lines[a], lines[b], &nf);
+                       e = BM_Connect_Verts(bm, lines[a], lines[b], &nf);
+                       if (flag & SELTYPE_INNER) {
+                               BM_Select_Edge(bm, e, 1);
+                               BM_Select_Face(bm, nf, 1);
+                       }
                }
        }
 
@@ -448,12 +478,12 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
        BMEdge *e, *ne;
        BMVert ***lines, *v;
        void *stackarr[1];
-       int i, j, u, a, b;
+       int i, j, a, b;
        
        /*number of verts in each line*/
        lines = MEM_callocN(sizeof(void*)*(numcuts+2), "triangle vert table");
        
-       lines[0] = stackarr;
+       lines[0] = (BMVert**) stackarr;
        lines[0][0] = vlist[numcuts*2+1];
        
        lines[1+numcuts] = MEM_callocN(sizeof(void*)*(numcuts+2), 
@@ -470,6 +500,11 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
                a = numcuts*2 + 2 + i;
                b = numcuts + numcuts - i;
                e = BM_Connect_Verts(bm, vlist[a], vlist[b], &nf);
+               
+               if (flag & SELTYPE_INNER) {
+                       BM_Select_Edge(bm, e, 1);
+                       BM_Select_Face(bm, nf, 1);
+               }
 
                lines[i+1][0] = vlist[a];
                lines[i+1][1+i] = vlist[b];
@@ -478,6 +513,10 @@ static void t_3edge_split(BMesh *bm, BMFace *face, BMVert **vlist,
                        v = subdivideedgenum(bm, e, j, i, rad, flag, &ne,
                                             vlist[a], vlist[b]);
                        lines[i+1][j+1] = v;
+
+                       if (flag & SELTYPE_INNER) {
+                               BM_Select_Edge(bm, ne, 1);
+                       }
                }
        }
        
@@ -493,12 +532,23 @@ sv7/---v---\ v3 s
 */
        for (i=1; i<numcuts+1; i++) {
                for (j=0; j<i; j++) {
-                       BM_Connect_Verts(bm, lines[i][j], lines[i+1][j+1],&nf);
-                       BM_Connect_Verts(bm,lines[i][j+1],lines[i+1][j+1],&nf);
+                       e= BM_Connect_Verts(bm, lines[i][j], lines[i+1][j+1],
+                                          &nf);
+                       if (flag & SELTYPE_INNER) {
+                               BM_Select_Edge(bm, e, 1);
+                               BM_Select_Face(bm, nf, 1);
+                       }
+
+                       e= BM_Connect_Verts(bm,lines[i][j+1],lines[i+1][j+1],
+                                          &nf);
+                       if (flag & SELTYPE_INNER) {
+                               BM_Select_Edge(bm, e, 1);
+                               BM_Select_Face(bm, nf, 1);
+                       }
                }
        }
 
-       for (i=0; i<numcuts; i++) {
+       for (i=1; i<numcuts+2; i++) {
                MEM_freeN(lines[i]);
        }
 
@@ -538,10 +588,12 @@ typedef struct subd_facedata {
 void esubdivide_exec(BMesh *bmesh, BMOperator *op)
 {
        BMOpSlot *einput;
-       BMEdge *edge, *edges[MAX_FACE];
+       BMEdge *edge, **edges = NULL;
+       V_DECLARE(edges);
        BMFace *face;
        BMLoop *nl;
-       BMVert *verts[MAX_FACE];
+       BMVert **verts = NULL;
+       V_DECLARE(verts);
        BMIter fiter, liter;
        subdpattern *pat;
        float rad;
@@ -554,7 +606,9 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        numcuts = BMO_GetSlot(op, BMOP_ESUBDIVIDE_NUMCUTS)->data.i;
        flag = BMO_GetSlot(op, BMOP_ESUBDIVIDE_FLAG)->data.i;
        rad = BMO_GetSlot(op, BMOP_ESUBDIVIDE_RADIUS)->data.f;
+
        selaction = BMO_GetSlot(op, BMOP_ESUBDIVIDE_SELACTION)->data.i;
+       if (selaction == SUBDIV_SELECT_INNER) flag |= SELTYPE_INNER;
 
        einput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
        
@@ -567,11 +621,13 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
             face; face=BMIter_Step(&fiter)) {
                /*figure out which pattern to use*/
-               if (face->len > MAX_FACE) continue;
-
                i = 0;
+               V_RESET(edges);
+               V_RESET(verts);
                for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face);
                     nl; nl=BMIter_Step(&liter)) {
+                       V_GROW(edges);
+                       V_GROW(verts);
                        edges[i] = nl->e;
                        verts[i] = nl->v;
                        i++;
@@ -619,7 +675,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        for (face=BMIter_New(&fiter, bmesh, BM_FACES, NULL);
             face; face=BMIter_Step(&fiter)) {
                /*figure out which pattern to use*/
-               if (face->len > MAX_FACE) continue;
+               V_RESET(verts);
                if (BMO_TestFlag(bmesh, face, SUBD_SPLIT) == 0) continue;
                
                pat = facedata[i].pat;
@@ -639,6 +695,7 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                for (nl=BMIter_New(&liter, bmesh, BM_LOOPS_OF_FACE, face);
                     nl; nl=BMIter_Step(&liter)) {
                        b = (j-a+face->len) % face->len;
+                       V_GROW(verts);
                        verts[b] = nl->v;
                        j += 1;
                }
@@ -648,6 +705,8 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        }
 
        if (facedata) V_FREE(facedata);
+       if (edges) V_FREE(edges);
+       if (verts) V_FREE(verts);
 }
 
 /*editmesh-emulating function*/
index 875fc79d2adb9cd59116ec3c2a57048581e27c65..c7e36b27836e3d8865ceaa84415f7c28433b7bea 100644 (file)
@@ -14,9 +14,10 @@ void triangulate_exec(BMesh *bmesh, BMOperator *op)
 {
        BMOpSlot *finput;
        BMFace *face;
-       float projectverts[400][3];
+       float (*projectverts)[3] = NULL;
+       V_DECLARE(projectverts);
        void *projverts;
-       int i, count = 0;
+       int i, lastlen=0, count = 0;
        
        finput = BMO_GetSlot(op, BMOP_ESUBDIVIDE_EDGES);
 
@@ -25,8 +26,16 @@ void triangulate_exec(BMesh *bmesh, BMOperator *op)
 
                /*HACK! need to discuss with Briggs why the function takes an 
                  externally-allocated array of vert coordinates in the first place.*/
-               if (face->len > 400) projverts = MEM_callocN(sizeof(float)*3*face->len, "projverts");
-               else projverts = projectverts;
+               //if (face->len > 400) projverts = MEM_callocN(sizeof(float)*3*face->len, "projverts");
+               //else projverts = projectverts;
+               if (lastlen < face->len) {
+                       V_RESET(projectverts);
+                       for (lastlen=0; lastlen<face->len; lastlen++) {
+                               V_GROW(projectverts);
+                               V_GROW(projectverts);
+                               V_GROW(projectverts);
+                       }
+               }
                
                BM_Triangulate_Face(bmesh, face, projectverts, EDGE_NEW, FACE_NEW);
                
index 49f785cfe52b71cbb677ab1abdee42c5738369ca..778a7b36842e1195902367674d71703ae5a14b52 100644 (file)
@@ -3461,7 +3461,7 @@ static int bmesh_test_exec(bContext *C, wmOperator *op)
 
 #if 1 /*edge subdivide test*/
        //BM_esubdivideflag(obedit, bm, SELECT, 0.292f*5.0, B_SMOOTH, G.rt==0?1:G.rt, 0);
-       BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, 0);
+       BM_esubdivideflag(obedit, bm, SELECT, 0, 0, G.rt==0?1:G.rt, SUBDIV_SELECT_INNER);
 
 #endif