diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 8c3d9a95c9..e0cd72803d 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -902,18 +902,16 @@ void GERBER_PLOTTER::plotArc( const VECTOR2I& aCenter, const EDA_ANGLE& aStartAn } -void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aData ) +void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADATA* aGbrMetadata ) { if( aPoly.PointCount() <= 2 ) return; - GBR_METADATA* gbr_metadata = static_cast( aData ); - bool clearTA_AperFunction = false; // true if a TA.AperFunction is used - if( gbr_metadata ) + if( aGbrMetadata ) { - std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format ); + std::string attrib = aGbrMetadata->m_ApertureMetadata.FormatAttribute( !m_useX2format ); if( !attrib.empty() ) { @@ -922,7 +920,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aDat } } - PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0 , gbr_metadata ); + PlotPoly( aPoly, FILL_T::FILLED_SHAPE, 0 , aGbrMetadata ); // Clear the TA attribute, to avoid the next item to inherit it: if( clearTA_AperFunction ) @@ -939,18 +937,17 @@ void GERBER_PLOTTER::PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aDat } -void GERBER_PLOTTER::PlotGerberRegion( const std::vector& aCornerList, void* aData ) +void GERBER_PLOTTER::PlotGerberRegion( const std::vector& aCornerList, + GBR_METADATA* aGbrMetadata ) { if( aCornerList.size() <= 2 ) return; - GBR_METADATA* gbr_metadata = static_cast( aData ); - bool clearTA_AperFunction = false; // true if a TA.AperFunction is used - if( gbr_metadata ) + if( aGbrMetadata ) { - std::string attrib = gbr_metadata->m_ApertureMetadata.FormatAttribute( !m_useX2format ); + std::string attrib = aGbrMetadata->m_ApertureMetadata.FormatAttribute( !m_useX2format ); if( !attrib.empty() ) { @@ -959,7 +956,7 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector& aCornerList, } } - PlotPoly( aCornerList, FILL_T::FILLED_SHAPE, 0, gbr_metadata ); + PlotPoly( aCornerList, FILL_T::FILLED_SHAPE, 0, aGbrMetadata ); // Clear the TA attribute, to avoid the next item to inherit it: if( clearTA_AperFunction ) @@ -976,6 +973,19 @@ void GERBER_PLOTTER::PlotGerberRegion( const std::vector& aCornerList, } +void GERBER_PLOTTER::PlotPolyAsRegion( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, + int aWidth, GBR_METADATA* aGbrMetadata ) +{ + // plot a filled polygon using Gerber region, therefore adding X2 attributes + // to the solid polygon + if( aWidth ) + PlotPoly( aPoly, FILL_T::NO_FILL, aWidth, aGbrMetadata ); + + if( aFill != FILL_T::NO_FILL ) + PlotGerberRegion( aPoly, aGbrMetadata ); +} + + void GERBER_PLOTTER::PlotPoly( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, int aWidth, void* aData ) { diff --git a/include/plotters/plotter_gerber.h b/include/plotters/plotter_gerber.h index 75c42bd43e..90d5a01da4 100644 --- a/include/plotters/plotter_gerber.h +++ b/include/plotters/plotter_gerber.h @@ -30,6 +30,7 @@ #include "gbr_plotter_apertures.h" class SHAPE_ARC; +class GBR_METADATA; class GERBER_PLOTTER : public PLOTTER { @@ -100,6 +101,13 @@ public: virtual void PlotPoly( const SHAPE_LINE_CHAIN& aCornerList, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void* aData = nullptr ) override; + /** + * Similar to PlotPoly(), plot a filled polygon using Gerber region, + * therefore adding X2 attributes to the region object, like TA.xxx + */ + void PlotPolyAsRegion( const SHAPE_LINE_CHAIN& aPoly, FILL_T aFill, + int aWidth, GBR_METADATA* aGbrMetadata ); + virtual void PenTo( const VECTOR2I& pos, char plume ) override; virtual void Text( const VECTOR2I& aPos, @@ -169,12 +177,12 @@ public: /** * Plot a Gerber region: similar to PlotPoly but plot only filled polygon, - * and add the TA.AperFunction if aData contains this attribute, and clear it + * and add the TA.AperFunction if aGbrMetadata contains this attribute, and clear it * after plotting. */ - void PlotGerberRegion( const std::vector& aCornerList, void* aData = nullptr ); + void PlotGerberRegion( const std::vector& aCornerList, GBR_METADATA* aGbrMetadata ); - void PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, void* aData = nullptr ); + void PlotGerberRegion( const SHAPE_LINE_CHAIN& aPoly, GBR_METADATA* aGbrMetadata ); /** * Change the plot polarity and begin a new layer. diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index b3124a67e3..5aa24662d3 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -776,10 +776,20 @@ void BRDITEMS_PLOTTER::PlotFootprintShape( const FP_SHAPE* aShape ) for( int jj = 0; jj < tmpPoly.OutlineCount(); ++jj ) { - SHAPE_LINE_CHAIN &poly = tmpPoly.Outline( jj ); - m_plotter->PlotPoly( poly, aShape->IsFilled() ? FILL_T::FILLED_SHAPE - : FILL_T::NO_FILL, - thickness, &gbr_metadata ); + SHAPE_LINE_CHAIN& poly = tmpPoly.Outline( jj ); + FILL_T fill_mode = aShape->IsFilled() ? FILL_T::FILLED_SHAPE + : FILL_T::NO_FILL; + // Plot the current filled area + // (as region for Gerber plotter to manage attributes) + if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) + { + static_cast( m_plotter )-> + PlotPolyAsRegion( poly, fill_mode, + thickness, &gbr_metadata ); + } + else + m_plotter->PlotPoly( poly, fill_mode, + thickness, &gbr_metadata ); } } } @@ -1073,7 +1083,15 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) // Ensure the polygon is closed: poly.SetClosed( true ); - m_plotter->PlotPoly( poly, fill, thickness, &gbr_metadata ); + // Plot the current filled area + // (as region for Gerber plotter to manage attributes) + if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) + { + static_cast( m_plotter )-> + PlotPolyAsRegion( poly, fill, thickness, &gbr_metadata ); + } + else + m_plotter->PlotPoly( poly, fill, thickness, &gbr_metadata ); } } } @@ -1084,22 +1102,32 @@ void BRDITEMS_PLOTTER::PlotPcbShape( const PCB_SHAPE* aShape ) { std::vector pts = aShape->GetRectCorners(); - if( sketch || thickness > 0 ) + if( sketch ) { m_plotter->ThickSegment( pts[0], pts[1], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[1], pts[2], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[2], pts[3], thickness, GetPlotMode(), &gbr_metadata ); m_plotter->ThickSegment( pts[3], pts[0], thickness, GetPlotMode(), &gbr_metadata ); } - - if( !sketch && aShape->IsFilled() ) + else { SHAPE_LINE_CHAIN poly; for( const VECTOR2I& pt : pts ) poly.Append( pt ); - m_plotter->PlotPoly( poly, FILL_T::FILLED_SHAPE, -1, &gbr_metadata ); + poly.Append( pts[0] ); // Close polygon. + + FILL_T fill_mode = aShape->IsFilled() ? FILL_T::FILLED_SHAPE + : FILL_T::NO_FILL; + + if( m_plotter->GetPlotterType() == PLOT_FORMAT::GERBER ) + { + static_cast( m_plotter )-> + PlotPolyAsRegion( poly, fill_mode, thickness, &gbr_metadata ); + } + else + m_plotter->PlotPoly( poly, fill_mode, thickness, &gbr_metadata ); } break;