KiCad PCB EDA Suite
pcbplot.cpp File Reference
#include <fctsys.h>
#include <plotter.h>
#include <confirm.h>
#include <pcb_edit_frame.h>
#include <pcbplot.h>
#include <base_units.h>
#include <reporter.h>
#include <class_board.h>
#include <pcbnew.h>
#include <plotcontroller.h>
#include <pcb_plot_params.h>
#include <wx/ffile.h>
#include <dialog_plot.h>
#include <macros.h>
#include <build_version.h>
#include <gbr_metadata.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 354 of file pcbplot.cpp.

356 {
357  AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );
358 
359  wxString text;
360 
361  // Add the TF.FileFunction
362  text = GetGerberFileFunctionAttribute( aBoard, aLayer );
363  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
364 
365  // Add the TF.FilePolarity (for layers which support that)
366  text = GetGerberFilePolarityAttribute( aLayer );
367 
368  if( !text.IsEmpty() )
369  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
370 }
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:282
void AddLineToHeader(const wxString &aExtraString)
Function AddLineToHeader Add a line to the list of free lines to print at the beginning of the file.
Definition: plotter.h:179
static const wxString GetGerberFilePolarityAttribute(LAYER_NUM aLayer)
Definition: pcbplot.cpp:211
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:270
const wxString GetGerberFileFunctionAttribute(const BOARD *aBoard, LAYER_NUM aLayer)
Function GetGerberFileFunctionAttribute Returns the "file function" attribute for aLayer,...
Definition: pcbplot.cpp:89

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 282 of file pcbplot.cpp.

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

References PLOTTER::AddLineToHeader(), GBR_NC_STRING_FORMAT_X1, GBR_NC_STRING_FORMAT_X2, GbrMakeCreationDateAttributeString(), GbrMakeProjectGUIDfromString(), GetBuildVersion(), GetChars(), BOARD::GetDesignSettings(), BOARD::GetFileName(), BOARD::GetPlotOptions(), PCB_PLOT_PARAMS::GetUseAuxOrigin(), BOARD_DESIGN_SETTINGS::m_AuxOrigin, makeStringCompatX1(), wxPoint::x, and wxPoint::y.

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 373 of file pcbplot.cpp.

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

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 89 of file pcbplot.cpp.

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

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, GetChars(), 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 211 of file pcbplot.cpp.

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

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

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

Referenced by AddGerberX2Attribute(), and AddGerberX2Header().