From d6ab81809e25eb827f450006efa1442a52bcec11 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Fri, 27 Jun 2014 20:26:35 +1000 Subject: BMesh: tweaks to dissolve, remove wire edges before other calculations also avoid feedback loop when checking topology giving nondeterministic results. --- source/blender/bmesh/operators/bmo_dissolve.c | 45 ++++++++++++++++++--------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'source/blender/bmesh/operators') diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index bebfeaa5b06..f7b8352ed78 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -48,6 +48,7 @@ #define EDGE_ISGC 8 #define VERT_MARK 1 +#define VERT_MARK_PAIR 4 #define VERT_TAG 2 #define VERT_ISGC 8 @@ -346,13 +347,7 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op) const bool use_face_split = BMO_slot_bool_get(op->slots_in, "use_face_split"); BMO_ITER (v, &oiter, op->slots_in, "verts", BM_VERT) { - BMIter itersub; - BMO_elem_flag_enable(bm, v, VERT_MARK | VERT_ISGC); - - BM_ITER_ELEM (e, &itersub, v, BM_EDGES_OF_VERT) { - BMO_elem_flag_enable(bm, e, EDGE_ISGC); - } } if (use_face_split) { @@ -370,12 +365,32 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, l_iter->e, EDGE_ISGC); } while ((l_iter = l_iter->next) != l_first); } + + /* clean wire edges and mark vert-edge-pairs (unrelated to checks above) */ + if ((e = v->e)) { + int edge_count = 0; + do { + e_next = BM_DISK_EDGE_NEXT(e, v); + if (BM_edge_is_wire(e)) { + BM_edge_kill(bm, e); + } + else { + BMO_elem_flag_enable(bm, e, EDGE_ISGC); + edge_count += 1; + } + } while (v->e && (e = e_next) != v->e); + + /* tag here so we avoid feedback loop (checking topology as we edit) */ + if (edge_count == 2) { + BMO_elem_flag_enable(bm, v, VERT_MARK_PAIR); + } + } } BMO_ITER (v, &oiter, op->slots_in, "verts", BM_VERT) { BMIter itersub; - if (BM_vert_edge_count(v) != 2) { + if (!BMO_elem_flag_test(bm, v, VERT_MARK_PAIR)) { BM_ITER_ELEM (e, &itersub, v, BM_EDGES_OF_VERT) { BMFace *fa, *fb; if (BM_edge_face_pair(e, &fa, &fb)) { @@ -400,20 +415,20 @@ void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op) BM_edge_kill(bm, e); } } - BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { - if ((v->e == NULL) && BMO_elem_flag_test(bm, v, VERT_ISGC)) { - BM_vert_kill(bm, v); + + /* final cleanup */ + BMO_ITER (v, &oiter, op->slots_in, "verts", BM_VERT) { + if (BM_vert_is_edge_pair(v)) { + BM_vert_collapse_edge(bm, v->e, v, false, true); } } - /* done with cleanup */ BM_ITER_MESH_MUTABLE (v, v_next, &iter, bm, BM_VERTS_OF_MESH) { - if (BMO_elem_flag_test(bm, v, VERT_MARK)) { - if (BM_vert_edge_count(v) == 2) { - BM_vert_collapse_edge(bm, v->e, v, true, true); - } + if ((v->e == NULL) && BMO_elem_flag_test(bm, v, VERT_ISGC)) { + BM_vert_kill(bm, v); } } + /* done with cleanup */ } /* Limited Dissolve */ -- cgit v1.2.3