diff options
author | Campbell Barton <ideasman42@gmail.com> | 2013-05-31 19:48:42 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2013-05-31 19:48:42 +0400 |
commit | db42a596aafeb7b33bee63c6bc8da205582b5257 (patch) | |
tree | 017c76bb07f87fe4079e3dc2c81011bfce47dbc4 /source/blender/bmesh | |
parent | fe02323632bca510b9900d45ad4c45e8f16b0098 (diff) |
fix [#35578] New bridge tool; bowtie crossing when destination edges form one half of an 'X'
Diffstat (limited to 'source/blender/bmesh')
-rw-r--r-- | source/blender/bmesh/intern/bmesh_edgeloop.c | 47 | ||||
-rw-r--r-- | source/blender/bmesh/intern/bmesh_edgeloop.h | 4 | ||||
-rw-r--r-- | source/blender/bmesh/operators/bmo_bridge.c | 16 |
3 files changed, 66 insertions, 1 deletions
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c index 816b2a1547e..294cf23c613 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.c +++ b/source/blender/bmesh/intern/bmesh_edgeloop.c @@ -383,6 +383,14 @@ void BM_mesh_edgeloops_calc_normal(BMesh *bm, ListBase *eloops) } } +void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm, ListBase *eloops, const float no_align[3]) +{ + BMEdgeLoopStore *el_store; + for (el_store = eloops->first; el_store; el_store = el_store->next) { + BM_edgeloop_calc_normal_aligned(bm, el_store, no_align); + } +} + void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals) { ListBase eloops_ordered = {NULL}; @@ -574,6 +582,8 @@ void BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store) float const *v_prev = NODE_AS_CO(el_store->verts.last); float const *v_curr = NODE_AS_CO(node_curr); + zero_v3(el_store->no); + /* Newell's Method */ do { add_newell_cross_v3_v3v3(el_store->no, v_prev, v_curr); @@ -592,6 +602,43 @@ void BM_edgeloop_calc_normal(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store) } } +/** + * For open loops that are stright lines, + * calculating the normal as if it were a polygon is meaningless. + * + * Instead use an alignment vector and calculate the normal based on that. + */ +void BM_edgeloop_calc_normal_aligned(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store, const float no_align[3]) +{ + LinkData *node_curr = el_store->verts.first; + float const *v_prev = NODE_AS_CO(el_store->verts.last); + float const *v_curr = NODE_AS_CO(node_curr); + + zero_v3(el_store->no); + + /* Own Method */ + do { + float cross[3], no[3], dir[3]; + sub_v3_v3v3(dir, v_curr, v_prev); + cross_v3_v3v3(cross, no_align, dir); + cross_v3_v3v3(no, dir, cross); + add_v3_v3(el_store->no, no); + + if ((node_curr = node_curr->next)) { + v_prev = v_curr; + v_curr = NODE_AS_CO(node_curr); + } + else { + break; + } + } while (true); + + if (UNLIKELY(normalize_v3(el_store->no) == 0.0f)) { + el_store->no[2] = 1.0f; /* other axis set to 0.0 */ + } +} + + void BM_edgeloop_flip(BMesh *UNUSED(bm), BMEdgeLoopStore *el_store) { diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.h b/source/blender/bmesh/intern/bmesh_edgeloop.h index fcb8b4869f2..70c30ec73bd 100644 --- a/source/blender/bmesh/intern/bmesh_edgeloop.h +++ b/source/blender/bmesh/intern/bmesh_edgeloop.h @@ -41,6 +41,8 @@ bool BM_mesh_edgeloops_find_path(BMesh *bm, ListBase *r_eloops, void BM_mesh_edgeloops_free(struct ListBase *eloops); void BM_mesh_edgeloops_calc_center(BMesh *bm, struct ListBase *eloops); void BM_mesh_edgeloops_calc_normal(BMesh *bm, struct ListBase *eloops); +void BM_mesh_edgeloops_calc_normal_aligned(BMesh *bm, struct ListBase *eloops, + const float no_align[3]); void BM_mesh_edgeloops_calc_order(BMesh *UNUSED(bm), ListBase *eloops, const bool use_normals); @@ -57,6 +59,8 @@ const float *BM_edgeloop_center_get(struct BMEdgeLoopStore *el_store); void BM_edgeloop_edges_get(struct BMEdgeLoopStore *el_store, BMEdge **e_arr); void BM_edgeloop_calc_center(BMesh *bm, struct BMEdgeLoopStore *el_store); void BM_edgeloop_calc_normal(BMesh *bm, struct BMEdgeLoopStore *el_store); +void BM_edgeloop_calc_normal_aligned(BMesh *bm, struct BMEdgeLoopStore *el_store, + const float no_align[3]); void BM_edgeloop_flip(BMesh *bm, struct BMEdgeLoopStore *el_store); void BM_edgeloop_expand(BMesh *bm, struct BMEdgeLoopStore *el_store, int el_store_len); diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index 53bb88aee0a..9da6e812032 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -168,6 +168,21 @@ static void bridge_loop_pair(BMesh *bm, } sub_v3_v3v3(el_dir, BM_edgeloop_center_get(el_store_a), BM_edgeloop_center_get(el_store_b)); + + if (is_closed) { + /* if all loops are closed this will calculate twice for all loops */ + BM_edgeloop_calc_normal(bm, el_store_a); + BM_edgeloop_calc_normal(bm, el_store_b); + } + else { + /* normalizing isn't strictly needed but without we may get very large values */ + float no[3]; + normalize_v3_v3(no, el_dir); + BM_edgeloop_calc_normal_aligned(bm, el_store_a, no); + negate_v3(no); + BM_edgeloop_calc_normal_aligned(bm, el_store_b, no); + } + if ((dot_v3v3(BM_edgeloop_normal_get(el_store_a), el_dir) < 0.0f) != (dot_v3v3(BM_edgeloop_normal_get(el_store_b), el_dir) < 0.0f)) { @@ -426,7 +441,6 @@ void bmo_bridge_loops_exec(BMesh *bm, BMOperator *op) count = BM_mesh_edgeloops_find(bm, &eloops, bm_edge_test_cb, bm); - BM_mesh_edgeloops_calc_normal(bm, &eloops); BM_mesh_edgeloops_calc_center(bm, &eloops); if (count < 2) { |