tesselation: Check winding order

Although copper layers are always tesselated CCW, polygons in footprints
will be CW if flipped to the back layer, resulting in a bad render.
This commit is contained in:
Seth Hillbrand 2018-12-17 06:34:56 -07:00
parent 98d6d68e2d
commit e49242bc54
2 changed files with 40 additions and 5 deletions

View File

@ -301,9 +301,31 @@ private:
Vertex* createList( const ClipperLib::Path& aPath )
{
Vertex* tail = nullptr;
double sum = 0.0;
auto len = aPath.size();
// Check for winding order
for( size_t i = 0; i < len; i++ )
{
auto p1 = aPath.at( i );
auto p2 = aPath.at( ( i + 1 ) < len ? i + 1 : 0 );
sum += ( ( p2.X - p1.X ) * ( p2.Y - p1.Y ) );
}
if( sum <= 0.0 )
{
for( auto point : aPath )
tail = insertVertex( VECTOR2I( point.X, point.Y ), tail );
}
else
{
for( size_t i = 0; i < len; i++ )
{
auto p = aPath.at( len - i );
tail = insertVertex( VECTOR2I( p.X, p.Y ), tail );
}
}
if( tail && ( *tail == *tail->next ) )
{
@ -322,7 +344,21 @@ private:
Vertex* createList( const SHAPE_LINE_CHAIN& points )
{
Vertex* tail = nullptr;
double sum = 0.0;
// Check for winding order
for( int i = 0; i < points.PointCount(); i++ )
{
VECTOR2D p1 = points.CPoint( i );
VECTOR2D p2 = points.CPoint( i + 1 );
sum += ( ( p2.x - p1.x ) * ( p2.y - p1.y ) );
}
if( sum > 0.0 )
for( int i = points.PointCount() - 1; i >= 0; i--)
tail = insertVertex( points.CPoint( i ), tail );
else
for( int i = 0; i < points.PointCount(); i++ )
tail = insertVertex( points.CPoint( i ), tail );

View File

@ -973,7 +973,6 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
if( shape.OutlineCount() == 0 )
break;
#if 0
// On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives.
// Although CacheTriangulation() can create basic triangle primitives
// to draw the polygon solid shape on Opengl, it is not used because it does not work fine
@ -985,7 +984,7 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
{
shape.CacheTriangulation();
}
#endif
m_gal->Save();
if( MODULE* module = aSegment->GetParentModule() )