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
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/geometry/intern/mesh_merge_by_distance.cc')
-rw-r--r--source/blender/geometry/intern/mesh_merge_by_distance.cc162
1 files changed, 67 insertions, 95 deletions
diff --git a/source/blender/geometry/intern/mesh_merge_by_distance.cc b/source/blender/geometry/intern/mesh_merge_by_distance.cc
index e45b84632ab..d3a5a194555 100644
--- a/source/blender/geometry/intern/mesh_merge_by_distance.cc
+++ b/source/blender/geometry/intern/mesh_merge_by_distance.cc
@@ -82,7 +82,7 @@ struct WeldPoly {
int loop_start;
int loop_end;
/* Final Polygon Size. */
- int len;
+ int loop_len;
/* Group of loops that will be affected. */
struct WeldGroup loops;
};
@@ -104,9 +104,6 @@ struct WeldMesh {
/* References all polygons and loops that will be affected. */
Vector<WeldLoop> wloop;
Vector<WeldPoly> wpoly;
- MutableSpan<WeldPoly> wpoly_new;
- int wloop_len;
- int wpoly_len;
int wpoly_new_len;
/* From the actual index of the element in the mesh, it indicates what is the index of the Weld
@@ -147,14 +144,14 @@ struct WeldLoopOfPolyIter {
* \{ */
#ifdef USE_WELD_DEBUG
-static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter *iter,
+static bool weld_iter_loop_of_poly_begin(WeldLoopOfPolyIter &iter,
const WeldPoly &wp,
Span<WeldLoop> wloop,
Span<MLoop> mloop,
Span<int> loop_map,
int *group_buffer);
-static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter *iter);
+static bool weld_iter_loop_of_poly_next(WeldLoopOfPolyIter &iter);
static void weld_assert_edge_kill_len(Span<WeldEdge> wedge, const int supposed_kill_len)
{
@@ -170,12 +167,8 @@ static void weld_assert_edge_kill_len(Span<WeldEdge> wedge, const int supposed_k
BLI_assert(kills == supposed_kill_len);
}
-static void weld_assert_poly_and_loop_kill_len(Span<WeldPoly> wpoly,
- Span<WeldPoly> wpoly_new,
- Span<WeldLoop> wloop,
+static void weld_assert_poly_and_loop_kill_len(WeldMesh *weld_mesh,
Span<MLoop> mloop,
- Span<int> loop_map,
- Span<int> poly_map,
Span<MPoly> mpoly,
const int supposed_poly_kill_len,
const int supposed_loop_kill_len)
@@ -184,11 +177,12 @@ static void weld_assert_poly_and_loop_kill_len(Span<WeldPoly> wpoly,
int loop_kills = mloop.size();
const MPoly *mp = &mpoly[0];
for (int i = 0; i < mpoly.size(); i++, mp++) {
- int poly_ctx = poly_map[i];
+ int poly_ctx = weld_mesh->poly_map[i];
if (poly_ctx != OUT_OF_CONTEXT) {
- const WeldPoly *wp = &wpoly[poly_ctx];
+ const WeldPoly *wp = &weld_mesh->wpoly[poly_ctx];
WeldLoopOfPolyIter iter;
- if (!weld_iter_loop_of_poly_begin(&iter, *wp, wloop, mloop, loop_map, nullptr)) {
+ if (!weld_iter_loop_of_poly_begin(
+ iter, *wp, weld_mesh->wloop, mloop, weld_mesh->loop_map, nullptr)) {
poly_kills++;
continue;
}
@@ -197,13 +191,13 @@ static void weld_assert_poly_and_loop_kill_len(Span<WeldPoly> wpoly,
poly_kills++;
continue;
}
- int remain = wp->len;
+ int remain = wp->loop_len;
int l = wp->loop_start;
while (remain) {
int l_next = l + 1;
- int loop_ctx = loop_map[l];
+ int loop_ctx = weld_mesh->loop_map[l];
if (loop_ctx != OUT_OF_CONTEXT) {
- const WeldLoop *wl = &wloop[loop_ctx];
+ const WeldLoop *wl = &weld_mesh->wloop[loop_ctx];
if (wl->loop_skip_to != OUT_OF_CONTEXT) {
l_next = wl->loop_skip_to;
}
@@ -225,19 +219,19 @@ static void weld_assert_poly_and_loop_kill_len(Span<WeldPoly> wpoly,
}
}
- const WeldPoly *wp = wpoly_new.data();
- for (int i = wpoly_new.size(); i--; wp++) {
- if (wp->poly_dst != OUT_OF_CONTEXT) {
+ for (const int i : weld_mesh->wpoly.index_range().take_back(weld_mesh->wpoly_new_len)) {
+ const WeldPoly &wp = weld_mesh->wpoly[i];
+ if (wp.poly_dst != OUT_OF_CONTEXT) {
poly_kills++;
continue;
}
- int remain = wp->len;
- int l = wp->loop_start;
+ int remain = wp.loop_len;
+ int l = wp.loop_start;
while (remain) {
int l_next = l + 1;
- int loop_ctx = loop_map[l];
+ int loop_ctx = weld_mesh->loop_map[l];
if (loop_ctx != OUT_OF_CONTEXT) {
- const WeldLoop *wl = &wloop[loop_ctx];
+ const WeldLoop *wl = &weld_mesh->wloop[loop_ctx];
if (wl->loop_skip_to != OUT_OF_CONTEXT) {
l_next = wl->loop_skip_to;
}
@@ -263,10 +257,10 @@ static void weld_assert_poly_no_vert_repetition(const WeldPoly &wp,
Span<MLoop> mloop,
Span<int> loop_map)
{
- const int len = wp.len;
- Array<int, 64> verts(len);
+ const int loop_len = wp.loop_len;
+ Array<int, 64> verts(loop_len);
WeldLoopOfPolyIter iter;
- if (!weld_iter_loop_of_poly_begin(&iter, wp, wloop, mloop, loop_map, nullptr)) {
+ if (!weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) {
return;
}
else {
@@ -275,9 +269,9 @@ static void weld_assert_poly_no_vert_repetition(const WeldPoly &wp,
verts[i++] = iter.v;
}
}
- for (int i = 0; i < len; i++) {
+ for (int i = 0; i < loop_len; i++) {
int va = verts[i];
- for (int j = i + 1; j < len; j++) {
+ for (int j = i + 1; j < loop_len; j++) {
int vb = verts[j];
BLI_assert(va != vb);
}
@@ -290,7 +284,7 @@ static void weld_assert_poly_len(const WeldPoly *wp, const Span<WeldLoop> wloop)
return;
}
- int len = wp->len;
+ int loop_len = wp->loop_len;
const WeldLoop *wl = &wloop[wp->loops.ofs];
BLI_assert(wp->loop_start <= wl->loop_orig);
@@ -304,10 +298,10 @@ static void weld_assert_poly_len(const WeldPoly *wp, const Span<WeldLoop> wloop)
min_len++;
}
}
- BLI_assert(len >= min_len);
+ BLI_assert(loop_len >= min_len);
int max_len = wp->loop_end - wp->loop_start + 1;
- BLI_assert(len <= max_len);
+ BLI_assert(loop_len <= max_len);
}
#endif /* USE_WELD_DEBUG */
@@ -786,7 +780,7 @@ static void weld_poly_loop_ctx_alloc(Span<MPoly> mpoly,
wp.loops.ofs = prev_wloop_len;
wp.loop_start = loopstart;
wp.loop_end = loopstart + totloop - 1;
- wp.len = totloop;
+ wp.loop_len = totloop;
wpoly.append(wp);
poly_map[i] = wpoly_len++;
@@ -802,15 +796,10 @@ static void weld_poly_loop_ctx_alloc(Span<MPoly> mpoly,
}
}
- if (mpoly.size() < (wpoly_len + maybe_new_poly)) {
- wpoly.resize(wpoly_len + maybe_new_poly);
- }
+ wpoly.reserve(wpoly.size() + maybe_new_poly);
r_weld_mesh->wloop = std::move(wloop);
r_weld_mesh->wpoly = std::move(wpoly);
- r_weld_mesh->wpoly_new = r_weld_mesh->wpoly.as_mutable_span().drop_front(wpoly_len);
- r_weld_mesh->wloop_len = wloop_len;
- r_weld_mesh->wpoly_len = wpoly_len;
r_weld_mesh->wpoly_new_len = 0;
r_weld_mesh->loop_map = std::move(loop_map);
r_weld_mesh->poly_map = std::move(poly_map);
@@ -827,8 +816,8 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
int *r_poly_kill,
int *r_loop_kill)
{
- int poly_len = r_wp->len;
- if (poly_len < 3 || ctx_verts_len < 1) {
+ int poly_loop_len = r_wp->loop_len;
+ if (poly_loop_len < 3 || ctx_verts_len < 1) {
return;
}
@@ -870,7 +859,7 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
}
if (vert_a == vert_b) {
const int dist_a = wlb->loop_orig - wla->loop_orig - killed_ab;
- const int dist_b = poly_len - dist_a;
+ const int dist_b = poly_loop_len - dist_a;
BLI_assert(dist_a != 0 && dist_b != 0);
if (dist_a == 1 || dist_b == 1) {
@@ -886,7 +875,7 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
wla->flag = ELEM_COLLAPSED;
wl_tmp->flag = ELEM_COLLAPSED;
loop_kill += 2;
- poly_len -= 2;
+ poly_loop_len -= 2;
}
if (dist_b == 2) {
if (wl_tmp != nullptr) {
@@ -901,20 +890,22 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
wl_tmp->flag = ELEM_COLLAPSED;
}
loop_kill += 2;
- poly_len -= 2;
+ poly_loop_len -= 2;
}
if (wl_tmp == nullptr) {
const int new_loops_len = lb - la;
const int new_loops_ofs = ctx_loops_ofs + la;
- WeldPoly *new_wp = &r_weld_mesh->wpoly_new[r_weld_mesh->wpoly_new_len++];
+ r_weld_mesh->wpoly.increase_size_by_unchecked(1);
+ WeldPoly *new_wp = &r_weld_mesh->wpoly.last();
new_wp->poly_dst = OUT_OF_CONTEXT;
new_wp->poly_orig = r_wp->poly_orig;
new_wp->loops.len = new_loops_len;
new_wp->loops.ofs = new_loops_ofs;
new_wp->loop_start = wla->loop_orig;
new_wp->loop_end = wlb_prev->loop_orig;
- new_wp->len = dist_a;
+ new_wp->loop_len = dist_a;
+ r_weld_mesh->wpoly_new_len++;
weld_poly_split_recursive(vert_dest_map,
#ifdef USE_WELD_DEBUG
mloop,
@@ -924,8 +915,8 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
r_weld_mesh,
r_poly_kill,
r_loop_kill);
- BLI_assert(dist_b == poly_len - dist_a);
- poly_len = dist_b;
+ BLI_assert(dist_b == poly_loop_len - dist_a);
+ poly_loop_len = dist_b;
if (wla_prev->loop_orig > wla->loop_orig) {
/* New start. */
r_wp->loop_start = wlb->loop_orig;
@@ -950,7 +941,7 @@ static void weld_poly_split_recursive(Span<int> vert_dest_map,
wla_prev = wla;
}
}
- r_wp->len = poly_len;
+ r_wp->loop_len = poly_loop_len;
*r_loop_kill += loop_kill;
#ifdef USE_WELD_DEBUG
@@ -968,10 +959,8 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
MutableSpan<WeldGroup> r_vlinks,
WeldMesh *r_weld_mesh)
{
- MutableSpan<WeldPoly> wpoly = r_weld_mesh->wpoly;
+ WeldPoly *wpoly = r_weld_mesh->wpoly.data();
MutableSpan<WeldLoop> wloop = r_weld_mesh->wloop;
- int wpoly_len = r_weld_mesh->wpoly_len;
- int wpoly_new_len = 0;
int poly_kill_len = 0;
int loop_kill_len = 0;
@@ -979,28 +968,31 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
if (remain_edge_ctx_len) {
- /* Setup Poly/Loop. Note that `wpoly_len` may be different than `wpoly.size()` here. */
- for (const int i : IndexRange(wpoly_len)) {
+ /* Setup Poly/Loop. */
+ /* `wpoly.size()` may change during the loop,
+ * so make it clear that we are only working with the original wpolys. */
+ IndexRange wpoly_original_range = r_weld_mesh->wpoly.index_range();
+ for (const int i : wpoly_original_range) {
WeldPoly &wp = wpoly[i];
const int ctx_loops_len = wp.loops.len;
const int ctx_loops_ofs = wp.loops.ofs;
- int poly_len = wp.len;
+ int poly_loop_len = wp.loop_len;
int ctx_verts_len = 0;
WeldLoop *wl = &wloop[ctx_loops_ofs];
for (int l = ctx_loops_len; l--; wl++) {
const int edge_dest = wl->edge;
if (edge_dest == ELEM_COLLAPSED) {
wl->flag = ELEM_COLLAPSED;
- if (poly_len == 3) {
+ if (poly_loop_len == 3) {
wp.flag = ELEM_COLLAPSED;
poly_kill_len++;
loop_kill_len += 3;
- poly_len = 0;
+ poly_loop_len = 0;
break;
}
loop_kill_len++;
- poly_len--;
+ poly_loop_len--;
}
else {
const int vert_dst = wl->vert;
@@ -1010,10 +1002,10 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
}
}
- if (poly_len) {
- wp.len = poly_len;
+ if (poly_loop_len) {
+ wp.loop_len = poly_loop_len;
#ifdef USE_WELD_DEBUG
- weld_assert_poly_len(wp, wloop);
+ weld_assert_poly_len(&wp, wloop);
#endif
weld_poly_split_recursive(vert_dest_map,
@@ -1025,32 +1017,19 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
r_weld_mesh,
&poly_kill_len,
&loop_kill_len);
-
- wpoly_new_len = r_weld_mesh->wpoly_new_len;
}
}
#ifdef USE_WELD_DEBUG
- weld_assert_poly_and_loop_kill_len(wpoly,
- r_weld_mesh->wpoly_new,
- wloop,
- mloop,
- loop_map,
- r_weld_mesh->poly_map,
- mpoly,
- poly_kill_len,
- loop_kill_len);
+ weld_assert_poly_and_loop_kill_len(r_weld_mesh, mloop, mpoly, poly_kill_len, loop_kill_len);
#endif
/* Setup Polygon Overlap. */
- const int wpoly_and_new_len = wpoly_len + wpoly_new_len;
-
r_vlinks.fill({0, 0});
MutableSpan<WeldGroup> v_links = r_vlinks;
- for (const int i : IndexRange(wpoly_and_new_len)) {
- const WeldPoly &wp = wpoly[i];
+ for (const WeldPoly &wp : r_weld_mesh->wpoly) {
WeldLoopOfPolyIter iter;
if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) {
while (weld_iter_loop_of_poly_next(iter)) {
@@ -1068,7 +1047,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
if (link_len) {
Array<int> link_poly_buffer(link_len);
- for (const int i : IndexRange(wpoly_and_new_len)) {
+ for (const int i : IndexRange(r_weld_mesh->wpoly.size())) {
const WeldPoly &wp = wpoly[i];
WeldLoopOfPolyIter iter;
if (weld_iter_loop_of_poly_begin(iter, wp, wloop, mloop, loop_map, nullptr)) {
@@ -1086,7 +1065,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
int polys_len_a, polys_len_b, *polys_ctx_a, *polys_ctx_b, p_ctx_a, p_ctx_b;
polys_len_b = p_ctx_b = 0; /* silence warnings */
- for (const int i : IndexRange(wpoly_and_new_len)) {
+ for (const int i : IndexRange(r_weld_mesh->wpoly.size())) {
const WeldPoly &wp = wpoly[i];
if (wp.poly_dst != OUT_OF_CONTEXT) {
/* No need to retest poly.
@@ -1103,7 +1082,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
BLI_assert(link_poly_buffer[link_a->ofs] == i);
continue;
}
- int wp_len = wp.len;
+ int wp_loop_len = wp.loop_len;
polys_ctx_a = &link_poly_buffer[link_a->ofs];
for (; polys_len_a--; polys_ctx_a++) {
p_ctx_a = *polys_ctx_a;
@@ -1112,7 +1091,7 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
}
WeldPoly *wp_tmp = &wpoly[p_ctx_a];
- if (wp_tmp->len != wp_len) {
+ if (wp_tmp->loop_len != wp_loop_len) {
continue;
}
@@ -1151,31 +1130,23 @@ static void weld_poly_loop_ctx_setup(Span<MLoop> mloop,
BLI_assert(wp_tmp->poly_dst == OUT_OF_CONTEXT);
BLI_assert(wp_tmp != &wp);
wp_tmp->poly_dst = wp.poly_orig;
- loop_kill_len += wp_tmp->len;
+ loop_kill_len += wp_tmp->loop_len;
poly_kill_len++;
}
}
}
}
else {
- poly_kill_len = r_weld_mesh->wpoly_len;
- loop_kill_len = r_weld_mesh->wloop_len;
+ poly_kill_len = r_weld_mesh->wpoly.size();
+ loop_kill_len = r_weld_mesh->wloop.size();
- for (WeldPoly &wp : wpoly) {
+ for (WeldPoly &wp : r_weld_mesh->wpoly) {
wp.flag = ELEM_COLLAPSED;
}
}
#ifdef USE_WELD_DEBUG
- weld_assert_poly_and_loop_kill_len(wpoly,
- r_weld_mesh->wpoly_new,
- wloop,
- mloop,
- loop_map,
- r_weld_mesh->poly_map,
- mpoly,
- poly_kill_len,
- loop_kill_len);
+ weld_assert_poly_and_loop_kill_len(r_weld_mesh, mloop, mpoly, poly_kill_len, loop_kill_len);
#endif
r_weld_mesh->poly_kill_len = poly_kill_len;
@@ -1545,8 +1516,9 @@ static Mesh *create_merged_mesh(const Mesh &mesh,
r_i++;
}
- for (const int i : IndexRange(weld_mesh.wpoly_new_len)) {
- const WeldPoly &wp = weld_mesh.wpoly_new[i];
+ /* New Polygons. */
+ for (const int i : weld_mesh.wpoly.index_range().take_back(weld_mesh.wpoly_new_len)) {
+ const WeldPoly &wp = weld_mesh.wpoly[i];
const int loop_start = loop_cur;
WeldLoopOfPolyIter iter;
if (!weld_iter_loop_of_poly_begin(