KiCad PCB EDA Suite
board_design_settings.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) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, you may find one here:
18  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
19  * or you may search the http://www.gnu.org website for the version 2 license,
20  * or you may write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22  */
23 
24 #include <fctsys.h>
25 #include <common.h>
26 #include <class_board.h>
27 #include <class_track.h>
29 #include <kiface_i.h>
30 #include <pcbnew.h>
31 #include <board_design_settings.h>
32 #include <drc/drc.h>
33 #include <widgets/ui_common.h>
34 #include <drc/drc_rule.h>
35 #include <settings/parameters.h>
36 #include <project/project_file.h>
37 
38 
39 const int bdsSchemaVersion = 0;
40 
41 
42 BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
43  NESTED_SETTINGS( "board_design_settings", bdsSchemaVersion, aParent, aPath ),
44  m_Pad_Master( NULL )
45 {
46  // We want to leave alone parameters that aren't found in the project JSON as they may be
47  // initialized by the board file parser before NESTED_SETTINGS::LoadFromFile is called.
48  m_resetParamsIfMissing = false;
49 
50  // Create a default NETCLASS list so that things don't break horribly if there's no project
51  // loaded. This also is used during file load for legacy boards that have netclasses stored
52  // in the file. After load, this information will be moved to the project and the pointer
53  // updated.
55 
56  m_HasStackup = false; // no stackup defined by default
57 
58  LSET all_set = LSET().set();
59  m_enabledLayers = all_set; // All layers enabled at first.
60  // SetCopperLayerCount() will adjust this.
61 
62  SetCopperLayerCount( 2 ); // Default design is a double sided board
64 
65  // if true, when creating a new track starting on an existing track, use this track width
67 
69  m_MicroViasAllowed = false;
70 
71  // First is always the reference designator
72  m_DefaultFPTextItems.emplace_back( wxT( "REF**" ), true, F_SilkS );
73  // Second is always the value
74  m_DefaultFPTextItems.emplace_back( wxT( "" ), true, F_Fab );
75  // Any following ones are freebies
76  m_DefaultFPTextItems.emplace_back( wxT( "${REF}" ), true, F_Fab );
77 
82  m_TextItalic[ LAYER_CLASS_SILK ] = false;
84 
91 
92  // Edges & Courtyards; text properties aren't used but better to have them holding
93  // reasonable values than not.
100 
107 
112  m_TextItalic[ LAYER_CLASS_FAB ] = false;
113  m_TextUpright[ LAYER_CLASS_FAB ] = false;
114 
119  m_TextItalic[ LAYER_CLASS_OTHERS ] = false;
121 
122  m_DimensionUnits = 0; // Inches
123  m_DimensionPrecision = 1; // 0.001mm / 0.1 mil
124 
125  m_useCustomTrackVia = false;
129 
130  m_useCustomDiffPair = false;
134 
144 
145  for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode )
146  m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR;
147 
151 
154 
158 
159  m_MaxError = ARC_HIGH_DEF;
160  m_ZoneUseNoOutlineInFill = false; // Use compatibility mode by default
161 
162  // Global mask margins:
165  m_SolderPasteMargin = 0; // Solder paste margin absolute value
166  m_SolderPasteMarginRatio = 0.0; // Solder paste margin as a ratio of pad size
167  // The final margin is the sum of these 2 values
168  // Usually < 0 because the mask is smaller than pad
169  // Layer thickness for 3D viewer
171 
172  m_viaSizeIndex = 0;
173  m_trackWidthIndex = 0;
174  m_diffPairIndex = 0;
175 
176  // Parameters stored in JSON in the project file
177 
178  // NOTE: Previously, BOARD_DESIGN_SETTINGS stored the basic board layer information (layer
179  // names and enable/disable state) in the project file even though this information is also
180  // stored in the board file. This was implemented for importing these settings from another
181  // project. Going forward, the import feature will just import from other board files (since
182  // we could have multi-board projects in the future anyway) so this functionality is dropped.
183 
184  m_params.emplace_back( new PARAM<bool>( "rules.allow_microvias", &m_MicroViasAllowed, false ) );
185 
186  m_params.emplace_back(
187  new PARAM<bool>( "rules.allow_blind_buried_vias", &m_BlindBuriedViaAllowed, false ) );
188 
189  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_clearance", &m_MinClearance,
191  MM_PER_IU ) );
192 
193  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_track_width", &m_TrackMinWidth,
195  MM_PER_IU ) );
196 
197  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_via_annulus", &m_ViasMinAnnulus,
199  MM_PER_IU ) );
200 
201  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_via_diameter", &m_ViasMinSize,
203  MM_PER_IU ) );
204 
205  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_through_hole_diameter",
207  Millimeter2iu( 25.0 ), MM_PER_IU ) );
208 
209  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_microvia_diameter",
211  Millimeter2iu( 10.0 ), MM_PER_IU ) );
212 
213  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_microvia_drill", &m_MicroViasMinDrill,
215  Millimeter2iu( 10.0 ), MM_PER_IU ) );
216 
217  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_hole_to_hole", &m_HoleToHoleMin,
219  MM_PER_IU ) );
220 
221  // Note: a clearance of -0.01 is a flag indicating we should use the legacy (pre-6.0) method
222  // based on the edge cut thicknesses.
223  m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_copper_edge_clearance",
225  Millimeter2iu( -0.01 ), Millimeter2iu( 25.0 ), MM_PER_IU ) );
226 
227  m_params.emplace_back( new PARAM_SCALED<int>( "rules.solder_mask_clearance",
229  Millimeter2iu( -1.0 ), Millimeter2iu( 1.0 ), MM_PER_IU ) );
230 
231  m_params.emplace_back( new PARAM_SCALED<int>( "rules.solder_mask_min_width",
233  Millimeter2iu( 1.0 ), MM_PER_IU ) );
234 
235  m_params.emplace_back( new PARAM_SCALED<int>( "rules.solder_paste_clearance",
237  Millimeter2iu( -1.0 ), Millimeter2iu( 1.0 ), MM_PER_IU ) );
238 
239  m_params.emplace_back( new PARAM<double>( "rules.solder_paste_margin_ratio",
241 
242  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
243  [&]() -> nlohmann::json
244  {
245  nlohmann::json ret = {};
246 
247  for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities() )
248  {
249  int code = item.GetErrorCode();
250 
251  if( !m_DRCSeverities.count( code ) )
252  continue;
253 
254  wxString name = item.GetSettingsKey();
255 
256  ret[std::string( name.ToUTF8() )] =
257  SeverityToString( static_cast<SEVERITY>( m_DRCSeverities[code] ) );
258  }
259 
260  return ret;
261  },
262  [&]( const nlohmann::json& aJson )
263  {
264  if( !aJson.is_object() )
265  return;
266 
267  for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities() )
268  {
269  wxString name = item.GetSettingsKey();
270  std::string key( name.ToUTF8() );
271 
272  if( aJson.contains( key ) )
273  m_DRCSeverities[item.GetErrorCode()] = SeverityFromString( aJson[key] );
274  }
275  }, {} ) );
276 
277  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "drc_exclusions",
278  [&]() -> nlohmann::json
279  {
280  nlohmann::json js = nlohmann::json::array();
281 
282  for( const auto& entry : m_DrcExclusions )
283  js.push_back( entry );
284 
285  return js;
286  },
287  [&]( const nlohmann::json& aObj )
288  {
289  m_DrcExclusions.clear();
290 
291  if( !aObj.is_array() )
292  return;
293 
294  for( const nlohmann::json& entry : aObj )
295  {
296  if( entry.empty() )
297  continue;
298 
299  m_DrcExclusions.insert( entry.get<wxString>() );
300  }
301  },
302  {} ) );
303 
304  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "track_widths",
305  [&]() -> nlohmann::json
306  {
307  nlohmann::json js = nlohmann::json::array();
308 
309  for( const int& width : m_TrackWidthList )
310  js.push_back( Iu2Millimeter( width ) );
311 
312  return js;
313  },
314  [&]( const nlohmann::json& aJson )
315  {
316  if( !aJson.is_array() )
317  return;
318 
319  m_TrackWidthList.clear();
320 
321  for( const nlohmann::json& entry : aJson )
322  {
323  if( entry.empty() )
324  continue;
325 
326  m_TrackWidthList.emplace_back( Millimeter2iu( entry.get<double>() ) );
327  }
328  },
329  {} ) );
330 
331  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "via_dimensions",
332  [&]() -> nlohmann::json
333  {
334  nlohmann::json js = nlohmann::json::array();
335 
336  for( const auto& via : m_ViasDimensionsList )
337  {
338  nlohmann::json entry = {};
339 
340  entry["diameter"] = Iu2Millimeter( via.m_Diameter );
341  entry["drill"] = Iu2Millimeter( via.m_Drill );
342 
343  js.push_back( entry );
344  }
345 
346  return js;
347  },
348  [&]( const nlohmann::json& aObj )
349  {
350  if( !aObj.is_array() )
351  return;
352 
353  m_ViasDimensionsList.clear();
354 
355  for( const nlohmann::json& entry : aObj )
356  {
357  if( entry.empty() || !entry.is_object() )
358  continue;
359 
360  if( !entry.contains( "diameter" ) || !entry.contains( "drill" ) )
361  continue;
362 
363  int diameter = Millimeter2iu( entry["diameter"].get<double>() );
364  int drill = Millimeter2iu( entry["drill"].get<double>() );
365 
366  m_ViasDimensionsList.emplace_back( VIA_DIMENSION( diameter, drill ) );
367  }
368  },
369  {} ) );
370 
371  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "diff_pair_dimensions",
372  [&]() -> nlohmann::json
373  {
374  nlohmann::json js = nlohmann::json::array();
375 
376  for( const auto& pair : m_DiffPairDimensionsList )
377  {
378  nlohmann::json entry = {};
379 
380  entry["width"] = Iu2Millimeter( pair.m_Width );
381  entry["gap"] = Iu2Millimeter( pair.m_Gap );
382  entry["via_gap"] = Iu2Millimeter( pair.m_ViaGap );
383 
384  js.push_back( entry );
385  }
386 
387  return js;
388  },
389  [&]( const nlohmann::json& aObj )
390  {
391  if( !aObj.is_array() )
392  return;
393 
394  m_DiffPairDimensionsList.clear();
395 
396  for( const nlohmann::json& entry : aObj )
397  {
398  if( entry.empty() || !entry.is_object() )
399  continue;
400 
401  if( !entry.contains( "width" ) || !entry.contains( "gap" )
402  || !entry.contains( "via_gap" ) )
403  continue;
404 
405  int width = Millimeter2iu( entry["width"].get<int>() );
406  int gap = Millimeter2iu( entry["gap"].get<int>() );
407  int via_gap = Millimeter2iu( entry["via_gap"].get<int>() );
408 
409  m_DiffPairDimensionsList.emplace_back(
410  DIFF_PAIR_DIMENSION( width, gap, via_gap ) );
411  }
412  },
413  {} ) );
414 
415  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_line_width",
417  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
418 
419  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_v",
421  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
422 
423  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_h",
425  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
426 
427  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_thickness",
429  TEXTS_MAX_WIDTH, MM_PER_IU ) );
430 
431  m_params.emplace_back( new PARAM<bool>(
432  "defaults.silk_text_italic", &m_TextItalic[LAYER_CLASS_SILK], false ) );
433 
434  m_params.emplace_back( new PARAM<bool>(
435  "defaults.silk_text_upright", &m_TextUpright[ LAYER_CLASS_SILK ], true ) );
436 
437  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_line_width",
439  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
440 
441  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_v",
443  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
444 
445  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_h",
447  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
448 
449  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_thickness",
451  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
452 
453  m_params.emplace_back( new PARAM<bool>(
454  "defaults.copper_text_italic", &m_TextItalic[LAYER_CLASS_COPPER], false ) );
455 
456  m_params.emplace_back( new PARAM<bool>(
457  "defaults.copper_text_upright", &m_TextUpright[LAYER_CLASS_COPPER], true ) );
458 
459  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.board_outline_line_width",
461  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
462 
463  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.courtyard_line_width",
465  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
466 
467  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_line_width",
469  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
470 
471  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_v",
473  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
474 
475  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_h",
477  TEXTS_MIN_SIZE, TEXTS_MAX_SIZE, MM_PER_IU ) );
478 
479  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_thickness",
481  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
482 
483  m_params.emplace_back(
484  new PARAM<bool>( "defaults.fab_text_italic", &m_TextItalic[LAYER_CLASS_FAB], false ) );
485 
486  m_params.emplace_back(
487  new PARAM<bool>( "defaults.fab_text_upright", &m_TextUpright[LAYER_CLASS_FAB], true ) );
488 
489  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_line_width",
491  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
492 
493  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_v",
495  TEXTS_MAX_SIZE, MM_PER_IU ) );
496 
497  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_h",
499  TEXTS_MAX_SIZE, MM_PER_IU ) );
500 
501  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_thickness",
503  Millimeter2iu( 0.01 ), Millimeter2iu( 5.0 ), MM_PER_IU ) );
504 
505  m_params.emplace_back( new PARAM<bool>(
506  "defaults.other_text_italic", &m_TextItalic[LAYER_CLASS_OTHERS], false ) );
507 
508  m_params.emplace_back( new PARAM<bool>(
509  "defaults.other_text_upright", &m_TextUpright[LAYER_CLASS_OTHERS], true ) );
510 
511  m_params.emplace_back(
512  new PARAM<int>( "defaults.dimension_units", &m_DimensionUnits, 0, 0, 2 ) );
513 
514  m_params.emplace_back(
515  new PARAM<int>( "defaults.dimension_precision", &m_DimensionPrecision, 1, 0, 2 ) );
516 
517  m_params.emplace_back( new PARAM<bool>(
518  "defaults.zones.45_degree_only", &m_defaultZoneSettings.m_Zone_45_Only, false ) );
519 
520  m_params.emplace_back( new PARAM_SCALED<int>( "defaults.zones.min_clearance",
522  Millimeter2iu( 0.0 ), Millimeter2iu( 25.0 ), MM_PER_IU ) );
523 
524  m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "defaults.pads",
525  [&]() -> nlohmann::json
526  {
527  nlohmann::json ret =
528  {
529  { "width", Iu2Millimeter( m_Pad_Master.GetSize().x ) },
530  { "height", Iu2Millimeter( m_Pad_Master.GetSize().y ) },
531  { "drill", Iu2Millimeter( m_Pad_Master.GetDrillSize().x ) }
532  };
533 
534  return ret;
535  },
536  [&]( const nlohmann::json& aJson )
537  {
538  if( aJson.contains( "width" ) && aJson.contains( "height" )
539  && aJson.contains( "drill" ) )
540  {
541  wxSize sz;
542  sz.SetWidth( Millimeter2iu( aJson["width"].get<double>() ) );
543  sz.SetHeight( Millimeter2iu( aJson["height"].get<double>() ) );
544 
545  m_Pad_Master.SetSize( sz );
546 
547  int drill = Millimeter2iu( aJson["drill"].get<double>() );
548 
549  m_Pad_Master.SetDrillSize( wxSize( drill, drill ) );
550  }
551  }, {} ) );
552 
553  m_params.emplace_back( new PARAM_SCALED<int>( "rules.max_error", &m_MaxError, ARC_HIGH_DEF,
554  Millimeter2iu( 0.0001 ), Millimeter2iu( 1.0 ), MM_PER_IU ) );
555 
556  m_params.emplace_back(
557  new PARAM<bool>( "zones_use_no_outline", &m_ZoneUseNoOutlineInFill, false ) );
558 }
559 
560 
562 {
563  if( m_parent )
564  {
566  m_parent = nullptr;
567  }
568 }
569 
570 
572  NESTED_SETTINGS( "board_design_settings", bdsSchemaVersion, aOther.m_parent,
573  aOther.m_path ),
574  m_Pad_Master( nullptr )
575 {
576  initFromOther( aOther );
577 }
578 
579 
581 {
582  initFromOther( aOther );
583  return *this;
584 }
585 
586 
588 {
589  // Copy of NESTED_SETTINGS around is not allowed, so let's just update the params.
593  m_DRCRules = aOther.m_DRCRules;
601  m_ViasMinSize = aOther.m_ViasMinSize;
610  m_MaxError = aOther.m_MaxError;
616 
617  std::copy( std::begin( aOther.m_LineThickness ), std::end( aOther.m_LineThickness ),
618  std::begin( m_LineThickness ) );
619 
620  std::copy( std::begin( aOther.m_TextSize ), std::end( aOther.m_TextSize ),
621  std::begin( m_TextSize ) );
622 
623  std::copy( std::begin( aOther.m_TextThickness ), std::end( aOther.m_TextThickness ),
624  std::begin( m_TextThickness ) );
625 
626  std::copy( std::begin( aOther.m_TextItalic ), std::end( aOther.m_TextItalic ),
627  std::begin( m_TextItalic ) );
628 
629  std::copy( std::begin( aOther.m_TextUpright ), std::end( aOther.m_TextUpright ),
630  std::begin( m_TextUpright ) );
631 
634  m_AuxOrigin = aOther.m_AuxOrigin;
635  m_GridOrigin = aOther.m_GridOrigin;
636  m_HasStackup = aOther.m_HasStackup;
637 
650  m_stackup = aOther.m_stackup;
651 
652  // Only take the pointer from the other if it isn't the default
653  if( aOther.m_netClasses == &aOther.m_internalNetClasses )
655  else
656  m_netClasses = aOther.m_netClasses;
657 
659 }
660 
661 
662 bool BOARD_DESIGN_SETTINGS::LoadFromFile( const wxString& aDirectory )
663 {
664  bool ret = NESTED_SETTINGS::LoadFromFile( aDirectory );
665 
666  // A number of things won't have been translated by the PROJECT_FILE migration because of
667  // descoped objects required to decode this data. So, it will be in the legacy.pcbnew
668  // section and needs to be pulled out here
669 
670  PROJECT_FILE* project = dynamic_cast<PROJECT_FILE*>( GetParent() );
671 
672  if( !project )
673  return ret;
674 
675  bool migrated = false;
676 
677  auto drcName =
678  []( int aCode ) -> std::string
679  {
680  DRC_ITEM* item = DRC_ITEM::Create( aCode );
681  wxString name = item->GetSettingsKey();
682  delete item;
683  return std::string( name.ToUTF8() );
684  };
685 
686  std::string bp = "board.design_settings.rule_severities.";
687  std::string rs = "rule_severities.";
688 
689  if( OPT<bool> v =
690  project->Get<bool>( PointerFromString( bp + "legacy_no_courtyard_defined" ) ) )
691  {
692  if( *v )
693  ( *this )[PointerFromString( rs + drcName( DRCE_MISSING_COURTYARD ) )] = "error";
694  else
695  ( *this )[PointerFromString( rs + drcName( DRCE_MISSING_COURTYARD ) )] = "ignore";
696 
697  project->erase( PointerFromString( bp + "legacy_no_courtyard_defined" ) );
698  migrated = true;
699  }
700 
701  if( OPT<bool> v = project->Get<bool>( PointerFromString( bp + "legacy_courtyards_overlap" ) ) )
702  {
703  if( *v )
704  ( *this )[PointerFromString( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ) )] = "error";
705  else
706  ( *this )[PointerFromString( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ) )] = "ignore";
707 
708  project->erase( PointerFromString( bp + "legacy_courtyards_overlap" ) );
709  migrated = true;
710  }
711 
712  if( project->contains( "legacy" ) )
713  project->at( "legacy" ).erase( "pcbnew" );
714 
715  // Now that we have everything, we need to load again
716  if( migrated )
717  Load();
718 
719  return ret;
720 }
721 
722 
723 int BOARD_DESIGN_SETTINGS::GetSeverity( int aDRCErrorCode )
724 {
725  return m_DRCSeverities[ aDRCErrorCode ];
726 }
727 
728 
729 bool BOARD_DESIGN_SETTINGS::Ignore( int aDRCErrorCode )
730 {
731  return m_DRCSeverities[ aDRCErrorCode ] == RPT_SEVERITY_IGNORE;
732 }
733 
734 
735 bool BOARD_DESIGN_SETTINGS::SetCurrentNetClass( const wxString& aNetClassName )
736 {
737  NETCLASSPTR netClass = GetNetClasses().Find( aNetClassName );
738  bool lists_sizes_modified = false;
739 
740  // if not found (should not happen) use the default
741  if( !netClass )
742  netClass = GetNetClasses().GetDefault();
743 
744  m_currentNetClassName = netClass->GetName();
745 
746  // Initialize others values:
747  if( m_TrackWidthList.size() == 0 )
748  {
749  lists_sizes_modified = true;
750  m_TrackWidthList.push_back( 0 );
751  }
752 
753  if( m_ViasDimensionsList.size() == 0 )
754  {
755  lists_sizes_modified = true;
756  m_ViasDimensionsList.emplace_back( VIA_DIMENSION() );
757  }
758 
759  if( m_DiffPairDimensionsList.size() == 0 )
760  {
761  lists_sizes_modified = true;
763  }
764 
765  /* note the m_ViasDimensionsList[0] and m_TrackWidthList[0] values
766  * are always the Netclass values
767  */
768  if( m_TrackWidthList[0] != netClass->GetTrackWidth() )
769  {
770  lists_sizes_modified = true;
771  m_TrackWidthList[0] = netClass->GetTrackWidth();
772  }
773 
774  if( m_ViasDimensionsList[0].m_Diameter != netClass->GetViaDiameter() )
775  {
776  lists_sizes_modified = true;
777  m_ViasDimensionsList[0].m_Diameter = netClass->GetViaDiameter();
778  }
779 
780  if( m_ViasDimensionsList[0].m_Drill != netClass->GetViaDrill() )
781  {
782  lists_sizes_modified = true;
783  m_ViasDimensionsList[0].m_Drill = netClass->GetViaDrill();
784  }
785 
786  if( m_DiffPairDimensionsList[0].m_Width != netClass->GetDiffPairWidth() )
787  {
788  lists_sizes_modified = true;
789  m_DiffPairDimensionsList[0].m_Width = netClass->GetDiffPairWidth();
790  }
791 
792  if( m_DiffPairDimensionsList[0].m_Gap != netClass->GetDiffPairGap() )
793  {
794  lists_sizes_modified = true;
795  m_DiffPairDimensionsList[0].m_Gap = netClass->GetDiffPairGap();
796  }
797 
798  if( m_DiffPairDimensionsList[0].m_ViaGap != netClass->GetDiffPairViaGap() )
799  {
800  lists_sizes_modified = true;
801  m_DiffPairDimensionsList[0].m_ViaGap = netClass->GetDiffPairViaGap();
802  }
803 
804  if( GetViaSizeIndex() >= m_ViasDimensionsList.size() )
806 
807  if( GetTrackWidthIndex() >= m_TrackWidthList.size() )
809 
812 
813  return lists_sizes_modified;
814 }
815 
816 
818 {
819  int clearance = GetDefault()->GetClearance();
820 
821  for( const std::pair<const wxString, NETCLASSPTR>& netclass : GetNetClasses().NetClasses() )
822  clearance = std::max( clearance, netclass.second->GetClearance() );
823 
824  for( const DRC_RULE* rule : m_DRCRules )
825  {
826  for( const DRC_CONSTRAINT& constraint : rule->m_Constraints )
827  {
828  if( constraint.m_Type == DRC_RULE_ID_CLEARANCE )
829  clearance = std::max( clearance, constraint.m_Value.Min() );
830  }
831  }
832 
833  return clearance;
834 }
835 
836 
838 {
839  int clearance = GetDefault()->GetClearance();
840 
841  for( const std::pair<const wxString, NETCLASSPTR>& netclass : GetNetClasses().NetClasses() )
842  clearance = std::min( clearance, netclass.second->GetClearance() );
843 
844  return clearance;
845 }
846 
847 
849 {
850  NETCLASSPTR netclass = GetNetClasses().Find( m_currentNetClassName );
851 
852  return netclass->GetuViaDiameter();
853 }
854 
855 
857 {
858  NETCLASSPTR netclass = GetNetClasses().Find( m_currentNetClassName );
859 
860  return netclass->GetuViaDrill();
861 }
862 
863 
865 {
866  m_viaSizeIndex = std::min( aIndex, (unsigned) m_ViasDimensionsList.size() );
867  m_useCustomTrackVia = false;
868 }
869 
870 
872 {
873  int drill;
874 
875  if( m_useCustomTrackVia )
876  drill = m_customViaSize.m_Drill;
877  else
878  drill = m_ViasDimensionsList[m_viaSizeIndex].m_Drill;
879 
880  return drill > 0 ? drill : -1;
881 }
882 
883 
885 {
886  m_trackWidthIndex = std::min( aIndex, (unsigned) m_TrackWidthList.size() );
887  m_useCustomTrackVia = false;
888 }
889 
890 
892 {
893  m_diffPairIndex = std::min( aIndex, (unsigned) 8 );
894  m_useCustomDiffPair = false;
895 }
896 
897 
899 {
900  m_HoleToHoleMin = aDistance;
901 }
902 
903 
905 {
906  m_CopperEdgeClearance = aDistance;
907 }
908 
909 
911 {
912  m_copperLayerCount = aNewLayerCount;
913 
914  // Update only enabled copper layers mask
915  m_enabledLayers &= ~LSET::AllCuMask();
916 
917  if( aNewLayerCount > 0 )
918  m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
919 }
920 
921 
923 {
924  // Back and front layers are always enabled.
925  aMask.set( B_Cu ).set( F_Cu );
926 
927  m_enabledLayers = aMask;
928 
929  // update m_CopperLayerCount to ensure its consistency with m_EnabledLayers
930  m_copperLayerCount = ( aMask & LSET::AllCuMask() ).count();
931 }
932 
933 
934 // Return the layer class index { silk, copper, edges & courtyards, fab, others } of the
935 // given layer.
937 {
938  if( aLayer == F_SilkS || aLayer == B_SilkS )
939  return LAYER_CLASS_SILK;
940  else if( IsCopperLayer( aLayer ) )
941  return LAYER_CLASS_COPPER;
942  else if( aLayer == Edge_Cuts )
943  return LAYER_CLASS_EDGES;
944  else if( aLayer == F_CrtYd || aLayer == B_CrtYd )
945  return LAYER_CLASS_COURTYARD;
946  else if( aLayer == F_Fab || aLayer == B_Fab )
947  return LAYER_CLASS_FAB;
948  else
949  return LAYER_CLASS_OTHERS;
950 }
951 
952 
954 {
955  return m_LineThickness[ GetLayerClass( aLayer ) ];
956 }
957 
958 
960 {
961  return m_TextSize[ GetLayerClass( aLayer ) ];
962 }
963 
964 
966 {
967  return m_TextThickness[ GetLayerClass( aLayer ) ];
968 }
969 
970 
972 {
973  return m_TextItalic[ GetLayerClass( aLayer ) ];
974 }
975 
976 
978 {
979  return m_TextUpright[ GetLayerClass( aLayer ) ];
980 }
981 
982 
int GetCurrentMicroViaSize()
Function GetCurrentMicroViaSize.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Function AllCuMask returns a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:712
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_SILK_TEXT_WIDTH
int m_SolderMaskMargin
Solder mask margin.
void SetCopperLayerCount(int aNewLayerCount)
Function SetCopperLayerCount do what its name says...
#define DEFAULT_TRACKMINWIDTH
Struct VIA_DIMENSION is a small helper container to handle a stock of specific vias each with unique ...
void SetEnabledLayers(LSET aMask)
Function SetEnabledLayers changes the bit-mask of enabled layers.
void SetCopperEdgeClearance(int aDistance)
Function SetCopperEdgeClearance.
#define DEFAULT_COURTYARD_WIDTH
void SetTrackWidthIndex(unsigned aIndex)
Function SetTrackWidthIndex sets the current track width list index to aIndex.
more than one footprints found for netlist item
wxString m_currentNetClassName
Current net class name used to display netclass info.
std::vector< TEXT_ITEM_INFO > m_DefaultFPTextItems
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
footprint not found for netlist item
#define DEFAULT_SOLDERPASTE_RATIO
wxPoint m_GridOrigin
origin for grid offsets
NETCLASSPTR Find(const wxString &aName) const
Function Find searches this container for a NETCLASS given by aName.
Definition: netclass.cpp:132
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:296
int GetCurrentViaDrill() const
Function GetCurrentViaDrill.
JSON_SETTINGS * GetParent()
int m_SolderPasteMargin
Solder paste margin absolute value.
#define DEFAULT_VIASMINSIZE
#define TEXTS_MAX_WIDTH
Maximum text width in internal units (10 inches)
Definition: pcbnew.h:34
BOARD_DESIGN_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
std::vector< int > m_TrackWidthList
int GetSmallestClearanceValue()
Function GetSmallestClearanceValue.
int GetBiggestClearanceValue()
Function GetBiggestClearanceValue.
BOARD_STACKUP m_stackup
the description of layers stackup, for board fabrication only physical layers are in layers stackup.
int GetCurrentMicroViaDrill()
Function GetCurrentMicroViaDrill.
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
std::map< int, int > m_DRCSeverities
RC_ITEM is a holder for a DRC (in Pcbnew) or ERC (in Eeschema) error item.
Definition: rc_item.h:73
NETCLASSES m_internalNetClasses
Net classes that are loaded from the board file before these were stored in the project.
bool Ignore(int aDRCErrorCode)
returns true if the DRC error code's severity is SEVERITY_IGNORE
#define LEGACY_COPPEREDGECLEARANCE
#define DEFAULT_BOARD_THICKNESS_MM
ZONE_SETTINGS m_defaultZoneSettings
The defualt settings that will be used for new zones.
#define DEFAULT_LINE_WIDTH
#define DEFAULT_COPPER_LINE_WIDTH
#define DEFAULT_HOLETOHOLEMIN
void SetDrillSize(const wxSize &aSize)
Definition: class_pad.h:229
int GetClearance(wxString *aSource=nullptr) const
Definition: netclass.h:158
DIFF_PAIR_DIMENSION m_customDiffPair
#define DEFAULT_CUSTOMDPAIRGAP
int GetTextThickness(PCB_LAYER_ID aLayer) const
Function GetTextThickness Returns the default text thickness from the layer class for the given layer...
VIATYPE m_CurrentViaType
(VIA_BLIND_BURIED, VIA_THROUGH, VIA_MICROVIA)
bool LoadFromFile(const wxString &aDirectory="") override
Loads the JSON document from the parent and then calls Load()
nlohmann::json json
Definition: gerbview.cpp:40
PROJECT_FILE is the backing store for a PROJECT, in JSON format.
Definition: project_file.h:62
Struct DIFF_PAIR_DIMENSION is a small helper container to handle a stock of specific differential pai...
#define DEFAULT_MINCLEARANCE
#define DEFAULT_MINTHROUGHDRILL
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
#define DEFAULT_CUSTOMDPAIRVIAGAP
OPT< ValueType > Get(const std::string &aPath) const
Fetches a value from within the JSON document.
int GetLayerClass(PCB_LAYER_ID aLayer) const
bool GetTextUpright(PCB_LAYER_ID aLayer) const
#define DEFAULT_SOLDERPASTE_CLEARANCE
bool GetTextItalic(PCB_LAYER_ID aLayer) const
int GetLineThickness(PCB_LAYER_ID aLayer) const
Function GetLineThickness Returns the default graphic segment thickness from the layer class for the ...
#define DEFAULT_TEXT_WIDTH
wxSize m_TextSize[LAYER_CLASS_COUNT]
void SetViaSizeIndex(unsigned aIndex)
Function SetViaSizeIndex sets the current via size list index to aIndex.
MINOPTMAX< int > m_Value
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
#define DEFAULT_CUSTOMDPAIRWIDTH
PCB_LAYER_ID
A quick note on layer IDs:
#define DEFAULT_SILK_TEXT_SIZE
int m_TextThickness[LAYER_CLASS_COUNT]
LSET is a set of PCB_LAYER_IDs.
#define DEFAULT_SILK_LINE_WIDTH
footprint courtyards overlap
#define NULL
unsigned GetViaSizeIndex() const
Function GetViaSizeIndex.
void SetMinHoleSeparation(int aDistance)
Function SetMinHoleSeparation.
bool LoadFromFile(const wxString &aDirectory="") override
Loads the backing file from disk and then calls Load()
netlist item not found for footprint
footprint has no courtyard defined
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
unsigned GetTrackWidthIndex() const
Function GetTrackWidthIndex.
bool m_TextItalic[LAYER_CLASS_COUNT]
track with at least one end not connected to anything
Represents a parameter that has a scaling factor between the value in the file and the value used int...
Definition: parameters.h:388
Functions to provide common constants and other functions to assist in making a consistent UI.
void SetSize(const wxSize &aSize)
Definition: class_pad.h:223
#define ZONE_CLEARANCE_MIL
Definition: zones.h:33
static DRC_ITEM * Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
BOARD_DESIGN_SETTINGS & operator=(const BOARD_DESIGN_SETTINGS &aOther)
NETCLASSES & GetNetClasses() const
bool m_BlindBuriedViaAllowed
true to allow blind/buried vias
const int bdsSchemaVersion
#define TEXTS_MAX_SIZE
Maximum text size in internal units (10 inches)
Definition: pcbnew.h:33
void SetDiffPairIndex(unsigned aIndex)
Function SetDiffPairIndex.
#define DEFAULT_MICROVIASMINSIZE
via which isn't connected to anything
#define DEFAULT_MICROVIASMINDRILL
#define DEFAULT_SOLDERMASK_MIN_WIDTH
int m_LineThickness[LAYER_CLASS_COUNT]
#define TEXTS_MIN_SIZE
Minimum text size in internal units (1 mil)
Definition: pcbnew.h:32
#define DEFAULT_COPPEREDGECLEARANCE
bool m_resetParamsIfMissing
Whether or not to set parameters to their default value if missing from JSON on Load()
bool SetCurrentNetClass(const wxString &aNetClassName)
Function SetCurrentNetClass Must be called after a netclass selection (or after a netclass parameter ...
wxString SeverityToString(const SEVERITY &aSeverity)
Definition: ui_common.cpp:119
Board layer functions and definitions.
const char * name
Definition: DXF_plotter.cpp:60
bool m_ZoneUseNoOutlineInFill
Option to handle filled polygons in zones: the "legacy" option is using thick outlines around filled ...
SEVERITY SeverityFromString(const wxString &aSeverity)
Definition: ui_common.cpp:108
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities()
const wxSize & GetDrillSize() const
Definition: class_pad.h:230
D_PAD m_Pad_Master
A dummy pad to store all default parameters.
NETCLASS * GetDefault() const
Function GetDefault.
void initFromOther(const BOARD_DESIGN_SETTINGS &aOther)
The common library.
#define DEFAULT_COPPER_TEXT_WIDTH
std::vector< VIA_DIMENSION > m_ViasDimensionsList
boost::optional< T > OPT
Definition: optional.h:7
wxString GetSettingsKey() const
Definition: rc_item.h:170
#define DEFAULT_CUSTOMTRACKWIDTH
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer tests whether a layer is a copper layer.
NETCLASSPTR GetDefault() const
Function GetDefault.
Definition: netclass.h:262
#define DEFAULT_TEXT_SIZE
unsigned GetDiffPairIndex() const
Function GetDiffPairIndex.
NETCLASSES * m_netClasses
This will point to m_internalNetClasses until it is repointed to the project after load.
#define DEFAULT_SOLDERMASK_CLEARANCE
int m_copperLayerCount
Number of copper layers for this design.
#define DEFAULT_COPPER_TEXT_SIZE
bool m_MicroViasAllowed
true to allow micro vias
bool m_HasStackup
Set to true if the board has a stackup management.
double m_SolderPasteMarginRatio
Solder pask margin ratio value of pad size The final margin is the sum of these 2 values.
const wxSize & GetSize() const
Definition: class_pad.h:224
int GetSeverity(int aDRCErrorCode)
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
std::set< wxString > m_DrcExclusions
static constexpr int Millimeter2iu(double mm)
static nlohmann::json::json_pointer PointerFromString(std::string aPath)
Builds a JSON pointer based on a given string.
DRC_RULE_ID_T m_Type
LSET m_enabledLayers
Bit-mask for layer enabling.
std::vector< DRC_RULE * > m_DRCRules
wxPoint m_AuxOrigin
origin for plot exports
wxSize GetTextSize(PCB_LAYER_ID aLayer) const
Function GetTextSize Returns the default text size from the layer class for the given layer.
int m_boardThickness
Board thickness for 3D viewer.
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
bool m_TextUpright[LAYER_CLASS_COUNT]
int m_SolderMaskMinWidth
Solder mask min width.
BOARD_DESIGN_SETTINGS contains design settings for a BOARD object.