Handle polygons' triangulation

Graphic polygons may be invalid and so need to be explicitly simplified
before triangulation.

Also clean up hole handling in triangulation routine
This commit is contained in:
Seth Hillbrand 2022-11-28 14:54:53 -08:00
parent 8165fc6c44
commit bd40684ecd
3 changed files with 21 additions and 4 deletions

View File

@ -508,8 +508,9 @@ public:
* in partition calculations the grid size is hard coded to 1e7. * in partition calculations the grid size is hard coded to 1e7.
* This is a good value for Pcbnew: 1cm, in internal units. * This is a good value for Pcbnew: 1cm, in internal units.
* But not good for Gerbview (1e7 = 10cm), however using a partition is not useful. * But not good for Gerbview (1e7 = 10cm), however using a partition is not useful.
* @param aSimplify = force the algorithm to simplify the POLY_SET before triangulating
*/ */
void CacheTriangulation( bool aPartition = true ); void CacheTriangulation( bool aPartition = true, bool aSimplify = false );
bool IsTriangulationUpToDate() const; bool IsTriangulationUpToDate() const;
MD5_HASH GetHash() const; MD5_HASH GetHash() const;

View File

@ -2681,7 +2681,7 @@ static SHAPE_POLY_SET partitionPolyIntoRegularCellGrid( const SHAPE_POLY_SET& aP
} }
void SHAPE_POLY_SET::CacheTriangulation( bool aPartition ) void SHAPE_POLY_SET::CacheTriangulation( bool aPartition, bool aSimplify )
{ {
bool recalculate = !m_hash.IsValid(); bool recalculate = !m_hash.IsValid();
MD5_HASH hash; MD5_HASH hash;
@ -2752,18 +2752,34 @@ void SHAPE_POLY_SET::CacheTriangulation( bool aPartition )
{ {
// This partitions into regularly-sized grids (1cm in Pcbnew) // This partitions into regularly-sized grids (1cm in Pcbnew)
SHAPE_POLY_SET flattened( Outline( ii ) ); SHAPE_POLY_SET flattened( Outline( ii ) );
for( int jj = 0; jj < HoleCount( ii ); ++jj )
flattened.AddHole( Hole( ii, jj ) );
flattened.ClearArcs(); flattened.ClearArcs();
if( flattened.HasHoles() )
flattened.Fracture( PM_FAST );
else if( aSimplify )
flattened.Simplify( PM_FAST );
SHAPE_POLY_SET partitions = partitionPolyIntoRegularCellGrid( flattened, 1e7 ); SHAPE_POLY_SET partitions = partitionPolyIntoRegularCellGrid( flattened, 1e7 );
m_triangulationValid &= triangulate( partitions, ii, m_triangulatedPolys ); // This pushes the triangulation for all polys in partitions
// to be referenced to the ii-th polygon
m_triangulationValid &= triangulate( partitions, ii , m_triangulatedPolys );
} }
} }
else else
{ {
SHAPE_POLY_SET tmpSet( *this ); SHAPE_POLY_SET tmpSet( *this );
tmpSet.ClearArcs();
if( tmpSet.HasHoles() ) if( tmpSet.HasHoles() )
tmpSet.Fracture( PM_FAST ); tmpSet.Fracture( PM_FAST );
else if( aSimplify )
tmpSet.Simplify( PM_FAST );
m_triangulationValid = triangulate( tmpSet, -1, m_triangulatedPolys ); m_triangulationValid = triangulate( tmpSet, -1, m_triangulatedPolys );
} }

View File

@ -1701,7 +1701,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
// draw the polygon solid shape on Opengl. GLU tessellation is much slower, // draw the polygon solid shape on Opengl. GLU tessellation is much slower,
// so currently we are using our tessellation. // so currently we are using our tessellation.
if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() ) if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
shape.CacheTriangulation(); shape.CacheTriangulation( true, true );
m_gal->DrawPolygon( shape ); m_gal->DrawPolygon( shape );
} }