From b48deabf4e3dd815d70ffd01942aeaa8dff64d53 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Mon, 13 May 2013 14:31:45 +0000 Subject: new bevel: fix for crash in merge, could result in collapsing faces being invalid. rather then splice each edge, use weld_verts operator which handles removing degenerate geometry. --- source/blender/bmesh/operators/bmo_bridge.c | 70 ++++++++++------------------- 1 file changed, 24 insertions(+), 46 deletions(-) (limited to 'source') diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index 30a0f0a3dba..37929b4720f 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -39,6 +39,29 @@ #define EDGE_MARK 4 #define FACE_OUT 16 +/* el_a and el_b _must_ be same size */ +static void bm_bridge_splice_loops(BMesh *bm, LinkData *el_a, LinkData *el_b, const float merge_factor) +{ + BMOperator op_weld; + BMOpSlot *slot_targetmap; + + BMO_op_init(bm, &op_weld, 0, "weld_verts"); + + slot_targetmap = BMO_slot_get(op_weld.slots_in, "targetmap"); + + do { + BMVert *v_a = el_a->data, *v_b = el_b->data; + BM_data_interp_from_verts(bm, v_a, v_b, v_b, merge_factor); + interp_v3_v3v3(v_b->co, v_a->co, v_b->co, merge_factor); + BLI_assert(v_a != v_b); + BMO_slot_map_elem_insert(&op_weld, slot_targetmap, v_a, v_b); + } while ((el_b = el_b->next), + (el_a = el_a->next)); + + BMO_op_exec(bm, &op_weld); + BMO_op_finish(bm, &op_weld); +} + /* get the 2 loops matching 2 verts. * first attempt to get the face corners that use the edge defined by v1 & v2, * if that fails just get any loop thats on the vert (the first one) */ @@ -198,52 +221,7 @@ static void bridge_loop_pair(BMesh *bm, if (use_merge) { - LinkData *el_a; - LinkData *el_b; - const int vert_len = BM_edgeloop_length_get(el_store_a); - const int edge_len = is_closed ? vert_len : vert_len - 1; - BMEdge **earr_a = MEM_mallocN(sizeof(*earr_a) * vert_len, __func__); - BMEdge **earr_b = MEM_mallocN(sizeof(*earr_b) * vert_len, __func__); - int i; - - el_a = el_a_first; - el_b = el_b_first; - - /* first get the edges in order (before splicing verts) */ - for (i = 0; i < vert_len; i++) { - LinkData *el_a_next = BM_EDGELOOP_NEXT(el_store_a, el_a); - LinkData *el_b_next = BM_EDGELOOP_NEXT(el_store_b, el_b); - - /* last edge will be NULL for non closed loops */ - earr_a[i] = BM_edge_exists(el_a->data, el_a_next->data); - earr_b[i] = BM_edge_exists(el_b->data, el_b_next->data); - - el_a = el_a_next; - el_b = el_b_next; - } - - el_a = el_a_first; - el_b = el_b_first; - for (i = 0; i < vert_len; i++) { - BMVert *v_a = el_a->data, *v_b = el_b->data; - BM_data_interp_from_verts(bm, v_a, v_b, v_b, merge_factor); - interp_v3_v3v3(v_b->co, v_a->co, v_b->co, merge_factor); - BM_elem_flag_merge(v_a, v_b); - BM_vert_splice(bm, v_a, v_b); - - el_a = el_a->next; - el_b = el_b->next; - } - for (i = 0; i < edge_len; i++) { - BMEdge *e1 = earr_a[i]; - BMEdge *e2 = earr_b[i]; - BM_data_interp_from_edges(bm, e1, e2, e2, merge_factor); - BM_elem_flag_merge(e1, e2); - BM_edge_splice(bm, e1, e2); - } - - MEM_freeN(earr_a); - MEM_freeN(earr_b); + bm_bridge_splice_loops(bm, el_a_first, el_b_first, merge_factor); } else { LinkData *el_a = el_a_first; -- cgit v1.2.3