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.
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; 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*/
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user