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