From e985e10eecccb6239950d5e5f58090c79000ea5a Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 5 Aug 2019 21:23:57 -0700 Subject: [PATCH] gerber: Fracture footprint polygons before exporting Footprint polygons can be degenerate and need to be simplified before exporting --- include/geometry/shape_line_chain.h | 11 +++++++++++ pcbnew/plot_brditems_plotter.cpp | 28 +++++++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/include/geometry/shape_line_chain.h b/include/geometry/shape_line_chain.h index 843a1f3d68..16897fcfeb 100644 --- a/include/geometry/shape_line_chain.h +++ b/include/geometry/shape_line_chain.h @@ -127,6 +127,17 @@ public: m_points[i] = *aV++; } + + SHAPE_LINE_CHAIN( const std::vector& aV ) : + SHAPE( SH_LINE_CHAIN ), + m_closed( false ) + { + m_points.reserve( aV.size() ); + + for( auto pt : aV ) + m_points.emplace_back( pt.x, pt.y ); + } + SHAPE_LINE_CHAIN( const ClipperLib::Path& aPath ) : SHAPE( SH_LINE_CHAIN ), m_closed( true ) diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 6c3c84df13..73f3e5e93d 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -505,13 +505,13 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge ) case S_POLYGON: if( aEdge->IsPolyShapeValid() ) { - const std::vector& polyPoints = aEdge->BuildPolyPointsList(); + const std::vector &polyPoints = aEdge->BuildPolyPointsList(); // We must compute true coordinates from m_PolyList // which are relative to module position, orientation 0 - MODULE* module = aEdge->GetParentModule(); + MODULE *module = aEdge->GetParentModule(); - std::vector< wxPoint > cornerList; + std::vector cornerList; cornerList.reserve( polyPoints.size() ); @@ -530,17 +530,31 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge ) { for( size_t i = 1; i < cornerList.size(); i++ ) { - m_plotter->ThickSegment( cornerList[i-1], cornerList[i], thickness, - GetPlotMode(), &gbr_metadata ); + m_plotter->ThickSegment( cornerList[i - 1], cornerList[i], thickness, + GetPlotMode(), &gbr_metadata ); } m_plotter->ThickSegment( cornerList.back(), cornerList.front(), thickness, - GetPlotMode(), &gbr_metadata ); + GetPlotMode(), &gbr_metadata ); } else { - m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata ); + // This must be simplified and fractured to prevent overlapping polygons + // from generating invalid Gerber files + + SHAPE_LINE_CHAIN line( cornerList ); + SHAPE_POLY_SET tmpPoly; + + line.SetClosed( true ); + tmpPoly.AddOutline( line ); + tmpPoly.Fracture( SHAPE_POLY_SET::PM_FAST ); + + for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) + { + SHAPE_LINE_CHAIN &poly = tmpPoly.Outline( jj ); + m_plotter->PlotPoly( poly, FILLED_SHAPE, thickness, &gbr_metadata ); + } } } break;