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;
|
||||
std::vector<int> vf_head(vert_count, -1), slot_face(S), slot_vert(S), slot_next(S, -1),
|
||||
slot_prev(S, -1), face_slot(S, -1);
|
||||
std::vector<int> vf_head(vert_count, -1), vf_count(vert_count, 0), slot_face(S), slot_vert(S),
|
||||
slot_next(S, -1), slot_prev(S, -1), face_slot(S, -1);
|
||||
for (size_t f = 0; f < face_count; ++f)
|
||||
for (int k = 0; k < 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;
|
||||
vf_head[size_t(v)] = s;
|
||||
face_slot[size_t(s)] = s;
|
||||
++vf_count[size_t(v)];
|
||||
}
|
||||
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;
|
||||
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;
|
||||
--vf_count[size_t(v)];
|
||||
};
|
||||
const auto move_slot = [&](int s, int nv) {
|
||||
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;
|
||||
vf_head[size_t(nv)] = s;
|
||||
slot_vert[size_t(s)] = nv;
|
||||
++vf_count[size_t(nv)];
|
||||
};
|
||||
|
||||
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;
|
||||
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)
|
||||
continue;
|
||||
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;
|
||||
// Quadric penalty weight for a crease plane.
|
||||
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,
|
||||
// since the cost sums squared distances over all incident faces.
|
||||
|
||||
Reference in New Issue
Block a user