KiCad PCB EDA Suite
pcbplot.cpp File Reference
#include <plotters/plotter.h>
#include <pcbplot.h>
#include <base_units.h>
#include <locale_io.h>
#include <reporter.h>
#include <board.h>
#include <board_design_settings.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)
 
const wxString GetGerberFileFunctionAttribute (const BOARD *aBoard, LAYER_NUM aLayer)
 Return 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)
 Calculate some X2 attributes as defined in the Gerber file format specification J4 (chapter 5) and add them the to the gerber file header. More...
 
void AddGerberX2Attribute (PLOTTER *aPlotter, const BOARD *aBoard, LAYER_NUM aLayer, bool aUseX1CompatibilityMode)
 Calculate some X2 attributes as defined in the Gerber file format specification and add them to the gerber file header. More...
 
void BuildPlotFileName (wxFileName *aFilename, const wxString &aOutputDir, const wxString &aSuffix, const wxString &aExtension)
 Complete a plot filename. More...
 

Function Documentation

◆ AddGerberX2Attribute()

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

Calculate 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
aPlotteris the current plotter.
aBoardis the board, needed to extract some info.
aLayeris the layer number to create the attribute for.
aUseX1CompatibilityModeset to 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 353 of file pcbplot.cpp.

355 {
356  AddGerberX2Header( aPlotter, aBoard, aUseX1CompatibilityMode );
357 
358  wxString text;
359 
360  // Add the TF.FileFunction
361  text = GetGerberFileFunctionAttribute( aBoard, aLayer );
362  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
363 
364  // Add the TF.FilePolarity (for layers which support that)
366 
367  if( !text.IsEmpty() )
368  aPlotter->AddLineToHeader( makeStringCompatX1( text, aUseX1CompatibilityMode ) );
369 }
void AddGerberX2Header(PLOTTER *aPlotter, const BOARD *aBoard, bool aUseX1CompatibilityMode)
Calculate some X2 attributes as defined in the Gerber file format specification J4 (chapter 5) and ad...
Definition: pcbplot.cpp:282
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:183
static const wxString GetGerberFilePolarityAttribute(LAYER_NUM aLayer)
Definition: pcbplot.cpp:209
static wxString & makeStringCompatX1(wxString &aText, bool aUseX1CompatibilityMode)
Definition: pcbplot.cpp:270
const wxString GetGerberFileFunctionAttribute(const BOARD *aBoard, LAYER_NUM aLayer)
Return the "file function" attribute for aLayer, as defined in the Gerber file format specification J...
Definition: pcbplot.cpp:87

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

Referenced by StartPlotBoard().

◆ AddGerberX2Header()

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

Calculate 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
aPlotteris the current plotter.
aBoardis the board, needed to extract some info.
aUseX1CompatibilityModeset to 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.

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

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 
)

Complete a plot filename.

It forces the output directory, adds a suffix to the name, and sets the specified extension. The suffix is usually the layer name and replaces illegal file name character in the suffix with an underscore character.

Parameters
aFilenameis the file name to initialize that contains the base filename.
aOutputDiris the path.
aSuffixis the suffix to add to the base filename.
aExtensionis the file extension.

Definition at line 372 of file pcbplot.cpp.

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

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

◆ GetGerberFileFunctionAttribute()

const wxString GetGerberFileFunctionAttribute ( const BOARD aBoard,
LAYER_NUM  aLayer 
)

Return 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
aBoardis the board, needed to get the total count of copper layers.
aLayeris the layer number to create the attribute for.
Returns
The attribute, as a text string

Definition at line 87 of file pcbplot.cpp.

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

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

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)
Returns
the appropriate Gerber file extension for aLayer

Definition at line 46 of file pcbplot.cpp.

47 {
48  if( IsCopperLayer( aLayer ) )
49  {
50  if( aLayer == F_Cu )
51  return wxT( "gtl" );
52  else if( aLayer == B_Cu )
53  return wxT( "gbl" );
54  else
55  {
56  return wxString::Format( wxT( "g%d" ), aLayer+1 );
57  }
58  }
59  else
60  {
61  switch( aLayer )
62  {
63  case B_Adhes: return wxT( "gba" );
64  case F_Adhes: return wxT( "gta" );
65 
66  case B_Paste: return wxT( "gbp" );
67  case F_Paste: return wxT( "gtp" );
68 
69  case B_SilkS: return wxT( "gbo" );
70  case F_SilkS: return wxT( "gto" );
71 
72  case B_Mask: return wxT( "gbs" );
73  case F_Mask: return wxT( "gts" );
74 
75  case Edge_Cuts: return wxT( "gm1" );
76 
77  case Dwgs_User:
78  case Cmts_User:
79  case Eco1_User:
80  case Eco2_User:
81  default: return wxT( "gbr" );
82  }
83  }
84 }
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:787
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
Definition: layer_ids.h:70

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().