better face error handler

This commit is contained in:
Irlan 2018-05-12 19:58:34 -03:00
parent 59990ed981
commit 096747a49d
2 changed files with 30 additions and 17 deletions

View File

@ -132,7 +132,9 @@ private:
bool MergeLargeFace(qhFace* face); bool MergeLargeFace(qhFace* face);
void FixMerge(qhFace* face, qhHalfEdge* ein); bool FixFace(qhFace* face);
qhHalfEdge* FixMerge(qhFace* face, qhHalfEdge* ein);
qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const; qhHalfEdge* FindHalfEdge(const qhVertex* v1, const qhVertex* v2) const;

View File

@ -732,7 +732,7 @@ static u32 b3VertexCount(const qhFace* face)
return n; return n;
} }
void qhHull::FixMerge(qhFace* face1, qhHalfEdge* ein) qhHalfEdge* qhHull::FixMerge(qhFace* face1, qhHalfEdge* ein)
{ {
qhHalfEdge* eout = ein->next; qhHalfEdge* eout = ein->next;
@ -745,8 +745,6 @@ void qhHull::FixMerge(qhFace* face1, qhHalfEdge* ein)
// Is the face 3 a triangle? // Is the face 3 a triangle?
if (count == 3) if (count == 3)
{ {
u32 vn = b3VertexCount(ein->face);
// Unlink incoming edge from face 1 // Unlink incoming edge from face 1
B3_ASSERT(ein->prev->next == ein); B3_ASSERT(ein->prev->next == ein);
ein->prev->next = ein->twin->next; ein->prev->next = ein->twin->next;
@ -854,6 +852,8 @@ void qhHull::FixMerge(qhFace* face1, qhHalfEdge* ein)
FreeEdge(eout->twin); FreeEdge(eout->twin);
FreeEdge(eout); FreeEdge(eout);
} }
return face1->edge;
} }
qhFace* qhHull::RemoveEdge(qhHalfEdge* edge) qhFace* qhHull::RemoveEdge(qhHalfEdge* edge)
@ -923,16 +923,24 @@ qhFace* qhHull::RemoveEdge(qhHalfEdge* edge)
FreeEdge(edge->twin); FreeEdge(edge->twin);
FreeEdge(edge); FreeEdge(edge);
// Check for topological errors and apply a fix on them // Repair topological errors in the face
// if detected. while (FixFace(face1));
// Return face 1
return face1;
}
bool qhHull::FixFace(qhFace* face)
{
// Maintained invariants: // Maintained invariants:
// - Each vertex must have at least three neighbor faces // - Each vertex must have at least three neighbor faces
// - Face 1 must be convex // - Face 1 must be convex
// Search a incoming and outgoing edge in the face 1 // Search a incoming (and outgoing edge) in the face 1
// which have the same neighbour face. // which have the same neighbour face.
qhHalfEdge* ein = face1->edge; qhHalfEdge* edge = NULL;
qhHalfEdge* ein = face->edge;
do do
{ {
qhHalfEdge* eout = ein->next; qhHalfEdge* eout = ein->next;
@ -940,19 +948,22 @@ qhFace* qhHull::RemoveEdge(qhHalfEdge* edge)
// Has the outgoing vertex become redundant? // Has the outgoing vertex become redundant?
if (ein->twin->face == eout->twin->face) if (ein->twin->face == eout->twin->face)
{ {
qhHalfEdge* ein0 = ein; edge = ein;
ein = eout; break;
// Remove the outgoing vertex.
FixMerge(face1, ein0);
continue;
} }
ein = eout; ein = eout;
} while (ein != face1->edge); } while (ein != face->edge);
// Return face 1 if (edge)
return face1; {
// Remove the outgoing vertex.
FixMerge(face, edge);
return true;
}
// Topological error not found.
return false;
} }
qhFace* qhHull::AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3) qhFace* qhHull::AddFace(qhVertex* v1, qhVertex* v2, qhVertex* v3)