fix [#35578] New bridge tool; bowtie crossing when destination edges form one half of an 'X'
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user