KiCad PCB EDA Suite
GERBER_JOBFILE_WRITER Class Reference

GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make a board: list of gerber files info about the board itsel: size, number of copper layers thickness of the board, copper and dielectric and some other info (colors, finish type ...) More...

#include <gerber_jobfile_writer.h>

Public Member Functions

 GERBER_JOBFILE_WRITER (BOARD *aPcb, REPORTER *aReporter=nullptr)
 
virtual ~GERBER_JOBFILE_WRITER ()
 
void AddGbrFile (PCB_LAYER_ID aLayer, wxString &aFilename)
 add a gerber file name and type in job file list More...
 
bool CreateJobFile (const wxString &aFullFilename)
 Creates a Gerber job file. More...
 
bool WriteJSONJobFile (const wxString &aFullFilename)
 Creates an Gerber job file in JSON format. More...
 

Private Member Functions

enum ONSIDE hasSilkLayers ()
 
enum ONSIDE hasSolderMasks ()
 
const char * sideKeyValue (enum ONSIDE aValue)
 
void addJSONHeader ()
 Add the job file header in JSON format to m_JSONbuffer. More...
 
void addJSONGeneralSpecs ()
 Add the General Specs in JSON format to m_JSONbuffer. More...
 
void addJSONFilesAttributes ()
 Add the Files Attributes section in JSON format to m_JSONbuffer. More...
 
void addJSONMaterialStackup ()
 Add the Material Stackup section in JSON format to m_JSONbuffer This is the ordered list of stackup layers (mask, paste, silk, copper, dielectric) used to make the physical board. More...
 
void addJSONDesignRules ()
 Add the Design Rules section in JSON format to m_JSONbuffer. More...
 
void removeJSONSepararator ()
 Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a
. More...
 
void addIndent ()
 add m_indent spaces in m_JSONbuffer More...
 
void openBlock ()
 open a JSON block: add '{' and increment indentation More...
 
void openArrayBlock ()
 open a JSON array block: add '[' and increment indentation More...
 
void closeBlock ()
 close a JSON block: decrement indentation and add '}' More...
 
void closeBlockWithSep ()
 close a JSON block: decrement indentation and add '}' and ',' More...
 
void closeArrayBlock ()
 close a JSON array block: decrement indentation and add ']' More...
 
void closeArrayBlockWithSep ()
 close a JSON array block: decrement indentation and add ']' and ',' More...
 
void addJSONObject (const wxString &aParam)
 Add aParam to m_JSONbuffer, with suitable indentation. More...
 
void addJSONObject (const char *aParam)
 

Private Attributes

BOARDm_pcb
 
REPORTERm_reporter
 
JOBFILE_PARAMS m_params
 
double m_conversionUnits
 
wxString m_JSONbuffer
 
int m_indent
 

Detailed Description

GERBER_JOBFILE_WRITER is a class used to create Gerber job file a Gerber job file stores info to make a board: list of gerber files info about the board itsel: size, number of copper layers thickness of the board, copper and dielectric and some other info (colors, finish type ...)

note: dimensions are always in mm in Kicad job file (can be also in inches in a job file) and they are in floating point notation

Definition at line 69 of file gerber_jobfile_writer.h.

Constructor & Destructor Documentation

◆ GERBER_JOBFILE_WRITER()

GERBER_JOBFILE_WRITER::GERBER_JOBFILE_WRITER ( BOARD aPcb,
REPORTER aReporter = nullptr 
)

Definition at line 50 of file gerber_jobfile_writer.cpp.

51 {
52  m_pcb = aPcb;
53  m_reporter = aReporter;
54  m_conversionUnits = 1.0 / IU_PER_MM; // Gerber units = mm
55  m_indent = 0;
56 }

References m_conversionUnits, m_indent, m_pcb, and m_reporter.

◆ ~GERBER_JOBFILE_WRITER()

virtual GERBER_JOBFILE_WRITER::~GERBER_JOBFILE_WRITER ( )
inlinevirtual

Definition at line 74 of file gerber_jobfile_writer.h.

75  {
76  }

Member Function Documentation

◆ AddGbrFile()

void GERBER_JOBFILE_WRITER::AddGbrFile ( PCB_LAYER_ID  aLayer,
wxString &  aFilename 
)
inline

add a gerber file name and type in job file list

Parameters
aLayeris the PCB_LAYER_ID corresponding to the gerber file
aFilenameis the filename (without path) of the gerber file

Definition at line 83 of file gerber_jobfile_writer.h.

84  {
85  m_params.m_GerberFileList.Add( aFilename );
86  m_params.m_LayerId.push_back( aLayer );
87  }
wxArrayString m_GerberFileList
std::vector< PCB_LAYER_ID > m_LayerId

References JOBFILE_PARAMS::m_GerberFileList, JOBFILE_PARAMS::m_LayerId, and m_params.

Referenced by DIALOG_PLOT::Plot().

◆ addIndent()

void GERBER_JOBFILE_WRITER::addIndent ( )
inlineprivate

add m_indent spaces in m_JSONbuffer

Definition at line 160 of file gerber_jobfile_writer.h.

References m_indent, and m_JSONbuffer.

Referenced by addJSONObject(), closeArrayBlock(), closeArrayBlockWithSep(), closeBlock(), closeBlockWithSep(), openArrayBlock(), and openBlock().

◆ addJSONDesignRules()

void GERBER_JOBFILE_WRITER::addJSONDesignRules ( )
private

Add the Design Rules section in JSON format to m_JSONbuffer.

Definition at line 417 of file gerber_jobfile_writer.cpp.

418 {
419  // Add the Design Rules section in JSON format to m_JSONbuffer
420  // Job file support a few design rules:
421  const BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
422  NETCLASS defaultNC = *dsnSettings.GetDefault();
423  int minclearanceOuter = defaultNC.GetClearance();
424  bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2;
425 
426  // Search a smaller clearance in other net classes, if any.
427  for( NETCLASSES::const_iterator it = dsnSettings.m_NetClasses.begin();
428  it != dsnSettings.m_NetClasses.end();
429  ++it )
430  {
431  NETCLASS netclass = *it->second;
432  minclearanceOuter = std::min( minclearanceOuter, netclass.GetClearance() );
433  }
434 
435  // job file knows different clearance types.
436  // Kicad knows only one clearance for pads and tracks
437  int minclearance_track2track = minclearanceOuter;
438 
439  // However, pads can have a specific clearance defined for a pad or a footprint,
440  // and min clearance can be dependent on layers.
441  // Search for a minimal pad clearance:
442  int minPadClearanceOuter = defaultNC.GetClearance();
443  int minPadClearanceInner = defaultNC.GetClearance();
444 
445  for( MODULE* module : m_pcb->Modules() )
446  {
447  for( auto& pad : module->Pads() )
448  {
449  if( ( pad->GetLayerSet() & LSET::InternalCuMask() ).any() )
450  minPadClearanceInner = std::min( minPadClearanceInner, pad->GetClearance() );
451 
452  if( ( pad->GetLayerSet() & LSET::ExternalCuMask() ).any() )
453  minPadClearanceOuter = std::min( minPadClearanceOuter, pad->GetClearance() );
454  }
455  }
456 
457 
458  addJSONObject( "\"DesignRules\":\n" );
459  openArrayBlock();
460 
461  openBlock();
462  addJSONObject( "\"Layers\": \"Outer\",\n" );
463  addJSONObject( wxString::Format( "\"PadToPad\": %.3f,\n", minPadClearanceOuter*m_conversionUnits ) );
464  addJSONObject( wxString::Format( "\"PadToTrack\": %.3f,\n", minPadClearanceOuter*m_conversionUnits ) );
465  addJSONObject( wxString::Format( "\"TrackToTrack\": %.3f,\n", minclearance_track2track*m_conversionUnits ) );
466 
467  // Until this is changed in Kicad, use the same value for internal tracks
468  int minclearanceInner = minclearanceOuter;
469 
470  // Output the minimal track width
471  int mintrackWidthOuter = INT_MAX;
472  int mintrackWidthInner = INT_MAX;
473 
474  for( TRACK* track : m_pcb->Tracks() )
475  {
476  if( track->Type() == PCB_VIA_T )
477  continue;
478 
479  if( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu )
480  mintrackWidthOuter = std::min( mintrackWidthOuter, track->GetWidth() );
481  else
482  mintrackWidthInner = std::min( mintrackWidthInner, track->GetWidth() );
483  }
484 
485  if( mintrackWidthOuter != INT_MAX )
486  addJSONObject( wxString::Format( "\"MinLineWidth\": %.3f,\n",
487  mintrackWidthOuter*m_conversionUnits ) );
488 
489  // Output the minimal zone to xx clearance
490  // Note: zones can have a zone clearance set to 0
491  // if happens, the actual zone clearance is the clearance of its class
492  minclearanceOuter = INT_MAX;
493  minclearanceInner = INT_MAX;
494 
495  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
496  {
497  ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
498 
499  if( zone->GetIsKeepout() || !zone->IsOnCopperLayer() )
500  continue;
501 
502  int zclerance = zone->GetClearance();
503 
504  if( zone->GetLayer() == B_Cu || zone->GetLayer() == F_Cu )
505  minclearanceOuter = std::min( minclearanceOuter, zclerance );
506  else
507  minclearanceInner = std::min( minclearanceInner, zclerance );
508  }
509 
510  if( minclearanceOuter != INT_MAX )
511  addJSONObject( wxString::Format( "\"TrackToRegion\": %.3f,\n",
512  minclearanceOuter*m_conversionUnits ) );
513 
514  if( minclearanceOuter != INT_MAX )
515  addJSONObject( wxString::Format( "\"RegionToRegion\": %.3f,\n",
516  minclearanceOuter*m_conversionUnits ) );
517 
518  removeJSONSepararator(); // remove the last separator
519 
520  if( !hasInnerLayers )
521  closeBlock();
522  else
524 
525 
526  if( hasInnerLayers )
527  {
528  openBlock();
529  addJSONObject( "\"Layers\": \"Inner\",\n" );
530  addJSONObject( wxString::Format( "\"PadToPad\": %.3f,\n", minPadClearanceInner*m_conversionUnits ) );
531  addJSONObject( wxString::Format( "\"PadToTrack\": %.3f,\n", minPadClearanceInner*m_conversionUnits ) );
532  addJSONObject( wxString::Format( "\"TrackToTrack\": %.3f,\n", minclearance_track2track*m_conversionUnits ) );
533 
534  if( mintrackWidthInner != INT_MAX )
535  addJSONObject( wxString::Format( "\"MinLineWidth\": %.3f,\n", mintrackWidthInner*m_conversionUnits ) );
536 
537  if( minclearanceInner != INT_MAX )
538  addJSONObject( wxString::Format( "\"TrackToRegion\": %.3f,\n", minclearanceInner*m_conversionUnits ) );
539 
540  if( minclearanceInner != INT_MAX )
541  addJSONObject( wxString::Format( "\"RegionToRegion\": %.3f,\n", minclearanceInner*m_conversionUnits ) );
542 
543  removeJSONSepararator(); // remove the last separator
544  closeBlock();
545  }
546 
547  // Close DesignRules
549 }
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:59
void removeJSONSepararator()
Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a ...
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:185
void addJSONObject(const wxString &aParam)
Add aParam to m_JSONbuffer, with suitable indentation.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
iterator end()
Definition: netclass.h:249
void closeBlock()
close a JSON block: decrement indentation and add '}'
NETCLASS_MAP::const_iterator const_iterator
Definition: netclass.h:251
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:775
void openBlock()
open a JSON block: add '{' and increment indentation
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:981
iterator begin()
Definition: netclass.h:248
DLIST_ITERATOR_WRAPPER< MODULE > Modules()
Definition: class_board.h:252
Class NETCLASS handles a collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:55
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:636
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:706
void openArrayBlock()
open a JSON array block: add '[' and increment indentation
void closeBlockWithSep()
close a JSON block: decrement indentation and add '}' and ','
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:651
void closeArrayBlockWithSep()
close a JSON array block: decrement indentation and add ']' and ','
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
NETCLASSPTR GetDefault() const
Function GetDefault.
int GetClearance() const
Definition: netclass.h:162
int GetCopperLayerCount() const
Function GetCopperLayerCount.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:96
DLIST_ITERATOR_WRAPPER< TRACK > Tracks()
Definition: class_board.h:251
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:952
bool IsOnCopperLayer() const
Function IsOnCopperLayer.
Definition: class_zone.cpp:191
#define min(a, b)
Definition: auxiliary.h:85
Class BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.

References addJSONObject(), B_Cu, NETCLASSES::begin(), closeArrayBlockWithSep(), closeBlock(), closeBlockWithSep(), NETCLASSES::end(), LSET::ExternalCuMask(), F_Cu, Format(), BOARD::GetArea(), BOARD::GetAreaCount(), ZONE_CONTAINER::GetClearance(), NETCLASS::GetClearance(), BOARD::GetCopperLayerCount(), BOARD_DESIGN_SETTINGS::GetDefault(), BOARD::GetDesignSettings(), ZONE_CONTAINER::GetIsKeepout(), ZONE_CONTAINER::GetLayer(), LSET::InternalCuMask(), ZONE_CONTAINER::IsOnCopperLayer(), m_conversionUnits, BOARD_DESIGN_SETTINGS::m_NetClasses, m_pcb, min, BOARD::Modules(), openArrayBlock(), openBlock(), PCB_VIA_T, removeJSONSepararator(), and BOARD::Tracks().

Referenced by WriteJSONJobFile().

◆ addJSONFilesAttributes()

void GERBER_JOBFILE_WRITER::addJSONFilesAttributes ( )
private

Add the Files Attributes section in JSON format to m_JSONbuffer.

Definition at line 315 of file gerber_jobfile_writer.cpp.

316 {
317  // Add the Files Attributes section in JSON format to m_JSONbuffer
318  addJSONObject( "\"FilesAttributes\":\n" );
319  openArrayBlock();
320 
321  for( unsigned ii = 0; ii < m_params.m_GerberFileList.GetCount(); ii ++ )
322  {
323  wxString& name = m_params.m_GerberFileList[ii];
324  PCB_LAYER_ID layer = m_params.m_LayerId[ii];
325  wxString gbr_layer_id;
326  bool skip_file = false; // true to skip files which should not be in job file
327  const char* polarity = "Positive";
328 
329  if( layer <= B_Cu )
330  {
331  gbr_layer_id = "Copper,L";
332 
333  if( layer == B_Cu )
334  gbr_layer_id << m_pcb->GetCopperLayerCount();
335  else
336  gbr_layer_id << layer+1;
337 
338  gbr_layer_id << ",";
339 
340  if( layer == B_Cu )
341  gbr_layer_id << "Bot";
342  else if( layer == F_Cu )
343  gbr_layer_id << "Top";
344  else
345  gbr_layer_id << "Inr";
346  }
347 
348  else
349  {
350  switch( layer )
351  {
352  case B_Adhes:
353  gbr_layer_id = "Glue,Bot"; break;
354  case F_Adhes:
355  gbr_layer_id = "Glue,Top"; break;
356 
357  case B_Paste:
358  gbr_layer_id = "SolderPaste,Bot"; break;
359  case F_Paste:
360  gbr_layer_id = "SolderPaste,Top"; break;
361 
362  case B_SilkS:
363  gbr_layer_id = "Legend,Bot"; break;
364  case F_SilkS:
365  gbr_layer_id = "Legend,Top"; break;
366 
367  case B_Mask:
368  gbr_layer_id = "SolderMask,Bot"; polarity = "Negative"; break;
369  case F_Mask:
370  gbr_layer_id = "SolderMask,Top"; polarity = "Negative"; break;
371 
372  case Edge_Cuts:
373  gbr_layer_id = "Profile"; break;
374 
375  case B_Fab:
376  gbr_layer_id = "AssemblyDrawing,Bot"; break;
377  case F_Fab:
378  gbr_layer_id = "AssemblyDrawing,Top"; break;
379 
380  case Dwgs_User:
381  case Cmts_User:
382  case Eco1_User:
383  case Eco2_User:
384  case Margin:
385  case B_CrtYd:
386  case F_CrtYd:
387  skip_file = true; break;
388 
389  default:
390  skip_file = true;
391  m_reporter->Report( "Unexpected layer id in job file",
393  break;
394  }
395  }
396 
397  if( !skip_file )
398  {
399  // name can contain non ASCII7 chars.
400  // Only ASCII7 chars are accepted in gerber files. others must be converted to
401  // a gerber hexa sequence.
402  std::string strname = formatStringToGerber( name );
403 
404  openBlock();
405  addJSONObject( wxString::Format( "\"Path\": \"%s\",\n", strname.c_str() ) );
406  addJSONObject( wxString::Format( "\"FileFunction\": \"%s\",\n", gbr_layer_id ) ),
407  addJSONObject( wxString::Format( "\"FilePolarity\": \"%s\"\n", polarity ) );
409  }
410  }
411  // Close the file list:
412  removeJSONSepararator(); // remove the last separator
414 }
void removeJSONSepararator()
Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a ...
void addJSONObject(const wxString &aParam)
Add aParam to m_JSONbuffer, with suitable indentation.
std::string formatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
void openBlock()
open a JSON block: add '{' and increment indentation
wxArrayString m_GerberFileList
PCB_LAYER_ID
A quick note on layer IDs:
void openArrayBlock()
open a JSON array block: add '[' and increment indentation
void closeBlockWithSep()
close a JSON block: decrement indentation and add '}' and ','
void closeArrayBlockWithSep()
close a JSON array block: decrement indentation and add ']' and ','
const char * name
Definition: DXF_plotter.cpp:61
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
int GetCopperLayerCount() const
Function GetCopperLayerCount.
std::vector< PCB_LAYER_ID > m_LayerId
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.

References addJSONObject(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, closeArrayBlockWithSep(), closeBlockWithSep(), Cmts_User, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Cu, F_Fab, F_Mask, F_Paste, F_SilkS, Format(), formatStringToGerber(), BOARD::GetCopperLayerCount(), JOBFILE_PARAMS::m_GerberFileList, JOBFILE_PARAMS::m_LayerId, m_params, m_pcb, m_reporter, Margin, name, openArrayBlock(), openBlock(), removeJSONSepararator(), REPORTER::Report(), and REPORTER::RPT_ERROR.

Referenced by WriteJSONJobFile().

◆ addJSONGeneralSpecs()

void GERBER_JOBFILE_WRITER::addJSONGeneralSpecs ( )
private

Add the General Specs in JSON format to m_JSONbuffer.

Definition at line 227 of file gerber_jobfile_writer.cpp.

228 {
229  addJSONObject( "\"GeneralSpecs\":\n" );
230  openBlock();
231 
232  addJSONObject( "\"ProjectId\":\n" );
233  openBlock();
234 
235  // Creates the ProjectId. Format is (from Gerber file format doc):
236  // ProjectId,<project id>,<project GUID>,<revision id>*%
237  // <project id> is the name of the project, restricted to basic ASCII symbols only,
238  // and comma not accepted
239  // All illegal chars will be replaced by underscore
240  // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
241  //
242  // <project GUID> is a string which is an unique id of a project.
243  // However Kicad does not handle such a project GUID, so it is built from the board name
244  wxFileName fn = m_pcb->GetFileName();
245  wxString msg = fn.GetFullName();
246 
247  // Build a <project GUID>, from the board name
248  wxString guid = GbrMakeProjectGUIDfromString( msg );
249 
250  // build the <project id> string: this is the board short filename (without ext)
251  // and all non ASCII chars are replaced by '_'
252  msg = fn.GetName();
253 
254  // build the <rec> string. All non ASCII chars and comma are replaced by '_'
255  wxString rev = m_pcb->GetTitleBlock().GetRevision();
256 
257  if( rev.IsEmpty() )
258  rev = wxT( "rev?" );
259 
260  addJSONObject( wxString::Format( "\"Name\": \"%s\",\n", msg.ToAscii() ) );
261  addJSONObject( wxString::Format( "\"GUID\": \"%s\",\n", guid ) );
262  addJSONObject( wxString::Format( "\"Revision\": \"%s\"\n", rev.ToAscii() ) );
263 
265 
266  // output the bord size in mm:
268  addJSONObject( "\"Size\":\n" );
269  openBlock();
270 
271  addJSONObject( wxString::Format( "\"X\": %.3f,\n", brect.GetWidth()*m_conversionUnits ) );
272  addJSONObject( wxString::Format( "\"Y\": %.3f\n", brect.GetHeight()*m_conversionUnits ) );
274 
275  // Add some data to the JSON header, GeneralSpecs:
276  // number of copper layers
277  addJSONObject( wxString::Format( "\"LayerNumber\": %d,\n", m_pcb->GetCopperLayerCount() ) );
278 
279  // Board thickness
280  addJSONObject( wxString::Format( "\"BoardThickness\": %.3f,\n",
282 
283 #if 0 // Not yet in use
284  /* The board type according to IPC-2221. There are six primary board types:
285  - Type 1 - Single-sided
286  - Type 2 - Double-sided
287  - Type 3 - Multilayer, TH components only
288  - Type 4 - Multilayer, with TH, blind and/or buried vias.
289  - Type 5 - Multilayer metal-core board, TH components only
290  - Type 6 - Multilayer metal-core
291  */
292  addJSONObject( wxString::Format( "\"IPC-2221-Type\": \"%d\",\n", 4 ) );
293 
294  /* Via protection: key words:
295  Ia Tented - Single-sided
296  Ib Tented - Double-sided
297  IIa Tented and Covered - Single-sided
298  IIb Tented and Covered - Double-sided
299  IIIa Plugged - Single-sided
300  IIIb Plugged - Double-sided
301  IVa Plugged and Covered - Single-sided
302  IVb Plugged and Covered - Double-sided
303  V Filled (fully plugged)
304  VI Filled and Covered
305  VIII Filled and Capped
306  None...No protection
307  */
308  addJSONObject( wxString::Format( "\"ViaProtection\": \"%s\",\n", "Ib" ) );
309 #endif
312 }
void removeJSONSepararator()
Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a ...
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:802
int GetWidth() const
Definition: eda_rect.h:117
void addJSONObject(const wxString &aParam)
Add aParam to m_JSONbuffer, with suitable indentation.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:534
const wxString & GetFileName() const
Definition: class_board.h:237
void openBlock()
open a JSON block: add '{' and increment indentation
const wxString & GetRevision() const
Definition: title_block.h:89
wxString GbrMakeProjectGUIDfromString(wxString &aText)
A helper function to build a project GUID using format RFC4122 Version 1 or 4 from the project name,...
void closeBlockWithSep()
close a JSON block: decrement indentation and add '}' and ','
int GetHeight() const
Definition: eda_rect.h:118
TITLE_BLOCK & GetTitleBlock()
Definition: class_board.h:555
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
int GetCopperLayerCount() const
Function GetCopperLayerCount.
Class EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44

References addJSONObject(), closeBlockWithSep(), Format(), GbrMakeProjectGUIDfromString(), BOARD::GetBoardEdgesBoundingBox(), BOARD_DESIGN_SETTINGS::GetBoardThickness(), BOARD::GetCopperLayerCount(), BOARD::GetDesignSettings(), BOARD::GetFileName(), EDA_RECT::GetHeight(), TITLE_BLOCK::GetRevision(), BOARD::GetTitleBlock(), EDA_RECT::GetWidth(), m_conversionUnits, m_pcb, openBlock(), and removeJSONSepararator().

Referenced by WriteJSONJobFile().

◆ addJSONHeader()

void GERBER_JOBFILE_WRITER::addJSONHeader ( )
private

Add the job file header in JSON format to m_JSONbuffer.

Definition at line 142 of file gerber_jobfile_writer.cpp.

143 {
144  wxString text;
145  openBlock();
146  addJSONObject( "\"Header\":\n" );
147  openBlock();
148 
149  // Creates the GenerationSoftware
150  addJSONObject( "\"GenerationSoftware\":\n" );
151  openBlock();
152  addJSONObject( "\"Vendor\": \"KiCad\",\n" );
153  addJSONObject( "\"Application\": \"Pcbnew\",\n" );
154  text.Printf( "\"Version\": \"%s\"\n", GetBuildVersion() );
155  addJSONObject( text );
157 
158  // creates the CreationDate attribute:
159  // The attribute value must conform to the full version of the ISO 8601
160  // date and time format, including time and time zone.
162  addJSONObject( text );
163 
165 }
void addJSONObject(const wxString &aParam)
Add aParam to m_JSONbuffer, with suitable indentation.
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
void openBlock()
open a JSON block: add '{' and increment indentation
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
void closeBlockWithSep()
close a JSON block: decrement indentation and add '}' and ','

References addJSONObject(), closeBlockWithSep(), GBR_NC_STRING_FORMAT_GBRJOB, GbrMakeCreationDateAttributeString(), GetBuildVersion(), and openBlock().

Referenced by WriteJSONJobFile().

◆ addJSONMaterialStackup()

void GERBER_JOBFILE_WRITER::addJSONMaterialStackup ( )
private

Add the Material Stackup section in JSON format to m_JSONbuffer This is the ordered list of stackup layers (mask, paste, silk, copper, dielectric) used to make the physical board.

Therefore not all layers are listed here

Definition at line 552 of file gerber_jobfile_writer.cpp.

553 {
554  // Add the Material Stackup section in JSON format to m_JSONbuffer
555  addJSONObject( "\"MaterialStackup\":\n" );
556  openArrayBlock();
557 
558  // Build the candidates: only layers on a board are candidates:
559  LSET maskLayer;
560 
561  for( unsigned ii = 0; ii < m_params.m_GerberFileList.GetCount(); ii ++ )
562  {
563  PCB_LAYER_ID layer = m_params.m_LayerId[ii];
564 
565  if( layer <= B_Cu )
566  maskLayer.set( layer );
567  else
568  {
569  switch( layer )
570  {
571  case B_Paste:
572  case F_Paste:
573  case B_SilkS:
574  case F_SilkS:
575  case B_Mask:
576  case F_Mask:
577  maskLayer.set( layer );
578  break;
579 
580  case Edge_Cuts:
581  case B_Adhes:
582  case F_Adhes:
583  case B_Fab:
584  case F_Fab:
585  case Dwgs_User:
586  case Cmts_User:
587  case Eco1_User:
588  case Eco2_User:
589  case Margin:
590  case B_CrtYd:
591  case F_CrtYd:
592  break;
593 
594  default:
596  wxString::Format( "Unexpected layer id %d in job file", layer ),
598  break;
599  }
600  }
601  }
602 
603  // build a candidate list (in reverse order: bottom to top):
604  LSEQ list = maskLayer.SeqStackupBottom2Top();
605  // Generate the list (top to bottom):
606  for( int ii = list.size()-1; ii >= 0; --ii )
607  {
608  PCB_LAYER_ID layer = list[ii];
609  wxString layer_type;
610  wxString color;
611  wxString dielectric;
612  double thickness = 0.0; // layer thickness in mm
613 
614  if( layer <= B_Cu )
615  {
616  layer_type = "Copper";
617  //thickness = 0.035;
618  }
619  else
620  {
621  switch( layer )
622  {
623  case B_Paste:
624  case F_Paste:
625  layer_type = "SolderPaste";
626  break;
627 
628  case B_SilkS:
629  case F_SilkS:
630  //color = "White";
631  layer_type = "Legend";
632  break;
633 
634  case B_Mask:
635  case F_Mask:
636  //color = "Green";
637  //thickness = 0.025;
638  layer_type = "SolderMask";
639  break;
640 
641  default:
642  break;
643  }
644  }
645 
646  openBlock();
647  addJSONObject( wxString::Format( "\"Type\": \"%s\",\n", layer_type ) );
648 
649  if( !color.IsEmpty() )
650  addJSONObject( wxString::Format( "\"Color\": \"%s\",\n", color ) );
651 
652  if( thickness > 0.0 )
653  addJSONObject( wxString::Format( "\"Thickness\": %f,\n", thickness ) );
654 
655  std::string strname = formatStringToGerber( m_pcb->GetLayerName( layer ) );
656  addJSONObject( wxString::Format( "\"Notes\": \"Layer %s\",\n", strname.c_str() ) );
659 
660  if( layer < B_Cu ) // Add dielectric between copper layers
661  {
662  dielectric = "FR4"; // Temporary
663 
664  openBlock();
665  addJSONObject( wxString::Format( "\"Type\": \"%s\",\n", "Dielectric" ) );
666 
667  if( thickness > 0.0 )
668  addJSONObject( wxString::Format( "\"Thickness\": %f,\n", color ) );
669 
670  if( !dielectric.IsEmpty() )
671  addJSONObject( wxString::Format( "\"Material\": \"%s\",\n", dielectric ) );
672 
673  addJSONObject( wxString::Format( "\"Notes\": \"Layers L%d/L%d\",\n",
674  layer+1, layer+2 ) );
677  }
678  }
679 
682 }
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
void removeJSONSepararator()
Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a ...
int color
Definition: DXF_plotter.cpp:62
void addJSONObject(const wxString &aParam)
Add aParam to m_JSONbuffer, with suitable indentation.
LSEQ SeqStackupBottom2Top() const
Function SeqStackBottom2Top returns the sequence that is typical for a bottom-to-top stack-up.
Definition: lset.cpp:415
std::string formatStringToGerber(const wxString &aString)
This helper function "normalize" aString and convert it to a Gerber std::string Normalisation means c...
void openBlock()
open a JSON block: add '{' and increment indentation
wxArrayString m_GerberFileList
PCB_LAYER_ID
A quick note on layer IDs:
Class LSET is a set of PCB_LAYER_IDs.
void openArrayBlock()
open a JSON array block: add '[' and increment indentation
void closeBlockWithSep()
close a JSON block: decrement indentation and add '}' and ','
Class LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
void closeArrayBlockWithSep()
close a JSON array block: decrement indentation and add ']' and ','
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
std::vector< PCB_LAYER_ID > m_LayerId
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.

References addJSONObject(), B_Adhes, B_CrtYd, B_Cu, B_Fab, B_Mask, B_Paste, B_SilkS, closeArrayBlockWithSep(), closeBlockWithSep(), Cmts_User, color, Dwgs_User, Eco1_User, Eco2_User, Edge_Cuts, F_Adhes, F_CrtYd, F_Fab, F_Mask, F_Paste, F_SilkS, Format(), formatStringToGerber(), BOARD::GetLayerName(), JOBFILE_PARAMS::m_GerberFileList, JOBFILE_PARAMS::m_LayerId, m_params, m_pcb, m_reporter, Margin, openArrayBlock(), openBlock(), removeJSONSepararator(), REPORTER::Report(), REPORTER::RPT_ERROR, and LSET::SeqStackupBottom2Top().

Referenced by WriteJSONJobFile().

◆ addJSONObject() [1/2]

void GERBER_JOBFILE_WRITER::addJSONObject ( const wxString &  aParam)
inlineprivate

Add aParam to m_JSONbuffer, with suitable indentation.

Definition at line 195 of file gerber_jobfile_writer.h.

196  {
197  addIndent(); m_JSONbuffer << aParam;
198  }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), and m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), addJSONGeneralSpecs(), addJSONHeader(), and addJSONMaterialStackup().

◆ addJSONObject() [2/2]

void GERBER_JOBFILE_WRITER::addJSONObject ( const char *  aParam)
inlineprivate

Definition at line 200 of file gerber_jobfile_writer.h.

201  {
202  addIndent(); m_JSONbuffer << aParam;
203  }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), and m_JSONbuffer.

◆ closeArrayBlock()

void GERBER_JOBFILE_WRITER::closeArrayBlock ( )
inlineprivate

close a JSON array block: decrement indentation and add ']'

Definition at line 185 of file gerber_jobfile_writer.h.

185 { m_indent -= 2; addIndent(); m_JSONbuffer << "]\n"; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

◆ closeArrayBlockWithSep()

void GERBER_JOBFILE_WRITER::closeArrayBlockWithSep ( )
inlineprivate

close a JSON array block: decrement indentation and add ']' and ','

Definition at line 190 of file gerber_jobfile_writer.h.

190 { m_indent -= 2; addIndent(); m_JSONbuffer << "],\n"; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), and addJSONMaterialStackup().

◆ closeBlock()

void GERBER_JOBFILE_WRITER::closeBlock ( )
inlineprivate

close a JSON block: decrement indentation and add '}'

Definition at line 175 of file gerber_jobfile_writer.h.

175 { m_indent -= 2; addIndent(); m_JSONbuffer << "}\n"; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

Referenced by addJSONDesignRules(), and WriteJSONJobFile().

◆ closeBlockWithSep()

void GERBER_JOBFILE_WRITER::closeBlockWithSep ( )
inlineprivate

close a JSON block: decrement indentation and add '}' and ','

Definition at line 180 of file gerber_jobfile_writer.h.

180 { m_indent -= 2; addIndent(); m_JSONbuffer << "},\n"; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), addJSONGeneralSpecs(), addJSONHeader(), and addJSONMaterialStackup().

◆ CreateJobFile()

bool GERBER_JOBFILE_WRITER::CreateJobFile ( const wxString &  aFullFilename)

Creates a Gerber job file.

Parameters
aFullFilename= the full filename
Returns
true, or false if the file cannot be created

Definition at line 117 of file gerber_jobfile_writer.cpp.

118 {
119  bool success;
120  wxString msg;
121 
122  success = WriteJSONJobFile( aFullFilename );
123 
124  if( !success )
125  {
126  if( m_reporter )
127  {
128  msg.Printf( _( "Unable to create job file \"%s\"" ), aFullFilename );
130  }
131  }
132  else if( m_reporter )
133  {
134  msg.Printf( _( "Create Gerber job file \"%s\"" ), aFullFilename );
136  }
137 
138  return success;
139 }
bool WriteJSONJobFile(const wxString &aFullFilename)
Creates an Gerber job file in JSON format.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_UNDEFINED)=0
Function Report is a pure virtual function to override in the derived object.

References m_reporter, REPORTER::Report(), REPORTER::RPT_ACTION, REPORTER::RPT_ERROR, and WriteJSONJobFile().

Referenced by DIALOG_PLOT::Plot().

◆ hasSilkLayers()

enum ONSIDE GERBER_JOBFILE_WRITER::hasSilkLayers ( )
private
Returns
SIDE_NONE if no silk screen layer is in list SIDE_TOP if top silk screen layer is in list SIDE_BOTTOM if bottom silk screen layer is in list SIDE_BOTH if top and bottom silk screen layers are in list

Definition at line 58 of file gerber_jobfile_writer.cpp.

59 {
60  int flag = SIDE_NONE;
61 
62  for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
63  {
64  if( m_params.m_LayerId[ii] == B_SilkS )
65  flag |= SIDE_BOTTOM;
66 
67  if( m_params.m_LayerId[ii] == F_SilkS )
68  flag |= SIDE_TOP;
69  }
70 
71  return (enum ONSIDE)flag;
72 }
std::vector< PCB_LAYER_ID > m_LayerId

References B_SilkS, F_SilkS, JOBFILE_PARAMS::m_LayerId, m_params, SIDE_BOTTOM, SIDE_NONE, and SIDE_TOP.

◆ hasSolderMasks()

enum ONSIDE GERBER_JOBFILE_WRITER::hasSolderMasks ( )
private
Returns
SIDE_NONE if no soldermask layer is in list SIDE_TOP if top soldermask layer is in list SIDE_BOTTOM if bottom soldermask layer is in list SIDE_BOTH if top and bottom soldermask layers are in list

Definition at line 75 of file gerber_jobfile_writer.cpp.

76 {
77  int flag = SIDE_NONE;
78 
79  for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
80  {
81  if( m_params.m_LayerId[ii] == B_Mask )
82  flag |= SIDE_BOTTOM;
83 
84  if( m_params.m_LayerId[ii] == F_Mask )
85  flag |= SIDE_TOP;
86  }
87 
88  return (enum ONSIDE)flag;
89 }
std::vector< PCB_LAYER_ID > m_LayerId

References B_Mask, F_Mask, JOBFILE_PARAMS::m_LayerId, m_params, SIDE_BOTTOM, SIDE_NONE, and SIDE_TOP.

◆ openArrayBlock()

void GERBER_JOBFILE_WRITER::openArrayBlock ( )
inlineprivate

open a JSON array block: add '[' and increment indentation

Definition at line 170 of file gerber_jobfile_writer.h.

170 { addIndent(); m_JSONbuffer << "[\n"; m_indent += 2; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), and addJSONMaterialStackup().

◆ openBlock()

void GERBER_JOBFILE_WRITER::openBlock ( )
inlineprivate

open a JSON block: add '{' and increment indentation

Definition at line 165 of file gerber_jobfile_writer.h.

165 { addIndent(); m_JSONbuffer << "{\n"; m_indent += 2; }
void addIndent()
add m_indent spaces in m_JSONbuffer

References addIndent(), m_indent, and m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), addJSONGeneralSpecs(), addJSONHeader(), and addJSONMaterialStackup().

◆ removeJSONSepararator()

void GERBER_JOBFILE_WRITER::removeJSONSepararator ( )
private

Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a
.

Definition at line 168 of file gerber_jobfile_writer.cpp.

169 {
170  if( m_JSONbuffer.Last() == ',' )
171  {
172  m_JSONbuffer.RemoveLast();
173  return;
174  }
175 
176  if( m_JSONbuffer.Last() == '\n' )
177  {
178  m_JSONbuffer.RemoveLast();
179 
180  if( m_JSONbuffer.Last() == ',' )
181  m_JSONbuffer.RemoveLast();
182 
183  m_JSONbuffer.Append( '\n' );
184  }
185 }

References m_JSONbuffer.

Referenced by addJSONDesignRules(), addJSONFilesAttributes(), addJSONGeneralSpecs(), addJSONMaterialStackup(), and WriteJSONJobFile().

◆ sideKeyValue()

const char * GERBER_JOBFILE_WRITER::sideKeyValue ( enum ONSIDE  aValue)
private
Returns
the key associated to sides used for some layers No TopOnly BotOnly Both

Definition at line 91 of file gerber_jobfile_writer.cpp.

92 {
93  // return the key associated to sides used for some layers
94  // "No, TopOnly, BotOnly or Both"
95  const char* value = nullptr;
96 
97  switch( aValue )
98  {
99  case SIDE_NONE:
100  value = "No"; break;
101 
102  case SIDE_TOP:
103  value = "TopOnly"; break;
104 
105  case SIDE_BOTTOM:
106  value = "BotOnly"; break;
107 
108  case SIDE_BOTH:
109  value = "Both"; break;
110 
111  }
112 
113  return value;
114 }

References SIDE_BOTH, SIDE_BOTTOM, SIDE_NONE, and SIDE_TOP.

◆ WriteJSONJobFile()

bool GERBER_JOBFILE_WRITER::WriteJSONJobFile ( const wxString &  aFullFilename)

Creates an Gerber job file in JSON format.

Parameters
aFullFilename= the full filename
aParams= true for a NPTH file, false for a PTH file
Returns
true, or false if the file cannot be created

Definition at line 187 of file gerber_jobfile_writer.cpp.

188 {
189  // Note: in Gerber job file, dimensions are in mm, and are floating numbers
190  FILE* jobFile = wxFopen( aFullFilename, "wt" );
191 
192  m_JSONbuffer.Empty();
193  m_indent = 0;
194 
195  if( jobFile == nullptr )
196  return false;
197 
199 
200  // output the job file header
201  addJSONHeader();
202 
203  // Add the General Specs
205 
206  // Job file support a few design rules:
208 
209  // output the gerber file list:
211 
212  // output the board stackup:
214 
215  // Close job file full block data
216  removeJSONSepararator(); // remove the last separator
217  closeBlock();
218 
219  fputs( TO_UTF8( m_JSONbuffer ), jobFile );
220 
221  fclose( jobFile );
222 
223  return true;
224 }
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:177
void removeJSONSepararator()
Remove the comma if it is the last char in m_JSONbuffer, or the previous char if the last char is a ...
void addJSONHeader()
Add the job file header in JSON format to m_JSONbuffer.
void closeBlock()
close a JSON block: decrement indentation and add '}'
void addJSONFilesAttributes()
Add the Files Attributes section in JSON format to m_JSONbuffer.
#define TO_UTF8(wxstring)
Macro TO_UTF8 converts a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Definition: macros.h:47
static LIB_PART * dummy()
Used when a LIB_PART is not found in library to draw a dummy shape This component is a 400 mils squar...
void addJSONDesignRules()
Add the Design Rules section in JSON format to m_JSONbuffer.
void addJSONMaterialStackup()
Add the Material Stackup section in JSON format to m_JSONbuffer This is the ordered list of stackup l...
void addJSONGeneralSpecs()
Add the General Specs in JSON format to m_JSONbuffer.

References addJSONDesignRules(), addJSONFilesAttributes(), addJSONGeneralSpecs(), addJSONHeader(), addJSONMaterialStackup(), closeBlock(), dummy(), m_indent, m_JSONbuffer, removeJSONSepararator(), and TO_UTF8.

Referenced by CreateJobFile().

Member Data Documentation

◆ m_conversionUnits

double GERBER_JOBFILE_WRITER::m_conversionUnits
private

◆ m_indent

◆ m_JSONbuffer

◆ m_params

JOBFILE_PARAMS GERBER_JOBFILE_WRITER::m_params
private

◆ m_pcb

BOARD* GERBER_JOBFILE_WRITER::m_pcb
private

◆ m_reporter

REPORTER* GERBER_JOBFILE_WRITER::m_reporter
private

The documentation for this class was generated from the following files: