Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2016-05-06 03:20:16 +0300
committerCampbell Barton <ideasman42@gmail.com>2016-05-06 03:22:02 +0300
commit304501193be6fe1bedd19e819841a3a5363a79ef (patch)
treeeea7b47031bb56ec8add51bcbfd8d6d9c59aeccb /source
parent86abddc96ad6d46ec1d64afd2435abbf5ab5e32e (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.c44
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);
+ }
}
}
}