KiCad PCB EDA Suite
pcbplot.cpp File Reference
#include <plotter.h>
#include <pcbplot.h>
#include <base_units.h>
#include <locale_io.h>
#include <reporter.h>
#include <board.h>
#include <plotcontroller.h>
#include <pcb_plot_params.h>
#include <wx/ffile.h>
#include <dialog_plot.h>
#include <build_version.h>
#include <gbr_metadata.h>
#include <render_settings.h>

Go to the source code of this file.

Functions

const wxString GetGerberProtelExtension (LAYER_NUM aLayer)
 Function GetGerberProtelExtension. More...
 
const wxString GetGerberFileFunctionAttribute (const BOARD *aBoard, LAYER_NUM aLayer)
 Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer, as defined in the Gerber file format specification J1 (chapter 5). More...
 
static const wxString GetGerberFilePolarityAttribute (LAYER_NUM aLayer)
 
static wxString & makeStringCompatX1 (wxString &aText, bool aUseX1CompatibilityMode)
 
void AddGerberX2Header (PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
 Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId file format attribute is not added. More...
 
void AddGerberX2Attribute (PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
 Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId TF.FileFunction TF.FilePolarity. More...
 
void BuildPlotFileName (wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
 Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory, add a suffix to the name and sets the specified extension the suffix is usually the layer name replaces not allowed chars in suffix by '_'. More...
 

Function Documentation

◆ AddGerberX2Attribute()

void AddGerberX2Attribute ( PLOTTER aPlotter,
const BOARD aBoard,
LAYER_NUM  aLayer,
bool  aUseX1CompatibilityMode 
)

Calculates some X2 attributes, as defined in the Gerber file format specification and add them to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId TF.FileFunction TF.FilePolarity.

Parameters
aPlotter= the current plotter.
aBoard= the board, needed to extract some info
aLayer= the layer number to create the attribute for
aUseX1CompatibilityMode= false to generate X2 attributes, true to use X1 compatibility (X2 attributes added as structured comments, starting by "G04 #@! " followed by the X2 attribute

Definition at line 350 of file pcbplot.cpp.

352 {
353  AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );
354 
355  wxString text;
356 
357  // Add the TF.FileFunction
358  text = GetGerberFileFunctionAttribute( aBoard, aLayer );
359  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
360 
361  // Add the TF.FilePolarity (for layers which support that)
362  text = GetGerberFilePolarityAttribute( aLayer );
363 
364  if( !text.IsEmpty() )
365  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
366 }
void AddGerberX2Header(PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and ...
Definition: pcbplot.cpp:279
void AddLineToHeader(const wxString &aExtraString)
Add a line to the list of free lines to print at the beginning of the file.
Definition: plotter.h:180
static const wxString GetGerberFilePolarityAttribute(LAYER_NUM aLayer)
Definition: pcbplot.cpp:208
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:267
const wxString GetGerberFileFunctionAttribute(const BOARD *aBoard, LAYER_NUM aLayer)
Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer,...
Definition: pcbplot.cpp:86

References AddGerberX2Header(), PLOTTER::AddLineToHeader(), GetGerberFileFunctionAttribute(), GetGerberFilePolarityAttribute(), and makeStringCompatX1().

Referenced by StartPlotBoard().

◆ AddGerberX2Header()

void AddGerberX2Header ( PLOTTER aPlotter,
const BOARD aBoard,
bool  aUseX1CompatibilityMode = false 
)

Calculates some X2 attributes, as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header: TF.GenerationSoftware TF.CreationDate TF.ProjectId file format attribute is not added.

Parameters
aPlotter= the current plotter.
aBoard= the board, needed to extract some info
aUseX1CompatibilityMode= false to generate X2 attributes, true to use X1 compatibility (X2 attributes added as structured comments, starting by "G04 #@! " followed by the X2 attribute

Definition at line 279 of file pcbplot.cpp.

280 {
281  wxString text;
282 
283  // Creates the TF,.GenerationSoftware. Format is:
284  // %TF,.GenerationSoftware,<vendor>,<application name>[,<application version>]*%
285  text.Printf( wxT( "%%TF.GenerationSoftware,KiCad,Pcbnew,%s*%%" ), GetBuildVersion() );
286  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
287 
288  // creates the TF.CreationDate attribute:
289  text = GbrMakeCreationDateAttributeString( aUseX1CompatibilityMode ?
292  aPlotter->AddLineToHeader( text );
293 
294  // Creates the TF,.ProjectId. Format is (from Gerber file format doc):
295  // %TF.ProjectId,<project id>,<project GUID>,<revision id>*%
296  // <project id> is the name of the project, restricted to basic ASCII symbols only,
297  // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
298  // and comma not accepted
299  // All illegal chars will be replaced by underscore
300  //
301  // <project GUID> is a string which is an unique id of a project.
302  // However Kicad does not handle such a project GUID, so it is built from the board name
303  wxFileName fn = aBoard->GetFileName();
304  wxString msg = fn.GetFullName();
305 
306  // Build a <project GUID>, from the board name
307  wxString guid = GbrMakeProjectGUIDfromString( msg );
308 
309  // build the <project id> string: this is the board short filename (without ext)
310  // and all non ASCII chars and comma are replaced by '_'
311  msg = fn.GetName();
312  msg.Replace( wxT( "," ), wxT( "_" ) );
313 
314  // build the <revision id> string. All non ASCII chars and comma are replaced by '_'
315  wxString rev = ExpandTextVars( aBoard->GetTitleBlock().GetRevision(), aBoard->GetProject() );
316  rev.Replace( wxT( "," ), wxT( "_" ) );
317 
318  if( rev.IsEmpty() )
319  rev = wxT( "rev?" );
320 
321  text.Printf( wxT( "%%TF.ProjectId,%s,%s,%s*%%" ), msg.ToAscii(), guid, rev.ToAscii() );
322  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
323 
324  // Add the TF.SameCoordinates, that specify all gerber files uses the same
325  // origin and orientation, and the registration between files is OK.
326  // The parameter of TF.SameCoordinates is a string that is common
327  // to all files using the same registration and has no special meaning:
328  // this is just a key
329  // Because there is no mirroring/rotation in Kicad, only the plot offset origin
330  // can create incorrect registration.
331  // So we create a key from plot offset options.
332  // and therefore for a given board, all Gerber files having the same key have the same
333  // plot origin and use the same registration
334  //
335  // Currently the key is "Original" when using absolute Pcbnew coordinates,
336  // and te PY ans PY position od auxiliary axis, when using it.
337  // Please, if absolute Pcbnew coordinates, one day, are set by user, change the way
338  // the key is built to ensure file only using the *same* axis have the same key.
339  wxString registration_id = "Original";
340  wxPoint auxOrigin = aBoard->GetDesignSettings().m_AuxOrigin;
341 
342  if( aBoard->GetPlotOptions().GetUseAuxOrigin() && auxOrigin.x && auxOrigin.y )
343  registration_id.Printf( "PX%xPY%x", auxOrigin.x, auxOrigin.y );
344 
345  text.Printf( "%%TF.SameCoordinates,%s*%%", registration_id.GetData() );
346  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
347 }
const PCB_PLOT_PARAMS & GetPlotOptions() const
Definition: board.h:609
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject)
Definition: common.cpp:58
PROJECT * GetProject() const
Definition: board.h:430
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Definition: board.h:591
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
void AddLineToHeader(const wxString &aExtraString)
Add a line to the list of free lines to print at the beginning of the file.
Definition: plotter.h:180
const wxString & GetFileName() const
Definition: board.h:298
wxString GetBuildVersion()
Get the full KiCad version string.
const wxString & GetRevision() const
Definition: title_block.h:86
wxString GbrMakeProjectGUIDfromString(const wxString &aText)
Build a project GUID using format RFC4122 Version 1 or 4 from the project name, because a KiCad proje...
TITLE_BLOCK & GetTitleBlock()
Definition: board.h:612
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:267
bool GetUseAuxOrigin() const
wxPoint m_AuxOrigin
origin for plot exports

References PLOTTER::AddLineToHeader(), ExpandTextVars(), GBR_NC_STRING_FORMAT_X1, GBR_NC_STRING_FORMAT_X2, GbrMakeCreationDateAttributeString(), GbrMakeProjectGUIDfromString(), GetBuildVersion(), BOARD::GetDesignSettings(), BOARD::GetFileName(), BOARD::GetPlotOptions(), BOARD::GetProject(), TITLE_BLOCK::GetRevision(), BOARD::GetTitleBlock(), PCB_PLOT_PARAMS::GetUseAuxOrigin(), BOARD_DESIGN_SETTINGS::m_AuxOrigin, and makeStringCompatX1().

Referenced by AddGerberX2Attribute(), GERBER_WRITER::createDrillFile(), and PLACEFILE_GERBER_WRITER::CreatePlaceFile().

◆ BuildPlotFileName()

void BuildPlotFileName ( wxFileName *  aFilename,
const wxString &  aOutputDir,
const wxString &  aSuffix,
const wxString &  aExtension 
)

Function BuildPlotFileName (helper function) Complete a plot filename: forces the output directory, add a suffix to the name and sets the specified extension the suffix is usually the layer name replaces not allowed chars in suffix by '_'.

Parameters
aFilename= the wxFileName to initialize Contains the base filename
aOutputDir= the path
aSuffix= the suffix to add to the base filename
aExtension= the file extension

Definition at line 369 of file pcbplot.cpp.

371 {
372  // aFilename contains the base filename only (without path and extension)
373  // when calling this function.
374  // It is expected to be a valid filename (this is usually the board filename)
375  aFilename->SetPath( aOutputDir );
376 
377  // Set the file extension
378  aFilename->SetExt( aExtension );
379 
380  // remove leading and trailing spaces if any from the suffix, if
381  // something survives add it to the name;
382  // also the suffix can contain some not allowed chars in filename (/ \ . : and some others),
383  // so change them to underscore
384  // Remember it can be called from a python script, so the illegal chars
385  // have to be filtered here.
386  wxString suffix = aSuffix;
387  suffix.Trim( true );
388  suffix.Trim( false );
389 
390  wxString badchars = wxFileName::GetForbiddenChars(wxPATH_DOS);
391  badchars.Append( "%." );
392 
393  for( unsigned ii = 0; ii < badchars.Len(); ii++ )
394  suffix.Replace( badchars[ii], wxT("_") );
395 
396  if( !suffix.IsEmpty() )
397  aFilename->SetName( aFilename->GetName() + wxT( "-" ) + suffix );
398 }

Referenced by DIALOG_EXPORT_SVG::ExportSVGFile(), PLOT_CONTROLLER::OpenPlotfile(), and DIALOG_PLOT::Plot().

◆ GetGerberFileFunctionAttribute()

const wxString GetGerberFileFunctionAttribute ( const BOARD aBoard,
LAYER_NUM  aLayer 
)

Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer, as defined in the Gerber file format specification J1 (chapter 5).

The returned string includes the "%TF.FileFunction" attribute prefix and the "*%" suffix.

Parameters
aBoard= the board, needed to get the total count of copper layers
aLayer= the layer number to create the attribute for
Returns
The attribute, as a text string

Definition at line 86 of file pcbplot.cpp.

87 {
88  wxString attrib;
89 
90  switch( aLayer )
91  {
92  case F_Adhes:
93  attrib = "Glue,Top";
94  break;
95 
96  case B_Adhes:
97  attrib = "Glue,Bot";
98  break;
99 
100  case F_SilkS:
101  attrib = "Legend,Top";
102  break;
103 
104  case B_SilkS:
105  attrib = "Legend,Bot";
106  break;
107 
108  case F_Mask:
109  attrib = "Soldermask,Top";
110  break;
111 
112  case B_Mask:
113  attrib = "Soldermask,Bot";
114  break;
115 
116  case F_Paste:
117  attrib = "Paste,Top";
118  break;
119 
120  case B_Paste:
121  attrib = "Paste,Bot";
122  break;
123 
124  case Edge_Cuts:
125  // Board outline.
126  // Can be "Profile,NP" (Not Plated: usual) or "Profile,P"
127  // This last is the exception (Plated)
128  attrib = "Profile,NP";
129  break;
130 
131  case Dwgs_User:
132  attrib = "OtherDrawing,Comment";
133  break;
134 
135  case Cmts_User:
136  attrib = "Other,Comment";
137  break;
138 
139  case Eco1_User:
140  attrib = "Other,ECO1";
141  break;
142 
143  case Eco2_User:
144  attrib = "Other,ECO2";
145  break;
146 
147  case B_Fab:
148  // This is actually a assembly layer
149  attrib = "AssemblyDrawing,Bot";
150  break;
151 
152  case F_Fab:
153  // This is actually a assembly layer
154  attrib = "AssemblyDrawing,Top";
155  break;
156 
157  case B_Cu:
158  attrib.Printf( wxT( "Copper,L%d,Bot" ), aBoard->GetCopperLayerCount() );
159  break;
160 
161  case F_Cu:
162  attrib = "Copper,L1,Top";
163  break;
164 
165  default:
166  if( IsCopperLayer( aLayer ) )
167  attrib.Printf( wxT( "Copper,L%d,Inr" ), aLayer+1 );
168  else
169  attrib.Printf( wxT( "Other,User" ), aLayer+1 );
170  break;
171  }
172 
173  // This code adds a optional parameter: the type of copper layers.
174  // Because it is not used by Pcbnew (it can be used only by external autorouters)
175  // user do not really set this parameter.
176  // Therefore do not add it.
177  // However, this code is left here, for perhaps a future usage.
178 #if 0
179  // Add the signal type of the layer, if relevant
180  if( IsCopperLayer( aLayer ) )
181  {
182  LAYER_T type = aBoard->GetLayerType( ToLAYER_ID( aLayer ) );
183 
184  switch( type )
185  {
186  case LT_SIGNAL:
187  attrib += ",Signal";
188  break;
189  case LT_POWER:
190  attrib += ",Plane";
191  break;
192  case LT_MIXED:
193  attrib += ",Mixed";
194  break;
195  default:
196  break; // do nothing (but avoid a warning for unhandled LAYER_T values from GCC)
197  }
198  }
199 #endif
200 
201  wxString fileFct;
202  fileFct.Printf( "%%TF.FileFunction,%s*%%", attrib );
203 
204  return fileFct;
205 }
Definition: board.h:67
Definition: board.h:68
LAYER_T GetLayerType(PCB_LAYER_ID aLayer) const
Return the type of the copper layer given by aLayer.
Definition: board.cpp:376
int GetCopperLayerCount() const
Definition: board.cpp:435
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
LAYER_T
The allowed types of layers, same as Specctra DSN spec.
Definition: board.h:63
PCB_LAYER_ID ToLAYER_ID(int aLayer)
Definition: lset.cpp:905

References B_Adhes, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, BOARD::GetCopperLayerCount(), BOARD::GetLayerType(), IsCopperLayer(), LT_MIXED, LT_POWER, LT_SIGNAL, and ToLAYER_ID().

Referenced by AddGerberX2Attribute().

◆ GetGerberFilePolarityAttribute()

static const wxString GetGerberFilePolarityAttribute ( LAYER_NUM  aLayer)
static

Definition at line 208 of file pcbplot.cpp.

209 {
210  /* build the string %TF.FilePolarity,Positive*%
211  * or %TF.FilePolarity,Negative*%
212  * an emply string for layers which do not use a polarity
213  *
214  * The value of the .FilePolarity specifies whether the image represents the
215  * presence or absence of material.
216  * This attribute can only be used when the file represents a pattern in a material layer,
217  * e.g. copper, solder mask, legend.
218  * Together with.FileFunction it defines the role of that image in
219  * the layer structure of the PCB.
220  * Note that the .FilePolarity attribute does not change the image -
221  * no attribute does.
222  * It changes the interpretation of the image.
223  * For example, in a copper layer in positive polarity a round flash generates a copper pad.
224  * In a copper layer in negative polarity it generates a clearance.
225  * Solder mask images usually represent solder mask openings and are then negative.
226  * This may be counter-intuitive.
227  */
228  int polarity = 0;
229 
230  switch( aLayer )
231  {
232  case F_Adhes:
233  case B_Adhes:
234  case F_SilkS:
235  case B_SilkS:
236  case F_Paste:
237  case B_Paste:
238  polarity = 1;
239  break;
240 
241  case F_Mask:
242  case B_Mask:
243  polarity = -1;
244  break;
245 
246  default:
247  if( IsCopperLayer( aLayer ) )
248  polarity = 1;
249  break;
250  }
251 
252  wxString filePolarity;
253 
254  if( polarity == 1 )
255  filePolarity = "%TF.FilePolarity,Positive*%";
256  if( polarity == -1 )
257  filePolarity = "%TF.FilePolarity,Negative*%";
258 
259  return filePolarity;
260 }
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.

References B_Adhes, B_Mask, B_Paste, B_SilkS, F_Adhes, F_Mask, F_Paste, F_SilkS, and IsCopperLayer().

Referenced by AddGerberX2Attribute().

◆ GetGerberProtelExtension()

const wxString GetGerberProtelExtension ( LAYER_NUM  aLayer)

Function GetGerberProtelExtension.

Returns
the appropriate Gerber file extension for aLayer used by Protel, and still sometimes in use (although the official Gerber Ext is now .gbr)

Definition at line 45 of file pcbplot.cpp.

46 {
47  if( IsCopperLayer( aLayer ) )
48  {
49  if( aLayer == F_Cu )
50  return wxT( "gtl" );
51  else if( aLayer == B_Cu )
52  return wxT( "gbl" );
53  else
54  {
55  return wxString::Format( wxT( "g%d" ), aLayer+1 );
56  }
57  }
58  else
59  {
60  switch( aLayer )
61  {
62  case B_Adhes: return wxT( "gba" );
63  case F_Adhes: return wxT( "gta" );
64 
65  case B_Paste: return wxT( "gbp" );
66  case F_Paste: return wxT( "gtp" );
67 
68  case B_SilkS: return wxT( "gbo" );
69  case F_SilkS: return wxT( "gto" );
70 
71  case B_Mask: return wxT( "gbs" );
72  case F_Mask: return wxT( "gts" );
73 
74  case Edge_Cuts: return wxT( "gm1" );
75 
76  case Dwgs_User:
77  case Cmts_User:
78  case Eco1_User:
79  case Eco2_User:
80  default: return wxT( "gbr" );
81  }
82  }
83 }
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.

References B_Adhes, B_Cu, B_Mask, B_Paste, B_SilkS, Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_Cu, F_Mask, F_Paste, F_SilkS, Format(), and IsCopperLayer().

Referenced by PLOT_CONTROLLER::OpenPlotfile(), and DIALOG_PLOT::Plot().

◆ makeStringCompatX1()

static wxString& makeStringCompatX1 ( wxString &  aText,
bool  aUseX1CompatibilityMode 
)
static

Definition at line 267 of file pcbplot.cpp.

268 {
269  if( aUseX1CompatibilityMode )
270  {
271  aText.Replace( "%", "" );
272  aText.Prepend( "G04 #@! " );
273  }
274 
275  return aText;
276 }

Referenced by AddGerberX2Attribute(), and AddGerberX2Header().