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.
This commit is contained in:
jean-pierre charras 2019-10-02 17:16:27 +02:00
parent 6179dfde37
commit ac2373ae16
6 changed files with 236 additions and 30 deletions

View File

@ -826,6 +826,16 @@ void DXF_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorner
FinishTo( coord[0] ); 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. * 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 * FIXME: the performance of this code is really poor, but in this case it can be

View File

@ -290,7 +290,7 @@ void GERBER_PLOTTER::SetCurrentLineWidth( int width, void* aData )
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData ); GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
int aperture_attribute = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; 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; 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() void GERBER_PLOTTER::writeApertureList()
{ {
@ -390,25 +406,38 @@ void GERBER_PLOTTER::writeApertureList()
switch( tool->m_Type ) switch( tool->m_Type )
{ {
case APERTURE::Circle: case APERTURE::AT_CIRCLE:
sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale ); sprintf( text, "C,%#f*%%\n", tool->GetDiameter() * fscale );
break; break;
case APERTURE::Rect: case APERTURE::AT_RECT:
sprintf( text, "R,%#fX%#f*%%\n", sprintf( text, "R,%#fX%#f*%%\n", tool->m_Size.x * fscale,
tool->m_Size.x * fscale,
tool->m_Size.y * fscale ); tool->m_Size.y * fscale );
break; break;
case APERTURE::Plotting: case APERTURE::AT_PLOTTING:
sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale ); sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale );
break; break;
case APERTURE::Oval: case APERTURE::AT_OVAL:
sprintf( text, "O,%#fX%#f*%%\n", sprintf( text, "O,%#fX%#f*%%\n", tool->m_Size.x * fscale,
tool->m_Size.x * fscale,
tool->m_Size.y * fscale ); tool->m_Size.y * fscale );
break; break;
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;
} }
fputs( cbuf, outputFile ); fputs( cbuf, outputFile );
@ -667,7 +696,7 @@ void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_
DPOINT pos_dev = userToDeviceCoordinates( pos ); DPOINT pos_dev = userToDeviceCoordinates( pos );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; 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 ) if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); 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 ); DPOINT pos_dev = userToDeviceCoordinates( pos );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; 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 ) if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
@ -790,7 +819,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
{ {
DPOINT pos_dev = userToDeviceCoordinates( pos ); DPOINT pos_dev = userToDeviceCoordinates( pos );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0; 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 ) if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata ); 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<GBR_METADATA*>( 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, void GERBER_PLOTTER::Text( const wxPoint& aPos, const COLOR4D aColor,
const wxString& aText, double aOrient, const wxSize& aSize, const wxString& aText, double aOrient, const wxSize& aSize,
enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify, enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify,

View File

@ -700,3 +700,12 @@ void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorne
PlotPoly( cornerList, aTraceMode == FILLED ? FILLED_SHAPE : NO_FILL ); 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 );
}

View File

@ -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 * Write on a stream a string escaped for postscript/PDF
*/ */

View File

@ -381,6 +381,16 @@ public:
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, double aPadOrient, EDA_DRAW_MODE_T aTraceMode,
void* aData ) = 0; 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 * 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, virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, double aPadOrient, EDA_DRAW_MODE_T aTraceMode,
void* aData ) override; void* aData ) override;
virtual void FlashRegularPolygon( const wxPoint& aShapePos, int aDiameter, int aCornerCount,
double aOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
protected: protected:
void penControl( char plume ); void penControl( char plume );
@ -707,6 +719,8 @@ public:
EDA_DRAW_MODE_T aTraceMode, void* aData ) override; EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; 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 SetColor implementation is split with the subclasses:
* The PSLIKE computes the rgb values, the subclass emits the * The PSLIKE computes the rgb values, the subclass emits the
@ -1009,25 +1023,101 @@ protected:
void setFillMode( FILL_T fill ); 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 #define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool
class APERTURE class APERTURE
{ {
public: public:
enum APERTURE_TYPE { enum APERTURE_TYPE {
Circle = 1, AT_CIRCLE = 1, // round aperture, to flash pads
Rect = 2, AT_RECT = 2, // rect aperture, to flash pads
Plotting = 3, AT_PLOTTING = 3, // round aperture, to plot lines
Oval = 4 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 void SetSize( const wxSize& aSize )
APERTURE_TYPE m_Type; // Type ( Line, rect , circulaire , ovale .. ) {
int m_DCode; // code number ( >= 10 ); m_Size = aSize;
int m_ApertureAttribute; // the attribute attached to this aperture }
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 // Only one attribute is allowed by aperture
// 0 = no specific aperture attribute // 0 = no specific aperture attribute
int m_ApertureAttribute;
}; };
@ -1139,6 +1229,9 @@ public:
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; 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 * Change the plot polarity and begin a new layer
* Used to 'scratch off' silk screen away from solder mask * Used to 'scratch off' silk screen away from solder mask
@ -1183,6 +1276,14 @@ protected:
*/ */
void selectAperture( const wxSize& aSize, APERTURE::APERTURE_TYPE aType, void selectAperture( const wxSize& aSize, APERTURE::APERTURE_TYPE aType,
int aApertureAttribute ); 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 * Emit a D-Code record, using proper conversions
@ -1329,6 +1430,8 @@ public:
EDA_DRAW_MODE_T aTraceMode, void* aData ) override; EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners, virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) override; 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, virtual void Text( const wxPoint& aPos,
const COLOR4D aColor, const COLOR4D aColor,

View File

@ -7,5 +7,5 @@ __Zin = Zout__<br><br>
* __L = 10<sup>a/20</sup>__ (the loss) * __L = 10<sup>a/20</sup>__ (the loss)
* ___A = (L + 1)/(L - 1)___<br><br> * ___A = (L + 1)/(L - 1)___<br><br>
* ___R2 = 2&radic;(L \* Z<sub>in</sub> \* Z<sub>out</sub> )/(L - 1)___ * ___R2 = 2&radic;(L \* Z<sub>in</sub> \* Z<sub>out</sub> )/(L - 1)___
* ___R1 = Z<sub>in</sub> * A - R2___ * ___R1 = Z<sub>in</sub> \* A - R2___
* ___R3 = Z<sub>out</sub> * A - R2___ * ___R3 = Z<sub>out</sub> \* A - R2___