Protect TesselatePolygon() against degenerated polygons (less than 3 corners) to avoid crashes.
Use TesselatePolygon() to draw polygons in Gerbview instead of GLU tesselation, much slower. Add helper methods in GAL to know if the current GAL engine is Cairo, OpenGL or something else, useful to optimize drawing code.
This commit is contained in:
parent
7f5503a783
commit
388397f97d
|
@ -1872,6 +1872,9 @@ void SHAPE_POLY_SET::CacheTriangulation()
|
|||
|
||||
for( int i = 0; i < tmpSet.OutlineCount(); i++ )
|
||||
{
|
||||
if( tmpSet.Outline( i ).PointCount() < 3 ) // malformed polygon
|
||||
continue;
|
||||
|
||||
m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>() );
|
||||
PolygonTriangulation tess( *m_triangulatedPolys.back() );
|
||||
|
||||
|
|
|
@ -260,10 +260,20 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer )
|
|||
for( auto it = absolutePolygon.Iterate( 0 ); it; ++it )
|
||||
*it = aItem->GetABPosition( *it );
|
||||
|
||||
if( !isFilled )
|
||||
// Degenerated polygons (having < 3 points) are drawn as lines
|
||||
// to avoid issues in draw polygon functions
|
||||
if( !isFilled || absolutePolygon.COutline( 0 ).PointCount() < 3 )
|
||||
m_gal->DrawPolyline( absolutePolygon.COutline( 0 ) );
|
||||
else
|
||||
{
|
||||
// On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives.
|
||||
// CacheTriangulation() can create basic triangle primitives to draw the polygon solid shape
|
||||
// on Opengl
|
||||
if( m_gal->IsOpenGlEngine() )
|
||||
absolutePolygon.CacheTriangulation();
|
||||
|
||||
m_gal->DrawPolygon( absolutePolygon );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -72,6 +72,8 @@ public:
|
|||
|
||||
virtual ~CAIRO_GAL_BASE();
|
||||
|
||||
virtual bool IsCairoEngine() override { return true; }
|
||||
|
||||
// ---------------
|
||||
// Drawing methods
|
||||
// ---------------
|
||||
|
|
|
@ -75,6 +75,12 @@ public:
|
|||
/// @brief Returns true if the GAL canvas is visible on the screen.
|
||||
virtual bool IsVisible() const { return true; }
|
||||
|
||||
/// @brief Returns true if the GAL engine is a cairo based type.
|
||||
virtual bool IsCairoEngine() { return false; }
|
||||
|
||||
/// @brief Returns true if the GAL engine is a opengl based type.
|
||||
virtual bool IsOpenGlEngine() { return false; }
|
||||
|
||||
// ---------------
|
||||
// Drawing methods
|
||||
// ---------------
|
||||
|
|
|
@ -86,6 +86,8 @@ public:
|
|||
|
||||
virtual ~OPENGL_GAL();
|
||||
|
||||
virtual bool IsOpenGlEngine() override { return true; }
|
||||
|
||||
/// @copydoc GAL::IsInitialized()
|
||||
virtual bool IsInitialized() const override
|
||||
{
|
||||
|
|
|
@ -650,6 +650,10 @@ public:
|
|||
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
|
||||
{
|
||||
ClipperLib::Clipper c;
|
||||
|
||||
if( aPoly.PointCount() < 3 ) // Malformed polygon
|
||||
return false;
|
||||
|
||||
m_bbox = aPoly.BBox();
|
||||
m_result.Clear();
|
||||
|
||||
|
|
|
@ -974,13 +974,10 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
|||
break;
|
||||
|
||||
// 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
|
||||
// with any polygon. It must be a simple polygon.
|
||||
// And unfortunately, calling shape.Simplify( PM_FAST) is very slow.
|
||||
// So for now we just use GLU tesselation (much slower, but works with any polygon)
|
||||
// This section is left until a better way is found
|
||||
if( !shape.IsTriangulationUpToDate() )
|
||||
// CacheTriangulation() can create basic triangle primitives to draw the polygon solid shape
|
||||
// on Opengl.
|
||||
// GLU tesselation is much slower, so currently we are using our tesselation.
|
||||
if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
|
||||
{
|
||||
shape.CacheTriangulation();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue