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>() ); m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>() );
PolygonTriangulation tess( *m_triangulatedPolys.back() ); 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; m_triangulationValid = true;

View File

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