diff options
author | Campbell Barton <ideasman42@gmail.com> | 2016-05-06 03:20:16 +0300 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2016-05-06 03:22:02 +0300 |
commit | 304501193be6fe1bedd19e819841a3a5363a79ef (patch) | |
tree | eea7b47031bb56ec8add51bcbfd8d6d9c59aeccb /source | |
parent | 86abddc96ad6d46ec1d64afd2435abbf5ab5e32e (diff) |
Fix T48356: Bridge tool creates self-intersecting loop
When loops are planar to eachother, initialize their winding based on surrounding geometry.
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/bmesh/operators/bmo_bridge.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/source/blender/bmesh/operators/bmo_bridge.c b/source/blender/bmesh/operators/bmo_bridge.c index c7bf481d7d5..a0149a41921 100644 --- a/source/blender/bmesh/operators/bmo_bridge.c +++ b/source/blender/bmesh/operators/bmo_bridge.c @@ -262,7 +262,7 @@ static void bridge_loop_pair( if (bm->totface) { struct BMEdgeLoopStore *estore_pair[2] = {el_store_a, el_store_b}; int i; - int winding_votes = 0; + int winding_votes[2] = {0, 0}; int winding_dir = 1; for (i = 0; i < 2; i++, winding_dir = -winding_dir) { LinkData *el; @@ -271,15 +271,49 @@ static void bridge_loop_pair( if (el_next) { BMEdge *e = BM_edge_exists(el->data, el_next->data); if (e && BM_edge_is_boundary(e)) { - winding_votes += ((e->l->v == el->data) ? winding_dir : -winding_dir); + winding_votes[i] += ((e->l->v == el->data) ? winding_dir : -winding_dir); } } } } - if (winding_votes < 0) { - BM_edgeloop_flip(bm, el_store_a); - BM_edgeloop_flip(bm, el_store_b); + if (winding_votes[0] || winding_votes[1]) { + bool flip[2] = {false, false}; + + /* for direction aligned loops we can't rely on the directly we have, + * use the winding defined by the connected faces (see T48356). */ + if (fabsf(dot_a) < eps) { + if (winding_votes[0] < 0) { + flip[0] = !flip[0]; + winding_votes[0] *= -1; + + } + } + if (fabsf(dot_b) < eps) { + if (winding_votes[1] < 0) { + flip[1] = !flip[1]; + winding_votes[1] *= -1; + } + } + + /* when both loops contradict the winding, flip them so surrounding geometry matches */ + if ((winding_votes[0] + winding_votes[1]) < 0) { + flip[0] = !flip[0]; + flip[1] = !flip[1]; + + /* valid but unused */ +#if 0 + winding_votes[0] *= -1; + winding_votes[1] *= -1; +#endif + } + + if (flip[0]) { + BM_edgeloop_flip(bm, el_store_a); + } + if (flip[1]) { + BM_edgeloop_flip(bm, el_store_b); + } } } } |