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:
@@ -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 {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user