extrude uses dupe/delete rather then split, and it detects when to not delete geometry (though this could be smarter in the future). also BMO_pop had two lines out of order, which was causing flags layer to not always be freed when they should.

This commit is contained in:
Joseph Eagar
2009-02-15 00:47:19 +00:00
parent 84b7ebd764
commit aac8daa177
9 changed files with 147 additions and 44 deletions

View 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 {

View File

@@ -25,12 +25,13 @@
#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);

View 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,

View 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;
}

View 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,

View 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));
}
}

View 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);

View File

@@ -12,55 +12,87 @@
#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 (rlen < 2) {
BMO_SetFlag(bm, edge, EXT_KEEP);
BMO_SetFlag(bm, edge->v1, EXT_KEEP);
BMO_SetFlag(bm, edge->v2, EXT_KEEP);
#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);
}
BMO_CopySlot(op, &splitop, BMOP_EXFACE_EDGEFACEIN, BMOP_SPLIT_MULTIN);
BMO_Flag_To_Slot(bm, &splitop, BMOP_SPLIT_KEEPIN, EXT_KEEP, BM_ALL);
BMO_Exec_Op(bm, &splitop);
/*calculate verts to delete*/
for (v = BMIter_New(&iter, bm, BM_VERTS, NULL); v; v=BMIter_Step(&iter)) {
found = 0;
BMO_CopySlot(&splitop, op, BMOP_SPLIT_MULTOUT, BMOP_EXFACE_MULTOUT);
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 (found) break;
}
if (!found) {
BMO_SetFlag(bm, v, EXT_DEL);
}
}
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;
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(op, &dupeop, BMOP_EXFACE_EDGEFACEIN, BMOP_DUPE_MULTIN);
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);
}

View 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}
};