From ac2373ae161481eb4c2d40ccdfb952c86b97813f Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Wed, 2 Oct 2019 17:16:27 +0200 Subject: [PATCH] Gerber plotter: add support of standard aperture regular polygon as flashed shape. Standard apertures are circle, rect, oblong and polygon (regular polygonal shapes with 3 to 12 vertices) The support of the standard aperture type polygon was missing in Gerber plotter. --- common/plotters/DXF_plotter.cpp | 10 ++ common/plotters/GERBER_plotter.cpp | 109 ++++++++++++++++--- common/plotters/HPGL_plotter.cpp | 9 ++ common/plotters/PS_plotter.cpp | 9 ++ include/plotter.h | 125 ++++++++++++++++++++-- pcb_calculator/attenuators/tee_formula.md | 4 +- 6 files changed, 236 insertions(+), 30 deletions(-) diff --git a/common/plotters/DXF_plotter.cpp b/common/plotters/DXF_plotter.cpp index 927acca80e..1a9f6def18 100644 --- a/common/plotters/DXF_plotter.cpp +++ b/common/plotters/DXF_plotter.cpp @@ -826,6 +826,16 @@ void DXF_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorner FinishTo( coord[0] ); } + +void DXF_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, + int aRadius, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) +{ + // Do nothing + wxASSERT( 0 ); +} + + /** * Checks if a given string contains non-ASCII characters. * FIXME: the performance of this code is really poor, but in this case it can be diff --git a/common/plotters/GERBER_plotter.cpp b/common/plotters/GERBER_plotter.cpp index a0eab168f3..ba33b0f1b8 100644 --- a/common/plotters/GERBER_plotter.cpp +++ b/common/plotters/GERBER_plotter.cpp @@ -290,7 +290,7 @@ void GERBER_PLOTTER::SetCurrentLineWidth( int width, void* aData ) GBR_METADATA* gbr_metadata = static_cast( aData ); int aperture_attribute = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; - selectAperture( wxSize( pen_width, pen_width ), APERTURE::Plotting, aperture_attribute ); + selectAperture( wxSize( pen_width, pen_width ), APERTURE::AT_PLOTTING, aperture_attribute ); currentPenWidth = pen_width; } @@ -348,6 +348,22 @@ void GERBER_PLOTTER::selectAperture( const wxSize& aSize, } } +void GERBER_PLOTTER::selectAperture( int aDiameter, double aPolygonRotation, + APERTURE::APERTURE_TYPE aType, int aApertureAttribute ) +{ + // Pick an existing aperture or create a new one, matching the + // aDiameter, aPolygonRotation, type and attributes for type = + // AT_REGULAR_POLY3 to AT_REGULAR_POLY12 + + wxASSERT( aType>= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY3 && + aType <= APERTURE::APERTURE_TYPE::AT_REGULAR_POLY12 ); + + // To use selectAperture( size, ... ) calculate a equivalent aperture size: + // for AT_REGULAR_POLYxx the parameter APERTURE::m_Size contains + // aDiameter (in m_Size.x) and aPolygonRotation in 1/1000 degree (in m_Size.y) + wxSize size( aDiameter, (int)( aPolygonRotation * 1000.0 ) ); + selectAperture( size, aType, aApertureAttribute ); +} void GERBER_PLOTTER::writeApertureList() { @@ -390,24 +406,37 @@ void GERBER_PLOTTER::writeApertureList() switch( tool->m_Type ) { - case APERTURE::Circle: + case APERTURE::AT_CIRCLE: + sprintf( text, "C,%#f*%%\n", tool->GetDiameter() * fscale ); + break; + + case APERTURE::AT_RECT: + sprintf( text, "R,%#fX%#f*%%\n", tool->m_Size.x * fscale, + tool->m_Size.y * fscale ); + break; + + case APERTURE::AT_PLOTTING: sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale ); break; - case APERTURE::Rect: - sprintf( text, "R,%#fX%#f*%%\n", - tool->m_Size.x * fscale, - tool->m_Size.y * fscale ); + case APERTURE::AT_OVAL: + sprintf( text, "O,%#fX%#f*%%\n", tool->m_Size.x * fscale, + tool->m_Size.y * fscale ); break; - case APERTURE::Plotting: - sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale ); - break; - - case APERTURE::Oval: - sprintf( text, "O,%#fX%#f*%%\n", - tool->m_Size.x * fscale, - tool->m_Size.y * fscale ); + case APERTURE::AT_REGULAR_POLY: + case APERTURE::AT_REGULAR_POLY3: + case APERTURE::AT_REGULAR_POLY4: + case APERTURE::AT_REGULAR_POLY5: + case APERTURE::AT_REGULAR_POLY6: + case APERTURE::AT_REGULAR_POLY7: + case APERTURE::AT_REGULAR_POLY8: + case APERTURE::AT_REGULAR_POLY9: + case APERTURE::AT_REGULAR_POLY10: + case APERTURE::AT_REGULAR_POLY11: + case APERTURE::AT_REGULAR_POLY12: + sprintf( text, "P,%#fX%dX%#f*%%\n", tool->GetDiameter() * fscale, + tool->GetVerticeCount(), tool->GetRotation() ); break; } @@ -667,7 +696,7 @@ void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_ DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; - selectAperture( size, APERTURE::Circle, aperture_attrib ); + selectAperture( size, APERTURE::AT_CIRCLE, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); @@ -693,7 +722,7 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; - selectAperture( size, APERTURE::Oval, aperture_attrib ); + selectAperture( size, APERTURE::AT_OVAL, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); @@ -790,7 +819,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize, { DPOINT pos_dev = userToDeviceCoordinates( pos ); int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; - selectAperture( size, APERTURE::Rect, aperture_attrib ); + selectAperture( size, APERTURE::AT_RECT, aperture_attrib ); if( gbr_metadata ) formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); @@ -999,6 +1028,52 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo } +void GERBER_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, + int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, + void* aData ) +{ + GBR_METADATA* gbr_metadata = static_cast( aData ); + + if( aTraceMode == SKETCH ) + { + // Build the polygon: + std::vector< wxPoint > cornerList; + + double angle_delta = 3600.0 / aCornerCount; // in 0.1 degree + + for( int ii = 0; ii < aCornerCount; ii++ ) + { + double rot = aOrient + (angle_delta*ii); + wxPoint vertice( aDiameter/2, 0 ); + RotatePoint( &vertice, rot ); + vertice += aShapePos; + cornerList.push_back( vertice ); + } + + cornerList.push_back( cornerList[0] ); // Close the shape + + SetCurrentLineWidth( aDiameter/8, gbr_metadata ); + PlotPoly( cornerList, NO_FILL, GetCurrentLineWidth(), gbr_metadata ); + } + else + { + DPOINT pos_dev = userToDeviceCoordinates( aShapePos ); + + int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; + + APERTURE::APERTURE_TYPE apert_type = + (APERTURE::APERTURE_TYPE)(APERTURE::AT_REGULAR_POLY3 + aCornerCount - 3); + selectAperture( aDiameter, aOrient, apert_type, aperture_attrib ); + + if( gbr_metadata ) + formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); + + emitDcode( pos_dev, 3 ); + } +} + + void GERBER_PLOTTER::Text( const wxPoint& aPos, const COLOR4D aColor, const wxString& aText, double aOrient, const wxSize& aSize, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, diff --git a/common/plotters/HPGL_plotter.cpp b/common/plotters/HPGL_plotter.cpp index a8044a5377..9c32907274 100644 --- a/common/plotters/HPGL_plotter.cpp +++ b/common/plotters/HPGL_plotter.cpp @@ -700,3 +700,12 @@ void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorne PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL ); } + + +void HPGL_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, + int aRadius, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) +{ + // Do nothing + wxASSERT( 0 ); +} diff --git a/common/plotters/PS_plotter.cpp b/common/plotters/PS_plotter.cpp index 94322db528..7ccfba329b 100644 --- a/common/plotters/PS_plotter.cpp +++ b/common/plotters/PS_plotter.cpp @@ -297,6 +297,15 @@ void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCor } +void PSLIKE_PLOTTER::FlashRegularPolygon( const wxPoint& aShapePos, + int aRadius, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) +{ + // Do nothing + wxASSERT( 0 ); +} + + /** * Write on a stream a string escaped for postscript/PDF */ diff --git a/include/plotter.h b/include/plotter.h index 142a678cba..0f7b78a6db 100644 --- a/include/plotter.h +++ b/include/plotter.h @@ -381,6 +381,16 @@ public: double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0; + /** Flash a regular polygon. Usefull only in Gerber files to flash a regular polygon + * @param aShapePos is the center of the circle containing the polygon + * @param aRadius is the radius of the circle containing the polygon + * @param aCornerCount is the number of vertices + * @param aOrient is the polygon rotation in degrees + * @param aData is a auxiliary parameter used (if needed) to handle extra info + * specific to the plotter + */ + virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0 ; /** * Draws text with the plotter. For convenience it accept the color to use @@ -649,6 +659,8 @@ public: virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; + virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; protected: void penControl( char plume ); @@ -707,6 +719,8 @@ public: EDA_DRAW_MODE_T aTraceMode, void* aData ) override; virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; + virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; /** The SetColor implementation is split with the subclasses: * The PSLIKE computes the rgb values, the subclass emits the @@ -1009,25 +1023,101 @@ protected: void setFillMode( FILL_T fill ); }; -/* Class to handle a D_CODE when plotting a board : */ +/* Class to handle a D_CODE when plotting a board using Standard Aperture Templates + * (complex apertures need aperture macros + * 5 types: + * Circle (round) + * Rectangle + * Obround (oval) + * regular polygon + * + * We need round apertures to plot lines, so we also defined a aperture type for plotting + */ #define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool class APERTURE { public: enum APERTURE_TYPE { - Circle = 1, - Rect = 2, - Plotting = 3, - Oval = 4 + AT_CIRCLE = 1, // round aperture, to flash pads + AT_RECT = 2, // rect aperture, to flash pads + AT_PLOTTING = 3, // round aperture, to plot lines + AT_OVAL = 4, // oval aperture, to flash pads + AT_REGULAR_POLY = 5,// Regular polygon (n vertices, n = 3 .. 12, with rotation) + AT_REGULAR_POLY3, // Regular polygon 3 vertices, with rotation + AT_REGULAR_POLY4, // Regular polygon 4 vertices, with rotation + AT_REGULAR_POLY5, // Regular polygon 5 vertices, with rotation + AT_REGULAR_POLY6, // Regular polygon 6 vertices, with rotation + AT_REGULAR_POLY7, // Regular polygon 7 vertices, with rotation + AT_REGULAR_POLY8, // Regular polygon 8 vertices, with rotation + AT_REGULAR_POLY9, // Regular polygon 9 vertices, with rotation + AT_REGULAR_POLY10, // Regular polygon 10 vertices, with rotation + AT_REGULAR_POLY11, // Regular polygon 11 vertices, with rotation + AT_REGULAR_POLY12, // Regular polygon 12 vertices, with rotation }; - wxSize m_Size; // horiz and Vert size - APERTURE_TYPE m_Type; // Type ( Line, rect , circulaire , ovale .. ) - int m_DCode; // code number ( >= 10 ); - int m_ApertureAttribute; // the attribute attached to this aperture - // Only one attribute is allowed by aperture - // 0 = no specific aperture attribute + void SetSize( const wxSize& aSize ) + { + m_Size = aSize; + } + + const wxSize GetSize() + { + return m_Size; + } + + void SetDiameter( int aDiameter ) + { + m_Size.x = aDiameter; + } + + int GetDiameter() + { + return m_Size.x; + } + + void SetVerticeCount( int aCount ) + { + if( aCount < 3 ) + aCount = 3; + else if( aCount > 12 ) + aCount = 12; + + m_Type = (APERTURE_TYPE)(AT_REGULAR_POLY3 - 3 + aCount); + } + + int GetVerticeCount() + { + return m_Type - AT_REGULAR_POLY3 + 3; + } + + void SetRotation( double aRotDegree ) + { + // The rotation is stored in 1/1000 degree + m_Size.y = int( aRotDegree * 1000.0 ); + } + + double GetRotation() + { + // The rotation is stored in 1/1000 degree + return m_Size.y / 1000.0; + } + + // Type ( Line, rect , circulaire , ovale poly 3 to 12 vertices ) + APERTURE_TYPE m_Type; + + // horiz and Vert size, or diameter and rotation for regular polygon + // The diameter (for circle and polygons) is stored in m_Size.x + // the rotation is stored in m_Size.y in 1/1000 degree + wxSize m_Size; + + // code number ( >= 10 ) + int m_DCode; + + // the attribute attached to this aperture + // Only one attribute is allowed by aperture + // 0 = no specific aperture attribute + int m_ApertureAttribute; }; @@ -1139,6 +1229,9 @@ public: virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; + virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; + /** * Change the plot polarity and begin a new layer * Used to 'scratch off' silk screen away from solder mask @@ -1183,6 +1276,14 @@ protected: */ void selectAperture( const wxSize& aSize, APERTURE::APERTURE_TYPE aType, int aApertureAttribute ); + /** + * Pick an existing aperture or create a new one, matching the + * aDiameter, aPolygonRotation, type and attributes. + * It apply only to apertures with type = AT_REGULAR_POLY3 to AT_REGULAR_POLY12 + * write the DCode selection on gerber file + */ + void selectAperture( int aDiameter, double aPolygonRotation, + APERTURE::APERTURE_TYPE aType, int aApertureAttribute ); /** * Emit a D-Code record, using proper conversions @@ -1329,6 +1430,8 @@ public: EDA_DRAW_MODE_T aTraceMode, void* aData ) override; virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; + virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount, + double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; virtual void Text( const wxPoint& aPos, const COLOR4D aColor, diff --git a/pcb_calculator/attenuators/tee_formula.md b/pcb_calculator/attenuators/tee_formula.md index 7361e33778..bcbe8c4ffd 100644 --- a/pcb_calculator/attenuators/tee_formula.md +++ b/pcb_calculator/attenuators/tee_formula.md @@ -7,5 +7,5 @@ __Zin = Zout__

* __L = 10a/20__ (the loss) * ___A = (L + 1)/(L - 1)___

* ___R2 = 2√(L \* Zin \* Zout )/(L - 1)___ -* ___R1 = Zin * A - R2___ -* ___R3 = Zout * A - R2___ +* ___R1 = Zin \* A - R2___ +* ___R3 = Zout \* A - R2___