diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index f62a59c47..92392140f 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -346,6 +346,11 @@ void Group::GenerateShellAndMesh() { SMesh outm = {}; GenerateForBoolean(&prevm, &thism, &outm, srcg->meshCombine); + // Remove degenerate triangles; if we don't, they'll get split in SnapToMesh + // in every generated group, resulting in polynomial increase in triangle count, + // and corresponding slowdown. + outm.RemoveDegenerateTriangles(); + // And make sure that the output mesh is vertex-to-vertex. SKdNode *root = SKdNode::From(&outm); root->SnapToMesh(&outm); diff --git a/src/mesh.cpp b/src/mesh.cpp index daeec4cc1..aaa066190 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -1114,3 +1114,13 @@ void SMesh::PrecomputeTransparency() { return (opaquea != opaqueb && opaquea == true); }); } + +void SMesh::RemoveDegenerateTriangles() { + for(auto &tr : l) { + bool isDegenerate = tr.a.OnLineSegment(tr.b, tr.c) || + tr.b.OnLineSegment(tr.a, tr.c) || + tr.c.OnLineSegment(tr.a, tr.b); + tr.tag = (int)isDegenerate; + } + l.RemoveTagged(); +} diff --git a/src/polygon.h b/src/polygon.h index abb39feec..5767dc035 100644 --- a/src/polygon.h +++ b/src/polygon.h @@ -278,6 +278,7 @@ class SMesh { void MakeOutlinesInto(SOutlineList *sol, EdgeKind type); void PrecomputeTransparency(); + void RemoveDegenerateTriangles(); bool IsEmpty() const; void RemapFaces(Group *g, int remap);