From 15cc3689182a93a383f1aa1f7df2a4d12d287f37 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sat, 23 Jan 2021 18:02:58 +0100 Subject: [PATCH] Gerber plotter: prepare optimization of aperture macros type free polygons. They are used for chamfered round rect pads, and can be used for custom shaped pads. No actual change currently, but the shape rotation of custom pads and chamfered rr pads can be now used in gerber plots. --- common/plotters/DXF_plotter.cpp | 4 +-- common/plotters/GERBER_plotter.cpp | 48 ++++++++++++++++++++++++++++-- common/plotters/HPGL_plotter.cpp | 2 +- common/plotters/PS_plotter.cpp | 2 +- common/plotters/plotter_dxf.h | 2 +- common/plotters/plotter_gerber.h | 26 ++++------------ common/plotters/plotter_hpgl.h | 2 +- common/plotters/plotters_pslike.h | 2 +- include/plotter.h | 5 ++-- pcbnew/plot_brditems_plotter.cpp | 6 ++-- 10 files changed, 63 insertions(+), 36 deletions(-) diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index f1334f2d8b..294414b3b7 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -795,8 +795,8 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize } void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, - OUTLINE_MODE aTraceMode, void* aData ) + double aOrient, SHAPE_POLY_SET* aPolygons, + OUTLINE_MODE aTraceMode, void* aData ) { for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt ) { diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index 7e22cdd9c9..9c197e88b0 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -52,6 +52,13 @@ #define GBR_USE_MACROS_FOR_TRAPEZOID #define GBR_USE_MACROS_FOR_ROTATED_OVAL #define GBR_USE_MACROS_FOR_ROTATED_RECT +//#define GBR_USE_MACROS_FOR_CUSTOM_PAD // work in progress + +// max count of corners to create a aperture macro for a custom shape. +// provided just in case a aperture macro type free polygon creates issues +// when the number of corners is too high. +// (1 corner = up to 24 chars) +#define GBR_MACRO_FOR_CUSTOM_PAD_MAX_CORNER_COUNT 100000 GERBER_PLOTTER::GERBER_PLOTTER() { @@ -690,6 +697,10 @@ void GERBER_PLOTTER::writeApertureList() fprintf( m_outputFile, "%%%s%d*\n", "AMFp", tool.m_DCode ); fprintf( m_outputFile, "4,1,%d,", (int)tool.m_Corners.size() ); + // Insert a newline after curr_line_count_max coordiantes. + int curr_line_corner_count = 0; + const int curr_line_count_max = 50; // <= 0 to disable newlines + for( size_t ii = 0; ii <= tool.m_Corners.size(); ii++ ) { int jj = ii; @@ -697,8 +708,14 @@ void GERBER_PLOTTER::writeApertureList() if( ii >= tool.m_Corners.size() ) jj = 0; - fprintf( m_outputFile, "%#f,%#f,", - tool.m_Corners[jj].x * fscale, -tool.m_Corners[jj].y * fscale ); + fprintf( m_outputFile, "%#f,%#f,", + tool.m_Corners[jj].x * fscale, -tool.m_Corners[jj].y * fscale ); + if( curr_line_count_max >= 0 + && ++curr_line_corner_count >= curr_line_count_max ) + { + fprintf( m_outputFile, "\n" ); + curr_line_corner_count = 0; + } } // output rotation parameter fputs( "$1*%\n", m_outputFile ); @@ -1428,7 +1445,7 @@ void GERBER_PLOTTER::plotRoundRectAsRegion( const wxPoint& aRectCenter, const wx void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, + double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) { @@ -1463,7 +1480,32 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize if( aTraceMode == SKETCH ) PlotPoly( cornerList, FILL_TYPE::NO_FILL, GetCurrentLineWidth(), &gbr_metadata ); else + { +#ifdef GBR_USE_MACROS_FOR_CUSTOM_PAD + if( m_gerberDisableApertMacros + || cornerList.size() > GBR_MACRO_FOR_CUSTOM_PAD_MAX_CORNER_COUNT ) + PlotGerberRegion( cornerList, &gbr_metadata ); + else + { + // An AM will be created. the shape must be in position 0,0 and orientation 0 + // to be able to reuse the same AM for pads having the same shape + for( size_t ii = 0; ii < cornerList.size(); ii++ ) + { + cornerList[ii] -= aPadPos; + RotatePoint( &cornerList[ii], -aOrient ); + } + + DPOINT pos_dev = userToDeviceCoordinates( aPadPos ); + selectAperture( cornerList, aOrient/10.0, + APERTURE::AM_FREE_POLYGON, gbr_metadata.GetApertureAttrib() ); + formatNetAttribute( &gbr_metadata.m_NetlistMetadata ); + + emitDcode( pos_dev, 3 ); + } +#else PlotGerberRegion( cornerList, &gbr_metadata ); +#endif + } } } diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp index 9fe8787eb5..ce1ed447b9 100644 --- a/common/plotters/HPGL_plotter.cpp +++ b/common/plotters/HPGL_plotter.cpp @@ -797,7 +797,7 @@ void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSiz } void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, + double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) { std::vector< wxPoint > cornerList; diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index eb0e11f463..32c777abf7 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -225,7 +225,7 @@ void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS } void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, + double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) { wxSize size( aSize ); diff --git a/common/plotters/plotter_dxf.h b/common/plotters/plotter_dxf.h index 8e1eb039fd..c6051d283a 100644 --- a/common/plotters/plotter_dxf.h +++ b/common/plotters/plotter_dxf.h @@ -97,7 +97,7 @@ public: virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, OUTLINE_MODE aTraceMode, void* aData ) override; - virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, + virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) override; virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, diff --git a/common/plotters/plotter_gerber.h b/common/plotters/plotter_gerber.h index 47c872d09b..437bb465a6 100644 --- a/common/plotters/plotter_gerber.h +++ b/common/plotters/plotter_gerber.h @@ -118,35 +118,19 @@ public: virtual void FlashPadCircle( const wxPoint& pos, int diametre, OUTLINE_MODE trace_mode, void* aData ) override; - /** - * Filled oval flashes are handled as aperture in the 90 degree positions only - */ - virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient, + virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& size, double orient, OUTLINE_MODE trace_mode, void* aData ) override; - /** - * Filled rect flashes are handled as aperture in the 0 90 180 or 270 degree orientation only - * and as polygon for other orientations - * TODO: always use flashed shapes (aperture macros) - */ - virtual void FlashPadRect( const wxPoint& pos, const wxSize& size, + + virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& size, double orient, OUTLINE_MODE trace_mode, void* aData ) override; - /** - * Roundrect pad at the moment are not handled as aperture, since - * they require aperture macros - * TODO: always use flashed shapes (aperture macros) - */ virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, OUTLINE_MODE aTraceMode, void* aData ) override; virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, + double aPadOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) override; - /** - * Trapezoidal pad at the moment are *never* handled as aperture, since - * they require aperture macros - * TODO: always use flashed shapes (aperture macros) - */ + virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, OUTLINE_MODE aTraceMode, void* aData ) override; diff --git a/common/plotters/plotter_hpgl.h b/common/plotters/plotter_hpgl.h index 1e948fb343..96a2b22c25 100644 --- a/common/plotters/plotter_hpgl.h +++ b/common/plotters/plotter_hpgl.h @@ -110,7 +110,7 @@ public: virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, OUTLINE_MODE aTraceMode, void* aData ) override; - virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, + virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) override; virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, diff --git a/common/plotters/plotters_pslike.h b/common/plotters/plotters_pslike.h index 12a24b6677..e96ec75214 100644 --- a/common/plotters/plotters_pslike.h +++ b/common/plotters/plotters_pslike.h @@ -75,7 +75,7 @@ public: virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize, int aCornerRadius, double aOrient, OUTLINE_MODE aTraceMode, void* aData ) override; - virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, + virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, double aOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) override; virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, diff --git a/include/plotter.h b/include/plotter.h index 7aa136e3bc..00fefd4946 100644 --- a/include/plotter.h +++ b/include/plotter.h @@ -378,14 +378,15 @@ public: OUTLINE_MODE aTraceMode, void* aData ) = 0; /** - * @param aPadPos Position of the shape (center of the rectangle + * @param aPadPos Position of the shape * @param aSize = size of round reference pad + * @param aPadOrient = pad rotation, used only with aperture macros (Gerber plotter) * @param aPolygons the shape as polygon set * @param aTraceMode FILLED or SKETCH * @param aData an auxiliary info (mainly for gerber format attributes) */ virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize, - SHAPE_POLY_SET* aPolygons, + double aPadOrient, SHAPE_POLY_SET* aPolygons, OUTLINE_MODE aTraceMode, void* aData ) = 0; /** diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp index 58f08663ba..b218b437e8 100644 --- a/pcbnew/plot_brditems_plotter.cpp +++ b/pcbnew/plot_brditems_plotter.cpp @@ -277,8 +277,8 @@ void BRDITEMS_PLOTTER::PlotPad( PAD* aPad, COLOR4D aColor, OUTLINE_MODE aPlotMod if( polygons->OutlineCount() ) { - m_plotter->FlashPadCustom( shape_pos, aPad->GetSize(), polygons.get(), aPlotMode, - &gbr_metadata ); + m_plotter->FlashPadCustom( shape_pos, aPad->GetSize(), aPad->GetOrientation(), + polygons.get(), aPlotMode, &gbr_metadata ); } } break; @@ -1015,7 +1015,7 @@ void BRDITEMS_PLOTTER::PlotDrillMarks() { /* If small drills marks were requested prepare a clamp value to pass to the helper function */ - int smallDrill = GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE + int smallDrill = GetDrillMarksType() == PCB_PLOT_PARAMS::SMALL_DRILL_SHAPE ? Millimeter2iu( ADVANCED_CFG::GetCfg().m_SmallDrillMarkSize ) : 0; /* In the filled trace mode drill marks are drawn white-on-black to scrape