mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-10-01 12:51:12 +00:00
Fix texture bake stalling at 99% while simplifying
A vertex pinned on flat ground could collect a fan of thousands of slivers, and validating each collapse next to it walked the whole fan, turning a second of simplification into minutes. Collapses that would leave more than 64 faces around a vertex are now skipped.
This commit is contained in:
@@ -236,10 +236,10 @@ DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool h
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertex-face incidence as intrusive linked lists of slots over flat arrays.
|
// Vertex-face incidence as intrusive linked lists of slots over flat arrays, with each list's length.
|
||||||
const size_t S = face_count * 3;
|
const size_t S = face_count * 3;
|
||||||
std::vector<int> vf_head(vert_count, -1), slot_face(S), slot_vert(S), slot_next(S, -1),
|
std::vector<int> vf_head(vert_count, -1), vf_count(vert_count, 0), slot_face(S), slot_vert(S),
|
||||||
slot_prev(S, -1), face_slot(S, -1);
|
slot_next(S, -1), slot_prev(S, -1), face_slot(S, -1);
|
||||||
for (size_t f = 0; f < face_count; ++f)
|
for (size_t f = 0; f < face_count; ++f)
|
||||||
for (int k = 0; k < 3; ++k) {
|
for (int k = 0; k < 3; ++k) {
|
||||||
const int s = int(f) * 3 + k;
|
const int s = int(f) * 3 + k;
|
||||||
@@ -252,12 +252,14 @@ DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool h
|
|||||||
slot_prev[size_t(vf_head[size_t(v)])] = s;
|
slot_prev[size_t(vf_head[size_t(v)])] = s;
|
||||||
vf_head[size_t(v)] = s;
|
vf_head[size_t(v)] = s;
|
||||||
face_slot[size_t(s)] = s;
|
face_slot[size_t(s)] = s;
|
||||||
|
++vf_count[size_t(v)];
|
||||||
}
|
}
|
||||||
const auto unlink_slot = [&](int s) {
|
const auto unlink_slot = [&](int s) {
|
||||||
const int p = slot_prev[size_t(s)], nx = slot_next[size_t(s)];
|
const int p = slot_prev[size_t(s)], nx = slot_next[size_t(s)], v = slot_vert[size_t(s)];
|
||||||
if (p >= 0) slot_next[size_t(p)] = nx;
|
if (p >= 0) slot_next[size_t(p)] = nx;
|
||||||
else vf_head[size_t(slot_vert[size_t(s)])] = nx;
|
else vf_head[size_t(v)] = nx;
|
||||||
if (nx >= 0) slot_prev[size_t(nx)] = p;
|
if (nx >= 0) slot_prev[size_t(nx)] = p;
|
||||||
|
--vf_count[size_t(v)];
|
||||||
};
|
};
|
||||||
const auto move_slot = [&](int s, int nv) {
|
const auto move_slot = [&](int s, int nv) {
|
||||||
unlink_slot(s);
|
unlink_slot(s);
|
||||||
@@ -267,6 +269,7 @@ DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool h
|
|||||||
slot_prev[size_t(vf_head[size_t(nv)])] = s;
|
slot_prev[size_t(vf_head[size_t(nv)])] = s;
|
||||||
vf_head[size_t(nv)] = s;
|
vf_head[size_t(nv)] = s;
|
||||||
slot_vert[size_t(s)] = nv;
|
slot_vert[size_t(s)] = nv;
|
||||||
|
++vf_count[size_t(nv)];
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<uint8_t> active(vert_count, 1);
|
std::vector<uint8_t> active(vert_count, 1);
|
||||||
@@ -463,6 +466,10 @@ DecimateResult decimate(const TriSoup &geometry, size_t target_triangles, bool h
|
|||||||
++stale_pops;
|
++stale_pops;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
// Ahead of the checks below, which walk the fans (see DECIMATE_MAX_VALENCE). The two shared
|
||||||
|
// faces, counted in both fans, go.
|
||||||
|
if (vf_count[size_t(v1)] + vf_count[size_t(v2)] - 4 > DECIMATE_MAX_VALENCE)
|
||||||
|
continue;
|
||||||
if (shared_face_count(v1, v2) < 2)
|
if (shared_face_count(v1, v2) < 2)
|
||||||
continue;
|
continue;
|
||||||
lk_epoch += 2; // +2 so ep and ep+1 cannot collide with the next call
|
lk_epoch += 2; // +2 so ep and ep+1 cannot collide with the next call
|
||||||
|
|||||||
@@ -25,6 +25,11 @@ static constexpr double DECIMATE_FLIP_DOT = 0.2;
|
|||||||
static constexpr double DECIMATE_CREASE_COS = 0.5;
|
static constexpr double DECIMATE_CREASE_COS = 0.5;
|
||||||
// Quadric penalty weight for a crease plane.
|
// Quadric penalty weight for a crease plane.
|
||||||
static constexpr double DECIMATE_CREASE_WEIGHT = 1e4;
|
static constexpr double DECIMATE_CREASE_WEIGHT = 1e4;
|
||||||
|
// Most faces a collapse may leave around its surviving vertex. Uncapped, a pinned vertex on flat
|
||||||
|
// ground grows a fan of thousands of slivers, and validating each of its edges walks the whole fan,
|
||||||
|
// which turns a decimation of a second or two into minutes. At 64 the triangle count moves by about
|
||||||
|
// 1% at most, and by far less on large bakes.
|
||||||
|
static constexpr int DECIMATE_MAX_VALENCE = 64;
|
||||||
|
|
||||||
// Upper bound in mm on the deviation a harvested collapse may introduce; the real one is smaller,
|
// Upper bound in mm on the deviation a harvested collapse may introduce; the real one is smaller,
|
||||||
// since the cost sums squared distances over all incident faces.
|
// since the cost sums squared distances over all incident faces.
|
||||||
|
|||||||
Reference in New Issue
Block a user