bmesh edge dissolve: add option use_face_split (matching vertex dissolve option),
useful to avoid odd shaped ngons surrounding dissolved edges.
This commit is contained in:
@@ -884,6 +884,7 @@ static BMOpDefine bmo_dissolve_edges_def = {
|
||||
/* slots_in */
|
||||
{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}},
|
||||
{"use_verts", BMO_OP_SLOT_BOOL}, /* dissolve verts left between only 2 edges. */
|
||||
{"use_face_split", BMO_OP_SLOT_BOOL},
|
||||
{{'\0'}},
|
||||
},
|
||||
/* slots_out */
|
||||
|
||||
@@ -39,8 +39,10 @@
|
||||
#define FACE_ORIG 2
|
||||
#define FACE_NEW 4
|
||||
#define EDGE_MARK 1
|
||||
#define EDGE_TAG 2
|
||||
|
||||
#define VERT_MARK 1
|
||||
#define VERT_TAG 2
|
||||
|
||||
static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f)
|
||||
{
|
||||
@@ -73,6 +75,30 @@ static bool UNUSED_FUNCTION(check_hole_in_region) (BMesh *bm, BMFace *f)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void bm_face_split(BMesh *bm, const short oflag)
|
||||
{
|
||||
BMIter iter;
|
||||
BMVert *v;
|
||||
|
||||
BMIter liter;
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, oflag)) {
|
||||
if (BM_vert_edge_count(v) > 2) {
|
||||
BMLoop *l;
|
||||
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
|
||||
if (l->f->len > 3) {
|
||||
if (BMO_elem_flag_test(bm, l->next->v, oflag) == 0 &&
|
||||
BMO_elem_flag_test(bm, l->prev->v, oflag) == 0)
|
||||
{
|
||||
BM_face_split(bm, l->f, l->next->v, l->prev->v, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bmo_dissolve_faces_exec(BMesh *bm, BMOperator *op)
|
||||
{
|
||||
BMOIter oiter;
|
||||
@@ -272,6 +298,28 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
|
||||
BMVert *v;
|
||||
|
||||
const bool use_verts = BMO_slot_bool_get(op->slots_in, "use_verts");
|
||||
const bool use_face_split = BMO_slot_bool_get(op->slots_in, "use_face_split");
|
||||
|
||||
if (use_face_split) {
|
||||
BMO_slot_buffer_flag_enable(bm, op->slots_in, "edges", BM_EDGE, EDGE_TAG);
|
||||
|
||||
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
|
||||
BMIter iter;
|
||||
int untag_count = 0;
|
||||
BM_ITER_ELEM(e, &iter, v, BM_EDGES_OF_VERT) {
|
||||
if (!BMO_elem_flag_test(bm, e, EDGE_TAG)) {
|
||||
untag_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* check that we have 2 edges remaining after dissolve */
|
||||
if (untag_count <= 2) {
|
||||
BMO_elem_flag_enable(bm, v, VERT_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
bm_face_split(bm, VERT_TAG);
|
||||
}
|
||||
|
||||
if (use_verts) {
|
||||
BM_ITER_MESH (v, &viter, bm, BM_VERTS_OF_MESH) {
|
||||
@@ -366,23 +414,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op)
|
||||
BMO_slot_buffer_flag_enable(bm, op->slots_in, "verts", BM_VERT, VERT_MARK);
|
||||
|
||||
if (use_face_split) {
|
||||
BMIter liter;
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
if (BMO_elem_flag_test(bm, v, VERT_MARK)) {
|
||||
if (BM_vert_edge_count(v) > 2) {
|
||||
BMLoop *l;
|
||||
BM_ITER_ELEM (l, &liter, v, BM_LOOPS_OF_VERT) {
|
||||
if (l->f->len > 3) {
|
||||
if (BMO_elem_flag_test(bm, l->next->v, VERT_MARK) == 0 &&
|
||||
BMO_elem_flag_test(bm, l->prev->v, VERT_MARK) == 0)
|
||||
{
|
||||
BM_face_split(bm, l->f, l->next->v, l->prev->v, NULL, NULL, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
bm_face_split(bm, VERT_MARK);
|
||||
}
|
||||
|
||||
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
|
||||
|
||||
@@ -2991,9 +2991,14 @@ static int edbm_dissolve_edges_exec(bContext *C, wmOperator *op)
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
|
||||
const bool use_verts = RNA_boolean_get(op->ptr, "use_verts");
|
||||
const bool use_face_split = RNA_boolean_get(op->ptr, "use_face_split");
|
||||
|
||||
if (!EDBM_op_callf(em, op, "dissolve_edges edges=%he use_verts=%b", BM_ELEM_SELECT, use_verts))
|
||||
if (!EDBM_op_callf(em, op,
|
||||
"dissolve_edges edges=%he use_verts=%b use_face_split=%b",
|
||||
BM_ELEM_SELECT, use_verts, use_face_split))
|
||||
{
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
EDBM_update_generic(em, true, true);
|
||||
|
||||
@@ -3015,6 +3020,8 @@ void MESH_OT_dissolve_edges(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_boolean(ot->srna, "use_verts", 0, "Dissolve Verts", "Dissolve remaining vertices");
|
||||
RNA_def_boolean(ot->srna, "use_face_split", 0, "Face Split",
|
||||
"Split off face corners to maintain surrounding geometry");
|
||||
}
|
||||
|
||||
static int edbm_dissolve_faces_exec(bContext *C, wmOperator *op)
|
||||
|
||||
Reference in New Issue
Block a user