From c0c575751d27198fc5bda18f0d51fafca4c3a967 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 23 Aug 2012 04:55:59 +0000 Subject: bmesh tool: support for merged-bridge (like bridge, collapsing), with a factor to blend between loops. --- source/blender/bmesh/operators/bmo_connect.c | 142 ++++++++++++++++++--------- 1 file changed, 93 insertions(+), 49 deletions(-) (limited to 'source/blender/bmesh/operators/bmo_connect.c') diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index a9599a48589..055e61596ee 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -223,6 +223,10 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) BMEdge *e, *nexte; int c = 0, cl1 = 0, cl2 = 0; + /* merge-bridge support */ + const int use_merge = BMO_slot_bool_get(op, "use_merge"); + const float merge_factor = BMO_slot_float_get(op, "merge_factor"); + BMO_slot_buffer_flag_enable(bm, op, "edges", BM_EDGE, EDGE_MARK); BMO_ITER (e, &siter, bm, op, "edges", BM_EDGE) { @@ -423,59 +427,99 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) } } - /* Generate the bridge quads */ - for (i = 0; i < BLI_array_count(ee1) && i < BLI_array_count(ee2); i++) { - BMFace *f; - - BMLoop *l_1 = NULL; - BMLoop *l_2 = NULL; - BMLoop *l_1_next = NULL; - BMLoop *l_2_next = NULL; - BMLoop *l_iter; - BMFace *f_example; - - int i1, i1next, i2, i2next; - - i1 = clamp_index(i * dir1 + starti, lenv1); - i1next = clamp_index((i + 1) * dir1 + starti, lenv1); - i2 = i; - i2next = clamp_index(i + 1, lenv2); - - if (vv1[i1] == vv1[i1next]) { - continue; - } - - if (wdir < 0) { - SWAP(int, i1, i1next); - SWAP(int, i2, i2next); + /* merge loops of bridge faces */ + if (use_merge) { + /* at the moment these will be the same */ + const int vert_len = mini(BLI_array_count(vv1), BLI_array_count(vv2)); + const int edge_len = mini(BLI_array_count(ee1), BLI_array_count(ee2)); + + if (merge_factor <= 0.0f) { + /* 2 --> 1 */ + for (i = 0; i < vert_len; i++) { + BM_vert_splice(bm, vv2[i], vv1[i]); + } + for (i = 0; i < edge_len; i++) { + BM_edge_splice(bm, ee2[i], ee1[i]); + } } - - /* get loop data - before making the face */ - bm_vert_loop_pair(bm, vv1[i1], vv2[i2], &l_1, &l_2); - bm_vert_loop_pair(bm, vv1[i1next], vv2[i2next], &l_1_next, &l_2_next); - /* copy if loop data if its is missing on one ring */ - if (l_1 && l_1_next == NULL) l_1_next = l_1; - if (l_1_next && l_1 == NULL) l_1 = l_1_next; - if (l_2 && l_2_next == NULL) l_2_next = l_2; - if (l_2_next && l_2 == NULL) l_2 = l_2_next; - f_example = l_1 ? l_1->f : (l_2 ? l_2->f : NULL); - - f = BM_face_create_quad_tri(bm, - vv1[i1], - vv2[i2], - vv2[i2next], - vv1[i1next], - f_example, TRUE); - if (!f || f->len != 4) { - fprintf(stderr, "%s: in bridge! (bmesh internal error)\n", __func__); + else if (merge_factor >= 1.0f) { + /* 1 --> 2 */ + for (i = 0; i < vert_len; i++) { + BM_vert_splice(bm, vv1[i], vv2[i]); + } + for (i = 0; i < edge_len; i++) { + BM_edge_splice(bm, ee1[i], ee2[i]); + } } else { - l_iter = BM_FACE_FIRST_LOOP(f); + /* mid factor, be tricky */ + /* 1 --> 2 */ + for (i = 0; i < vert_len; i++) { + BM_data_interp_from_verts(bm, vv1[i], vv2[i], vv2[i], merge_factor); + interp_v3_v3v3(vv2[i]->co, vv1[i]->co, vv2[i]->co, merge_factor); + BM_vert_splice(bm, vv1[i], vv2[i]); + } + for (i = 0; i < edge_len; i++) { + //BM_data_interp_from_edge(bm, vv1[i], vv2[i], vv2[i], merge_factor); + BM_edge_splice(bm, ee1[i], ee2[i]); + } + } + } + else { + /* Generate the bridge quads */ + for (i = 0; i < BLI_array_count(ee1) && i < BLI_array_count(ee2); i++) { + BMFace *f; + + BMLoop *l_1 = NULL; + BMLoop *l_2 = NULL; + BMLoop *l_1_next = NULL; + BMLoop *l_2_next = NULL; + BMLoop *l_iter; + BMFace *f_example; + + int i1, i1next, i2, i2next; + + i1 = clamp_index(i * dir1 + starti, lenv1); + i1next = clamp_index((i + 1) * dir1 + starti, lenv1); + i2 = i; + i2next = clamp_index(i + 1, lenv2); + + if (vv1[i1] == vv1[i1next]) { + continue; + } - if (l_1) BM_elem_attrs_copy(bm, bm, l_1, l_iter); l_iter = l_iter->next; - if (l_2) BM_elem_attrs_copy(bm, bm, l_2, l_iter); l_iter = l_iter->next; - if (l_2_next) BM_elem_attrs_copy(bm, bm, l_2_next, l_iter); l_iter = l_iter->next; - if (l_1_next) BM_elem_attrs_copy(bm, bm, l_1_next, l_iter); + if (wdir < 0) { + SWAP(int, i1, i1next); + SWAP(int, i2, i2next); + } + + /* get loop data - before making the face */ + bm_vert_loop_pair(bm, vv1[i1], vv2[i2], &l_1, &l_2); + bm_vert_loop_pair(bm, vv1[i1next], vv2[i2next], &l_1_next, &l_2_next); + /* copy if loop data if its is missing on one ring */ + if (l_1 && l_1_next == NULL) l_1_next = l_1; + if (l_1_next && l_1 == NULL) l_1 = l_1_next; + if (l_2 && l_2_next == NULL) l_2_next = l_2; + if (l_2_next && l_2 == NULL) l_2 = l_2_next; + f_example = l_1 ? l_1->f : (l_2 ? l_2->f : NULL); + + f = BM_face_create_quad_tri(bm, + vv1[i1], + vv2[i2], + vv2[i2next], + vv1[i1next], + f_example, TRUE); + if (!f || f->len != 4) { + fprintf(stderr, "%s: in bridge! (bmesh internal error)\n", __func__); + } + else { + l_iter = BM_FACE_FIRST_LOOP(f); + + if (l_1) BM_elem_attrs_copy(bm, bm, l_1, l_iter); l_iter = l_iter->next; + if (l_2) BM_elem_attrs_copy(bm, bm, l_2, l_iter); l_iter = l_iter->next; + if (l_2_next) BM_elem_attrs_copy(bm, bm, l_2_next, l_iter); l_iter = l_iter->next; + if (l_1_next) BM_elem_attrs_copy(bm, bm, l_1_next, l_iter); + } } } } -- cgit v1.2.3