Fix T48356: Bridge tool creates self-intersecting loop
When loops are planar to eachother, initialize their winding based on surrounding geometry.
This commit is contained in:
parent
86abddc96a
commit
304501193b
@ -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,18 +271,52 @@ 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) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (el_store_a_len > el_store_b_len) {
|
||||
el_store_b = BM_edgeloop_copy(el_store_b);
|
||||
|
Loading…
Reference in New Issue
Block a user