KiCad PCB EDA Suite
gerber_jobfile_writer.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2018 Jean_Pierre Charras <jp.charras at wanadoo.fr>
5  * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
30 #include <fctsys.h>
31 
32 #include <fstream>
33 #include <iomanip>
34 #include <vector>
35 
36 #include <build_version.h>
37 #include <pcb_edit_frame.h>
38 #include <plotter.h>
39 
40 #include <class_board.h>
41 #include <class_module.h>
42 #include <class_zone.h>
43 
45 #include <gbr_metadata.h>
46 #include <gerber_jobfile_writer.h>
47 #include <pcbnew.h>
48 #include <pcbplot.h>
49 #include <reporter.h>
51 
53 {
54  m_pcb = aPcb;
55  m_reporter = aReporter;
56  m_conversionUnits = 1.0 / IU_PER_MM; // Gerber units = mm
57 }
58 
59 std::string GERBER_JOBFILE_WRITER::formatStringFromUTF32( const wxString& aText )
60 {
61  std::string fmt_text; // the text after UTF32 to UTF8 conversion
62 
63  for( unsigned long letter : aText )
64  {
65  if( letter >= ' ' && letter <= 0x7F )
66  fmt_text += char( letter );
67  else
68  {
69  char buff[16];
70  sprintf( buff, "\\u%4.4lX", letter );
71  fmt_text += buff;
72  }
73  }
74  return fmt_text;
75 }
76 
77 
79 {
80  int flag = SIDE_NONE;
81 
82  for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
83  {
84  if( m_params.m_LayerId[ii] == B_SilkS )
85  flag |= SIDE_BOTTOM;
86 
87  if( m_params.m_LayerId[ii] == F_SilkS )
88  flag |= SIDE_TOP;
89  }
90 
91  return (enum ONSIDE) flag;
92 }
93 
94 
96 {
97  int flag = SIDE_NONE;
98 
99  for( unsigned ii = 0; ii < m_params.m_LayerId.size(); ii++ )
100  {
101  if( m_params.m_LayerId[ii] == B_Mask )
102  flag |= SIDE_BOTTOM;
103 
104  if( m_params.m_LayerId[ii] == F_Mask )
105  flag |= SIDE_TOP;
106  }
107 
108  return (enum ONSIDE) flag;
109 }
110 
111 const char* GERBER_JOBFILE_WRITER::sideKeyValue( enum ONSIDE aValue )
112 {
113  // return the key associated to sides used for some layers
114  // "No, TopOnly, BotOnly or Both"
115  const char* value = nullptr;
116 
117  switch( aValue )
118  {
119  case SIDE_NONE:
120  value = "No";
121  break;
122 
123  case SIDE_TOP:
124  value = "TopOnly";
125  break;
126 
127  case SIDE_BOTTOM:
128  value = "BotOnly";
129  break;
130 
131  case SIDE_BOTH:
132  value = "Both";
133  break;
134  }
135 
136  return value;
137 }
138 
139 
140 bool GERBER_JOBFILE_WRITER::CreateJobFile( const wxString& aFullFilename )
141 {
142  bool success;
143  wxString msg;
144 
145  success = WriteJSONJobFile( aFullFilename );
146 
147  if( !success )
148  {
149  if( m_reporter )
150  {
151  msg.Printf( _( "Unable to create job file \"%s\"" ), aFullFilename );
153  }
154  }
155  else if( m_reporter )
156  {
157  msg.Printf( _( "Create Gerber job file \"%s\"" ), aFullFilename );
159  }
160 
161  return success;
162 }
163 
164 
166 {
167  wxString text;
168 
169  m_json["Header"] = {
170  {
171  "GenerationSoftware",
172  {
173  { "Vendor", "KiCad" },
174  { "Application", "Pcbnew" },
175  { "Version", GetBuildVersion() }
176  }
177  },
178  {
179  // The attribute value must conform to the full version of the ISO 8601
180  // date and time format, including time and time zone.
182  }
183  };
184 }
185 
186 
187 bool GERBER_JOBFILE_WRITER::WriteJSONJobFile( const wxString& aFullFilename )
188 {
189  // Note: in Gerber job file, dimensions are in mm, and are floating numbers
190  std::ofstream file( aFullFilename.ToUTF8() );
191 
193 
194  m_json = json( {} );
195 
196  // output the job file header
197  addJSONHeader();
198 
199  // Add the General Specs
201 
202  // Job file support a few design rules:
204 
205  // output the gerber file list:
207 
208  // output the board stackup:
210 
211  file << std::setw( 2 ) << m_json << std::endl;
212 
213  return true;
214 }
215 
216 
218 {
219  m_json["GeneralSpecs"] = json( {} );
220  m_json["GeneralSpecs"]["ProjectId"] = json( {} );
221 
222  // Creates the ProjectId. Format is (from Gerber file format doc):
223  // ProjectId,<project id>,<project GUID>,<revision id>*%
224  // <project id> is the name of the project, restricted to basic ASCII symbols only,
225  // and comma not accepted
226  // All illegal chars will be replaced by underscore
227  // Rem: <project id> accepts only ASCII 7 code (only basic ASCII codes are allowed in gerber files).
228  //
229  // <project GUID> is a string which is an unique id of a project.
230  // However Kicad does not handle such a project GUID, so it is built from the board name
231  wxFileName fn = m_pcb->GetFileName();
232  wxString msg = fn.GetFullName();
233 
234  // Build a <project GUID>, from the board name
235  wxString guid = GbrMakeProjectGUIDfromString( msg );
236 
237  // build the <project id> string: this is the board short filename (without ext)
238  // and all non ASCII chars are replaced by '_', to be compatible with .gbr files.
239  msg = fn.GetName();
240 
241  // build the <rec> string. All non ASCII chars and comma are replaced by '_'
242  wxString rev = m_pcb->GetTitleBlock().GetRevision();
243 
244  if( rev.IsEmpty() )
245  rev = wxT( "rev?" );
246 
247  m_json["GeneralSpecs"]["ProjectId"]["Name"] = msg.ToAscii();
248  m_json["GeneralSpecs"]["ProjectId"]["GUID"] = guid;
249  m_json["GeneralSpecs"]["ProjectId"]["Revision"] = rev.ToAscii();
250 
251  // output the bord size in mm:
253 
254  m_json["GeneralSpecs"]["Size"]["X"] = brect.GetWidth() * m_conversionUnits;
255  m_json["GeneralSpecs"]["Size"]["Y"] = brect.GetHeight() * m_conversionUnits;
256 
257 
258  // Add some data to the JSON header, GeneralSpecs:
259  // number of copper layers
260  m_json["GeneralSpecs"]["LayerNumber"] = m_pcb->GetCopperLayerCount();
261 
262  // Board thickness
263  m_json["GeneralSpecs"]["BoardThickness"] =
265 
266  // Copper finish
268 
269  if( !brd_stackup.m_FinishType.IsEmpty() )
270  m_json["GeneralSpecs"]["Finish"] = brd_stackup.m_FinishType;
271 
272  if( brd_stackup.m_CastellatedPads )
273  m_json["GeneralSpecs"]["Castellated"] = true;
274 
275  if( brd_stackup.m_EdgePlating )
276  m_json["GeneralSpecs"]["EdgePlating"] = true;
277 
278  if( brd_stackup.m_EdgeConnectorConstraints )
279  {
280  m_json["GeneralSpecs"]["EdgeConnector"] = true;
281 
282  m_json["GeneralSpecs"]["EdgeConnectorBevelled"] =
284  }
285 
286 #if 0 // Not yet in use
287  /* The board type according to IPC-2221. There are six primary board types:
288  - Type 1 - Single-sided
289  - Type 2 - Double-sided
290  - Type 3 - Multilayer, TH components only
291  - Type 4 - Multilayer, with TH, blind and/or buried vias.
292  - Type 5 - Multilayer metal-core board, TH components only
293  - Type 6 - Multilayer metal-core
294  */
295  m_json["GeneralSpecs"]["IPC-2221-Type"] = 4;
296 
297  /* Via protection: key words:
298  Ia Tented - Single-sided
299  Ib Tented - Double-sided
300  IIa Tented and Covered - Single-sided
301  IIb Tented and Covered - Double-sided
302  IIIa Plugged - Single-sided
303  IIIb Plugged - Double-sided
304  IVa Plugged and Covered - Single-sided
305  IVb Plugged and Covered - Double-sided
306  V Filled (fully plugged)
307  VI Filled and Covered
308  VIII Filled and Capped
309  None...No protection
310  */
311  m_json["GeneralSpecs"]["ViaProtection"] = "Ib";
312 #endif
313 }
314 
315 
317 {
318  // Add the Files Attributes section in JSON format to m_JSONbuffer
319  m_json["FilesAttributes"] = json::array();
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  json file_json;
329 
330  if( layer <= B_Cu )
331  {
332  gbr_layer_id = "Copper,L";
333 
334  if( layer == B_Cu )
335  gbr_layer_id << m_pcb->GetCopperLayerCount();
336  else
337  gbr_layer_id << layer + 1;
338 
339  gbr_layer_id << ",";
340 
341  if( layer == B_Cu )
342  gbr_layer_id << "Bot";
343  else if( layer == F_Cu )
344  gbr_layer_id << "Top";
345  else
346  gbr_layer_id << "Inr";
347  }
348 
349  else
350  {
351  switch( layer )
352  {
353  case B_Adhes:
354  gbr_layer_id = "Glue,Bot";
355  break;
356  case F_Adhes:
357  gbr_layer_id = "Glue,Top";
358  break;
359 
360  case B_Paste:
361  gbr_layer_id = "SolderPaste,Bot";
362  break;
363  case F_Paste:
364  gbr_layer_id = "SolderPaste,Top";
365  break;
366 
367  case B_SilkS:
368  gbr_layer_id = "Legend,Bot";
369  break;
370  case F_SilkS:
371  gbr_layer_id = "Legend,Top";
372  break;
373 
374  case B_Mask:
375  gbr_layer_id = "SolderMask,Bot";
376  polarity = "Negative";
377  break;
378  case F_Mask:
379  gbr_layer_id = "SolderMask,Top";
380  polarity = "Negative";
381  break;
382 
383  case Edge_Cuts:
384  gbr_layer_id = "Profile";
385  break;
386 
387  case B_Fab:
388  gbr_layer_id = "AssemblyDrawing,Bot";
389  break;
390  case F_Fab:
391  gbr_layer_id = "AssemblyDrawing,Top";
392  break;
393 
394  case Dwgs_User:
395  case Cmts_User:
396  case Eco1_User:
397  case Eco2_User:
398  case Margin:
399  case B_CrtYd:
400  case F_CrtYd:
401  skip_file = true;
402  break;
403 
404  default:
405  skip_file = true;
406  m_reporter->Report( "Unexpected layer id in job file", REPORTER::RPT_ERROR );
407  break;
408  }
409  }
410 
411  if( !skip_file )
412  {
413  // name can contain non ASCII7 chars.
414  // Ensure the name is JSON compatible.
415  std::string strname = formatStringFromUTF32( name );
416 
417  file_json["Path"] = strname.c_str();
418  file_json["FileFunction"] = gbr_layer_id;
419  file_json["FilePolarity"] = polarity;
420 
421  m_json["FilesAttributes"] += file_json;
422  }
423  }
424 }
425 
426 
428 {
429  // Add the Design Rules section in JSON format to m_JSONbuffer
430  // Job file support a few design rules:
431  const BOARD_DESIGN_SETTINGS& dsnSettings = m_pcb->GetDesignSettings();
432  NETCLASS defaultNC = *dsnSettings.GetDefault();
433  int minclearanceOuter = defaultNC.GetClearance();
434  bool hasInnerLayers = m_pcb->GetCopperLayerCount() > 2;
435 
436  // Search a smaller clearance in other net classes, if any.
437  for( NETCLASSES::const_iterator it = dsnSettings.m_NetClasses.begin();
438  it != dsnSettings.m_NetClasses.end(); ++it )
439  {
440  NETCLASS netclass = *it->second;
441  minclearanceOuter = std::min( minclearanceOuter, netclass.GetClearance() );
442  }
443 
444  // job file knows different clearance types.
445  // Kicad knows only one clearance for pads and tracks
446  int minclearance_track2track = minclearanceOuter;
447 
448  // However, pads can have a specific clearance defined for a pad or a footprint,
449  // and min clearance can be dependent on layers.
450  // Search for a minimal pad clearance:
451  int minPadClearanceOuter = defaultNC.GetClearance();
452  int minPadClearanceInner = defaultNC.GetClearance();
453 
454  for( MODULE* module : m_pcb->Modules() )
455  {
456  for( auto& pad : module->Pads() )
457  {
458  if( ( pad->GetLayerSet() & LSET::InternalCuMask() ).any() )
459  minPadClearanceInner = std::min( minPadClearanceInner, pad->GetClearance() );
460 
461  if( ( pad->GetLayerSet() & LSET::ExternalCuMask() ).any() )
462  minPadClearanceOuter = std::min( minPadClearanceOuter, pad->GetClearance() );
463  }
464  }
465 
466  m_json["DesignRules"] = { {
467  { "Layers", "Outer" },
468  { "PadToPad", minPadClearanceOuter * m_conversionUnits },
469  { "PadToTrack", minPadClearanceOuter * m_conversionUnits },
470  { "TrackToTrack", minclearance_track2track * m_conversionUnits }
471  } };
472 
473  // Until this is changed in Kicad, use the same value for internal tracks
474  int minclearanceInner = minclearanceOuter;
475 
476  // Output the minimal track width
477  int mintrackWidthOuter = INT_MAX;
478  int mintrackWidthInner = INT_MAX;
479 
480  for( TRACK* track : m_pcb->Tracks() )
481  {
482  if( track->Type() == PCB_VIA_T )
483  continue;
484 
485  if( track->GetLayer() == B_Cu || track->GetLayer() == F_Cu )
486  mintrackWidthOuter = std::min( mintrackWidthOuter, track->GetWidth() );
487  else
488  mintrackWidthInner = std::min( mintrackWidthInner, track->GetWidth() );
489  }
490 
491  if( mintrackWidthOuter != INT_MAX )
492  m_json["DesignRules"][0]["MinLineWidth"] = mintrackWidthOuter * m_conversionUnits;
493 
494  // Output the minimal zone to xx clearance
495  // Note: zones can have a zone clearance set to 0
496  // if happens, the actual zone clearance is the clearance of its class
497  minclearanceOuter = INT_MAX;
498  minclearanceInner = INT_MAX;
499 
500  for( int ii = 0; ii < m_pcb->GetAreaCount(); ii++ )
501  {
502  ZONE_CONTAINER* zone = m_pcb->GetArea( ii );
503 
504  if( zone->GetIsKeepout() || !zone->IsOnCopperLayer() )
505  continue;
506 
507  int zclerance = zone->GetClearance();
508 
509  if( zone->GetLayer() == B_Cu || zone->GetLayer() == F_Cu )
510  minclearanceOuter = std::min( minclearanceOuter, zclerance );
511  else
512  minclearanceInner = std::min( minclearanceInner, zclerance );
513  }
514 
515  if( minclearanceOuter != INT_MAX )
516  m_json["DesignRules"][0]["TrackToRegion"] = minclearanceOuter * m_conversionUnits;
517 
518  if( minclearanceOuter != INT_MAX )
519  m_json["DesignRules"][0]["RegionToRegion"] = minclearanceOuter * m_conversionUnits;
520 
521  if( hasInnerLayers )
522  {
523  m_json["DesignRules"] += json( {
524  { "Layers", "Inner" },
525  { "PadToPad", minPadClearanceInner * m_conversionUnits },
526  { "PadToTrack", minPadClearanceInner * m_conversionUnits },
527  { "TrackToTrack", minclearance_track2track * m_conversionUnits }
528  } );
529 
530  if( mintrackWidthInner != INT_MAX )
531  m_json["DesignRules"][1]["MinLineWidth"] = mintrackWidthInner * m_conversionUnits;
532 
533  if( minclearanceInner != INT_MAX )
534  m_json["DesignRules"][1]["TrackToRegion"] = minclearanceInner * m_conversionUnits;
535 
536  if( minclearanceInner != INT_MAX )
537  m_json["DesignRules"][1]["RegionToRegion"] = minclearanceInner * m_conversionUnits;
538  }
539 }
540 
541 
543 {
544  // Add the Material Stackup section in JSON format to m_JSONbuffer
545  m_json["MaterialStackup"] = json::array();
546 
547  // Build the candidates list:
548  LSET maskLayer;
550 
551  // Ensure brd_stackup is up to date (i.e. no change made by SynchronizeWithBoard() )
552  bool uptodate = not brd_stackup.SynchronizeWithBoard( &m_pcb->GetDesignSettings() );
553 
554  if( !uptodate && m_pcb->GetDesignSettings().m_HasStackup )
555  m_reporter->Report( _( "Board stackup settings not up to date\n"
556  "Please fix the stackup" ),
558 
559  PCB_LAYER_ID last_copper_layer = F_Cu;
560 
561  // Generate the list (top to bottom):
562  for( int ii = 0; ii < brd_stackup.GetCount(); ++ii )
563  {
564  BOARD_STACKUP_ITEM* item = brd_stackup.GetStackupLayer( ii );
565 
566  int sub_layer_count =
567  item->GetType() == BS_ITEM_TYPE_DIELECTRIC ? item->GetSublayersCount() : 1;
568 
569  for( int sub_idx = 0; sub_idx < sub_layer_count; sub_idx++ )
570  {
571  // layer thickness is always in mm
572  double thickness = item->GetThickness( sub_idx ) * m_conversionUnits;
573  wxString layer_type;
574  std::string layer_name; // for comment
575  json layer_json;
576 
577  switch( item->GetType() )
578  {
579  case BS_ITEM_TYPE_COPPER:
580  layer_type = "Copper";
581  layer_name = formatStringFromUTF32( m_pcb->GetLayerName( item->GetBrdLayerId() ) );
582  last_copper_layer = item->GetBrdLayerId();
583  break;
584 
586  layer_type = "Legend";
587  layer_name = formatStringFromUTF32( item->GetTypeName() );
588  break;
589 
591  layer_type = "SolderMask";
592  layer_name = formatStringFromUTF32( item->GetTypeName() );
593  break;
594 
596  layer_type = "SolderPaste";
597  layer_name = formatStringFromUTF32( item->GetTypeName() );
598  break;
599 
601  layer_type = "Dielectric";
602  // The option core or prepreg is not added here, as it creates constraints
603  // in build process, not necessary wanted.
604  if( sub_layer_count > 1 )
605  {
606  layer_name =
607  formatStringFromUTF32( wxString::Format( "dielectric layer %d - %d/%d",
608  item->GetDielectricLayerId(), sub_idx + 1, sub_layer_count ) );
609  }
610  else
612  "dielectric layer %d", item->GetDielectricLayerId() ) );
613  break;
614 
615  default:
616  break;
617  }
618 
619  layer_json["Type"] = layer_type;
620 
621  if( item->IsColorEditable() && uptodate )
622  {
623  if( IsPrmSpecified( item->GetColor() ) )
624  {
625  wxString colorName = item->GetColor();
626 
627  if( colorName.StartsWith( "#" ) ) // This is a user defined color.
628  {
629  // In job file a color can be given by its RGB values (0...255)
630  wxColor color( colorName );
631  colorName.Printf( "R%dG%dB%d", color.Red(), color.Green(), color.Blue() );
632  }
633 
634  layer_json["Color"] = colorName;
635  }
636  }
637 
638  if( item->IsThicknessEditable() && uptodate )
639  layer_json["Thickness"] = thickness;
640 
641  if( item->GetType() == BS_ITEM_TYPE_DIELECTRIC )
642  {
643  if( item->HasMaterialValue() )
644  {
645  layer_json["Material"] = item->GetMaterial( sub_idx );
646 
647  // These constrains are only written if the board has impedance controlled tracks.
648  // If the board is not impedance controlled, they are useless.
649  // Do not add constrains that create more expensive boards.
650  if( brd_stackup.m_HasDielectricConstrains )
651  {
652  // Generate Epsilon R if > 1.0 (value <= 1.0 means not specified: it is not
653  // a possible value
654  if( item->GetEpsilonR() > 1.0 )
655  layer_json["DielectricConstant"] = item->FormatEpsilonR( sub_idx );
656 
657  // Generate LossTangent > 0.0 (value <= 0.0 means not specified: it is not
658  // a possible value
659  if( item->GetLossTangent() > 0.0 )
660  layer_json["LossTangent"] = item->FormatLossTangent( sub_idx );
661  }
662  }
663 
664  PCB_LAYER_ID next_copper_layer = ( PCB_LAYER_ID )( last_copper_layer + 1 );
665 
666  // If the next_copper_layer is the last copper layer, the next layer id is B_Cu
667  if( next_copper_layer >= m_pcb->GetCopperLayerCount() - 1 )
668  next_copper_layer = B_Cu;
669 
670  wxString subLayerName;
671 
672  if( sub_layer_count > 1 )
673  subLayerName.Printf( " (%d/%d)", sub_idx + 1, sub_layer_count );
674 
675  wxString name = wxString::Format( "%s/%s%s",
676  formatStringFromUTF32( m_pcb->GetLayerName( last_copper_layer ) ),
677  formatStringFromUTF32( m_pcb->GetLayerName( next_copper_layer ) ),
678  subLayerName );
679 
680  layer_json["Name"] = name;
681 
682  // Add a comment ("Notes"):
683  wxString note;
684 
685  note << wxString::Format( "Type: %s", layer_name.c_str() );
686 
687  note << wxString::Format( " (from %s to %s)",
688  formatStringFromUTF32( m_pcb->GetLayerName( last_copper_layer ) ),
689  formatStringFromUTF32( m_pcb->GetLayerName( next_copper_layer ) ) );
690 
691  layer_json["Notes"] = note;
692  }
693  else if( item->GetType() == BS_ITEM_TYPE_SOLDERMASK
694  || item->GetType() == BS_ITEM_TYPE_SILKSCREEN )
695  {
696  if( item->HasMaterialValue() )
697  {
698  layer_json["Material"] = item->GetMaterial();
699 
700  // These constrains are only written if the board has impedance controlled tracks.
701  // If the board is not impedance controlled, they are useless.
702  // Do not add constrains that create more expensive boards.
703  if( brd_stackup.m_HasDielectricConstrains )
704  {
705  // Generate Epsilon R if > 1.0 (value <= 1.0 means not specified: it is not
706  // a possible value
707  if( item->GetEpsilonR() > 1.0 )
708  layer_json["DielectricConstant"] = item->FormatEpsilonR();
709 
710  // Generate LossTangent > 0.0 (value <= 0.0 means not specified: it is not
711  // a possible value
712  if( item->GetLossTangent() > 0.0 )
713  layer_json["LossTangent"] = item->FormatLossTangent();
714  }
715  }
716 
717  layer_json["Name"] = layer_name.c_str();
718  }
719  else
720  {
721  layer_json["Name"] = layer_name.c_str();
722  }
723 
724  m_json["MaterialStackup"].insert( m_json["MaterialStackup"].end(), layer_json );
725  }
726  }
727 }
BOARD_STACKUP_ITEM_TYPE GetType() const
std::string formatStringFromUTF32(const wxString &aText)
A helper function to convert a wxString ( therefore a Unicode text ) to a JSON compatible string (a e...
a class to handle special data (items attributes) during plot.
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
BOARD_STACKUP_ITEM * GetStackupLayer(int aIndex)
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Function GetLayerName returns the name of a layer given by aLayer.
bool HasMaterialValue(int aDielectricSubLayer=0) const
bool CreateJobFile(const wxString &aFullFilename)
Creates a Gerber job file.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Definition: common.h:90
this class manage the layers needed to make a physical board they are solder mask,...
wxString m_FinishType
The name of external copper finish.
const EDA_RECT GetBoardEdgesBoundingBox() const
Function GetBoardEdgesBoundingBox Returns the board bounding box calculated using exclusively the boa...
Definition: class_board.h:791
bool m_EdgePlating
True if the edge board is plated.
void addJSONHeader()
Add the job file header in JSON format to m_JSONbuffer.
bool IsPrmSpecified(const wxString &aPrmValue)
int color
Definition: DXF_plotter.cpp:61
BS_EDGE_CONNECTOR_CONSTRAINTS m_EdgeConnectorConstraints
If the board has edge connector cards, some constrains can be specifed in job file: BS_EDGE_CONNECTOR...
virtual PCB_LAYER_ID GetLayer() const override
Function GetLayer returns the primary layer this item is on.
Definition: class_zone.cpp:204
int GetWidth() const
Definition: eda_rect.h:119
const char * sideKeyValue(enum ONSIDE aValue)
bool m_CastellatedPads
True if castellated pads exist.
wxString GetColor() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
Function GetDesignSettings.
Definition: class_board.h:530
iterator end()
Definition: netclass.h:249
wxString GbrMakeCreationDateAttributeString(GBR_NC_STRING_FORMAT aFormat)
REPORTER is a pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:61
nlohmann::json json
Definition: gerbview.cpp:38
const wxString & GetFileName() const
Definition: class_board.h:215
Classes used to generate a Gerber job file in JSON.
void addJSONFilesAttributes()
Add the Files Attributes section in JSON format to m_JSONbuffer.
double GetLossTangent(int aDielectricSubLayer=0) const
NETCLASS_MAP::const_iterator const_iterator
Definition: netclass.h:251
bool SynchronizeWithBoard(BOARD_DESIGN_SETTINGS *aSettings)
Synchronize the BOARD_STACKUP_ITEM* list with the board.
int GetClearance(BOARD_CONNECTED_ITEM *aItem=NULL) const override
Function GetClearance returns the clearance in internal units.
Definition: class_zone.cpp:650
Board plot function definition file.
wxArrayString m_GerberFileList
bool m_HasDielectricConstrains
True if some layers have impedance controlled tracks or have specific constrains for micro-wave appli...
BOARD_STACKUP & GetStackupDescriptor()
PCB_LAYER_ID
A quick note on layer IDs:
bool IsThicknessEditable() const
int GetAreaCount() const
Function GetAreaCount.
Definition: class_board.h:948
LSET is a set of PCB_LAYER_IDs.
iterator begin()
Definition: netclass.h:248
MODULES & Modules()
Definition: class_board.h:226
wxString GetBuildVersion()
Function GetBuildVersion Return the build version string.
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,...
int GetThickness(int aDielectricSubLayer=0) const
NETCLASS handles a collection of nets and the parameters used to route or test these nets.
Definition: netclass.h:55
double GetEpsilonR(int aDielectricSubLayer=0) const
wxString FormatEpsilonR(int aDielectricSubLayer=0) const
Definition of file extensions used in Kicad.
static LSET InternalCuMask()
Function InternalCuMask() returns a complete set of internal copper layers, which is all Cu layers ex...
Definition: lset.cpp:646
static LSET ExternalCuMask()
Function ExternalCuMask returns a mask holding the Front and Bottom layers.
Definition: lset.cpp:716
wxString GetTypeName() const
wxString FormatLossTangent(int aDielectricSubLayer=0) const
this class manage one layer needed to make a physical board it can be a solder mask,...
int GetHeight() const
Definition: eda_rect.h:120
bool WriteJSONJobFile(const wxString &aFullFilename)
Creates an Gerber job file in JSON format.
PCB_LAYER_ID GetBrdLayerId() const
bool GetIsKeepout() const
Accessors to parameters used in Keepout zones:
Definition: class_zone.h:631
TITLE_BLOCK & GetTitleBlock()
Definition: class_board.h:551
const char * name
Definition: DXF_plotter.cpp:60
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 GetDielectricLayerId() const
static LIB_PART * dummy()
Used to draw a dummy shape when a LIB_PART is not found in library.
BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:160
#define _(s)
Definition: 3d_actions.cpp:31
int GetClearance() const
Definition: netclass.h:162
void addJSONDesignRules()
Add the Design Rules section in JSON format to m_JSONbuffer.
int GetCopperLayerCount() const
Function GetCopperLayerCount.
EDA_RECT handles the component boundary box.
Definition: eda_rect.h:44
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.
class VIA, a via (like a track segment on a copper layer)
Definition: typeinfo.h:97
Module description (excepted pads)
ZONE_CONTAINER * GetArea(int index) const
Function GetArea returns the Area (Zone Container) at a given index.
Definition: class_board.h:913
bool m_HasStackup
Set to true if the board has a stackup management.
void addJSONMaterialStackup()
Add the Material Stackup section in JSON format to m_JSONbuffer This is the ordered list of stackup l...
wxString GetMaterial(int aDielectricSubLayer=0) const
void addJSONGeneralSpecs()
Add the General Specs in JSON format to m_JSONbuffer.
TRACKS & Tracks()
Definition: class_board.h:217
bool IsOnCopperLayer() const override
Function IsOnCopperLayer.
Definition: class_zone.cpp:210
GERBER_JOBFILE_WRITER(BOARD *aPcb, REPORTER *aReporter=nullptr)
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.