From 2934dff13dc640e657d85da4ad17ff15a777ecb5 Mon Sep 17 00:00:00 2001 From: Joseph Eagar Date: Sun, 8 Feb 2009 11:53:14 +0000 Subject: [PATCH] bmesh esubdivide now supports one of the selection actions the editmesh does (so newly created verts, and newly created edges/faces if all edges of a face are selected are selected). also replaced a few usages of stack temp arrays with dynamically-allocated ones. and made bmesh->face be signed. --- source/blender/bmesh/bmesh.h | 6 +- source/blender/bmesh/intern/bmesh_operators.c | 28 +++++- source/blender/bmesh/operators/subdivideop.c | 99 +++++++++++++++---- .../blender/bmesh/operators/triangulateop.c | 17 +++- source/blender/editors/mesh/editmesh_mods.c | 2 +- 5 files changed, 123 insertions(+), 29 deletions(-) diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 1ee07dd9a83..54ec9f321af 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -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 */ diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c index f843ae173f5..5be0ec881c0 100644 --- a/source/blender/bmesh/intern/bmesh_operators.c +++ b/source/blender/bmesh/intern/bmesh_operators.c @@ -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); + } +} diff --git a/source/blender/bmesh/operators/subdivideop.c b/source/blender/bmesh/operators/subdivideop.c index 4868cf37d54..70f17e20553 100644 --- a/source/blender/bmesh/operators/subdivideop.c +++ b/source/blender/bmesh/operators/subdivideop.c @@ -21,6 +21,15 @@ #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; idata.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*/ diff --git a/source/blender/bmesh/operators/triangulateop.c b/source/blender/bmesh/operators/triangulateop.c index 875fc79d2ad..c7e36b27836 100644 --- a/source/blender/bmesh/operators/triangulateop.c +++ b/source/blender/bmesh/operators/triangulateop.c @@ -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; lastlenlen; lastlen++) { + V_GROW(projectverts); + V_GROW(projectverts); + V_GROW(projectverts); + } + } BM_Triangulate_Face(bmesh, face, projectverts, EDGE_NEW, FACE_NEW); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index 49f785cfe52..778a7b36842 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -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