- rewrote tessMeshMergeConvexFaces() to avoid infinite loops
This commit is contained in:
Mikko Mononen 2018-04-16 11:35:01 +03:00
parent 955761f46f
commit 1952b91b46

View file

@ -699,54 +699,52 @@ static int CountFaceVerts( TESSface *f )
int tessMeshMergeConvexFaces( TESSmesh *mesh, int maxVertsPerFace ) int tessMeshMergeConvexFaces( TESSmesh *mesh, int maxVertsPerFace )
{ {
TESSface *f; TESShalfEdge *e, *eNext, *eSym;
TESShalfEdge *eCur, *eNext, *eSym; TESShalfEdge *eHead = &mesh->eHead;
TESSvertex *vStart; TESSvertex *va, *vb, *vc, *vd, *ve, *vf;
int curNv, symNv; int leftNv, rightNv;
for( f = mesh->fHead.next; f != &mesh->fHead; f = f->next ) for( e = eHead->next; e != eHead; e = eNext )
{ {
// Skip faces which are outside the result. eNext = e->next;
if( !f->inside ) eSym = e->Sym;
if( !eSym )
continue;
// Both faces must be inside
if( !e->Lface || !e->Lface->inside )
continue;
if( !eSym->Lface || !eSym->Lface->inside )
continue; continue;
eCur = f->anEdge; leftNv = CountFaceVerts( e->Lface );
vStart = eCur->Org; rightNv = CountFaceVerts( eSym->Lface );
if( (leftNv+rightNv-2) > maxVertsPerFace )
while (1) continue;
{
eNext = eCur->Lnext;
eSym = eCur->Sym;
// Try to merge if the neighbour face is valid. // Merge if the resulting poly is convex.
if( eSym && eSym->Lface && eSym->Lface->inside ) //
{ // vf--ve--vd
// Try to merge the neighbour faces if the resulting polygons // ^|
// does not exceed maximum number of vertices. // left e || right
curNv = CountFaceVerts( f ); // |v
symNv = CountFaceVerts( eSym->Lface ); // va--vb--vc
if( (curNv+symNv-2) <= maxVertsPerFace )
{ va = e->Lprev->Org;
// Merge if the resulting poly is convex. vb = e->Org;
if( VertCCW( eCur->Lprev->Org, eCur->Org, eSym->Lnext->Lnext->Org ) && vc = e->Sym->Lnext->Dst;
VertCCW( eSym->Lprev->Org, eSym->Org, eCur->Lnext->Lnext->Org ) )
{ vd = e->Sym->Lprev->Org;
eNext = eSym->Lnext; ve = e->Sym->Org;
if( !tessMeshDelete( mesh, eSym ) ) vf = e->Lnext->Dst;
return 0;
eCur = 0; if( VertCCW( va, vb, vc ) && VertCCW( vd, ve, vf ) ) {
} if( e == eNext || e == eNext->Sym ) { eNext = eNext->next; }
} if( !tessMeshDelete( mesh, e ) )
} return 0;
if( eCur && eCur->Lnext->Org == vStart )
break;
// Continue to next edge.
eCur = eNext;
} }
} }
return 1; return 1;
} }