Skip to content

Commit

Permalink
improved decimation
Browse files Browse the repository at this point in the history
  • Loading branch information
elalish committed Feb 17, 2025
1 parent a857f00 commit 228a14f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 39 deletions.
63 changes: 29 additions & 34 deletions src/edge_op.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,36 +317,35 @@ void Manifold::Impl::SimplifyTopology() {
numFlagged = 0;
ShortEdge se{halfedge_, vertPos_, epsilon_};
s.run(nbEdges, se, [&](size_t i) {
CollapseEdge(i, scratchBuffer);
const bool didCollapse = CollapseEdge(i, scratchBuffer);
if (didCollapse) numFlagged++;
scratchBuffer.resize(0);
numFlagged++;
});
}

#ifdef MANIFOLD_DEBUG
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "found " << numFlagged << " short edges to collapse"
<< std::endl;
}
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "collapsed " << numFlagged << " short edges" << std::endl;
}
#endif
}

{
while (1) {
ZoneScopedN("CollapseFlaggedEdge");
numFlagged = 0;
FlagEdge se{halfedge_, meshRelation_.triRef};
s.run(nbEdges, se, [&](size_t i) {
CollapseEdge(i, scratchBuffer);
const bool didCollapse = CollapseEdge(i, scratchBuffer);
if (didCollapse) numFlagged++;
scratchBuffer.resize(0);
numFlagged++;
});
}
if (numFlagged == 0) break;

#ifdef MANIFOLD_DEBUG
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "found " << numFlagged << " colinear edges to collapse"
<< std::endl;
}
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "collapsed " << numFlagged << " colinear edges" << std::endl;
}
#endif
}

{
ZoneScopedN("RecursiveEdgeSwap");
Expand All @@ -365,13 +364,13 @@ void Manifold::Impl::SimplifyTopology() {
RecursiveEdgeSwap(last, tag, visited, edgeSwapStack, scratchBuffer);
}
});
}

#ifdef MANIFOLD_DEBUG
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "found " << numFlagged << " edges to swap" << std::endl;
}
if (ManifoldParams().verbose && numFlagged > 0) {
std::cout << "swapped " << numFlagged << " edges" << std::endl;
}
#endif
}
}

// Deduplicate the given 4-manifold edge by duplicating endVert, thus making the
Expand Down Expand Up @@ -549,16 +548,17 @@ void Manifold::Impl::RemoveIfFolded(int edge) {
}
}

// Collapses the given edge by removing startVert. May split the mesh
// topologically if the collapse would have resulted in a 4-manifold edge. Do
// not collapse an edge if startVert is pinched - the vert will be marked NaN,
// but other edges may still be pointing to it.
void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
// Collapses the given edge by removing startVert - returns false if the edge
// cannot be collapsed. May split the mesh topologically if the collapse would
// have resulted in a 4-manifold edge. Do not collapse an edge if startVert is
// pinched - the vert would be marked NaN, but other edges could still be
// pointing to it.
bool Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
Vec<TriRef>& triRef = meshRelation_.triRef;
Vec<ivec3>& triProp = meshRelation_.triProperties;

const Halfedge toRemove = halfedge_[edge];
if (toRemove.pairedHalfedge < 0) return;
if (toRemove.pairedHalfedge < 0) return false;

const int endVert = toRemove.endVert;
const ivec3 tri0edge = TriOf(edge);
Expand All @@ -567,7 +567,7 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
const vec3 pNew = vertPos_[endVert];
const vec3 pOld = vertPos_[toRemove.startVert];
const vec3 delta = pNew - pOld;
const bool shortEdge = la::dot(delta, delta) < tolerance_ * tolerance_;
const bool shortEdge = la::dot(delta, delta) < epsilon_ * epsilon_;

// Orbit endVert
int current = halfedge_[tri0edge[1]].pairedHalfedge;
Expand All @@ -594,20 +594,14 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
if (!ref.SameFace(refCheck)) {
refCheck = triRef[edge / 3];
if (!ref.SameFace(refCheck)) {
return;
} else {
// Don't collapse if the edges separating the faces are not colinear
// (can happen when the two faces are coplanar).
if (CCW(projection * pOld, projection * pLast, projection * pNew,
epsilon_) != 0)
return;
return false;
}
}

// Don't collapse edge if it would cause a triangle to invert.
if (CCW(projection * pNext, projection * pLast, projection * pNew,
epsilon_) < 0)
return;
return false;

pLast = pNext;
current = halfedge_[current].pairedHalfedge;
Expand Down Expand Up @@ -654,6 +648,7 @@ void Manifold::Impl::CollapseEdge(const int edge, std::vector<int>& edges) {
UpdateVert(endVert, start, tri0edge[2]);
CollapseTri(tri0edge);
RemoveIfFolded(start);
return true;
}

void Manifold::Impl::RecursiveEdgeSwap(const int edge, int& tag,
Expand Down
2 changes: 1 addition & 1 deletion src/impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ struct Manifold::Impl {
void CleanupTopology();
void SimplifyTopology();
void DedupeEdge(int edge);
void CollapseEdge(int edge, std::vector<int>& edges);
bool CollapseEdge(int edge, std::vector<int>& edges);
void RecursiveEdgeSwap(int edge, int& tag, std::vector<int>& visited,
std::vector<int>& edgeSwapStack,
std::vector<int>& edges);
Expand Down
8 changes: 4 additions & 4 deletions test/properties_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,14 +77,14 @@ TEST(Properties, Tolerance) {
}

TEST(Properties, ToleranceSphere) {
const int n = 100;
const int n = 1000;
Manifold sphere = Manifold::Sphere(1, 4 * n);
EXPECT_EQ(sphere.NumTri(), 8 * n * n);

Manifold sphere2 = sphere.SetTolerance(0.01);
EXPECT_LT(sphere2.NumTri(), 15000);
EXPECT_NEAR(sphere.Volume(), sphere2.Volume(), 0.02);
EXPECT_NEAR(sphere.SurfaceArea(), sphere2.SurfaceArea(), 0.01);
EXPECT_LT(sphere2.NumTri(), 2500);
EXPECT_NEAR(sphere.Volume(), sphere2.Volume(), 0.05);
EXPECT_NEAR(sphere.SurfaceArea(), sphere2.SurfaceArea(), 0.05);
#ifdef MANIFOLD_EXPORT
if (options.exportModels) ExportMesh("sphere.glb", sphere2.GetMeshGL(), {});
#endif
Expand Down

0 comments on commit 228a14f

Please sign in to comment.