tesselation: In case of failure, re-fracture

Simplification with clipper can produce a polygon with holes.  We need
to re-call simplify followed by fracture to ensure valid triangulation
This commit is contained in:
Seth Hillbrand 2018-12-17 06:51:12 -07:00
parent e49242bc54
commit 657bf2b53e
2 changed files with 14 additions and 25 deletions

View File

@ -1875,7 +1875,13 @@ void SHAPE_POLY_SET::CacheTriangulation()
m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>() );
PolygonTriangulation tess( *m_triangulatedPolys.back() );
tess.TesselatePolygon( tmpSet.Polygon( i ).front() );
// If the tesselation fails, we re-fracture the polygon, which will
// first simplify the system before fracturing and removing the holes
if( !tess.TesselatePolygon( tmpSet.Polygon( i ).front() ) )
{
tmpSet.Fracture( PM_FAST );
tess.TesselatePolygon( tmpSet.Polygon( i ).front() );
}
}
m_triangulationValid = true;

View File

@ -322,7 +322,7 @@ private:
{
for( size_t i = 0; i < len; i++ )
{
auto p = aPath.at( len - i );
auto p = aPath.at( len - i - 1 );
tail = insertVertex( VECTOR2I( p.X, p.Y ), tail );
}
}
@ -647,44 +647,27 @@ private:
public:
void TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
{
ClipperLib::Clipper c;
m_bbox = aPoly.BBox();
m_result.Clear();
if( !m_bbox.GetWidth() || !m_bbox.GetHeight() )
return;
return false;
/// Place the polygon Vertices into a circular linked list
/// and check for lists that have only 0, 1 or 2 elements and
/// therefore cannot be polygons
Vertex* firstVertex = createList( aPoly );
if( !firstVertex || firstVertex->prev == firstVertex->next )
return;
return false;
firstVertex->updateList();
if( !earcutList( firstVertex ) )
{
m_vertices.clear();
m_result.Clear();
ClipperLib::Paths simplified;
ClipperLib::SimplifyPolygon( aPoly.convertToClipper( true ), simplified );
for( auto path : simplified )
{
firstVertex = createList( path );
if( !firstVertex )
return;
firstVertex->updateList();
earcutList( firstVertex );
}
}
auto retval = earcutList( firstVertex );
m_vertices.clear();
return retval;
}
};