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++ )
|
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>() );
|
m_triangulatedPolys.push_back( std::make_unique<TRIANGULATED_POLYGON>() );
|
||||||
PolygonTriangulation tess( *m_triangulatedPolys.back() );
|
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 )
|
for( auto it = absolutePolygon.Iterate( 0 ); it; ++it )
|
||||||
*it = aItem->GetABPosition( *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 ) );
|
m_gal->DrawPolyline( absolutePolygon.COutline( 0 ) );
|
||||||
else
|
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 );
|
m_gal->DrawPolygon( absolutePolygon );
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,6 +72,8 @@ public:
|
||||||
|
|
||||||
virtual ~CAIRO_GAL_BASE();
|
virtual ~CAIRO_GAL_BASE();
|
||||||
|
|
||||||
|
virtual bool IsCairoEngine() override { return true; }
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
// Drawing methods
|
// Drawing methods
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
|
@ -75,6 +75,12 @@ public:
|
||||||
/// @brief Returns true if the GAL canvas is visible on the screen.
|
/// @brief Returns true if the GAL canvas is visible on the screen.
|
||||||
virtual bool IsVisible() const { return true; }
|
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
|
// Drawing methods
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
|
@ -86,6 +86,8 @@ public:
|
||||||
|
|
||||||
virtual ~OPENGL_GAL();
|
virtual ~OPENGL_GAL();
|
||||||
|
|
||||||
|
virtual bool IsOpenGlEngine() override { return true; }
|
||||||
|
|
||||||
/// @copydoc GAL::IsInitialized()
|
/// @copydoc GAL::IsInitialized()
|
||||||
virtual bool IsInitialized() const override
|
virtual bool IsInitialized() const override
|
||||||
{
|
{
|
||||||
|
|
|
@ -650,6 +650,10 @@ public:
|
||||||
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
|
bool TesselatePolygon( const SHAPE_LINE_CHAIN& aPoly )
|
||||||
{
|
{
|
||||||
ClipperLib::Clipper c;
|
ClipperLib::Clipper c;
|
||||||
|
|
||||||
|
if( aPoly.PointCount() < 3 ) // Malformed polygon
|
||||||
|
return false;
|
||||||
|
|
||||||
m_bbox = aPoly.BBox();
|
m_bbox = aPoly.BBox();
|
||||||
m_result.Clear();
|
m_result.Clear();
|
||||||
|
|
||||||
|
|
|
@ -974,13 +974,10 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment, int aLayer )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives.
|
// On Opengl, a not convex filled polygon is usually drawn by using triangles as primitives.
|
||||||
// Although CacheTriangulation() can create basic triangle primitives
|
// CacheTriangulation() can create basic triangle primitives to draw the polygon solid shape
|
||||||
// to draw the polygon solid shape on Opengl, it is not used because it does not work fine
|
// on Opengl.
|
||||||
// with any polygon. It must be a simple polygon.
|
// GLU tesselation is much slower, so currently we are using our tesselation.
|
||||||
// And unfortunately, calling shape.Simplify( PM_FAST) is very slow.
|
if( m_gal->IsOpenGlEngine() && !shape.IsTriangulationUpToDate() )
|
||||||
// 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() )
|
|
||||||
{
|
{
|
||||||
shape.CacheTriangulation();
|
shape.CacheTriangulation();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue