Avoid degenerate triangles when snapping to mesh.

This can cause memory exhaustion when exporting to mesh with small
(but not excessively small) chord tolerance.
This commit is contained in:
EvilSpirit 2017-05-22 21:40:25 +07:00 committed by whitequark
parent 025bb960c0
commit 6ad5c684d8
3 changed files with 15 additions and 4 deletions

View File

@ -601,6 +601,10 @@ void SKdNode::SnapToVertex(Vector v, SMesh *extras) {
if(tr->b.Equals(v)) { tr->b = v; continue; }
if(tr->c.Equals(v)) { tr->c = v; continue; }
if(tr->IsDegenerate()) {
continue;
}
if(v.OnLineSegment(tr->a, tr->b)) {
STriangle nt = STriangle::From(tr->meta, tr->a, v, tr->c);
extras->AddTriangle(&nt);
@ -632,6 +636,9 @@ void SKdNode::SnapToMesh(SMesh *m) {
int i, j, k;
for(i = 0; i < m->l.n; i++) {
STriangle *tr = &(m->l.elem[i]);
if(tr->IsDegenerate()) {
continue;
}
for(j = 0; j < 3; j++) {
Vector v = tr->vertices[j];
@ -1117,10 +1124,7 @@ void SMesh::PrecomputeTransparency() {
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;
tr.tag = (int)tr.IsDegenerate();
}
l.RemoveTagged();
}

View File

@ -87,6 +87,12 @@ double STriangle::SignedVolume() const {
return a.Dot(b.Cross(c)) / 6.0;
}
bool STriangle::IsDegenerate() const {
return a.OnLineSegment(b, c) ||
b.OnLineSegment(a, c) ||
c.OnLineSegment(a, b);
}
void STriangle::FlipNormal() {
swap(a, b);
swap(an, bn);

View File

@ -191,6 +191,7 @@ public:
bool Raytrace(const Vector &rayPoint, const Vector &rayDir,
double *t, Vector *inters) const;
double SignedVolume() const;
bool IsDegenerate() const;
};
class SBsp2 {