From ab58dbfced793553d4154e7617e46607fd77b825 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Fri, 4 Jul 2014 16:22:38 +0200 Subject: [PATCH] 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. --- common/common_plotGERBER_functions.cpp | 57 +-- common/pcb_plot_params.keywords | 2 +- include/plot_common.h | 29 +- pcbnew/dialogs/dialog_plot.cpp | 11 +- pcbnew/dialogs/dialog_plot_base.cpp | 22 +- pcbnew/dialogs/dialog_plot_base.fbp | 471 +++++++++++++++---------- pcbnew/dialogs/dialog_plot_base.h | 2 + pcbnew/layer_widget.cpp | 2 +- pcbnew/pcb_plot_params.cpp | 56 ++- pcbnew/pcb_plot_params.h | 42 ++- pcbnew/pcbplot.cpp | 5 +- pcbnew/plot_board_layers.cpp | 4 + pcbnew/printout_controler.cpp | 5 +- 13 files changed, 464 insertions(+), 244 deletions(-) diff --git a/common/common_plotGERBER_functions.cpp b/common/common_plotGERBER_functions.cpp index bfbe00c3a7..94a84af4e3 100644 --- a/common/common_plotGERBER_functions.cpp +++ b/common/common_plotGERBER_functions.cpp @@ -15,6 +15,22 @@ #include +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 ); diff --git a/common/pcb_plot_params.keywords b/common/pcb_plot_params.keywords index 96e756c6d2..c64f70bca6 100644 --- a/common/pcb_plot_params.keywords +++ b/common/pcb_plot_params.keywords @@ -1,6 +1,7 @@ drillshape excludeedgelayer false +gerberprecision hpglpendiameter hpglpennumber hpglpenoverlay @@ -15,7 +16,6 @@ padsonsilk pcbplotparams plotframeref plotinvisibletext -plotothertext plotreference plotvalue psa4output diff --git a/include/plot_common.h b/include/plot_common.h index f7732db7cf..b6793962df 100644 --- a/include/plot_common.h +++ b/include/plot_common.h @@ -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 ); diff --git a/pcbnew/dialogs/dialog_plot.cpp b/pcbnew/dialogs/dialog_plot.cpp index 4cffce5151..9d5c689c1d 100644 --- a/pcbnew/dialogs/dialog_plot.cpp +++ b/pcbnew/dialogs/dialog_plot.cpp @@ -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,12 +671,12 @@ void DIALOG_PLOT::applyPlotSettings() ConfigBaseWriteDouble( m_config, CONFIG_PS_FINEWIDTH_ADJ, (double)m_PSWidthAdjust / IU_PER_MM ); - tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() ); - - tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() ); - tempOptions.SetFormat( GetPlotFormat() ); + tempOptions.SetUseGerberExtensions( m_useGerberExtensions->GetValue() ); + tempOptions.SetUseGerberAttributes( m_useGerberAttributes->GetValue() ); + tempOptions.SetGerberPrecision( m_rbGerberFormat->GetSelection() == 0 ? 5 : 6 ); + LSET selectedLayers; for( unsigned i = 0; i < m_layerList.size(); i++ ) diff --git a/pcbnew/dialogs/dialog_plot_base.cpp b/pcbnew/dialogs/dialog_plot_base.cpp index e8daf4c482..dfaf33b0b6 100644 --- a/pcbnew/dialogs/dialog_plot_base.cpp +++ b/pcbnew/dialogs/dialog_plot_base.cpp @@ -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 ); diff --git a/pcbnew/dialogs/dialog_plot_base.fbp b/pcbnew/dialogs/dialog_plot_base.fbp index 76d0fc9262..9bfcd299fe 100644 --- a/pcbnew/dialogs/dialog_plot_base.fbp +++ b/pcbnew/dialogs/dialog_plot_base.fbp @@ -2687,102 +2687,289 @@ Gerber Options m_GerberOptionsSizer - wxVERTICAL + wxHORIZONTAL protected - - 2 - wxLEFT|wxRIGHT|wxTOP + + 5 + wxALIGN_CENTER_VERTICAL 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Use proper filename extensions - - 0 - - - 0 + - 1 - m_useGerberExtensions - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Use proper Gerber extensions - .GBL, .GTL, etc... - - wxFILTER_NONE - wxDefaultValidator - - - - - - - - - - - - - - - - - - - - - - - - - - - - + bSizerGbrOpt + wxVERTICAL + none + + 2 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Use proper filename extensions + + 0 + + + 0 + + 1 + m_useGerberExtensions + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Use proper Gerber extensions - .GBL, .GTL, etc... + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Include extended attributes + + 0 + + + 0 + + 1 + m_useGerberAttributes + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Include extended attributes for non-image data in the Gerber file + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 + wxALL + 0 + + 1 + 1 + 1 + 1 + + + + + + + + 1 + 0 + 0 + 1 + + 1 + 0 + Dock + 0 + Left + 1 + + 1 + + 0 + 0 + wxID_ANY + Subtract soldermask from silkscreen + + 0 + + + 0 + + 1 + m_subtractMaskFromSilk + 1 + + + protected + 1 + + Resizable + 1 + + + + 0 + Remove silkscreen from areas without soldermask + + wxFILTER_NONE + wxDefaultValidator + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - 2 - wxTOP|wxRIGHT|wxLEFT - 0 - + 5 + wxEXPAND|wxALIGN_CENTER_VERTICAL|wxALL + 1 + 1 1 1 @@ -2796,7 +2983,7 @@ 1 0 - 0 + "4.5 (unit mm)" "4.6 (unit mm)" 1 1 @@ -2811,7 +2998,8 @@ 0 0 wxID_ANY - Include extended attributes + Format + 1 0 @@ -2819,7 +3007,7 @@ 0 1 - m_useGerberAttributes + m_rbGerberFormat 1 @@ -2827,12 +3015,13 @@ 1 Resizable + 1 1 - + wxRA_SPECIFY_COLS 0 - Include extended attributes for non-image data in the Gerber file + Precision of coordinates in Gerber files/ Use the highter value if possible. wxFILTER_NONE wxDefaultValidator @@ -2841,95 +3030,6 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - 2 - wxTOP|wxRIGHT|wxLEFT - 0 - - 1 - 1 - 1 - 1 - - - - - - - - 1 - 0 - 0 - 1 - - 1 - 0 - Dock - 0 - Left - 1 - - 1 - - 0 - 0 - wxID_ANY - Subtract soldermask from silkscreen - - 0 - - - 0 - - 1 - m_subtractMaskFromSilk - 1 - - - protected - 1 - - Resizable - 1 - - - - 0 - Remove silkscreen from areas without soldermask - - wxFILTER_NONE - wxDefaultValidator - - - - - - @@ -2946,6 +3046,7 @@ + @@ -3162,11 +3263,11 @@ - + 5 wxEXPAND 1 - + bSizer21 wxVERTICAL diff --git a/pcbnew/dialogs/dialog_plot_base.h b/pcbnew/dialogs/dialog_plot_base.h index f710b095cb..13c4972a29 100644 --- a/pcbnew/dialogs/dialog_plot_base.h +++ b/pcbnew/dialogs/dialog_plot_base.h @@ -27,6 +27,7 @@ class DIALOG_SHIM; #include #include #include +#include #include #include #include @@ -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; diff --git a/pcbnew/layer_widget.cpp b/pcbnew/layer_widget.cpp index 0250d92763..fda117b8e4 100644 --- a/pcbnew/layer_widget.cpp +++ b/pcbnew/layer_widget.cpp @@ -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 } diff --git a/pcbnew/pcb_plot_params.cpp b/pcbnew/pcb_plot_params.cpp index ea2993fe1e..c03acc51dd 100644 --- a/pcbnew/pcb_plot_params.cpp +++ b/pcbnew/pcb_plot_params.cpp @@ -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; + } + } +} diff --git a/pcbnew/pcb_plot_params.h b/pcbnew/pcb_plot_params.h index c3f6170a8c..9135475156 100644 --- a/pcbnew/pcb_plot_params.h +++ b/pcbnew/pcb_plot_params.h @@ -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; }; diff --git a/pcbnew/pcbplot.cpp b/pcbnew/pcbplot.cpp index 7b492ad349..d638439bbf 100644 --- a/pcbnew/pcbplot.cpp +++ b/pcbnew/pcbplot.cpp @@ -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: diff --git a/pcbnew/plot_board_layers.cpp b/pcbnew/plot_board_layers.cpp index 42c93949f1..e96dcb0702 100644 --- a/pcbnew/plot_board_layers.cpp +++ b/pcbnew/plot_board_layers.cpp @@ -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. diff --git a/pcbnew/printout_controler.cpp b/pcbnew/printout_controler.cpp index 595c39f2a7..3b982fe2bf 100644 --- a/pcbnew/printout_controler.cpp +++ b/pcbnew/printout_controler.cpp @@ -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() )