Commit ab58dbfc authored by jean-pierre charras's avatar jean-pierre charras

Pcbnew: Rework on Gerber ouput: allows choice between format 4.5 and 4.6. Fix...

Pcbnew: Rework on Gerber ouput: allows choice between format 4.5 and 4.6. Fix a minor issue in Gerber layers attributes.
fix print issue when printing each layer on a separate page.
parent 5a4c16dc
......@@ -15,6 +15,22 @@
#include <build_version.h>
GERBER_PLOTTER::GERBER_PLOTTER()
{
workFile = 0;
finalFile = 0;
currentAperture = apertures.end();
// number of digits after the point (number of digits of the mantissa
// Be carefull: the Gerber coordinates are stored in an integer
// so 6 digits (inches) or 5 digits (mm) is a good value
// To avoid overflow, 7 digits (inches) or 6 digits is a max.
// with lower values than 6 digits (inches) or 5 digits (mm),
// Creating self-intersecting polygons from non-intersecting polygons
// happen easily.
m_gerberUnitInch = false;
m_gerberUnitFmt = 6;
}
void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
double aScale, bool aMirror )
......@@ -26,40 +42,37 @@ void GERBER_PLOTTER::SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
wxASSERT( aScale == 1 ); // aScale parameter is not used in Gerber
plotScale = 1; // Plot scale is *always* 1.0
m_gerberUnitInch = false; // Currently fixed, but could be an option
// number of digits after the point (number of digits of the mantissa
// Be carefull: the Gerber coordinates are stored in an integer
// so 6 digits (inches) or 5 digits (mm) is a good value
// To avoid overflow, 7 digits (inches) or 6 digits is a max.
// with lower values than 6 digits (inches) or 5 digits (mm),
// Creating self-intersecting polygons from non-intersecting polygons
// happen easily.
m_gerberUnitFmt = m_gerberUnitInch ? 7 : 6;
m_IUsPerDecimil = aIusPerDecimil;
iuPerDeviceUnit = pow( 10.0, m_gerberUnitFmt ) / ( aIusPerDecimil * 10000.0 );
if( ! m_gerberUnitInch )
iuPerDeviceUnit *= 25.4; // gerber output in mm
/* We don't handle the filmbox, and it's more useful to keep the
* origin at the origin */
// We don't handle the filmbox, and it's more useful to keep the
// origin at the origin
paperSize.x = 0;
paperSize.y = 0;
SetDefaultLineWidth( 100 * aIusPerDecimil ); // Arbitrary default
}
void GERBER_PLOTTER::SetGerberCoordinatesFormat( int aResolution, bool aUseInches )
{
m_gerberUnitInch = aUseInches;
m_gerberUnitFmt = aResolution;
iuPerDeviceUnit = pow( 10.0, m_gerberUnitFmt ) / ( m_IUsPerDecimil * 10000.0 );
if( ! m_gerberUnitInch )
iuPerDeviceUnit *= 25.4; // gerber output in mm
}
/**
* Emit a D-Code record, using proper conversions
* to format a leading zero omitted gerber coordinate
* (for 4 decimal positions, see header generation in start_plot
* (for n decimal positions, see header generation in start_plot
*/
void GERBER_PLOTTER::emitDcode( const DPOINT& pt, int dcode )
{
fprintf( outputFile, "X%dY%dD%02d*\n",
int( pt.x ), int( pt.y ), dcode );
KiROUND( pt.x ), KiROUND( pt.y ), dcode );
}
/**
......@@ -357,16 +370,16 @@ void GERBER_PLOTTER::Arc( const wxPoint& aCenter, double aStAngle, double aEndAn
/**
* Gerber polygon: they can (and *should*) be filled with the
* appropriate G36/G37 sequence (raster fills are deprecated)
* appropriate G36/G37 sequence
*/
void GERBER_PLOTTER::PlotPoly( const std::vector< wxPoint >& aCornerList,
void GERBER_PLOTTER:: PlotPoly( const std::vector< wxPoint >& aCornerList,
FILL_T aFill, int aWidth )
{
if( aCornerList.size() <= 1 )
return;
// Gerber format does not know filled polygons with thick outline
// Thereore, to plot a filled polygon with outline having a thickness,
// Therefore, to plot a filled polygon with outline having a thickness,
// one should plot outline as thick segments
SetCurrentLineWidth( aWidth );
......
drillshape
excludeedgelayer
false
gerberprecision
hpglpendiameter
hpglpennumber
hpglpenoverlay
......@@ -15,7 +16,6 @@ padsonsilk
pcbplotparams
plotframeref
plotinvisibletext
plotothertext
plotreference
plotvalue
psa4output
......
......@@ -282,12 +282,17 @@ public:
*/
virtual void SetTextMode( PlotTextMode mode )
{
// NOP for most plotters
// NOP for most plotters.
}
virtual void SetLayerAttribFunction( const wxString& function )
{
// NOP for most plotters
// NOP for most plotters. Only for Gerber plotter
}
virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false )
{
// NOP for most plotters. Only for Gerber plotter
}
protected:
......@@ -769,12 +774,7 @@ struct APERTURE
class GERBER_PLOTTER : public PLOTTER
{
public:
GERBER_PLOTTER()
{
workFile = 0;
finalFile = 0;
currentAperture = apertures.end();
}
GERBER_PLOTTER();
virtual PlotFormat GetPlotterType() const
{
......@@ -794,6 +794,7 @@ public:
// RS274X has no dashing, nor colours
virtual void SetDash( bool dashed ) {};
virtual void SetColor( EDA_COLOR_T color ) {};
// Currently, aScale and aMirror are not used in gerber plotter
virtual void SetViewport( const wxPoint& aOffset, double aIusPerDecimil,
double aScale, bool aMirror );
virtual void Rect( const wxPoint& p1, const wxPoint& p2, FILL_T fill,
......@@ -823,6 +824,18 @@ public:
m_attribFunction = function;
}
/**
* Function SetGerberCoordinatesFormat
* selection of Gerber units and resolution (number of digits in mantissa)
* @param aResolution = number of digits in mantissa of coordinate
* use 5 or 6 for mm and 6 or 7 for inches
* do not use value > 6 (mm) or > 7 (in) to avoid overflow
* @param aUseInches = true to use inches, false to use mm (default)
*
* Should be called only after SetViewport() is called
*/
virtual void SetGerberCoordinatesFormat( int aResolution, bool aUseInches = false );
protected:
void selectAperture( const wxSize& size, APERTURE::APERTURE_TYPE type );
void emitDcode( const DPOINT& pt, int dcode );
......
......@@ -167,6 +167,9 @@ void DIALOG_PLOT::Init_Dialog()
// Option for including Gerber attributes (from Gerber X2 format) in the output
m_useGerberAttributes->SetValue( m_plotOpts.GetUseGerberAttributes() );
// Gerber precision for coordinates
m_rbGerberFormat->SetSelection( m_plotOpts.GetGerberPrecision() == 5 ? 0 : 1 );
// Option for excluding contents of "Edges Pcb" layer
m_excludeEdgeLayerOpt->SetValue( m_plotOpts.GetExcludeEdgeLayer() );
......@@ -668,11 +671,11 @@ void DIALOG_PLOT::applyPlotSettings()
ConfigBaseWriteDouble( m_config, CONFIG_PS_FINEWIDTH_ADJ,
(double)m_PSWidthAdjust / IU_PER_MM );
tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() );
tempOptions.SetFormat( GetPlotFormat() );
tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() );
tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() );
tempOptions.SetFormat( GetPlotFormat() );
tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 );
LSET selectedLayers;
......
......@@ -219,22 +219,36 @@ DIALOG_PLOT_BASE::DIALOG_PLOT_BASE( wxWindow* parent, wxWindowID id, const wxStr
m_PlotOptionsSizer->Add( sbSizerSoldMaskLayerOpt, 1, wxEXPAND, 5 );
m_GerberOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Gerber Options") ), wxVERTICAL );
m_GerberOptionsSizer = new wxStaticBoxSizer( new wxStaticBox( this, wxID_ANY, _("Gerber Options") ), wxHORIZONTAL );
wxBoxSizer* bSizerGbrOpt;
bSizerGbrOpt = new wxBoxSizer( wxVERTICAL );
m_useGerberExtensions = new wxCheckBox( this, wxID_ANY, _("Use proper filename extensions"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberExtensions->SetToolTip( _("Use proper Gerber extensions - .GBL, .GTL, etc...") );
m_GerberOptionsSizer->Add( m_useGerberExtensions, 0, wxLEFT|wxRIGHT|wxTOP, 2 );
bSizerGbrOpt->Add( m_useGerberExtensions, 0, wxALL, 2 );
m_useGerberAttributes = new wxCheckBox( this, wxID_ANY, _("Include extended attributes"), wxDefaultPosition, wxDefaultSize, 0 );
m_useGerberAttributes->SetToolTip( _("Include extended attributes for non-image data in the Gerber file") );
m_GerberOptionsSizer->Add( m_useGerberAttributes, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
bSizerGbrOpt->Add( m_useGerberAttributes, 0, wxALL, 2 );
m_subtractMaskFromSilk = new wxCheckBox( this, wxID_ANY, _("Subtract soldermask from silkscreen"), wxDefaultPosition, wxDefaultSize, 0 );
m_subtractMaskFromSilk->SetToolTip( _("Remove silkscreen from areas without soldermask") );
m_GerberOptionsSizer->Add( m_subtractMaskFromSilk, 0, wxTOP|wxRIGHT|wxLEFT, 2 );
bSizerGbrOpt->Add( m_subtractMaskFromSilk, 0, wxALL, 2 );
m_GerberOptionsSizer->Add( bSizerGbrOpt, 0, wxALIGN_CENTER_VERTICAL, 5 );
wxString m_rbGerberFormatChoices[] = { _("4.5 (unit mm)"), _("4.6 (unit mm)") };
int m_rbGerberFormatNChoices = sizeof( m_rbGerberFormatChoices ) / sizeof( wxString );
m_rbGerberFormat = new wxRadioBox( this, wxID_ANY, _("Format"), wxDefaultPosition, wxDefaultSize, m_rbGerberFormatNChoices, m_rbGerberFormatChoices, 1, wxRA_SPECIFY_COLS );
m_rbGerberFormat->SetSelection( 1 );
m_rbGerberFormat->SetToolTip( _("Precision of coordinates in Gerber files/\nUse the highter value if possible.") );
m_GerberOptionsSizer->Add( m_rbGerberFormat, 1, wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
m_PlotOptionsSizer->Add( m_GerberOptionsSizer, 0, wxALL|wxEXPAND, 3 );
......
This diff is collapsed.
......@@ -27,6 +27,7 @@ class DIALOG_SHIM;
#include <wx/checklst.h>
#include <wx/statbox.h>
#include <wx/checkbox.h>
#include <wx/radiobox.h>
#include <wx/bitmap.h>
#include <wx/image.h>
#include <wx/icon.h>
......@@ -91,6 +92,7 @@ class DIALOG_PLOT_BASE : public DIALOG_SHIM
wxCheckBox* m_useGerberExtensions;
wxCheckBox* m_useGerberAttributes;
wxCheckBox* m_subtractMaskFromSilk;
wxRadioBox* m_rbGerberFormat;
wxStaticBoxSizer* m_HPGLOptionsSizer;
wxStaticText* m_textPenSize;
wxTextCtrl* m_HPGLPenSizeOpt;
......
......@@ -726,7 +726,7 @@ void LAYER_WIDGET::SetLayerVisible( LAYER_NUM aLayer, bool isVisible )
int row = findLayerRow( aLayer );
if( row >= 0 )
{
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, 2 );
wxCheckBox* cb = (wxCheckBox*) getLayerComp( row, COLUMN_COLOR_LYR_CB );
wxASSERT( cb );
cb->SetValue( isVisible ); // does not fire an event
}
......
......@@ -49,6 +49,10 @@
*/
int g_DrawDefaultLineThickness = PLOT_LINEWIDTH_DEFAULT;
// default trailing digits in Gerber coordinates, when units are mm
// This is also the max usable precision (i.e. internal Pcbnew Units)
static const int gbrDefaultPrecision = 6;
using namespace PCBPLOTPARAMS_T;
......@@ -79,6 +83,7 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() :
{
m_useGerberExtensions = true;
m_useGerberAttributes = false;
m_gerberPrecision = gbrDefaultPrecision;
m_excludeEdgeLayer = true;
m_lineWidth = g_DrawDefaultLineThickness;
m_plotFrameRef = false;
......@@ -116,6 +121,17 @@ PCB_PLOT_PARAMS::PCB_PLOT_PARAMS() :
m_skipNPTH_Pads = false;
}
void PCB_PLOT_PARAMS::SetGerberPrecision( int aPrecision )
{
// Currently geber files use mm.
// accepted precision is only 6 (max value, this is the resolution of Pcbnew)
// or 5, min value for professional boards, when 6 creates problems
// to board makers.
m_gerberPrecision = aPrecision == gbrDefaultPrecision-1 ? gbrDefaultPrecision-1 :
gbrDefaultPrecision;
}
// PLEASE NOTE: only plot dialog options are processed
void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
......@@ -132,10 +148,15 @@ void PCB_PLOT_PARAMS::Format( OUTPUTFORMATTER* aFormatter,
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_usegerberextensions ),
m_useGerberExtensions ? trueStr : falseStr );
if( m_useGerberAttributes ) // save this option only if active,
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( 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",
getTokenName( T_gerberprecision ), m_gerberPrecision );
aFormatter->Print( aNestLevel+1, "(%s %s)\n", getTokenName( T_excludeedgelayer ),
m_excludeEdgeLayer ? trueStr : falseStr );
aFormatter->Print( aNestLevel+1, "(%s %f)\n", getTokenName( T_linewidth ),
......@@ -205,6 +226,8 @@ bool PCB_PLOT_PARAMS::operator==( const PCB_PLOT_PARAMS &aPcbPlotParams ) const
return false;
if( m_useGerberAttributes != aPcbPlotParams.m_useGerberAttributes )
return false;
if( m_gerberPrecision != aPcbPlotParams.m_gerberPrecision )
return false;
if( m_excludeEdgeLayer != aPcbPlotParams.m_excludeEdgeLayer )
return false;
if( m_lineWidth != aPcbPlotParams.m_lineWidth )
......@@ -371,6 +394,11 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
aPcbPlotParams->m_useGerberAttributes = parseBool();
break;
case T_gerberprecision:
aPcbPlotParams->m_gerberPrecision =
parseInt( gbrDefaultPrecision-1, gbrDefaultPrecision);
break;
case T_psa4output:
aPcbPlotParams->m_A4Output = parseBool();
break;
......@@ -438,10 +466,6 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
aPcbPlotParams->m_plotValue = parseBool();
break;
case T_plotothertext: // no more in use: keep for compatibility
parseBool(); // skip param value
break;
case T_plotinvisibletext:
aPcbPlotParams->m_plotInvisibleText = parseBool();
break;
......@@ -478,7 +502,7 @@ void PCB_PLOT_PARAMS_PARSER::Parse( PCB_PLOT_PARAMS* aPcbPlotParams )
break;
default:
Unexpected( CurText() );
skipCurrent();
break;
}
NeedRIGHT();
......@@ -526,3 +550,23 @@ double PCB_PLOT_PARAMS_PARSER::parseDouble()
return val;
}
void PCB_PLOT_PARAMS_PARSER::skipCurrent() throw( IO_ERROR, PARSE_ERROR )
{
int curr_level = 0;
T token;
while( ( token = NextTok() ) != T_EOF )
{
if( token == T_LEFT )
curr_level--;
if( token == T_RIGHT )
{
curr_level++;
if( curr_level > 0 )
return;
}
}
}
......@@ -65,6 +65,13 @@ private:
* @return double - the parsed double.
*/
double parseDouble();
/**
* Function skipCurrent
* Skip the current token level, i.e
* search for the RIGHT parenthesis which closes the current description
*/
void skipCurrent() throw( IO_ERROR, PARSE_ERROR );
};
......@@ -131,9 +138,15 @@ private:
* appending a suffix to the board name */
bool m_useGerberExtensions;
/// Include attributes from the Gerber X2 format (chapter 5 in revision J1)
/// Include attributes from the Gerber X2 format (chapter 5 in revision J2)
bool m_useGerberAttributes;
/// 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
/// 5 is the minimal value for professional boards.
int m_gerberPrecision;
/// Plot gerbers using auxiliary (drill) origin instead of page coordinates
bool m_useAuxOrigin;
......@@ -254,20 +267,29 @@ public:
void SetExcludeEdgeLayer( bool aFlag ) { m_excludeEdgeLayer = aFlag; }
bool GetExcludeEdgeLayer() const { return m_excludeEdgeLayer; }
void SetFormat( PlotFormat aFormat ) { m_format = aFormat; };
PlotFormat GetFormat() const { return m_format; };
void SetFormat( PlotFormat aFormat ) { m_format = aFormat; }
PlotFormat GetFormat() const { return m_format; }
void SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; };
wxString GetOutputDirectory() const { return m_outputDirectory; };
void SetOutputDirectory( wxString aDir ) { m_outputDirectory = aDir; }
wxString GetOutputDirectory() const { return m_outputDirectory; }
void SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; };
bool GetUseGerberAttributes() const { return m_useGerberAttributes; };
void SetUseGerberAttributes( bool aUse ) { m_useGerberAttributes = aUse; }
bool GetUseGerberAttributes() const { return m_useGerberAttributes; }
void SetUseGerberExtensions( bool aUse ) { m_useGerberExtensions = aUse; };
bool GetUseGerberExtensions() const { return m_useGerberExtensions; };
void SetUseGerberExtensions( bool aUse ) { m_useGerberExtensions = aUse; }
bool GetUseGerberExtensions() const { return m_useGerberExtensions; }
void SetGerberPrecision( int aPrecision );
int GetGerberPrecision() const { return m_gerberPrecision; }
/** Default precision of coordinates in Gerber files.
* when units are in mm (7 in inches, but Pcbnew uses mm).
* 6 is the internal resolution of Pcbnew, so the default is 6
*/
static int GetGerberDefaultPrecision() { return 6; }
void SetSubtractMaskFromSilk( bool aSubtract ) { m_subtractMaskFromSilk = aSubtract; };
bool GetSubtractMaskFromSilk() const { return m_subtractMaskFromSilk; };
bool GetSubtractMaskFromSilk() const { return m_subtractMaskFromSilk; }
void SetLayerSelection( LSET aSelection ) { m_layerSelection = aSelection; };
LSET GetLayerSelection() const { return m_layerSelection; };
......
......@@ -123,7 +123,10 @@ wxString GetGerberFileFunction( const BOARD *aBoard, LAYER_NUM aLayer )
break;
case Edge_Cuts:
attrib = wxString( wxT( "Profile" ) );
// Board outline.
// Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
// This last is the exception (Plated)
attrib = wxString( wxT( "Profile,NP" ) );
break;
case Dwgs_User:
......
......@@ -886,6 +886,10 @@ static void initializePlotter( PLOTTER *aPlotter, BOARD * aBoard,
aPlotter->SetViewport( offset, IU_PER_DECIMILS, compound_scale,
aPlotOpts->GetMirror() );
// has meaning only for gerber plotter. Must be called only after SetViewport
aPlotter->SetGerberCoordinatesFormat( aPlotOpts->GetGerberPrecision() );
aPlotter->SetDefaultLineWidth( aPlotOpts->GetLineWidth() );
aPlotter->SetCreator( wxT( "PCBNEW" ) );
aPlotter->SetColorMode( false ); // default is plot in Black and White.
......
......@@ -100,8 +100,9 @@ bool BOARD_PRINTOUT_CONTROLLER::OnPrintPage( int aPage )
// page order.
LSEQ seq = lset.UIOrder();
if( unsigned( aPage ) < seq.size() )
m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage] );
// aPage starts at 1, not 0
if( unsigned( aPage-1 ) < seq.size() )
m_PrintParams.m_PrintMaskLayer = LSET( seq[aPage-1] );
}
if( !m_PrintParams.m_PrintMaskLayer.any() )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment