Prepare Plot Gerber file to include advanced aperture and net attributes.

This option is not yet activated because the net attributes are not yet fully fixed by Ucamco, in Gerber file format specifications.
(To activate it, see dialog_plot.cpp, line 43)
This commit is contained in:
jean-pierre charras 2016-09-19 13:01:36 +02:00
parent 7f9380af26
commit 6edee2ae1d
26 changed files with 1607 additions and 306 deletions

View File

@ -227,6 +227,7 @@ set( COMMON_SRCS
eda_pattern_match.cpp
filter_reader.cpp
# findkicadhelppath.cpp.notused deprecated, use searchhelpfilefullpath.cpp
gbr_metadata.cpp
gestfich.cpp
getrunningmicrosecs.cpp
grid_tricks.cpp

View File

@ -393,7 +393,7 @@ void PLOTTER::segmentAsOval( const wxPoint& start, const wxPoint& end, int width
size.x = KiROUND( EuclideanNorm( size ) ) + width;
size.y = width;
FlashPadOval( center, size, orient, tracemode );
FlashPadOval( center, size, orient, tracemode, NULL );
}
@ -446,7 +446,7 @@ void PLOTTER::sketchOval( const wxPoint& pos, const wxSize& aSize, double orient
void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode )
EDA_DRAW_MODE_T tracemode, void* aData )
{
if( tracemode == FILLED )
{
@ -463,7 +463,7 @@ void PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
int radius, int width, EDA_DRAW_MODE_T tracemode )
int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
{
if( tracemode == FILLED )
Arc( centre, StAngle, EndAngle, radius, NO_FILL, width );
@ -479,7 +479,7 @@ void PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
EDA_DRAW_MODE_T tracemode )
EDA_DRAW_MODE_T tracemode, void* aData )
{
if( tracemode == FILLED )
Rect( p1, p2, NO_FILL, width );
@ -500,7 +500,7 @@ void PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
}
void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, EDA_DRAW_MODE_T tracemode )
void PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width, EDA_DRAW_MODE_T tracemode, void* aData )
{
if( tracemode == FILLED )
Circle( pos, diametre, NO_FILL, width );

View File

@ -347,7 +347,7 @@ void DXF_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill, int
* are converted to inflated polygon by aWidth/2
*/
void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
FILL_T aFill, int aWidth)
FILL_T aFill, int aWidth, void * aData )
{
if( aCornerList.size() <= 1 )
return;
@ -383,7 +383,7 @@ void DXF_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
for( unsigned ii = 1; ii < aCornerList.size(); ii++ )
ThickSegment( aCornerList[ii-1], aCornerList[ii],
aWidth, FILLED );
aWidth, FILLED, NULL );
return;
}
@ -481,7 +481,7 @@ void DXF_PLOTTER::SetDash( bool dashed )
void DXF_PLOTTER::ThickSegment( const wxPoint& aStart, const wxPoint& aEnd, int aWidth,
EDA_DRAW_MODE_T aPlotMode )
EDA_DRAW_MODE_T aPlotMode, void* aData )
{
segmentAsOval( aStart, aEnd, aWidth, aPlotMode );
}
@ -521,7 +521,7 @@ void DXF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
* DXF oval pad: always done in sketch mode
*/
void DXF_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient,
EDA_DRAW_MODE_T trace_mode )
EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
wxSize size( aSize );
@ -543,7 +543,7 @@ void DXF_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
* pretty if other kinds of pad aren't...
*/
void DXF_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode )
EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
Circle( pos, diametre, NO_FILL );
@ -554,7 +554,7 @@ void DXF_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
* DXF rectangular pad: alwayd done in sketch mode
*/
void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
double orient, EDA_DRAW_MODE_T trace_mode )
double orient, EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
wxSize size;
@ -619,7 +619,7 @@ void DXF_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
@ -639,7 +639,7 @@ void DXF_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize
void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
for( int cnt = 0; cnt < aPolygons->OutlineCount(); ++cnt )
{
@ -659,7 +659,7 @@ void DXF_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
* DXF trapezoidal pad: only sketch mode is supported
*/
void DXF_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData )
{
wxASSERT( outputFile );
wxPoint coord[4]; /* coord actual corners of a trapezoidal trace */
@ -708,7 +708,8 @@ void DXF_PLOTTER::Text( const wxPoint& aPos,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed )
bool aMultilineAllowed,
void* aData )
{
// Fix me: see how to use DXF text mode for multiline texts
if( aMultilineAllowed && !aText.Contains( wxT( "\n" ) ) )

View File

@ -40,12 +40,15 @@
#include <build_version.h>
#include <plot_auxiliary_data.h>
GERBER_PLOTTER::GERBER_PLOTTER()
{
workFile = 0;
finalFile = 0;
workFile = NULL;
finalFile = NULL;
currentAperture = apertures.end();
m_apertureAttribute = 0;
// number of digits after the point (number of digits of the mantissa
// Be carefull: the Gerber coordinates are stored in an integer
@ -56,6 +59,8 @@ GERBER_PLOTTER::GERBER_PLOTTER()
// happen easily.
m_gerberUnitInch = false;
m_gerberUnitFmt = 6;
m_useX2Attributes = false;
m_useNetAttributes = true;
}
@ -102,6 +107,56 @@ void GERBER_PLOTTER::emitDcode( const DPOINT& pt, int dcode )
}
void GERBER_PLOTTER::clearNetAttribute()
{
// disable a Gerber net attribute (exists only in X2 with net attributes mode).
if( m_objectAttributesDictionnary.empty() ) // No net attribute or not X2 mode
return;
// Remove all net attributes from object attributes dictionnary
fputs( "%TD*%\n", outputFile );
m_objectAttributesDictionnary.clear();
}
void GERBER_PLOTTER::StartBlock( void* aData )
{
// Currently, it is the same as EndBlock(): clear all aperture net attributes
EndBlock( aData );
}
void GERBER_PLOTTER::EndBlock( void* aData )
{
// Remove all net attributes from object attributes dictionnary
clearNetAttribute();
}
void GERBER_PLOTTER::formatNetAttribute( GBR_NETLIST_METADATA* aData )
{
// print a Gerber net attribute record.
// it is added to the object attributes dictionnary
// On file, only modified or new attributes are printed.
if( aData == NULL || !m_useX2Attributes || !m_useNetAttributes )
return;
bool clearDict;
std::string short_attribute_string;
if( !FormatNetAttribute( short_attribute_string, m_objectAttributesDictionnary,
aData, clearDict ) )
return;
if( clearDict )
clearNetAttribute();
if( !short_attribute_string.empty() )
fputs( short_attribute_string.c_str(), outputFile );
}
bool GERBER_PLOTTER::StartPlot()
{
wxASSERT( outputFile );
@ -156,7 +211,7 @@ bool GERBER_PLOTTER::StartPlot()
fputs( "G04 APERTURE LIST*\n", outputFile );
/* Select the default aperture */
SetCurrentLineWidth( -1 );
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, 0 );
return true;
}
@ -206,8 +261,11 @@ void GERBER_PLOTTER::SetDefaultLineWidth( int width )
}
void GERBER_PLOTTER::SetCurrentLineWidth( int width )
void GERBER_PLOTTER::SetCurrentLineWidth( int width, void* aData )
{
if( width == DO_NOT_SET_LINE_WIDTH )
return;
int pen_width;
if( width > 0 )
@ -215,13 +273,16 @@ void GERBER_PLOTTER::SetCurrentLineWidth( int width )
else
pen_width = defaultPenWidth;
selectAperture( wxSize( pen_width, pen_width ), APERTURE::Plotting );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
int aperture_attribute = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
selectAperture( wxSize( pen_width, pen_width ), APERTURE::Plotting, aperture_attribute );
currentPenWidth = pen_width;
}
std::vector<APERTURE>::iterator GERBER_PLOTTER::getAperture( const wxSize& size,
APERTURE::APERTURE_TYPE type )
std::vector<APERTURE>::iterator GERBER_PLOTTER::getAperture( const wxSize& aSize,
APERTURE::APERTURE_TYPE aType, int aApertureAttribute )
{
int last_D_code = 9;
@ -230,36 +291,45 @@ std::vector<APERTURE>::iterator GERBER_PLOTTER::getAperture( const wxSize&
while( tool != apertures.end() )
{
last_D_code = tool->DCode;
last_D_code = tool->m_DCode;
if( (tool->Type == type) && (tool->Size == size) )
if( (tool->m_Type == aType) && (tool->m_Size == aSize) && (tool->m_ApertureAttribute == aApertureAttribute) )
return tool;
tool++;
++tool;
}
// Allocate a new aperture
APERTURE new_tool;
new_tool.Size = size;
new_tool.Type = type;
new_tool.DCode = last_D_code + 1;
new_tool.m_Size = aSize;
new_tool.m_Type = aType;
new_tool.m_DCode = last_D_code + 1;
new_tool.m_ApertureAttribute = aApertureAttribute;
apertures.push_back( new_tool );
return apertures.end() - 1;
}
void GERBER_PLOTTER::selectAperture( const wxSize& size,
APERTURE::APERTURE_TYPE type )
void GERBER_PLOTTER::selectAperture( const wxSize& aSize,
APERTURE::APERTURE_TYPE aType,
int aApertureAttribute )
{
wxASSERT( outputFile );
bool change = ( currentAperture == apertures.end() ) ||
( currentAperture->m_Type != aType ) ||
( currentAperture->m_Size != aSize );
if( ( currentAperture == apertures.end() )
|| ( currentAperture->Type != type )
|| ( currentAperture->Size != size ) )
if( !m_useX2Attributes || !m_useNetAttributes )
aApertureAttribute = 0;
else
change = change || ( currentAperture->m_ApertureAttribute != aApertureAttribute );
if( change )
{
// Pick an existing aperture or create a new one
currentAperture = getAperture( size, type );
fprintf( outputFile, "D%d*\n", currentAperture->DCode );
currentAperture = getAperture( aSize, aType, aApertureAttribute );
fprintf( outputFile, "D%d*\n", currentAperture->m_DCode );
}
}
@ -271,7 +341,7 @@ void GERBER_PLOTTER::writeApertureList()
// Init
for( std::vector<APERTURE>::iterator tool = apertures.begin();
tool != apertures.end(); tool++ )
tool != apertures.end(); ++tool )
{
// apertude sizes are in inch or mm, regardless the
// coordinates format
@ -280,7 +350,13 @@ void GERBER_PLOTTER::writeApertureList()
if(! m_gerberUnitInch )
fscale *= 25.4; // size in mm
char* text = cbuf + sprintf( cbuf, "%%ADD%d", tool->DCode );
int attribute = tool->m_ApertureAttribute;
if( attribute != m_apertureAttribute )
fputs( GBR_APERTURE_METADATA::FormatAttribute(
(GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB) attribute ).c_str(), outputFile );
char* text = cbuf + sprintf( cbuf, "%%ADD%d", tool->m_DCode );
/* Please note: the Gerber specs for mass parameters say that
exponential syntax is *not* allowed and the decimal point should
@ -289,30 +365,41 @@ void GERBER_PLOTTER::writeApertureList()
can't remove trailing zeros but thats not a problem, since nothing
forbid it (the file is only slightly longer) */
switch( tool->Type )
switch( tool->m_Type )
{
case APERTURE::Circle:
sprintf( text, "C,%#f*%%\n", tool->Size.x * fscale );
sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale );
break;
case APERTURE::Rect:
sprintf( text, "R,%#fX%#f*%%\n",
tool->Size.x * fscale,
tool->Size.y * fscale );
tool->m_Size.x * fscale,
tool->m_Size.y * fscale );
break;
case APERTURE::Plotting:
sprintf( text, "C,%#f*%%\n", tool->Size.x * fscale );
sprintf( text, "C,%#f*%%\n", tool->m_Size.x * fscale );
break;
case APERTURE::Oval:
sprintf( text, "O,%#fX%#f*%%\n",
tool->Size.x * fscale,
tool->Size.y * fscale );
tool->m_Size.x * fscale,
tool->m_Size.y * fscale );
break;
}
fputs( cbuf, outputFile );
m_apertureAttribute = attribute;
// Currently reset the aperture attribute. Perhaps a better optimization
// is to store the last attribute
if( attribute )
{
fputs( "%TD*%\n", outputFile );
m_apertureAttribute = 0;
}
}
}
@ -366,11 +453,11 @@ void GERBER_PLOTTER::Circle( const wxPoint& aCenter, int aDiameter, FILL_T aFill
void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
int aRadius, FILL_T aFill, int aWidth )
{
wxASSERT( outputFile );
SetCurrentLineWidth( aWidth );
wxPoint start, end;
start.x = aCenter.x + KiROUND( cosdecideg( aRadius, aStAngle ) );
start.y = aCenter.y - KiROUND( sindecideg( aRadius, aStAngle ) );
SetCurrentLineWidth( aWidth );
MoveTo( start );
end.x = aCenter.x + KiROUND( cosdecideg( aRadius, aEndAngle ) );
end.y = aCenter.y - KiROUND( sindecideg( aRadius, aEndAngle ) );
@ -392,7 +479,7 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
void GERBER_PLOTTER:: PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth )
FILL_T aFill, int aWidth, void * aData )
{
if( aCornerList.size() <= 1 )
return;
@ -400,8 +487,12 @@ void GERBER_PLOTTER:: PlotPoly( const std::vector< wxPoint >& aCornerList,
// Gerber format does not know filled polygons with thick outline
// Therefore, to plot a filled polygon with outline having a thickness,
// one should plot outline as thick segments
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( aWidth );
SetCurrentLineWidth( aWidth, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
if( aFill )
{
@ -433,31 +524,137 @@ void GERBER_PLOTTER:: PlotPoly( const std::vector< wxPoint >& aCornerList,
}
void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode )
void GERBER_PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode, void* aData )
{
if( tracemode == FILLED )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( width, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
MoveTo( start );
FinishTo( end );
}
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
segmentAsOval( start, end, width, tracemode );
}
}
void GERBER_PLOTTER::ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
int radius, int width, EDA_DRAW_MODE_T tracemode, void* aData )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( width, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
if( tracemode == FILLED )
Arc( centre, StAngle, EndAngle, radius, NO_FILL, DO_NOT_SET_LINE_WIDTH );
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
Arc( centre, StAngle, EndAngle,
radius - ( width - currentPenWidth ) / 2,
NO_FILL, DO_NOT_SET_LINE_WIDTH );
Arc( centre, StAngle, EndAngle,
radius + ( width - currentPenWidth ) / 2, NO_FILL,
DO_NOT_SET_LINE_WIDTH );
}
}
void GERBER_PLOTTER::ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
EDA_DRAW_MODE_T tracemode, void* aData )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( width, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
if( tracemode == FILLED )
Rect( p1, p2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH );
wxPoint offsetp1( p1.x - (width - currentPenWidth) / 2,
p1.y - (width - currentPenWidth) / 2 );
wxPoint offsetp2( p2.x + (width - currentPenWidth) / 2,
p2.y + (width - currentPenWidth) / 2 );
Rect( offsetp1, offsetp2, NO_FILL, -1 );
offsetp1.x += (width - currentPenWidth);
offsetp1.y += (width - currentPenWidth);
offsetp2.x -= (width - currentPenWidth);
offsetp2.y -= (width - currentPenWidth);
Rect( offsetp1, offsetp2, NO_FILL, DO_NOT_SET_LINE_WIDTH );
}
}
void GERBER_PLOTTER::ThickCircle( const wxPoint& pos, int diametre, int width,
EDA_DRAW_MODE_T tracemode, void* aData )
{
GBR_METADATA *gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( width, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
if( tracemode == FILLED )
Circle( pos, diametre, NO_FILL, DO_NOT_SET_LINE_WIDTH );
else
{
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata );
Circle( pos, diametre - (width - currentPenWidth),
NO_FILL, DO_NOT_SET_LINE_WIDTH );
Circle( pos, diametre + (width - currentPenWidth),
NO_FILL, DO_NOT_SET_LINE_WIDTH );
}
}
void GERBER_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre, EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
wxSize size( diametre, diametre );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
if( trace_mode == SKETCH )
{
SetCurrentLineWidth( -1 );
Circle( pos, diametre - currentPenWidth, NO_FILL );
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
Circle( pos, diametre - currentPenWidth, NO_FILL, DO_NOT_SET_LINE_WIDTH );
}
else
{
DPOINT pos_dev = userToDeviceCoordinates( pos );
selectAperture( size, APERTURE::Circle );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
selectAperture( size, APERTURE::Circle, aperture_attrib );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
emitDcode( pos_dev, 3 );
}
}
void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient,
EDA_DRAW_MODE_T trace_mode )
EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
int x0, y0, x1, y1, delta;
wxSize size( aSize );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
/* Plot a flashed shape. */
if( ( orient == 0 || orient == 900 || orient == 1800 || orient == 2700 )
@ -467,7 +664,12 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
std::swap( size.x, size.y );
DPOINT pos_dev = userToDeviceCoordinates( pos );
selectAperture( size, APERTURE::Oval );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
selectAperture( size, APERTURE::Oval, aperture_attrib );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
emitDcode( pos_dev, 3 );
}
else /* Plot pad as a segment. */
@ -494,9 +696,24 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
y1 = delta / 2;
RotatePoint( &x0, &y0, orient );
RotatePoint( &x1, &y1, orient );
GBR_METADATA metadata;
if( gbr_metadata )
{
metadata = *gbr_metadata;
metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
wxString attrname( ".P" );
metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
}
ThickSegment( wxPoint( pos.x + x0, pos.y + y0 ),
wxPoint( pos.x + x1, pos.y + y1 ),
size.x, trace_mode );
size.x, trace_mode, &metadata );
// Now, flash a pad anchor, if a netlist attribute is set
if( aData )
FlashPadCircle( pos, size.x, trace_mode, aData );
}
else
{
@ -507,11 +724,12 @@ void GERBER_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, doub
void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
double orient, EDA_DRAW_MODE_T trace_mode )
double orient, EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
wxSize size( aSize );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
// Plot as an aperture flash
switch( int( orient ) )
@ -525,7 +743,11 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
case 1800:
if( trace_mode == SKETCH )
{
SetCurrentLineWidth( -1 );
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, gbr_metadata );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
Rect( wxPoint( pos.x - (size.x - currentPenWidth) / 2,
pos.y - (size.y - currentPenWidth) / 2 ),
wxPoint( pos.x + (size.x - currentPenWidth) / 2,
@ -535,7 +757,12 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
else
{
DPOINT pos_dev = userToDeviceCoordinates( pos );
selectAperture( size, APERTURE::Rect );
int aperture_attrib = gbr_metadata ? gbr_metadata->GetApertureAttrib() : 0;
selectAperture( size, APERTURE::Rect, aperture_attrib );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
emitDcode( pos_dev, 3 );
}
break;
@ -559,7 +786,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
coord[3].x = size.x/2; // lower right
coord[3].y = size.y/2;
FlashPadTrapez( pos, coord, orient, trace_mode );
FlashPadTrapez( pos, coord, orient, trace_mode, aData );
}
break;
}
@ -567,7 +794,7 @@ void GERBER_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& aSize,
void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
// Currently, a Pad RoundRect is plotted as polygon.
@ -588,22 +815,50 @@ void GERBER_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aS
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL );
GBR_METADATA gbr_metadata;
if( aData )
{
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
wxString attrname( ".P" );
gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
}
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
// Now, flash a pad anchor, if a netlist attribute is set
// (remove me when a Aperture macro will be used)
if( aData && aTraceMode == FILLED )
{
int diameter = std::min( aSize.x, aSize.y );
FlashPadCircle( aPadPos, diameter, aTraceMode , aData );
}
}
void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
// A Pad custom is plotted as polygon.
#if 1
// A flashed circle @aPadPos is added (anchor pad)
// However, because the anchor pad can be circle or rect, we use only
// a circle not bigger tahn the rect.
// the main purpose is to show a flashed DCode as pad anchor
FlashPadCircle( aPadPos, std::min( aSize.x, aSize.x ), aTraceMode );
#endif
// a circle not bigger than the rect.
// the main purpose is to print a flashed DCode as pad anchor
FlashPadCircle( aPadPos, std::min( aSize.x, aSize.x ), aTraceMode, aData );
GBR_METADATA gbr_metadata;
if( aData )
{
gbr_metadata = *static_cast<GBR_METADATA*>( aData );
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
wxString attrname( ".P" );
gbr_metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
}
std::vector< wxPoint > cornerList;
@ -618,13 +873,13 @@ void GERBER_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
// Close polygon
cornerList.push_back( cornerList[0] );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL );
PlotPoly( cornerList, ( aTraceMode == FILLED ) ? FILLED_SHAPE : NO_FILL, USE_DEFAULT_LINE_WIDTH, &gbr_metadata );
}
}
void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData )
{
// Currently, a Pad Trapezoid is plotted as polygon.
@ -636,6 +891,25 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
for( int ii = 0; ii < 4; ii++ )
cornerList.push_back( aCorners[ii] );
// Now, flash a pad anchor, if a netlist attribute is set
// (remove me when a Aperture macro will be used)
if( aData && (aTrace_Mode==FILLED) )
{
// Calculate the radius of the circle inside the shape
// It is the smaller dist from shape pos to edges
int radius = INT_MAX;
for( unsigned ii = 0, jj = cornerList.size()-1; ii < cornerList.size();
jj = ii, ii++ )
{
SEG segment( aCorners[ii], aCorners[jj] );
int dist = segment.LineDistance( VECTOR2I( 0, 0) );
radius = std::min( radius, dist );
}
FlashPadCircle( aPadPos, radius*2, aTrace_Mode, aData );
}
// Draw the polygon and fill the interior as required
for( unsigned ii = 0; ii < 4; ii++ )
{
@ -645,9 +919,36 @@ void GERBER_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCo
// Close the polygon
cornerList.push_back( cornerList[0] );
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
SetCurrentLineWidth( -1 );
PlotPoly( cornerList, aTrace_Mode==FILLED ? FILLED_SHAPE : NO_FILL );
GBR_METADATA metadata;
if( gbr_metadata )
{
metadata = *gbr_metadata;
metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
wxString attrname( ".P" );
metadata.m_NetlistMetadata.ClearAttribute( &attrname ); // not allowed on inner layers
}
SetCurrentLineWidth( USE_DEFAULT_LINE_WIDTH, &metadata );
PlotPoly( cornerList, aTrace_Mode==FILLED ? FILLED_SHAPE : NO_FILL, USE_DEFAULT_LINE_WIDTH, &metadata );
}
void GERBER_PLOTTER::Text( const wxPoint& aPos, enum EDA_COLOR_T aColor,
const wxString& aText, double aOrient, const wxSize& aSize,
enum EDA_TEXT_HJUSTIFY_T aH_justify, enum EDA_TEXT_VJUSTIFY_T aV_justify,
int aWidth, bool aItalic, bool aBold, bool aMultilineAllowed,
void* aData )
{
GBR_METADATA* gbr_metadata = static_cast<GBR_METADATA*>( aData );
if( gbr_metadata )
formatNetAttribute( &gbr_metadata->m_NetlistMetadata );
PLOTTER::Text( aPos, aColor, aText, aOrient, aSize,
aH_justify, aV_justify, aWidth, aItalic, aBold, aMultilineAllowed, aData );
}

View File

@ -315,7 +315,7 @@ void HPGL_PLOTTER::Circle( const wxPoint& centre, int diameter, FILL_T fill,
*/
void HPGL_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
FILL_T aFill, int aWidth )
FILL_T aFill, int aWidth, void * aData )
{
if( aCornerList.size() <= 1 )
return;
@ -433,7 +433,7 @@ void HPGL_PLOTTER::SetDash( bool dashed )
void HPGL_PLOTTER::ThickSegment( const wxPoint& start, const wxPoint& end,
int width, EDA_DRAW_MODE_T tracemode )
int width, EDA_DRAW_MODE_T tracemode, void* aData )
{
wxASSERT( outputFile );
wxPoint center;
@ -496,7 +496,7 @@ void HPGL_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
/* Plot oval pad.
*/
void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double orient,
EDA_DRAW_MODE_T trace_mode )
EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
int deltaxy, cx, cy;
@ -516,13 +516,13 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
if( trace_mode == FILLED )
{
FlashPadRect( pos, wxSize( size.x, deltaxy + KiROUND( penDiameter ) ),
orient, trace_mode );
orient, trace_mode, aData );
cx = 0; cy = deltaxy / 2;
RotatePoint( &cx, &cy, orient );
FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode );
FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode, aData );
cx = 0; cy = -deltaxy / 2;
RotatePoint( &cx, &cy, orient );
FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode );
FlashPadCircle( wxPoint( cx + pos.x, cy + pos.y ), size.x, trace_mode, aData );
}
else // Plot in outline mode.
{
@ -534,7 +534,7 @@ void HPGL_PLOTTER::FlashPadOval( const wxPoint& pos, const wxSize& aSize, double
/* Plot round pad or via.
*/
void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode )
EDA_DRAW_MODE_T trace_mode, void* aData )
{
wxASSERT( outputFile );
DPOINT pos_dev = userToDeviceCoordinates( pos );
@ -574,7 +574,7 @@ void HPGL_PLOTTER::FlashPadCircle( const wxPoint& pos, int diametre,
void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
double orient, EDA_DRAW_MODE_T trace_mode )
double orient, EDA_DRAW_MODE_T trace_mode, void* aData )
{
// Build rect polygon:
std::vector<wxPoint> corners;
@ -611,7 +611,7 @@ void HPGL_PLOTTER::FlashPadRect( const wxPoint& pos, const wxSize& padsize,
void HPGL_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 32;
@ -647,7 +647,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,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
std::vector< wxPoint > cornerList;
@ -667,7 +667,7 @@ void HPGL_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
void HPGL_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint* aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode )
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData )
{
std::vector< wxPoint > cornerList;
cornerList.reserve( 4 );

View File

@ -94,7 +94,7 @@ void PDF_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
* no outline thickness
* use in this case pen width = 1 does not actally change the polygon
*/
void PDF_PLOTTER::SetCurrentLineWidth( int width )
void PDF_PLOTTER::SetCurrentLineWidth( int width, void* aData )
{
wxASSERT( workFile );
int pen_width;
@ -263,7 +263,7 @@ void PDF_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
* Polygon plotting for PDF. Everything is supported
*/
void PDF_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth )
FILL_T aFill, int aWidth, void * aData )
{
wxASSERT( workFile );
if( aCornerList.size() <= 1 )
@ -756,7 +756,8 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed )
bool aMultilineAllowed,
void* aData )
{
// PDF files do not like 0 sized texts which create broken files.
if( aSize.x == 0 || aSize.y == 0 )
@ -781,7 +782,7 @@ void PDF_PLOTTER::Text( const wxPoint& aPos,
&ctm_d, &ctm_e, &ctm_f, &heightFactor );
SetColor( aColor );
SetCurrentLineWidth( aWidth );
SetCurrentLineWidth( aWidth, aData );
/* We use the full CTM instead of the text matrix because the same
coordinate system will be used for the overlining. Also the %f

View File

@ -90,7 +90,7 @@ void PSLIKE_PLOTTER::SetColor( EDA_COLOR_T color )
void PSLIKE_PLOTTER::FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode )
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData )
{
wxASSERT( outputFile );
int x0, y0, x1, y1, delta;
@ -113,14 +113,14 @@ void PSLIKE_PLOTTER::FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize,
if( aTraceMode == FILLED )
ThickSegment( wxPoint( aPadPos.x + x0, aPadPos.y + y0 ),
wxPoint( aPadPos.x + x1, aPadPos.y + y1 ), size.x, aTraceMode );
wxPoint( aPadPos.x + x1, aPadPos.y + y1 ), size.x, aTraceMode, NULL );
else
sketchOval( aPadPos, size, aPadOrient, -1 );
}
void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
if( aTraceMode == FILLED )
Circle( aPadPos, aDiameter, FILLED_SHAPE, 0 );
@ -141,7 +141,7 @@ void PSLIKE_PLOTTER::FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode )
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData )
{
static std::vector< wxPoint > cornerList;
wxSize size( aSize );
@ -191,7 +191,7 @@ void PSLIKE_PLOTTER::FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
void PSLIKE_PLOTTER::FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
wxSize size( aSize );
@ -228,7 +228,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,
EDA_DRAW_MODE_T aTraceMode )
EDA_DRAW_MODE_T aTraceMode, void* aData )
{
wxSize size( aSize );
@ -261,7 +261,7 @@ void PSLIKE_PLOTTER::FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize
}
void PSLIKE_PLOTTER::FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode )
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData )
{
static std::vector< wxPoint > cornerList;
cornerList.clear();
@ -515,7 +515,7 @@ void PSLIKE_PLOTTER::computeTextParameters( const wxPoint& aPos,
/* Set the current line width (in IUs) for the next plot
*/
void PS_PLOTTER::SetCurrentLineWidth( int width )
void PS_PLOTTER::SetCurrentLineWidth( int width, void* aData )
{
wxASSERT( outputFile );
int pen_width;
@ -614,7 +614,7 @@ void PS_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle,
void PS_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth )
FILL_T aFill, int aWidth, void * aData )
{
if( aCornerList.size() <= 1 )
return;
@ -936,7 +936,8 @@ void PS_PLOTTER::Text( const wxPoint& aPos,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed )
bool aMultilineAllowed,
void* aData )
{
SetCurrentLineWidth( aWidth );
SetColor( aColor );

View File

@ -244,7 +244,7 @@ void SVG_PLOTTER::setSVGPlotStyle()
/* Set the current line width (in IUs) for the next plot
*/
void SVG_PLOTTER::SetCurrentLineWidth( int width )
void SVG_PLOTTER::SetCurrentLineWidth( int width, void* aData )
{
int pen_width;
@ -439,7 +439,7 @@ void SVG_PLOTTER::Arc( const wxPoint& centre, double StAngle, double EndAngle, i
void SVG_PLOTTER::PlotPoly( const std::vector<wxPoint>& aCornerList,
FILL_T aFill, int aWidth )
FILL_T aFill, int aWidth, void * aData )
{
if( aCornerList.size() <= 1 )
return;
@ -611,7 +611,8 @@ void SVG_PLOTTER::Text( const wxPoint& aPos,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed )
bool aMultilineAllowed,
void* aData )
{
setFillMode( NO_FILL );
SetColor( aColor );

View File

@ -206,7 +206,7 @@ void DrawGraphicHaloText( EDA_RECT* aClipBox, wxDC * aDC,
}
/**
* Function PlotGraphicText
* Function PLOTTER::Text
* same as DrawGraphicText, but plot graphic text insteed of draw it
* @param aPos = text position (according to aH_justify, aV_justify)
* @param aColor (enum EDA_COLOR_T) = text color
@ -232,7 +232,8 @@ void PLOTTER::Text( const wxPoint& aPos,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed )
bool aMultilineAllowed,
void* aData )
{
int textPensize = aWidth;
@ -244,7 +245,7 @@ void PLOTTER::Text( const wxPoint& aPos,
else
textPensize = -Clamp_Text_PenSize( -aWidth, aSize, aBold );
SetCurrentLineWidth( textPensize );
SetCurrentLineWidth( textPensize, aData );
if( aColor >= 0 )
SetColor( aColor );
@ -255,5 +256,5 @@ void PLOTTER::Text( const wxPoint& aPos,
textPensize, aItalic, aBold, NULL, this );
if( aWidth != textPensize )
SetCurrentLineWidth( aWidth );
SetCurrentLineWidth( aWidth, aData );
}

291
common/gbr_metadata.cpp Normal file
View File

@ -0,0 +1,291 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see CHANGELOG.TXT for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @file gbr_metadata.cpp
* @brief helper functions to handle the gerber metadata in files,
* related to the netlist info and aperture attribute.
*/
#include <fctsys.h>
#include <plot_auxiliary_data.h>
std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribute )
{
std::string attribute_string;
// generate a string to print a Gerber Aperture attribute
switch( aAttribute )
{
case GBR_APERTURE_ATTRIB_END: // Dummy value (aAttribute must be < GBR_APERTURE_ATTRIB_END)
case GBR_APERTURE_ATTRIB_NONE: // idle command: do nothing
break;
case GBR_APERTURE_ATTRIB_ETCHEDCMP: // print info associated to an item
// which connects 2 different nets
// (Net tees, microwave component)
attribute_string = "%TA.AperFunction,EtchedComponent*%\n";
break;
case GBR_APERTURE_ATTRIB_CONDUCTOR: // print info associated to a track
attribute_string = "%TA.AperFunction,Conductor*%\n";
break;
case GBR_APERTURE_ATTRIB_CUTOUT: // print info associated to a outline
attribute_string = "%TA.AperFunction,CutOut*%\n";
break;
case GBR_APERTURE_ATTRIB_VIAPAD: // print info associated to a flashed via
attribute_string = "%TA.AperFunction,ViaPad*%\n";
break;
case GBR_APERTURE_ATTRIB_NONCONDUCTOR: // print info associated to a flashed pad
attribute_string = "%TA.AperFunction,NonConductor*%\n";
break;
case GBR_APERTURE_ATTRIB_COMPONENTPAD: // print info associated to a flashed
// through hole component on outer layer
attribute_string = "%TA.AperFunction,ComponentPad*%\n";
break;
case GBR_APERTURE_ATTRIB_SMDPAD_SMDEF: // print info associated to a flashed for SMD pad.
// with solder mask defined from the copper shape
// Excluded BGA pads which have their own type
attribute_string = "%TA.AperFunction,SMDPad,SMDef*%\n";
break;
case GBR_APERTURE_ATTRIB_SMDPAD_CUDEF: // print info associated to a flashed SMD pad with
// a solder mask defined by the solder mask
attribute_string = "%TA.AperFunction,SMDPad,CuDef*%\n";
break;
case GBR_APERTURE_ATTRIB_BGAPAD_SMDEF: // print info associated to flashed BGA pads with
// a solder mask defined by the copper shape
attribute_string = "%TA.AperFunction,BGAPad,SMDef*%\n";
break;
case GBR_APERTURE_ATTRIB_BGAPAD_CUDEF: // print info associated to a flashed BGA pad with
// a solder mask defined by the solder mask
attribute_string = "%TA.AperFunction,BGAPad,CuDef*%\n";
break;
case GBR_APERTURE_ATTRIB_CONNECTORPAD: // print info associated to a flashed edge connector pad (outer layers)
attribute_string = "%TA.AperFunction,ConnectorPad*%\n";
break;
case GBR_APERTURE_ATTRIB_WASHERPAD: // print info associated to flashed mechanical pads (NPTH)
attribute_string = "%TA.AperFunction,WasherPad*%\n";
break;
case GBR_APERTURE_ATTRIB_HEATSINKPAD: // print info associated to a flashed heat sink pad (typically for SMDs)
attribute_string = "%TA.AperFunction,HeatsinkPad*%\n";
break;
}
return attribute_string;
}
std::string formatStringToGerber( const wxString& aString )
{
/* format string means convert any code > 0x7F and unautorized code to a hexadecimal
* 16 bits sequence unicode
* unautorized codes are ',' '*' '%' '\'
*/
std::string txt;
txt.reserve( aString.Length() );
for( unsigned ii = 0; ii < aString.Length(); ++ii )
{
unsigned code = aString[ii];
bool convert = false;
switch( code )
{
case '\\':
case '%':
case '*':
case ',':
convert = true;
break;
default:
break;
}
if( convert || code > 0x7F )
{
txt += '\\';
// Convert code to 4 hexadecimal digit
// (Gerber allows only 4 hexadecimal digit)
char hexa[32];
sprintf( hexa,"%4.4X", code & 0xFFFF);
txt += hexa;
}
else
txt += char( code );
}
return txt;
}
// Netname and Pan num fields cannot be empty in Gerber files
// Normalized names must be used, if any
#define NO_NET_NAME wxT( "N/C" ) // net name of not connected pads (one pad net) (normalized)
#define NO_PAD_NAME wxT( "" ) // pad name of pads without pad name/number (not normalized)
bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes )
{
aClearPreviousAttributes = false;
// print a Gerber net attribute record.
// it is added to the object attributes dictionnary
// On file, only modified or new attributes are printed.
if( aData == NULL )
return false;
std::string pad_attribute_string;
std::string net_attribute_string;
std::string cmp_attribute_string;
if( aData->m_NetAttribType == GBR_NETLIST_METADATA::GBR_NETINFO_UNSPECIFIED )
return false; // idle command: do nothing
if( ( aData->m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) )
{
// print info associated to a flashed pad (cmpref, pad name)
// example: %TO.P,R5,3*%
pad_attribute_string = "%TO.P,";
pad_attribute_string += formatStringToGerber( aData->m_Cmpref ) + ",";
if( aData->m_Padname.IsEmpty() )
// Happens for "mechanical" or never connected pads
pad_attribute_string += formatStringToGerber( NO_PAD_NAME );
else
pad_attribute_string += formatStringToGerber( aData->m_Padname );
pad_attribute_string += "*%\n";
}
if( ( aData->m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_NET ) )
{
// print info associated to a net
// example: %TO.N,Clk3*%
net_attribute_string = "%TO.N,";
if( aData->m_Netname.IsEmpty() )
{
if( aData->m_NotInNet )
{
// Happens for not connectable pads: mechanical pads
// and pads with no padname/num
// In this case the net name must be left empty
}
else
{
// Happens for not connected pads: use a normalized
// dummy name
net_attribute_string += formatStringToGerber( NO_NET_NAME );
}
}
else
net_attribute_string += formatStringToGerber( aData->m_Netname );
net_attribute_string += "*%\n";
}
if( ( aData->m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_CMP ) &&
!( aData->m_NetAttribType & GBR_NETLIST_METADATA::GBR_NETINFO_PAD ) )
{
// print info associated to a footprint
// example: %TO.C,R2*%
// Because GBR_NETINFO_PAD option already contains this info, it is not
// created here for a GBR_NETINFO_PAD attribute
cmp_attribute_string = "%TO.C,";
cmp_attribute_string += formatStringToGerber( aData->m_Cmpref ) + "*%\n";
}
// the full list of requested attributes:
std::string full_attribute_string = pad_attribute_string + net_attribute_string
+ cmp_attribute_string;
// the short list of requested attributes
// (only modified or new attributes are stored here):
std::string short_attribute_string;
if( aLastNetAttributes != full_attribute_string )
{
// first, remove no more existing attributes.
// Because in Kicad the full attribute list is evaluated for each object,
// the entire dictionnary is cleared
bool clearDict = false;
if( aLastNetAttributes.find( "%TO.P," ) != std::string::npos )
{
if( pad_attribute_string.empty() ) // No more this attribute
clearDict = true;
else if( aLastNetAttributes.find( pad_attribute_string )
== std::string::npos ) // This attribute has changed
short_attribute_string += pad_attribute_string;
}
else // New attribute
short_attribute_string += pad_attribute_string;
if( aLastNetAttributes.find( "%TO.N," ) != std::string::npos )
{
if( net_attribute_string.empty() ) // No more this attribute
clearDict = true;
else if( aLastNetAttributes.find( net_attribute_string )
== std::string::npos ) // This attribute has changed
short_attribute_string += net_attribute_string;
}
else // New attribute
short_attribute_string += net_attribute_string;
if( aLastNetAttributes.find( "%TO.C," ) != std::string::npos )
{
if( cmp_attribute_string.empty() ) // No more this attribute
clearDict = true;
else if( aLastNetAttributes.find( cmp_attribute_string )
== std::string::npos ) // This attribute has changed
short_attribute_string += cmp_attribute_string;
}
else // New attribute
short_attribute_string += cmp_attribute_string;
aClearPreviousAttributes = clearDict;
aLastNetAttributes = full_attribute_string;
if( clearDict )
aPrintedText = full_attribute_string;
else
aPrintedText = short_attribute_string;
}
return true;
}

View File

@ -665,6 +665,13 @@ LSET LSET::AllNonCuMask()
}
LSET LSET::ExternalCuMask()
{
static const LSET saved( 2, F_Cu, B_Cu );
return saved;
}
LSET LSET::AllLayersMask()
{
static const LSET saved = LSET().set();
@ -674,20 +681,30 @@ LSET LSET::AllLayersMask()
LSET LSET::BackTechMask()
{
// (SILKSCREEN_LAYER_BACK | SOLDERMASK_LAYER_BACK | ADHESIVE_LAYER_BACK | SOLDERPASTE_LAYER_BACK)
static const LSET saved( 6, B_SilkS, B_Mask, B_Adhes, B_Paste, B_CrtYd, B_Fab );
return saved;
}
LSET LSET::BackBoardTechMask()
{
static const LSET saved( 4, B_SilkS, B_Mask, B_Adhes, B_Paste );
return saved;
}
LSET LSET::FrontTechMask()
{
// (SILKSCREEN_LAYER_FRONT | SOLDERMASK_LAYER_FRONT | ADHESIVE_LAYER_FRONT | SOLDERPASTE_LAYER_FRONT)
static const LSET saved( 6, F_SilkS, F_Mask, F_Adhes, F_Paste, F_CrtYd, F_Fab );
return saved;
}
LSET LSET::FrontBoardTechMask()
{
static const LSET saved( 4, F_SilkS, F_Mask, F_Adhes, F_Paste );
return saved;
}
LSET LSET::AllTechMask()
{
static const LSET saved = BackTechMask() | FrontTechMask();
@ -695,6 +712,13 @@ LSET LSET::AllTechMask()
}
LSET LSET::AllBoardTechMask()
{
static const LSET saved = BackBoardTechMask() | FrontBoardTechMask();
return saved;
}
LSET LSET::UserMask()
{
static const LSET saved( 6,

View File

@ -28,3 +28,4 @@ useauxorigin
usegerberextensions
viasonmask
usegerberattributes
usegerberadvancedattributes

View File

@ -270,6 +270,12 @@ public:
*/
static LSET AllCuMask( int aCuLayerCount = MAX_CU_LAYERS );
/**
* Function ExternalCuMask
* returns a mask holding the Front and Bottom layers.
*/
static LSET ExternalCuMask();
/**
* Function AllNonCuMask
* returns a mask holding all layer minus CU layers.
@ -284,13 +290,38 @@ public:
*/
static LSET FrontTechMask();
/**
* Function FrontBoardTechMask
* returns a mask holding technical layers used in a board fabrication
* (no CU layer) on front side.
*/
static LSET FrontBoardTechMask();
/**
* Function BackTechMask
* returns a mask holding all technical layers (no CU layer) on back side.
*/
static LSET BackTechMask();
/**
* Function BackBoardTechMask
* returns a mask holding technical layers used in a board fabrication
* (no CU layer) on Back side.
*/
static LSET BackBoardTechMask();
/**
* Function AllTechMask
* returns a mask holding all technical layers (no CU layer) on both side.
*/
static LSET AllTechMask();
/**
* Function AllTechMask
* returns a mask holding board technical layers (no CU layer) on both side.
*/
static LSET AllBoardTechMask();
/**
* Function FrontMask
* returns a mask holding all technical layers and the external CU layer on front side.

View File

@ -0,0 +1,154 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* a class to handle special data during plot.
* used in Gerber plotter to generate auxiliary data during plot
* (for instance info associated to flashed pads)
*
* @file plot_extra_data.h
*/
#ifndef PLOT_EXTRA_DATA_H
#define PLOT_EXTRA_DATA_H
#include <gbr_netlist_metadata.h>
// this class handle info which can be added in a gerber file as attribute
// of an aperture, by the %TA.AperFunction command
// This attribute is added when creating a new aperture (command %ADDxx)
// Only one aperture attribute can be added to a given aperture
//
class GBR_APERTURE_METADATA
{
public:
enum GBR_APERTURE_ATTRIB
{
GBR_APERTURE_ATTRIB_NONE, ///< uninitialized attribute
GBR_APERTURE_ATTRIB_ETCHEDCMP, ///< aperture used for etched components
GBR_APERTURE_ATTRIB_CONDUCTOR, ///< aperture used for connected items like tracks (not vias)
GBR_APERTURE_ATTRIB_CUTOUT, ///< aperture used for board cutout
GBR_APERTURE_ATTRIB_NONCONDUCTOR, ///< aperture used for not connected items (texts, outlines on copper)
GBR_APERTURE_ATTRIB_VIAPAD, ///< aperture used for vias
GBR_APERTURE_ATTRIB_COMPONENTPAD, ///< aperture used for through hole component on outer layer
GBR_APERTURE_ATTRIB_SMDPAD_SMDEF, ///< aperture used for SMD pad. Excluded BGA pads which have their own type
GBR_APERTURE_ATTRIB_SMDPAD_CUDEF, ///< aperture used for SMD pad with a solder mask defined by the solder mask
GBR_APERTURE_ATTRIB_BGAPAD_SMDEF, ///< aperture used for BGA pads with a solder mask defined by the copper shape
GBR_APERTURE_ATTRIB_BGAPAD_CUDEF, ///< aperture used for BGA pad with a solder mask defined by the solder mask
GBR_APERTURE_ATTRIB_CONNECTORPAD, ///< aperture used for edge connecto pad (outer layers)
GBR_APERTURE_ATTRIB_WASHERPAD, ///< aperture used for mechanical pads (NPTH)
GBR_APERTURE_ATTRIB_HEATSINKPAD, ///< aperture used for heat sink pad (typically for SMDs)
GBR_APERTURE_ATTRIB_END ///< sentinel: max value
};
GBR_APERTURE_METADATA()
:m_ApertAttribute( GBR_APERTURE_ATTRIB_NONE )
{}
/**
* @return the string corresponding to the aperture attribute
*/
static std::string GetAttributeName( GBR_APERTURE_ATTRIB aAttribute );
std::string GetAttributeName()
{
return GetAttributeName( m_ApertAttribute );
}
/**
* @return the full command string corresponding to the aperture attribute
* like "%TA.AperFunction,<function>*%"
*/
static std::string FormatAttribute( GBR_APERTURE_ATTRIB aAttribute );
std::string FormatAttribute()
{
return FormatAttribute( m_ApertAttribute );
}
// The id of the aperture attribute
GBR_APERTURE_ATTRIB m_ApertAttribute;
};
// this class handle metadata which can be added in a gerber file as attribute
// in X2 format
class GBR_METADATA
{
public:
GBR_METADATA() {}
void SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB aApertAttribute )
{
m_ApertureMetadata.m_ApertAttribute = aApertAttribute;
}
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB GetApertureAttrib()
{
return m_ApertureMetadata.m_ApertAttribute;
}
void SetNetAttribType( int aNetAttribType )
{
m_NetlistMetadata.m_NetAttribType = aNetAttribType;
}
int GetNetAttribType() const
{
return m_NetlistMetadata.m_NetAttribType;
}
void SetNetName( const wxString& aNetname ) { m_NetlistMetadata.m_Netname = aNetname; }
void SetPadName( const wxString& aPadname ) { m_NetlistMetadata.m_Padname = aPadname; }
void SetCmpReference( const wxString& aComponentRef ) { m_NetlistMetadata.m_Cmpref = aComponentRef; }
GBR_APERTURE_METADATA m_ApertureMetadata;
GBR_NETLIST_METADATA m_NetlistMetadata;
};
/**
* This helper function "normalize" aString and convert it to a Gerber std::string
* Normalisation means convert any code > 0x7F and unautorized code to a hexadecimal
* 16 bits sequence unicode
* unautorized codes are ',' '*' '%' '\'
* @param aString = the wxString to convert
* @return a std::string (ASCII7 coded) compliant with a gerber string
*/
std::string formatStringToGerber( const wxString& aString );
/**
* Generates the string to print to a gerber file, to set a net attribute
* for a graphic object.
* @param aPrintedText is the string to print
* @param aLastNetAttributes is the current full set of attributes.
* @param aClearPreviousAttributes returns true if the full set of attributes
* must be deleted from file before adding new attribute (happens when a previous
* attribute does not exist no more).
* @return false if nothing can be done (GBR_NETLIST_METADATA has GBR_APERTURE_ATTRIB_NONE,
* and true if OK
* if the new attribute(s) is the same as current attribute(s), aPrintedText
* will be empty
*/
bool FormatNetAttribute( std::string& aPrintedText, std::string& aLastNetAttributes,
GBR_NETLIST_METADATA* aData, bool& aClearPreviousAttributes );
#endif // PLOT_EXTRA_DATA_H

View File

@ -1,8 +1,8 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 KiCad Developers, see CHANGELOG.TXT for contributors.
* Copyright (C) 2016 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -39,6 +39,7 @@
#include <eda_text.h> // FILL_T
class SHAPE_POLY_SET;
class GBR_NETLIST_METADATA;
/**
* Enum PlotFormat
@ -89,7 +90,9 @@ private:
double m_dashGapLength_mm; ///< Dashed line parameter in mm: gap
public:
static const int USE_DEFAULT_LINE_WIDTH = -1;
// These values are used as flag for pen or aperture selection
static const int DO_NOT_SET_LINE_WIDTH = -2; // Skip selection
static const int USE_DEFAULT_LINE_WIDTH = -1; // use the default pen
PLOTTER();
@ -125,8 +128,9 @@ public:
/**
* Set the line width for the next drawing.
* @param width is specified in IUs
* @param aData is an auxiliary parameter, mainly used in gerber plotter
*/
virtual void SetCurrentLineWidth( int width ) = 0;
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) = 0;
/**
* Set the default line width. Used at the beginning and when a width
@ -247,9 +251,10 @@ public:
* @param aCornerList = corners list
* @param aFill = type of fill
* @param aWidth = line width
* @param aData an auxiliary info (mainly for gerber format)
*/
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList, FILL_T aFill,
int aWidth = USE_DEFAULT_LINE_WIDTH ) = 0;
int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ) = 0;
/**
* Function PlotImage
@ -266,21 +271,51 @@ public:
// Higher level primitives -- can be drawn as line, sketch or 'filled'
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode );
EDA_DRAW_MODE_T tracemode, void* aData );
virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, int width, EDA_DRAW_MODE_T tracemode );
int rayon, int width, EDA_DRAW_MODE_T tracemode, void* aData );
virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
EDA_DRAW_MODE_T tracemode );
EDA_DRAW_MODE_T tracemode, void* aData );
virtual void ThickCircle( const wxPoint& pos, int diametre, int width,
EDA_DRAW_MODE_T tracemode );
EDA_DRAW_MODE_T tracemode, void* aData );
// Flash primitives
/**
* virtual function FlashPadCircle
* @param aPadPos Position of the shape (center of the rectangle
* @param aSize = size of rounded rect
* @param cornerRadius Radius of the rounded corners
* @param aOrient The rotation of the shape
* @param aTraceMode FILLED or SKETCH
* @param aData an auxiliary info (mainly for gerber format)
*/
virtual void FlashPadCircle( const wxPoint& aPadPos, int aDiameter,
EDA_DRAW_MODE_T aTraceMode ) = 0;
EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/**
* virtual function FlashPadOval
* @param aPadPos Position of the shape (center of the rectangle
* @param aSize = size of rounded rect
* @param cornerRadius Radius of the rounded corners
* @param aOrient The rotation of the shape
* @param aTraceMode FILLED or SKETCH
* @param aData an auxiliary info (mainly for gerber format)
*/
virtual void FlashPadOval( const wxPoint& aPadPos, const wxSize& aSize, double aPadOrient,
EDA_DRAW_MODE_T aTraceMode ) = 0;
EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/**
* virtual function FlashPadRect
* @param aPadPos Position of the shape (center of the rectangle
* @param aSize = size of rounded rect
* @param cornerRadius Radius of the rounded corners
* @param aOrient The rotation of the shape
* @param aTraceMode FILLED or SKETCH
* @param aData an auxuliary info (mainly for gerber format)
*/
virtual void FlashPadRect( const wxPoint& aPadPos, const wxSize& aSize,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode ) = 0;
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/**
* virtual function FlashPadRoundRect
@ -289,10 +324,11 @@ public:
* @param cornerRadius Radius of the rounded corners
* @param aOrient The rotation of the shape
* @param aTraceMode FILLED or SKETCH
* @param aData an auxiliary info (mainly for gerber format)
*/
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode ) = 0;
EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/**
* virtual function FlashPadCustom
@ -300,10 +336,11 @@ public:
* @param aSize = size of round reference pad
* @param aPolygons the shape as polygon set
* @param aTraceMode FILLED or SKETCH
* @param aData an auxiliary info (mainly for gerber format)
*/
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode ) = 0;
EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/** virtual function FlashPadTrapez
* flash a trapezoidal pad
@ -314,11 +351,12 @@ public:
* @param aTrace_Mode = FILLED or SKETCH
*/
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTraceMode ) = 0;
double aPadOrient, EDA_DRAW_MODE_T aTraceMode, void* aData ) = 0;
/**
* Draws text with the plotter. For convenience it accept the color to use
* for specific plotters (GERBER) aData is used to pass extra parameters
*/
virtual void Text( const wxPoint& aPos,
enum EDA_COLOR_T aColor,
@ -330,7 +368,8 @@ public:
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false );
bool aMultilineAllowed = false,
void* aData = NULL );
/**
* Draw a marker (used for the drill map)
@ -373,6 +412,25 @@ public:
// NOP for most plotters. Only for Gerber plotter
}
/**
* calling this function allows to define the beginning of a group
* of drawing items, for instance in SVG or Gerber format.
* (example: group all segments of a letter or a text)
* @param aData can define any parameter
* for most of plotters: do nothing
*/
virtual void StartBlock( void* aData ) {}
/**
* calling this function allows to define the end of a group of drawing items
* for instance in SVG or Gerber format.
* the group is started by StartBlock()
* @param aData can define any parameter
* for most of plotters: do nothing
*/
virtual void EndBlock( void* aData ) {}
protected:
// These are marker subcomponents
/**
@ -508,7 +566,7 @@ public:
virtual bool EndPlot();
/// HPGL doesn't handle line thickness or color
virtual void SetCurrentLineWidth( int width )
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override
{
// This is the truth
currentPenWidth = userToDeviceSize( penDiameter );
@ -538,27 +596,28 @@ public:
virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
int width = USE_DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH);
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
void * aData = NULL) override;
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode );
EDA_DRAW_MODE_T tracemode, void* aData ) override;
virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void PenTo( const wxPoint& pos, char plume );
virtual void FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) override;
protected:
void penControl( char plume );
@ -603,19 +662,19 @@ public:
// Pad routines are handled with lower level primitives
virtual void FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) override;
/** The SetColor implementation is split with the subclasses:
* The PSLIKE computes the rgb values, the subclass emits the
@ -685,7 +744,7 @@ public:
virtual bool StartPlot();
virtual bool EndPlot();
virtual void SetCurrentLineWidth( int width );
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
virtual void SetDash( bool dashed );
virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
@ -698,7 +757,8 @@ public:
int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
void * aData = NULL ) override;
virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
double aScaleFactor );
@ -714,7 +774,8 @@ public:
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false );
bool aMultilineAllowed = false,
void* aData = NULL ) override;
protected:
virtual void emitSetRGBColor( double r, double g, double b );
};
@ -753,7 +814,7 @@ public:
virtual bool EndPlot();
virtual void StartPage();
virtual void ClosePage();
virtual void SetCurrentLineWidth( int width );
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
virtual void SetDash( bool dashed );
/** PDF can have multiple pages, so SetPageSettings can be called
@ -769,7 +830,8 @@ public:
int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH);
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
void * aData = NULL ) override;
virtual void PenTo( const wxPoint& pos, char plume );
@ -783,7 +845,8 @@ public:
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false );
bool aMultilineAllowed = false,
void* aData = NULL ) override;
virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
double aScaleFactor );
@ -824,7 +887,7 @@ public:
virtual void SetColor( EDA_COLOR_T color );
virtual bool StartPlot();
virtual bool EndPlot();
virtual void SetCurrentLineWidth( int width );
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
virtual void SetDash( bool dashed );
virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
@ -837,7 +900,8 @@ public:
int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
void * aData = NULL ) override;
virtual void PlotImage( const wxImage& aImage, const wxPoint& aPos,
double aScaleFactor );
@ -853,7 +917,8 @@ public:
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false );
bool aMultilineAllowed = false,
void* aData = NULL ) override;
protected:
FILL_T m_fillMode; // true if the current contour
@ -892,8 +957,9 @@ protected:
/* Class to handle a D_CODE when plotting a board : */
#define FIRST_DCODE_VALUE 10 // D_CODE < 10 is a command, D_CODE >= 10 is a tool
struct APERTURE
class APERTURE
{
public:
enum APERTURE_TYPE {
Circle = 1,
Rect = 2,
@ -901,12 +967,12 @@ struct APERTURE
Oval = 4
};
wxSize Size; // horiz and Vert size
APERTURE_TYPE Type; // Type ( Line, rect , circulaire , ovale .. )
int DCode; // code number ( >= 10 );
/* Trivia question: WHY Gerber decided to use D instead of the usual T for
* tool change? */
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
};
@ -932,7 +998,7 @@ public:
*/
virtual bool StartPlot();
virtual bool EndPlot();
virtual void SetCurrentLineWidth( int width );
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override;
virtual void SetDefaultLineWidth( int width );
// RS274X has no dashing, nor colours
@ -948,34 +1014,56 @@ public:
virtual void Arc( const wxPoint& aCenter, double aStAngle, double aEndAngle,
int aRadius, FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode, void* aData ) override;
virtual void ThickArc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, int width, EDA_DRAW_MODE_T tracemode, void* aData ) override;
virtual void ThickRect( const wxPoint& p1, const wxPoint& p2, int width,
EDA_DRAW_MODE_T tracemode, void* aData ) override;
virtual void ThickCircle( const wxPoint& pos, int diametre, int width,
EDA_DRAW_MODE_T tracemode, void* aData ) override;
/**
* Gerber polygon: they can (and *should*) be filled with the
* appropriate G36/G37 sequence
*/
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH,
void * aData = NULL ) override;
virtual void PenTo( const wxPoint& pos, char plume );
virtual void Text( const wxPoint& aPos,
enum EDA_COLOR_T aColor,
const wxString& aText,
double aOrient,
const wxSize& aSize,
enum EDA_TEXT_HJUSTIFY_T aH_justify,
enum EDA_TEXT_VJUSTIFY_T aV_justify,
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false,
void* aData = NULL ) override;
/**
* Filled circular flashes are stored as apertures
*/
virtual void FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T 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,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T 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,
double orient, EDA_DRAW_MODE_T trace_mode );
double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
/**
* Roundrect pad at the moment are not handled as aperture, since
@ -984,17 +1072,17 @@ public:
*/
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T 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, EDA_DRAW_MODE_T aTrace_Mode );
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) override;
/**
* Change the plot polarity and begin a new layer
@ -1014,8 +1102,32 @@ public:
*/
virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false );
void UseX2Attributes( bool aEnable ) { m_useX2Attributes = aEnable; }
void UseX2NetAttributes( bool aEnable ) { m_useNetAttributes = aEnable; }
/**
* calling this function allows to define the beginning of a group
* of drawing items (used in X2 format with netlist attributes)
* @param aData can define any parameter
*/
virtual void StartBlock( void* aData ) override;
/**
* calling this function allows to define the end of a group of drawing items
* the group is started by StartBlock()
* (used in X2 format with netlist attributes)
* @param aData can define any parameter
*/
virtual void EndBlock( void* aData ) override;
protected:
void selectAperture( const wxSize& size, APERTURE::APERTURE_TYPE type );
/**
* Pick an existing aperture or create a new one, matching the
* size, type and attributes.
* write the DCode selection on gerber file
*/
void selectAperture( const wxSize& aSize, APERTURE::APERTURE_TYPE aType,
int aApertureAttribute );
/**
* Emit a D-Code record, using proper conversions
@ -1024,8 +1136,43 @@ protected:
*/
void emitDcode( const DPOINT& pt, int dcode );
std::vector<APERTURE>::iterator
getAperture( const wxSize& size, APERTURE::APERTURE_TYPE type );
/**
* print a Gerber net attribute object record.
* In a gerber file, a net attribute is owned by a graphic object
* formatNetAttribute must be called before creating the object
* @param aData contains the dato to format.
* the generated string depends on the type of netlist info
*/
void formatNetAttribute( GBR_NETLIST_METADATA* aData );
/**
* clear a Gerber net attribute record (clear object attribute dictionnary)
* and output the clear object attribute dictionnary command to gerber file
*/
void clearNetAttribute();
/**
* Function getAperture returns a reference to the aperture which meets the size anf type of tool
* if the aperture does not exist, it is created and entered in aperture list
* @param aSize = the size of tool
* @param aType = the type ( shape ) of tool
* @param aApertureAttribute = an aperture attribute of the tool (a tool can have onlu one attribute)
* 0 = no specific attribute
*/
std::vector<APERTURE>::iterator getAperture( const wxSize& aSize,
APERTURE::APERTURE_TYPE aType, int aApertureAttribute );
// the attributes dictionnary created/modifed by %TO, attached the objects, when they are created
// by D01, D03 G36/G37 commands
// standard attributes are .P, .C and .N
// this is used by gerber readers when creating a new object. Cleared by %TD command
// Note: m_objectAttributesDictionnary can store more than one attribute
// the string stores the line(s) actually written to the gerber file
// it can store a .P, .C or .N attribute, or 2 or 3 attributes, separated by a \n char (EOL)
std::string m_objectAttributesDictionnary;
// The last aperture attribute generated (only one aperture attribute can be set)
int m_apertureAttribute;
FILE* workFile;
FILE* finalFile;
@ -1042,6 +1189,11 @@ protected:
bool m_gerberUnitInch; // true if the gerber units are inches, false for mm
int m_gerberUnitFmt; // number of digits in mantissa.
// usually 6 in Inches and 5 or 6 in mm
bool m_useX2Attributes; // In recent gerber files, attributes can be added.
// It will be added if this parm is true
bool m_useNetAttributes; // In recent gerber files, netlist info can be added.
// It will be added if this parm is true
// (imply m_useX2Attributes == true)
};
@ -1077,7 +1229,7 @@ public:
virtual bool EndPlot();
// For now we don't use 'thick' primitives, so no line width
virtual void SetCurrentLineWidth( int width )
virtual void SetCurrentLineWidth( int width, void* aData = NULL ) override
{
currentPenWidth = 0;
}
@ -1099,26 +1251,27 @@ public:
virtual void Circle( const wxPoint& pos, int diametre, FILL_T fill,
int width = USE_DEFAULT_LINE_WIDTH );
virtual void PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH );
FILL_T aFill, int aWidth = USE_DEFAULT_LINE_WIDTH, void * aData = NULL ) override;
virtual void ThickSegment( const wxPoint& start, const wxPoint& end, int width,
EDA_DRAW_MODE_T tracemode );
EDA_DRAW_MODE_T tracemode, void* aData ) override;
virtual void Arc( const wxPoint& centre, double StAngle, double EndAngle,
int rayon, FILL_T fill, int width = USE_DEFAULT_LINE_WIDTH );
virtual void PenTo( const wxPoint& pos, char plume );
virtual void FlashPadCircle( const wxPoint& pos, int diametre,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadOval( const wxPoint& pos, const wxSize& size, double orient,
EDA_DRAW_MODE_T trace_mode );
EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRect( const wxPoint& pos, const wxSize& size,
double orient, EDA_DRAW_MODE_T trace_mode );
double orient, EDA_DRAW_MODE_T trace_mode, void* aData ) override;
virtual void FlashPadRoundRect( const wxPoint& aPadPos, const wxSize& aSize,
int aCornerRadius, double aOrient,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadCustom( const wxPoint& aPadPos, const wxSize& aSize,
SHAPE_POLY_SET* aPolygons,
EDA_DRAW_MODE_T aTraceMode );
EDA_DRAW_MODE_T aTraceMode, void* aData ) override;
virtual void FlashPadTrapez( const wxPoint& aPadPos, const wxPoint *aCorners,
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode );
double aPadOrient, EDA_DRAW_MODE_T aTrace_Mode, void* aData ) override;
virtual void Text( const wxPoint& aPos,
enum EDA_COLOR_T aColor,
@ -1130,7 +1283,8 @@ public:
int aWidth,
bool aItalic,
bool aBold,
bool aMultilineAllowed = false );
bool aMultilineAllowed = false,
void* aData = NULL ) override;
protected:
bool textAsLines;

View File

@ -5,7 +5,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2015 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -40,6 +40,9 @@
#include <dialog_plot.h>
#include <wx_html_report_panel.h>
// Uncomment this line to allow experimetal net attributes in Gerber files:
//#define KICAD_USE_GBR_NETATTRIBUTES
DIALOG_PLOT::DIALOG_PLOT( PCB_EDIT_FRAME* aParent ) :
DIALOG_PLOT_BASE( aParent ), m_parent( aParent ),
m_board( aParent->GetBoard() ),
@ -158,8 +161,15 @@ void DIALOG_PLOT::Init_Dialog()
m_useGerberExtensions->SetValue( m_plotOpts.GetUseGerberProtelExtensions() );
// Option for including Gerber attributes (from Gerber X2 format) in the output
m_useGerberAttributes->SetValue( m_plotOpts.GetUseGerberAttributes() );
m_useGerberX2Attributes->SetValue( m_plotOpts.GetUseGerberAttributes() );
// Option for including Gerber netlist info (from Gerber X2 format) in the output
#ifdef KICAD_USE_GBR_NETATTRIBUTES
m_useGerberNetAttributes->SetValue( m_plotOpts.GetIncludeGerberNetlistInfo() );
#else
m_plotOpts.SetIncludeGerberNetlistInfo( false );
m_useGerberNetAttributes->SetValue( false );
#endif
// Gerber precision for coordinates
m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
@ -362,12 +372,6 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_linesWidth->Enable( true );
m_HPGLPenSizeOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_useGerberAttributes->Enable( false );
m_useGerberAttributes->SetValue( false );
m_scaleOpt->Enable( false );
m_scaleOpt->SetSelection( 1 );
m_fineAdjustXscaleOpt->Enable( false );
@ -391,12 +395,6 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_linesWidth->Enable( true );
m_HPGLPenSizeOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_useGerberAttributes->Enable( false );
m_useGerberAttributes->SetValue( false );
m_scaleOpt->Enable( true );
m_fineAdjustXscaleOpt->Enable( true );
m_fineAdjustYscaleOpt->Enable( true );
@ -420,9 +418,6 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_linesWidth->Enable( true );
m_HPGLPenSizeOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( true );
m_useGerberExtensions->Enable( true );
m_useGerberAttributes->Enable( true );
m_scaleOpt->Enable( false );
m_scaleOpt->SetSelection( 1 );
m_fineAdjustXscaleOpt->Enable( false );
@ -436,6 +431,9 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_PlotOptionsSizer->Show( m_GerberOptionsSizer );
m_PlotOptionsSizer->Hide( m_HPGLOptionsSizer );
m_PlotOptionsSizer->Hide( m_PSOptionsSizer );
#ifndef KICAD_USE_GBR_NETATTRIBUTES
m_useGerberNetAttributes->Show( false );
#endif
break;
case PLOT_FORMAT_HPGL:
@ -447,12 +445,6 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_linesWidth->Enable( false );
m_HPGLPenSizeOpt->Enable( true );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_useGerberAttributes->Enable( false );
m_useGerberAttributes->SetValue( false );
m_scaleOpt->Enable( true );
m_fineAdjustXscaleOpt->Enable( false );
m_fineAdjustYscaleOpt->Enable( false );
@ -475,12 +467,6 @@ void DIALOG_PLOT::SetPlotFormat( wxCommandEvent& event )
m_linesWidth->Enable( false );
m_HPGLPenSizeOpt->Enable( false );
m_excludeEdgeLayerOpt->Enable( true );
m_subtractMaskFromSilk->Enable( false );
m_subtractMaskFromSilk->SetValue( false );
m_useGerberExtensions->Enable( false );
m_useGerberExtensions->SetValue( false );
m_useGerberAttributes->Enable( false );
m_useGerberAttributes->SetValue( false );
m_scaleOpt->Enable( false );
m_scaleOpt->SetSelection( 1 );
m_fineAdjustXscaleOpt->Enable( false );
@ -649,7 +635,8 @@ void DIALOG_PLOT::applyPlotSettings()
tempOptions.SetFormat( getPlotFormat() );
tempOptions.SetUseGerberProtelExtensions( m_useGerberExtensions->GetValue() );
tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() );
tempOptions.SetUseGerberAttributes( m_useGerberX2Attributes->GetValue() );
tempOptions.SetIncludeGerberNetlistInfo( m_useGerberNetAttributes->GetValue() );
tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
LSET selectedLayers;

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 24 2016)
// C++ code generated with wxFormBuilder (version Sep 8 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -99,6 +99,7 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
bSizerPlotItems->Add( m_plotModuleValueOpt, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
m_plotModuleRefOpt = new wxCheckBox( sbOptionsSizer->GetStaticBox(), ID_PRINT_REF, _("Plot footprint references"), wxDefaultPosition, wxDefaultSize, 0 );
m_plotModuleRefOpt->SetValue(true);
bSizerPlotItems->Add( m_plotModuleRefOpt, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
m_plotInvisibleText = new wxCheckBox( sbOptionsSizer->GetStaticBox(), wxID_ANY, _("Force plotting of invisible values/references"), wxDefaultPosition, wxDefaultSize, 0 );
@ -223,14 +224,19 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
bSizerGbrOpt = new wxBoxSizer( wxVERTICAL );
m_useGerberExtensions = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Use Protel filename extensions"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberExtensions->SetToolTip( _("Use conventional Protel Gerber extensions - .GBL, .GTL, etc...") );
m_useGerberExtensions->SetToolTip( _("Use Protel Gerber extensions - .GBL, .GTL, etc...\nNo more recommended. The official extension is .gbr") );
bSizerGbrOpt->Add( m_useGerberExtensions, 0, wxALL, 2 );
m_useGerberAttributes = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Include extended attributes"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberAttributes->SetToolTip( _("Include extended attributes (X2 Gerber files format) in the Gerber file") );
m_useGerberX2Attributes = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Include extended (X2) attributes"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberX2Attributes->SetToolTip( _("Include extended attributes (X2 Gerber files format) in the Gerber file.\nMainly File Format attributes.") );
bSizerGbrOpt->Add( m_useGerberAttributes, 0, wxALL, 2 );
bSizerGbrOpt->Add( m_useGerberX2Attributes, 0, wxALL, 2 );
m_useGerberNetAttributes = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Include advanced X2 features"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberNetAttributes->SetToolTip( _("Only available in X2 Gerber files format.\nInclude netlist metadata and aperture attributes.") );
bSizerGbrOpt->Add( m_useGerberNetAttributes, 0, wxALL, 2 );
m_subtractMaskFromSilk = new wxCheckBox( m_GerberOptionsSizer->GetStaticBox(), wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") );

View File

@ -44,7 +44,7 @@
<property name="minimum_size">-1,-1</property>
<property name="name">DIALOG_PLOT_BASE</property>
<property name="pos"></property>
<property name="size">566,618</property>
<property name="size">733,673</property>
<property name="style">wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER</property>
<property name="subclass">DIALOG_SHIM; dialog_shim.h</property>
<property name="title">Plot</property>
@ -93,20 +93,20 @@
<property name="name">m_MainSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bupperSizer</property>
<property name="orient">wxHORIZONTAL</property>
<property name="permission">none</property>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerPlotFmt</property>
<property name="orient">wxVERTICAL</property>
@ -570,11 +570,11 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bmiddleSizer</property>
<property name="orient">wxHORIZONTAL</property>
@ -683,20 +683,20 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag"></property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">m_PlotOptionsSizer</property>
<property name="orient">wxVERTICAL</property>
<property name="permission">protected</property>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">Options</property>
<property name="minimum_size"></property>
@ -705,11 +705,11 @@
<property name="parent">1</property>
<property name="permission">none</property>
<event name="OnUpdateUI"></event>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer192</property>
<property name="orient">wxHORIZONTAL</property>
@ -1005,7 +1005,7 @@
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="checked">1</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
@ -1605,7 +1605,7 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxRIGHT|wxLEFT</property>
<property name="proportion">1</property>
@ -2748,7 +2748,7 @@
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Use conventional Protel Gerber extensions - .GBL, .GTL, etc...</property>
<property name="tooltip">Use Protel Gerber extensions - .GBL, .GTL, etc...&#x0A;No more recommended. The official extension is .gbr</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
@ -2815,7 +2815,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Include extended attributes</property>
<property name="label">Include extended (X2) attributes</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -2823,7 +2823,7 @@
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_useGerberAttributes</property>
<property name="name">m_useGerberX2Attributes</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
@ -2836,7 +2836,95 @@
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Include extended attributes (X2 Gerber files format) in the Gerber file</property>
<property name="tooltip">Include extended attributes (X2 Gerber files format) in the Gerber file.&#x0A;Mainly File Format attributes.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
<event name="OnChar"></event>
<event name="OnCheckBox"></event>
<event name="OnEnterWindow"></event>
<event name="OnEraseBackground"></event>
<event name="OnKeyDown"></event>
<event name="OnKeyUp"></event>
<event name="OnKillFocus"></event>
<event name="OnLeaveWindow"></event>
<event name="OnLeftDClick"></event>
<event name="OnLeftDown"></event>
<event name="OnLeftUp"></event>
<event name="OnMiddleDClick"></event>
<event name="OnMiddleDown"></event>
<event name="OnMiddleUp"></event>
<event name="OnMotion"></event>
<event name="OnMouseEvents"></event>
<event name="OnMouseWheel"></event>
<event name="OnPaint"></event>
<event name="OnRightDClick"></event>
<event name="OnRightDown"></event>
<event name="OnRightUp"></event>
<event name="OnSetFocus"></event>
<event name="OnSize"></event>
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<property name="border">2</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="1">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Include advanced X2 features</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_useGerberNetAttributes</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass"></property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Only available in X2 Gerber files format.&#x0A;Include netlist metadata and aperture attributes.</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
@ -3052,11 +3140,11 @@
</object>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">3</property>
<property name="flag">wxALL|wxEXPAND</property>
<property name="proportion">0</property>
<object class="wxStaticBoxSizer" expanded="1">
<object class="wxStaticBoxSizer" expanded="0">
<property name="id">wxID_ANY</property>
<property name="label">HPGL Options</property>
<property name="minimum_size"></property>
@ -3065,11 +3153,11 @@
<property name="parent">1</property>
<property name="permission">protected</property>
<event name="OnUpdateUI"></event>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizer22</property>
<property name="orient">wxVERTICAL</property>
@ -3929,7 +4017,7 @@
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="wxBoxSizer" expanded="0">
<object class="wxBoxSizer" expanded="1">
<property name="minimum_size"></property>
<property name="name">sbSizerMsg</property>
<property name="orient">wxVERTICAL</property>
@ -4020,7 +4108,7 @@
<property name="border">5</property>
<property name="flag">wxALIGN_RIGHT|wxRIGHT|wxLEFT</property>
<property name="proportion">0</property>
<object class="wxBoxSizer" expanded="1">
<object class="wxBoxSizer" expanded="0">
<property name="minimum_size"></property>
<property name="name">bSizerButtons</property>
<property name="orient">wxHORIZONTAL</property>
@ -4201,21 +4289,21 @@
<event name="OnUpdateUI"></event>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxEXPAND</property>
<property name="proportion">1</property>
<object class="spacer" expanded="1">
<object class="spacer" expanded="0">
<property name="height">0</property>
<property name="permission">protected</property>
<property name="width">10</property>
</object>
</object>
<object class="sizeritem" expanded="1">
<object class="sizeritem" expanded="0">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxButton" expanded="1">
<object class="wxButton" expanded="0">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
@ -4390,7 +4478,7 @@
</object>
</object>
</object>
<object class="wxMenu" expanded="1">
<object class="wxMenu" expanded="0">
<property name="label">MyMenu</property>
<property name="name">m_popMenu</property>
<property name="permission">protected</property>

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version Jul 24 2016)
// C++ code generated with wxFormBuilder (version Sep 8 2016)
// http://www.wxformbuilder.org/
//
// PLEASE DO "NOT" EDIT THIS FILE!
@ -92,7 +92,8 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
wxStaticText* m_SolderMaskMinWidthCurrValue;
wxStaticBoxSizer* m_GerberOptionsSizer;
wxCheckBox* m_useGerberExtensions;
wxCheckBox* m_useGerberAttributes;
wxCheckBox* m_useGerberX2Attributes;
wxCheckBox* m_useGerberNetAttributes;
wxCheckBox* m_subtractMaskFromSilk;
wxRadioBox* m_rbGerberFormat;
wxStaticBoxSizer* m_HPGLOptionsSizer;
@ -129,7 +130,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
public:
DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 566,618 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id = wxID_ANY, const wxString& title = _("Plot"), const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxSize( 733,673 ), long style = wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER );
~DIALOG_PLOT_BASE();
void DIALOG_PLOT_BASEOnContextMenu( wxMouseEvent &event )

View File

@ -403,7 +403,7 @@ bool EXCELLON_WRITER::PlotDrillMarks( PLOTTER* aPlotter )
if( hole.m_Hole_Shape != 0 )
{
wxSize oblong_size = hole.m_Hole_Size;
aPlotter->FlashPadOval( pos, oblong_size, hole.m_Hole_Orient, SKETCH );
aPlotter->FlashPadOval( pos, oblong_size, hole.m_Hole_Orient, SKETCH, NULL );
}
}

View File

@ -81,6 +81,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS()
{
m_useGerberProtelExtensions = false;
m_useGerberAttributes = false;
m_includeGerberNetlistInfo = false;
m_gerberPrecision = gbrDefaultPrecision;
m_excludeEdgeLayer = true;
m_lineWidth = g_DrawDefaultLineThickness;
@ -148,8 +149,13 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
if( m_useGerberAttributes ) // save this option only if active,
// to avoid incompatibility with older Pcbnew version
{
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberattributes ), trueStr );
if( GetIncludeGerberNetlistInfo() )
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberadvancedattributes ), trueStr );
}
if( m_gerberPrecision != gbrDefaultPrecision ) // save this option only if it is not the default value,
// to avoid incompatibility with older Pcbnew version
aFormatter->Print( aNestLevel+1, "(%s %d)\n",
@ -222,6 +228,8 @@ bool PCB_PLOT_PARAMS::operator==( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
return false;
if( m_useGerberAttributes != aPcbPlotParams.m_useGerberAttributes )
return false;
if( m_useGerberAttributes && m_includeGerberNetlistInfo != aPcbPlotParams.m_includeGerberNetlistInfo )
return false;
if( m_gerberPrecision != aPcbPlotParams.m_gerberPrecision )
return false;
if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer )
@ -384,6 +392,10 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
aPcbPlotParams->m_useGerberAttributes = parseBool();
break;
case T_usegerberadvancedattributes:
aPcbPlotParams->m_includeGerberNetlistInfo = parseBool();
break;
case T_gerberprecision:
aPcbPlotParams->m_gerberPrecision =
parseInt( gbrDefaultPrecision-1, gbrDefaultPrecision);

View File

@ -97,6 +97,9 @@ private:
/// Include attributes from the Gerber X2 format (chapter 5 in revision J2)
bool m_useGerberAttributes;
/// Include netlist info (only in Gerber X2 format) (chapter ? in revision ?)
bool m_includeGerberNetlistInfo;
/// precision of coordinates in Gerber files: accepted 5 or 6
/// when units are in mm (6 or 7 in inches, but Pcbnew uses mm).
/// 6 is the internal resolution of Pcbnew, but not alwys accepted by board maker
@ -231,6 +234,9 @@ public:
void SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; }
bool GetUseGerberAttributes() const { return m_useGerberAttributes; }
void SetIncludeGerberNetlistInfo( bool aUse ) { m_includeGerberNetlistInfo = aUse; }
bool GetIncludeGerberNetlistInfo() const { return m_includeGerberNetlistInfo; }
void SetUseGerberProtelExtensions( bool aUse ) { m_useGerberProtelExtensions = aUse; }
bool GetUseGerberProtelExtensions() const { return m_useGerberProtelExtensions; }

View File

@ -85,8 +85,7 @@ const wxString GetGerberProtelExtension( LAYER_NUM aLayer )
}
}
wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
const wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
LAYER_NUM aLayer, bool aUseX1CompatibilityMode )
{
wxString attrib;
@ -94,81 +93,81 @@ wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
switch( aLayer )
{
case F_Adhes:
attrib = wxString( wxT( "Glue,Top" ) );
attrib = "Glue,Top";
break;
case B_Adhes:
attrib = wxString( wxT( "Glue,Bot" ) );
attrib = "Glue,Bot";
break;
case F_SilkS:
attrib = wxString( wxT( "Legend,Top" ) );
attrib = "Legend,Top";
break;
case B_SilkS:
attrib = wxString( wxT( "Legend,Bot" ) );
attrib = "Legend,Bot";
break;
case F_Mask:
attrib = wxString( wxT( "Soldermask,Top" ) );
attrib = "Soldermask,Top";
break;
case B_Mask:
attrib = wxString( wxT( "Soldermask,Bot" ) );
attrib = "Soldermask,Bot";
break;
case F_Paste:
attrib = wxString( wxT( "Paste,Top" ) );
attrib = "Paste,Top";
break;
case B_Paste:
attrib = wxString( wxT( "Paste,Bot" ) );
attrib = "Paste,Bot";
break;
case Edge_Cuts:
// Board outline.
// Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
// This last is the exception (Plated)
attrib = wxString( wxT( "Profile,NP" ) );
attrib = "Profile,NP";
break;
case Dwgs_User:
attrib = wxString( wxT( "Drawing" ) );
attrib = "Drawing";
break;
case Cmts_User:
attrib = wxString( wxT( "Other,Comment" ) );
attrib = "Other,Comment";
break;
case Eco1_User:
attrib = wxString( wxT( "Other,ECO1" ) );
attrib = "Other,ECO1";
break;
case Eco2_User:
attrib = wxString( wxT( "Other,ECO2" ) );
attrib = "Other,ECO2";
break;
case B_Fab:
attrib = wxString( wxT( "Other,Fab,Bot" ) );
attrib = "Other,Fab,Bot";
break;
case F_Fab:
attrib = wxString( wxT( "Other,Fab,Top" ) );
attrib = "Other,Fab,Top";
break;
case B_Cu:
attrib = wxString::Format( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
attrib.Printf( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
break;
case F_Cu:
attrib = wxString::Format( wxT( "Copper,L1,Top" ) );
attrib = "Copper,L1,Top";
break;
default:
if( IsCopperLayer( aLayer ) )
attrib = wxString::Format( wxT( "Copper,L%d,Inr" ), aLayer+1 );
attrib.Printf( wxT( "Copper,L%d,Inr" ), aLayer+1 );
else
attrib = wxString::Format( wxT( "Other,User" ), aLayer+1 );
attrib.Printf( wxT( "Other,User" ), aLayer+1 );
break;
}
@ -180,13 +179,13 @@ wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
switch( type )
{
case LT_SIGNAL:
attrib += wxString( wxT( ",Signal" ) );
attrib += ",Signal";
break;
case LT_POWER:
attrib += wxString( wxT( ",Plane" ) );
attrib += ",Plane";
break;
case LT_MIXED:
attrib += wxString( wxT( ",Mixed" ) );
attrib += ",Mixed";
break;
default:
break; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
@ -203,16 +202,69 @@ wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
return fileFct;
}
static const wxString GetGerberFilePolarityAttribute( LAYER_NUM aLayer )
{
/* build the string %TF.FilePolarity,Positive*%
* or %TF.FilePolarity,Negative*%
* an emply string for layers which do not use a polarity
*
* The value of the .FilePolarity specifies whether the image represents the
* presence or absence of material.
* This attribute can only be used when the file represents a pattern in a material layer,
* e.g. copper, solder mask, legend.
* Together with.FileFunction it defines the role of that image in
* the layer structure of the PCB.
* Note that the .FilePolarity attribute does not change the image -
* no attribute does.
* It changes the interpretation of the image.
* For example, in a copper layer in positive polarity a round flash generates a copper pad.
* In a copper layer in negative polarity it generates a clearance.
* Solder mask images usually represent solder mask openings and are then negative.
* This may be counter-intuitive.
*/
int polarity = 0;
switch( aLayer )
{
case F_Adhes:
case B_Adhes:
case F_SilkS:
case B_SilkS:
case F_Paste:
case B_Paste:
polarity = 1;
break;
case F_Mask:
case B_Mask:
polarity = -1;
break;
default:
if( IsCopperLayer( aLayer ) )
polarity = 1;
break;
}
wxString filePolarity;
if( polarity == 1 )
filePolarity = "%TF.FilePolarity,Positive*%";
if( polarity == -1 )
filePolarity = "%TF.FilePolarity,Negative*%";
return filePolarity;
}
/* Add some X2 attributes to the file header, as defined in the
* Gerber file format specification J4 and "Revision 2015.06"
*/
#define USE_REVISION_2015_06_ATTR
void AddGerberX2Attribute( PLOTTER * aPlotter,
const BOARD *aBoard, LAYER_NUM aLayer )
{
wxString text;
#ifdef USE_REVISION_2015_06_ATTR
// Creates the TF,.GenerationSoftware. Format is:
// %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
@ -278,11 +330,16 @@ void AddGerberX2Attribute( PLOTTER * aPlotter,
text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), GetChars( guid ), rev.ToAscii() );
aPlotter->AddLineToHeader( text );
#endif
// Add the TF.FileFunction
text = GetGerberFileFunctionAttribute( aBoard, aLayer, false );
aPlotter->AddLineToHeader( text );
// Add the TF.FilePolarity (for layers which support that)
text = GetGerberFilePolarityAttribute( aLayer );
if( !text.IsEmpty() )
aPlotter->AddLineToHeader( text );
}

View File

@ -268,7 +268,7 @@ const wxString GetGerberProtelExtension( LAYER_NUM aLayer );
* , compatible with X1 (rx274) notation (G04#@!TF.FileFunction)
* @return The attribute, as a text string
*/
extern wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
const wxString GetGerberFileFunctionAttribute( const BOARD *aBoard,
LAYER_NUM aLayer, bool aUseX1CompatibilityMode );
/**

View File

@ -50,6 +50,7 @@
#include <pcbnew.h>
#include <pcbplot.h>
#include <plot_auxiliary_data.h>
// Local
/* Plot a solder mask layer.
@ -88,6 +89,8 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
{
for( MODULE* Module = aBoard->m_Modules; Module; Module = Module->Next() )
{
aPlotter->StartBlock( NULL );
for( D_PAD * pad = Module->Pads(); pad; pad = pad->Next() )
{
// See if the pad is on this layer
@ -105,6 +108,8 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
itemplotter.PlotPad( pad, color, SKETCH );
}
aPlotter->EndBlock( NULL );
}
}
@ -119,6 +124,8 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
}
// Plot filled areas
aPlotter->StartBlock( NULL );
for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* edge_zone = aBoard->GetArea( ii );
@ -129,6 +136,8 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
itemplotter.PlotFilledAreas( edge_zone );
}
aPlotter->EndBlock( NULL );
// Plot segments used to fill zone areas (outdated, but here for old boards
// compatibility):
for( SEGZONE* seg = aBoard->m_Zone; seg; seg = seg->Next() )
@ -137,7 +146,7 @@ void PlotSilkScreen( BOARD *aBoard, PLOTTER* aPlotter, LSET aLayerMask,
continue;
aPlotter->ThickSegment( seg->GetStart(), seg->GetEnd(), seg->GetWidth(),
itemplotter.GetPlotMode() );
itemplotter.GetPlotMode(), NULL );
}
}
@ -325,6 +334,8 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
// Plot footprint pads
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
aPlotter->StartBlock( NULL );
for( D_PAD* pad = module->Pads(); pad; pad = pad->Next() )
{
if( (pad->GetLayerSet() & aLayerMask) == 0 )
@ -388,10 +399,25 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
pad->SetSize( tmppadsize ); // Restore the pad size
}
aPlotter->EndBlock( NULL );
}
// Plot vias on copper layers, and if aPlotOpt.GetPlotViaOnMaskLayer() is true,
// plot them on solder mask
GBR_METADATA gbr_metadata;
bool isOnCopperLayer = ( aLayerMask & LSET::AllCuMask() ).any();
if( isOnCopperLayer )
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_VIAPAD );
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_NET );
}
aPlotter->StartBlock( NULL );
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
const VIA* Via = dyn_cast<const VIA*>( track );
@ -433,13 +459,19 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
if( diameter <= 0 )
continue;
gbr_metadata.SetNetName( Via->GetNetname() );
EDA_COLOR_T color = aBoard->GetVisibleElementColor(VIAS_VISIBLE + Via->GetViaType());
// Set plot color (change WHITE to LIGHTGRAY because
// the white items are not seen on a white paper or screen
aPlotter->SetColor( color != WHITE ? color : LIGHTGRAY);
aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode );
aPlotter->FlashPadCircle( Via->GetStart(), diameter, plotMode, &gbr_metadata );
}
aPlotter->EndBlock( NULL );
aPlotter->StartBlock( NULL );
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
// Plot tracks (not vias) :
for( TRACK* track = aBoard->m_Track; track; track = track->Next() )
{
@ -449,11 +481,14 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
if( !aLayerMask[track->GetLayer()] )
continue;
gbr_metadata.SetNetName( track->GetNetname() );
int width = track->GetWidth() + itemplotter.getFineWidthAdj();
aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode );
aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, &gbr_metadata );
}
aPlotter->EndBlock( NULL );
// Plot zones (outdated, for old boards compatibility):
for( TRACK* track = aBoard->m_Zone; track; track = track->Next() )
{
@ -462,10 +497,11 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
int width = track->GetWidth() + itemplotter.getFineWidthAdj();
aPlotter->SetColor( itemplotter.getColor( track->GetLayer() ) );
aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode );
aPlotter->ThickSegment( track->GetStart(), track->GetEnd(), width, plotMode, NULL );
}
// Plot filled ares
aPlotter->StartBlock( NULL );
for( int ii = 0; ii < aBoard->GetAreaCount(); ii++ )
{
ZONE_CONTAINER* zone = aBoard->GetArea( ii );
@ -475,6 +511,7 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
itemplotter.PlotFilledAreas( zone );
}
aPlotter->EndBlock( NULL );
// Adding drill marks, if required and if the plotter is able to plot them:
if( aPlotOpt.GetDrillMarksType() != PCB_PLOT_PARAMS::NO_DRILL_SHAPE )
@ -604,7 +641,7 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter,
int width;
pad->GetOblongDrillGeometry( drl_start, drl_end, width );
aPlotter->ThickSegment( pad->GetPosition() + drl_start,
pad->GetPosition() + drl_end, width, SKETCH );
pad->GetPosition() + drl_end, width, SKETCH, NULL );
}
}
}
@ -985,7 +1022,12 @@ PLOTTER* StartPlotBoard( BOARD *aBoard, PCB_PLOT_PARAMS *aPlotOpts,
bool useX2mode = plotOpts.GetUseGerberAttributes();
if( useX2mode )
{
AddGerberX2Attribute( plotter, aBoard, aLayer );
GERBER_PLOTTER* gbrplotter = static_cast <GERBER_PLOTTER*> ( plotter );
gbrplotter->UseX2Attributes( true );
gbrplotter->UseX2NetAttributes( plotOpts.GetIncludeGerberNetlistInfo() );
}
else
plotter->AddLineToHeader( GetGerberFileFunctionAttribute(
aBoard, aLayer, true ) );

View File

@ -7,7 +7,7 @@
/*
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 1992-2012 KiCad Developers, see AUTHORS.txt for contributors.
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@ -48,12 +48,12 @@
#include <pcbnew.h>
#include <pcbplot.h>
#include <plot_auxiliary_data.h>
/* class BRDITEMS_PLOTTER is a helper class to plot board items
* and a group of board items
*/
EDA_COLOR_T BRDITEMS_PLOTTER::getColor( LAYER_NUM aLayer )
{
EDA_COLOR_T color = m_board->GetLayerColor( ToLAYER_ID( aLayer ) );
@ -66,6 +66,91 @@ EDA_COLOR_T BRDITEMS_PLOTTER::getColor( LAYER_NUM aLayer )
void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T aPlotMode )
{
wxPoint shape_pos = aPad->ShapePos();
GBR_METADATA gbr_metadata;
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
bool isOnExternalCopperLayer = ( m_layerMask & LSET::ExternalCuMask() ).any();
bool isPadOnBoardTechLayers = ( aPad->GetLayerSet() & LSET::AllBoardTechMask() ).any();
gbr_metadata.SetCmpReference( aPad->GetParent()->GetReference() );
if( isOnCopperLayer )
{
gbr_metadata.SetNetAttribType( GBR_NETINFO_ALL );
if( isOnExternalCopperLayer )
gbr_metadata.SetPadName( aPad->GetPadName() );
gbr_metadata.SetNetName( aPad->GetNetname() );
// Some pads are mechanical pads ( through hole or smd )
// when this is the case, they have no pad name and/or are not plated.
// In this case gerber files have slightly different attributes.
if( aPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED ||
aPad->GetPadName().IsEmpty() )
gbr_metadata.m_NetlistMetadata.m_NotInNet = true;
if( !isOnExternalCopperLayer || !isPadOnBoardTechLayers )
{
// On internal layers one cannot use the GBR_NETLIST_METADATA::GBR_INFO_FLASHED_PAD
// attribute when the component is on an external layer (most of the case)
// Also, if a SMD pad is not on a tech layer (masks) use also net+cmp attribute, because
// it is not really a pad (can be a "pad", actually a node in a virtual component)
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_NET |
GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
if( !isPadOnBoardTechLayers )
// such a pad is not soldered and is not a connecting point.
// Just set aperture attribute as conductor
// If it is a through hole pad, it will be adjusted later
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
switch( aPad->GetAttribute() )
{
case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_WASHERPAD );
break;
case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_VIAPAD );
break;
default:
break;
}
}
else // Some attributes are reserved to the external copper layers
{
switch( aPad->GetAttribute() )
{
case PAD_ATTRIB_HOLE_NOT_PLATED: // Mechanical pad through hole
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_WASHERPAD );
break;
case PAD_ATTRIB_STANDARD : // Pad through hole, a hole is also expected
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_COMPONENTPAD );
break;
case PAD_ATTRIB_CONN: // Connector pads have no solder paste.
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONNECTORPAD );
break;
case PAD_ATTRIB_SMD: // SMD pads (One external copper layer only) with solder paste
if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) // perhaps a BGA pad
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_BGAPAD_CUDEF );
else
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_SMDPAD_CUDEF );
break;
}
}
if( aPad->GetAttribute() == PAD_ATTRIB_HOLE_NOT_PLATED )
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_WASHERPAD );
}
else
{
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
}
// Set plot color (change WHITE to LIGHTGRAY because
// the white items are not seen on a white paper or screen
@ -74,12 +159,12 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T
switch( aPad->GetShape() )
{
case PAD_SHAPE_CIRCLE:
m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode );
m_plotter->FlashPadCircle( shape_pos, aPad->GetSize().x, aPlotMode, &gbr_metadata );
break;
case PAD_SHAPE_OVAL:
m_plotter->FlashPadOval( shape_pos, aPad->GetSize(),
aPad->GetOrientation(), aPlotMode );
aPad->GetOrientation(), aPlotMode, &gbr_metadata );
break;
case PAD_SHAPE_TRAPEZOID:
@ -87,19 +172,19 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, EDA_COLOR_T aColor, EDA_DRAW_MODE_T
wxPoint coord[4];
aPad->BuildPadPolygon( coord, wxSize(0,0), 0 );
m_plotter->FlashPadTrapez( shape_pos, coord,
aPad->GetOrientation(), aPlotMode );
aPad->GetOrientation(), aPlotMode, &gbr_metadata );
}
break;
case PAD_SHAPE_ROUNDRECT:
m_plotter->FlashPadRoundRect( shape_pos, aPad->GetSize(), aPad->GetRoundRectCornerRadius(),
aPad->GetOrientation(), aPlotMode );
aPad->GetOrientation(), aPlotMode, &gbr_metadata );
break;
case PAD_SHAPE_RECT:
default:
m_plotter->FlashPadRect( shape_pos, aPad->GetSize(),
aPad->GetOrientation(), aPlotMode );
aPad->GetOrientation(), aPlotMode, &gbr_metadata );
break;
}
}
@ -236,11 +321,16 @@ void BRDITEMS_PLOTTER::PlotTextModule( TEXTE_MODULE* pt_texte, EDA_COLOR_T aColo
// So we set bold flag to true
bool allow_bold = pt_texte->IsBold() || thickness;
GBR_METADATA gbr_metadata;
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
MODULE* parent = static_cast<MODULE*> ( pt_texte->GetParent() );
gbr_metadata.SetCmpReference( parent->GetReference() );
m_plotter->Text( pos, aColor,
pt_texte->GetShownText(),
orient, size,
pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
thickness, pt_texte->IsItalic(), allow_bold );
thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
}
@ -379,15 +469,31 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
wxPoint pos( aEdge->GetStart() );
wxPoint end( aEdge->GetEnd() );
GBR_METADATA gbr_metadata;
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_CMP );
MODULE* parent = static_cast<MODULE*> ( aEdge->GetParent() );
gbr_metadata.SetCmpReference( parent->GetReference() );
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
if( isOnCopperLayer )
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_ETCHEDCMP );
}
else if( aEdge->GetLayer() == Edge_Cuts ) // happens also when plotting copper layers
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
}
switch( type_trace )
{
case S_SEGMENT:
m_plotter->ThickSegment( pos, end, thickness, GetPlotMode() );
m_plotter->ThickSegment( pos, end, thickness, GetPlotMode(), &gbr_metadata );
break;
case S_CIRCLE:
radius = KiROUND( GetLineLength( end, pos ) );
m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode() );
m_plotter->ThickCircle( pos, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
break;
case S_ARC:
@ -396,7 +502,7 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
double startAngle = ArcTangente( end.y - pos.y, end.x - pos.x );
double endAngle = startAngle + aEdge->GetAngle();
m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode() );
m_plotter->ThickArc( pos, -endAngle, -startAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
}
break;
@ -428,14 +534,14 @@ void BRDITEMS_PLOTTER::Plot_1_EdgeModule( EDGE_MODULE* aEdge )
cornerList.push_back( corner );
}
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness );
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, thickness, &gbr_metadata );
}
break;
}
}
// Plot a PCB Text, i;e. a text found on a copper or technical layer
// Plot a PCB Text, i.e. a text found on a copper or technical layer
void BRDITEMS_PLOTTER::PlotTextePcb( TEXTE_PCB* pt_texte )
{
double orient;
@ -450,6 +556,13 @@ void BRDITEMS_PLOTTER::PlotTextePcb( TEXTE_PCB* pt_texte )
if( !m_layerMask[pt_texte->GetLayer()] )
return;
GBR_METADATA gbr_metadata;
if( IsCopperLayer( pt_texte->GetLayer() ) )
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
}
m_plotter->SetColor( getColor( pt_texte->GetLayer() ) );
size = pt_texte->GetSize();
@ -480,14 +593,14 @@ void BRDITEMS_PLOTTER::PlotTextePcb( TEXTE_PCB* pt_texte )
wxString& txt = strings_list.Item( ii );
m_plotter->Text( positions[ii], UNSPECIFIED_COLOR, txt, orient, size,
pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
thickness, pt_texte->IsItalic(), allow_bold );
thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
}
}
else
{
m_plotter->Text( pos, UNSPECIFIED_COLOR, shownText, orient, size,
pt_texte->GetHorizJustify(), pt_texte->GetVertJustify(),
thickness, pt_texte->IsItalic(), allow_bold );
thickness, pt_texte->IsItalic(), allow_bold, false, &gbr_metadata );
}
}
@ -501,6 +614,26 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
if( polysList.IsEmpty() )
return;
GBR_METADATA gbr_metadata;
bool isOnCopperLayer = aZone->IsOnCopperLayer();
if( isOnCopperLayer )
{
gbr_metadata.SetNetName( aZone->GetNetname() );
// Zones with no net name can exist.
// they are not used to connect items, so the aperture attribute cannot
// be set as conductor
if( aZone->GetNetname().IsEmpty() )
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
else
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CONDUCTOR );
gbr_metadata.SetNetAttribType( GBR_NETLIST_METADATA::GBR_NETINFO_NET );
}
}
// We need a buffer to store corners coordinates:
static std::vector< wxPoint > cornerList;
cornerList.clear();
@ -533,7 +666,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
// The area can be filled by segments or uses solid polygons
if( aZone->GetFillMode() == 0 ) // We are using solid polygons
{
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness() );
m_plotter->PlotPoly( cornerList, FILLED_SHAPE, aZone->GetMinThickness(), &gbr_metadata );
}
else // We are using areas filled by segments: plot segments and outline
{
@ -543,7 +676,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
wxPoint end = aZone->FillSegments()[iseg].m_End;
m_plotter->ThickSegment( start, end,
aZone->GetMinThickness(),
GetPlotMode() );
GetPlotMode(), &gbr_metadata );
}
// Plot the area outline only
@ -558,7 +691,7 @@ void BRDITEMS_PLOTTER::PlotFilledAreas( ZONE_CONTAINER* aZone )
for( unsigned jj = 1; jj<cornerList.size(); jj++ )
m_plotter->ThickSegment( cornerList[jj -1], cornerList[jj],
aZone->GetMinThickness(),
GetPlotMode() );
GetPlotMode(), &gbr_metadata );
}
m_plotter->SetCurrentLineWidth( -1 );
@ -586,35 +719,42 @@ void BRDITEMS_PLOTTER::PlotDrawSegment( DRAWSEGMENT* aSeg )
wxPoint start( aSeg->GetStart() );
wxPoint end( aSeg->GetEnd() );
m_plotter->SetCurrentLineWidth( thickness );
GBR_METADATA gbr_metadata;
bool isOnCopperLayer = ( m_layerMask & LSET::AllCuMask() ).any();
if( isOnCopperLayer && aSeg->GetLayer() == Edge_Cuts ) // can happens when plotting copper layers
{
gbr_metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_NONCONDUCTOR );
}
switch( aSeg->GetShape() )
{
case S_CIRCLE:
radius = KiROUND( GetLineLength( end, start ) );
m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode() );
m_plotter->ThickCircle( start, radius * 2, thickness, GetPlotMode(), &gbr_metadata );
break;
case S_ARC:
radius = KiROUND( GetLineLength( end, start ) );
StAngle = ArcTangente( end.y - start.y, end.x - start.x );
EndAngle = StAngle + aSeg->GetAngle();
m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode() );
m_plotter->ThickArc( start, -EndAngle, -StAngle, radius, thickness, GetPlotMode(), &gbr_metadata );
break;
case S_CURVE:
{
m_plotter->SetCurrentLineWidth( thickness, &gbr_metadata );
const std::vector<wxPoint>& bezierPoints = aSeg->GetBezierPoints();
for( unsigned i = 1; i < bezierPoints.size(); i++ )
m_plotter->ThickSegment( bezierPoints[i - 1],
bezierPoints[i],
thickness, GetPlotMode() );
m_plotter->ThickSegment( bezierPoints[i - 1], bezierPoints[i],
thickness, GetPlotMode(), &gbr_metadata );
}
break;
default:
m_plotter->ThickSegment( start, end, thickness, GetPlotMode() );
m_plotter->ThickSegment( start, end, thickness, GetPlotMode(), &gbr_metadata );
}
}
@ -639,10 +779,10 @@ void BRDITEMS_PLOTTER::plotOneDrillMark( PAD_DRILL_SHAPE_T aDrillShape,
{
aDrillSize.y -= getFineWidthAdj();
aDrillSize.y = Clamp( 1, aDrillSize.y, aPadSize.y - 1 );
m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode() );
m_plotter->FlashPadOval( aDrillPos, aDrillSize, aOrientation, GetPlotMode(), NULL );
}
else
m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode() );
m_plotter->FlashPadCircle( aDrillPos, aDrillSize.x, GetPlotMode(), NULL );
}