add option to dissolve resulting verts with 2 edges after dissolving faces/edges.

in some cases you want these, but many times they end up neededing dissolving too.
This commit is contained in:
Campbell Barton
2012-02-10 01:40:37 +00:00
parent 63c4c18269
commit 0e89e2d6fb
3 changed files with 59 additions and 22 deletions

View File

@@ -636,6 +636,7 @@ static BMOpDefine def_dissolveedgessop = {
"dissolveedges",
{{BMOP_OPSLOT_ELEMENT_BUF, "edges"},
{BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
{BMOP_OPSLOT_INT, "use_verts"}, // dissolve verts left between only 2 edges.
{0} /* null-terminating sentine */},
dissolveedges_exec,
BMOP_UNTAN_MULTIRES
@@ -654,6 +655,7 @@ static BMOpDefine def_dissolvefacesop = {
"dissolvefaces",
{{BMOP_OPSLOT_ELEMENT_BUF, "faces"},
{BMOP_OPSLOT_ELEMENT_BUF, "regionout"},
{BMOP_OPSLOT_INT, "use_verts"}, // dissolve verts left between only 2 edges.
{0} /* null-terminating sentine */},
dissolvefaces_exec,
BMOP_UNTAN_MULTIRES

View File

@@ -83,6 +83,24 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
BMWalker regwalker;
int i;
int use_verts = BMO_Get_Int(op, "use_verts");
if (use_verts) {
/* tag verts that start out with only 2 edges,
* don't remove these later */
BMIter viter;
BMVert *v;
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
if (BM_Vert_EdgeCount(v) == 2) {
BMO_ClearFlag(bm, v, VERT_MARK);
}
else {
BMO_SetFlag(bm, v, VERT_MARK);
}
}
}
BMO_Flag_Buffer(bm, op, "faces", FACE_MARK, BM_FACE);
/* collect region */
@@ -147,6 +165,21 @@ void dissolvefaces_exec(BMesh *bm, BMOperator *op)
}
BMO_CallOpf(bm, "del geom=%ff context=%d", FACE_ORIG, DEL_FACES);
if (use_verts) {
BMIter viter;
BMVert *v;
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
if (BMO_TestFlag(bm, v, VERT_MARK)) {
if (BM_Vert_EdgeCount(v) == 2) {
BM_Collapse_Vert_Edges(bm, v->e, v);
}
}
}
}
if (BMO_HasError(bm)) goto cleanup;
BMO_Flag_To_Slot(bm, op, "regionout", FACE_NEW, BM_FACE);
@@ -210,33 +243,31 @@ void dissolve_edgeloop_exec(BMesh *bm, BMOperator *op)
void dissolveedges_exec(BMesh *bm, BMOperator *op)
{
/* might want to make this an option or mode - campbell */
#define DISSOLVE_EDGE_VERTS
/* BMOperator fop; */
BMOIter eiter;
BMEdge *e;
#ifdef DISSOLVE_EDGE_VERTS
BMIter viter;
BMVert *v;
#endif
int use_verts = BMO_Get_Int(op, "use_verts");
#ifdef DISSOLVE_EDGE_VERTS
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
BMO_ClearFlag(bm, v, VERT_MARK);
if (use_verts) {
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
BMO_ClearFlag(bm, v, VERT_MARK);
}
}
#endif /* DISSOLVE_EDGE_VERTS */
BMO_ITER(e, &eiter, bm, op, "edges", BM_EDGE) {
const int edge_face_count = BM_Edge_FaceCount(e);
if (edge_face_count == 2) {
#ifdef DISSOLVE_EDGE_VERTS
/* later check if these verts are between 2 edges and can dissolve */
BMO_SetFlag(bm, e->v1, VERT_MARK);
BMO_SetFlag(bm, e->v2, VERT_MARK);
#endif /* DISSOLVE_EDGE_VERTS */
if (use_verts) {
/* later check if these verts are between 2 edges and can dissolve */
BMO_SetFlag(bm, e->v1, VERT_MARK);
BMO_SetFlag(bm, e->v2, VERT_MARK);
}
/* join faces */
BM_Join_TwoFaces(bm, e->l->f,
@@ -254,16 +285,15 @@ void dissolveedges_exec(BMesh *bm, BMOperator *op)
}
}
#ifdef DISSOLVE_EDGE_VERTS
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
if (BMO_TestFlag(bm, v, VERT_MARK)) {
if (BM_Vert_EdgeCount(v) == 2) {
BM_Collapse_Vert_Edges(bm, v->e, v);
if (use_verts) {
BM_ITER(v, &viter, bm, BM_VERTS_OF_MESH, NULL) {
if (BMO_TestFlag(bm, v, VERT_MARK)) {
if (BM_Vert_EdgeCount(v) == 2) {
BM_Collapse_Vert_Edges(bm, v->e, v);
}
}
}
}
#endif /* DISSOLVE_EDGE_VERTS */
}
static int test_extra_verts(BMesh *bm, BMVert *v)

View File

@@ -915,13 +915,14 @@ static int delete_mesh(bContext *C, Object *obedit, wmOperator *op, int event, S
return OPERATOR_CANCELLED;
}
else if (event==7) {
int use_verts = RNA_boolean_get(op->ptr, "use_verts");
//"Dissolve"
if (bem->selectmode & SCE_SELECT_FACE) {
if (!EDBM_CallOpf(bem, op, "dissolvefaces faces=%hf",BM_SELECT))
if (!EDBM_CallOpf(bem, op, "dissolvefaces faces=%hf use_verts=%i", BM_SELECT, use_verts))
return OPERATOR_CANCELLED;
}
else if (bem->selectmode & SCE_SELECT_EDGE) {
if (!EDBM_CallOpf(bem, op, "dissolveedges edges=%he",BM_SELECT))
if (!EDBM_CallOpf(bem, op, "dissolveedges edges=%he use_verts=%i", BM_SELECT, use_verts))
return OPERATOR_CANCELLED;
}
else if (bem->selectmode & SCE_SELECT_VERTEX) {
@@ -1008,9 +1009,13 @@ void MESH_OT_delete(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
/*props */
ot->prop = RNA_def_enum(ot->srna, "type", prop_mesh_delete_types, 10, "Type", "Method used for deleting mesh data");
/* TODO, move dissolve into its own operator so this doesnt confuse non-dissolve options */
RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts",
"When dissolving faaces/edges, also dissolve remaining vertices");
}