Skip to content

Commit 7c3730b

Browse files
committed
Add test for self intersection
1 parent d66df2b commit 7c3730b

File tree

5 files changed

+25
-5
lines changed

5 files changed

+25
-5
lines changed

src/manifold/src/edge_op.cpp

+11-4
Original file line numberDiff line numberDiff line change
@@ -222,9 +222,10 @@ void Manifold::Impl::SimplifyTopology() {
222222
precision_};
223223
for_each_n(policy, countAt(0), nbEdges,
224224
[=] __host__ __device__(int i) { bflagsPtr[i] = se(i); });
225-
std::vector<int> visited(halfedge_.size(), -1);
225+
std::vector<glm::ivec2> visited(halfedge_.size(), glm::ivec2(-1));
226226
for (int i = 0; i < nbEdges; ++i) {
227227
if (bflags[i]) {
228+
visited.resize(0);
228229
RecursiveEdgeSwap(i, visited);
229230
numFlagged++;
230231
}
@@ -485,14 +486,17 @@ void Manifold::Impl::CollapseEdge(const int edge) {
485486
}
486487

487488
void Manifold::Impl::RecursiveEdgeSwap(const int edge,
488-
std::vector<int>& visited) {
489+
std::vector<glm::ivec2>& visited) {
489490
VecDH<TriRef>& triRef = meshRelation_.triRef;
490491

491492
if (edge < 0) return;
492493
const int pair = halfedge_[edge].pairedHalfedge;
493494
if (pair < 0) return;
494-
if (visited[edge] == pair) return;
495-
visited[edge] = pair;
495+
496+
// avoid infinite recursion
497+
for (int i = 0; i < visited.size(); ++i) {
498+
if (visited[i] == glm::ivec2(edge, pair)) return;
499+
}
496500

497501
const glm::ivec3 tri0edge = TriOf(edge);
498502
const glm::ivec3 tri1edge = TriOf(pair);
@@ -572,8 +576,10 @@ void Manifold::Impl::RecursiveEdgeSwap(const int edge,
572576
SwapEdge();
573577
const glm::vec2 e23 = v[3] - v[2];
574578
if (glm::dot(e23, e23) < precision_ * precision_) {
579+
visited.resize(0);
575580
CollapseEdge(tri0edge[2]);
576581
} else {
582+
visited.emplace_back(glm::ivec2(edge, pair));
577583
RecursiveEdgeSwap(tri0edge[0], visited);
578584
RecursiveEdgeSwap(tri0edge[1], visited);
579585
RecursiveEdgeSwap(tri1edge[0], visited);
@@ -586,6 +592,7 @@ void Manifold::Impl::RecursiveEdgeSwap(const int edge,
586592
}
587593
// Normal path
588594
SwapEdge();
595+
visited.emplace_back(glm::ivec2(edge, pair));
589596
RecursiveEdgeSwap(halfedge_[tri0edge[1]].pairedHalfedge, visited);
590597
RecursiveEdgeSwap(halfedge_[tri1edge[0]].pairedHalfedge, visited);
591598
}

src/manifold/src/impl.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ struct Manifold::Impl {
121121
void SimplifyTopology();
122122
void DedupeEdge(int edge);
123123
void CollapseEdge(int edge);
124-
void RecursiveEdgeSwap(int edge, std::vector<int>& visited);
124+
void RecursiveEdgeSwap(int edge, std::vector<glm::ivec2>& visited);
125125
void RemoveIfFolded(int edge);
126126
void PairUp(int edge0, int edge1);
127127
void UpdateVert(int vert, int startEdge, int endEdge);

test/models/self_intersectA.glb

317 KB
Binary file not shown.

test/models/self_intersectB.glb

317 KB
Binary file not shown.

test/samples_test.cpp

+13
Original file line numberDiff line numberDiff line change
@@ -255,3 +255,16 @@ TEST(Samples, Sponge4) {
255255
#endif
256256
}
257257
#endif
258+
259+
#ifdef MANIFOLD_EXPORT
260+
TEST(Samples, SelfIntersect) {
261+
manifold::PolygonParams().processOverlaps = true;
262+
std::string file = __FILE__;
263+
std::string dir = file.substr(0, file.rfind('/'));
264+
Manifold m1 = ImportMesh(dir + "/models/self_intersectA.glb");
265+
Manifold m2 = ImportMesh(dir + "/models/self_intersectB.glb");
266+
Manifold res = m1 + m2;
267+
res.GetMeshGL(); // test crash
268+
manifold::PolygonParams().processOverlaps = false;
269+
}
270+
#endif

0 commit comments

Comments
 (0)