Update triangulation

Allow for overlapping points in input polygon.  This is relatively
common on a grid and should be used as potential split points to shave
additional ears

Fixes https://gitlab.com/kicad/code/kicad/-/issues/16933
This commit is contained in:
Seth Hillbrand 2024-02-12 15:19:01 -08:00
parent ca148fb4d1
commit 745c52c2b7
2 changed files with 43 additions and 2 deletions

View File

@ -56,6 +56,7 @@
#include <math/box2.h>
#include <math/vector2d.h>
#define TRIANGULATE_TRACE "triangulate"
class POLYGON_TRIANGULATION
{
public:
@ -565,6 +566,46 @@ private:
{
VERTEX* origPoly = start;
// Our first attempts to split the polygon will be at overlapping points.
// These are natural split points and we only need to switch the loop directions
// to generate two new loops. Since they are overlapping, we are do not
// need to create a new segment to disconnect the two loops.
do
{
VERTEX* nextZ = origPoly->nextZ;
if( nextZ && *nextZ == *origPoly )
{
std::swap( origPoly->next, nextZ->next );
origPoly->next->prev = origPoly;
nextZ->next->prev = nextZ;
origPoly->updateList();
nextZ->updateList();
return earcutList( origPoly ) && earcutList( nextZ );
}
VERTEX* prevZ = origPoly->prevZ;
if( prevZ && *prevZ == *origPoly )
{
std::swap( origPoly->next, prevZ->next );
origPoly->next->prev = origPoly;
prevZ->next->prev = prevZ;
origPoly->updateList();
prevZ->updateList();
return earcutList( origPoly ) && earcutList( prevZ );
}
origPoly = origPoly->next;
} while ( origPoly != start );
// If we've made it through the split algorithm and we still haven't found a
// set of overlapping points, we need to create a new segment to split the polygon
// into two separate polygons. We do this by finding the two vertices that form
// a valid line (does not cross the existing polygon)
do
{
VERTEX* marker = origPoly->next->next;

View File

@ -3069,7 +3069,7 @@ void SHAPE_POLY_SET::CacheTriangulation( bool aPartition, bool aSimplify )
// to be referenced to the ii-th polygon
if( !triangulate( partitions, ii , m_triangulatedPolys ) )
{
wxLogDebug( "Failed to triangulate partitioned polygon %d", ii );
wxLogTrace( TRIANGULATE_TRACE, "Failed to triangulate partitioned polygon %d", ii );
}
}
}
@ -3083,7 +3083,7 @@ void SHAPE_POLY_SET::CacheTriangulation( bool aPartition, bool aSimplify )
if( !triangulate( tmpSet, -1, m_triangulatedPolys ) )
{
wxLogDebug( "Failed to triangulate polygon" );
wxLogTrace( TRIANGULATE_TRACE, "Failed to triangulate polygon" );
}
}