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:
parent
e49242bc54
commit
657bf2b53e
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue