KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The 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 <pcb_dimension.h>
25#include <pcb_track.h>
26#include <layer_ids.h>
27#include <lset.h>
28#include <kiface_base.h>
29#include <pad.h>
31#include <drc/drc_item.h>
32#include <drc/drc_engine.h>
34#include <settings/parameters.h>
36#include <advanced_config.h>
37
38const int bdsSchemaVersion = 2;
39
40
41BOARD_DESIGN_SETTINGS::BOARD_DESIGN_SETTINGS( JSON_SETTINGS* aParent, const std::string& aPath ) :
42 NESTED_SETTINGS( "board_design_settings", bdsSchemaVersion, aParent, aPath )
43{
44 // We want to leave alone parameters that aren't found in the project JSON as they may be
45 // initialized by the board file parser before NESTED_SETTINGS::LoadFromFile is called.
47
48 // Create a default NET_SETTINGS so that things don't break horribly if there's no project
49 // loaded. This also is used during file load for legacy boards that have netclasses stored
50 // in the file. After load, this information will be moved to the project and the pointer
51 // updated.
52 m_NetSettings = std::make_shared<NET_SETTINGS>( nullptr, "" );
53
54 m_HasStackup = false; // no stackup defined by default
55
56 m_Pad_Master = std::make_unique<PAD>( nullptr );
58
59 LSET all_set = LSET().set();
60 m_enabledLayers = all_set; // All layers enabled at first.
61 // SetCopperLayerCount() will adjust this.
62
63 SetCopperLayerCount( 2 ); // Default design is a double sided board
64 m_CurrentViaType = VIATYPE::THROUGH;
65
66 // if true, when creating a new track starting on an existing track, use this track width
69
70 // First is always the reference designator
71 m_DefaultFPTextItems.emplace_back( wxT( "REF**" ), true, F_SilkS );
72 // Second is always the value
73 m_DefaultFPTextItems.emplace_back( wxT( "" ), true, F_Fab );
74 // Any following ones are freebies
75 m_DefaultFPTextItems.emplace_back( wxT( "${REFERENCE}" ), true, F_Fab );
76
83
90
91 // Edges & Courtyards; text properties aren't used but better to have them holding
92 // reasonable values than not.
99
106
111 m_TextItalic[ LAYER_CLASS_FAB ] = false;
113
120
121 m_StyleFPFields = false;
122 m_StyleFPText = false;
123 m_StyleFPShapes = false;
124
125 m_DimensionPrecision = DIM_PRECISION::X_XXXX;
126 m_DimensionUnitsMode = DIM_UNITS_MODE::AUTOMATIC;
127 m_DimensionUnitsFormat = DIM_UNITS_FORMAT::NO_SUFFIX;
129 m_DimensionTextPosition = DIM_TEXT_POSITION::OUTSIDE;
133
134 m_useCustomTrackVia = false;
138
139 m_useCustomDiffPair = false;
143
160
161 for( int errorCode = DRCE_FIRST; errorCode <= DRCE_LAST; ++errorCode )
162 m_DRCSeverities[ errorCode ] = RPT_SEVERITY_ERROR;
163
166
170
173
176
178
185
191
193
196
198
201
205
206 // Global mask margins:
210
211 // Solder paste margin absolute value
213 // Solder paste margin as a ratio of pad size
214 // The final margin is the sum of these 2 values
215 // Usually < 0 because the mask is smaller than pad
217
219 m_TentViasFront = true;
220 m_TentViasBack = true;
221
222 // Layer thickness for 3D viewer
224
225 // Default spacing for meanders
229
230 m_viaSizeIndex = 0;
232 m_diffPairIndex = 0;
233
234 // Parameters stored in JSON in the project file
235
236 // NOTE: Previously, BOARD_DESIGN_SETTINGS stored the basic board layer information (layer
237 // names and enable/disable state) in the project file even though this information is also
238 // stored in the board file. This was implemented for importing these settings from another
239 // project. Going forward, the import feature will just import from other board files (since
240 // we could have multi-board projects in the future anyway) so this functionality is dropped.
241
242
243 m_params.emplace_back( new PARAM<bool>( "rules.use_height_for_length_calcs",
244 &m_UseHeightForLengthCalcs, true ) );
245
246 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_clearance",
249
250 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_connection",
252 pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
253
254 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_track_width",
257
258 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_via_annular_width",
261
262 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_via_diameter",
265
266 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_through_hole_diameter",
269
270 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_microvia_diameter",
273
274 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_microvia_drill",
277
278 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_hole_to_hole",
281
282 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_hole_clearance",
284 pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
285
286 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_silk_clearance",
288 pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
289
290 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_groove_width",
293
294 // While the maximum *effective* value is 4, we've had users interpret this as the count on
295 // all layers, and enter something like 10. They'll figure it out soon enough *unless* we
296 // enforce a max of 4 (and therefore reset it back to the default of 2), at which point it
297 // just looks buggy.
298 m_params.emplace_back( new PARAM<int>( "rules.min_resolved_spokes",
300
301 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_text_height",
303 pcbIUScale.mmToIU( 0.00 ), pcbIUScale.mmToIU( 100.0 ), pcbIUScale.MM_PER_IU ) );
304
305 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_text_thickness",
308
309 // Note: a clearance of -0.01 is a flag indicating we should use the legacy (pre-6.0) method
310 // based on the edge cut thicknesses.
311 m_params.emplace_back( new PARAM_SCALED<int>( "rules.min_copper_edge_clearance",
313 pcbIUScale.mmToIU( -0.01 ), pcbIUScale.mmToIU( 25.0 ), pcbIUScale.MM_PER_IU ) );
314
315 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "rule_severities",
316 [&]() -> nlohmann::json
317 {
318 nlohmann::json ret = {};
319
320 for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities() )
321 {
322 wxString name = item.GetSettingsKey();
323 int code = item.GetErrorCode();
324
325 if( name.IsEmpty() || m_DRCSeverities.count( code ) == 0 )
326 continue;
327
328 ret[std::string( name.ToUTF8() )] = SeverityToString( m_DRCSeverities[code] );
329 }
330
331 return ret;
332 },
333 [&]( const nlohmann::json& aJson )
334 {
335 if( !aJson.is_object() )
336 return;
337
338 for( const RC_ITEM& item : DRC_ITEM::GetItemsWithSeverities( true ) )
339 {
340 wxString name = item.GetSettingsKey();
341 std::string key( name.ToUTF8() );
342
343 if( aJson.contains( key ) )
344 m_DRCSeverities[item.GetErrorCode()] = SeverityFromString( aJson[key] );
345 }
346 }, {} ) );
347
348 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "drc_exclusions",
349 [&]() -> nlohmann::json
350 {
351 nlohmann::json js = nlohmann::json::array();
352
353 for( const wxString& entry : m_DrcExclusions )
354 js.push_back( { entry, m_DrcExclusionComments[ entry ] } );
355
356 return js;
357 },
358 [&]( const nlohmann::json& aObj )
359 {
360 m_DrcExclusions.clear();
361
362 if( !aObj.is_array() )
363 return;
364
365 for( const nlohmann::json& entry : aObj )
366 {
367 if( entry.is_array() )
368 {
369 wxString serialized = entry[0].get<wxString>();
370 m_DrcExclusions.insert( serialized );
371 m_DrcExclusionComments[ serialized ] = entry[1].get<wxString>();
372 }
373 else if( entry.is_string() )
374 {
375 m_DrcExclusions.insert( entry.get<wxString>() );
376 }
377 }
378 },
379 {} ) );
380
381 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "track_widths",
382 [&]() -> nlohmann::json
383 {
384 nlohmann::json js = nlohmann::json::array();
385
386 for( const int& width : m_TrackWidthList )
387 js.push_back( pcbIUScale.IUTomm( width ) );
388
389 return js;
390 },
391 [&]( const nlohmann::json& aJson )
392 {
393 if( !aJson.is_array() )
394 return;
395
396 m_TrackWidthList.clear();
397
398 for( const nlohmann::json& entry : aJson )
399 {
400 if( entry.empty() )
401 continue;
402
403 m_TrackWidthList.emplace_back( pcbIUScale.mmToIU( entry.get<double>() ) );
404 }
405 },
406 {} ) );
407
408 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "via_dimensions",
409 [&]() -> nlohmann::json
410 {
411 nlohmann::json js = nlohmann::json::array();
412
413 for( const auto& via : m_ViasDimensionsList )
414 {
415 nlohmann::json entry = {};
416
417 entry["diameter"] = pcbIUScale.IUTomm( via.m_Diameter );
418 entry["drill"] = pcbIUScale.IUTomm( via.m_Drill );
419
420 js.push_back( entry );
421 }
422
423 return js;
424 },
425 [&]( const nlohmann::json& aObj )
426 {
427 if( !aObj.is_array() )
428 return;
429
430 m_ViasDimensionsList.clear();
431
432 for( const nlohmann::json& entry : aObj )
433 {
434 if( entry.empty() || !entry.is_object() )
435 continue;
436
437 if( !entry.contains( "diameter" ) || !entry.contains( "drill" ) )
438 continue;
439
440 int diameter = pcbIUScale.mmToIU( entry["diameter"].get<double>() );
441 int drill = pcbIUScale.mmToIU( entry["drill"].get<double>() );
442
443 m_ViasDimensionsList.emplace_back( VIA_DIMENSION( diameter, drill ) );
444 }
445 },
446 {} ) );
447
448 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "diff_pair_dimensions",
449 [&]() -> nlohmann::json
450 {
451 nlohmann::json js = nlohmann::json::array();
452
453 for( const auto& pair : m_DiffPairDimensionsList )
454 {
455 nlohmann::json entry = {};
456
457 entry["width"] = pcbIUScale.IUTomm( pair.m_Width );
458 entry["gap"] = pcbIUScale.IUTomm( pair.m_Gap );
459 entry["via_gap"] = pcbIUScale.IUTomm( pair.m_ViaGap );
460
461 js.push_back( entry );
462 }
463
464 return js;
465 },
466 [&]( const nlohmann::json& aObj )
467 {
468 if( !aObj.is_array() )
469 return;
470
472
473 for( const nlohmann::json& entry : aObj )
474 {
475 if( entry.empty() || !entry.is_object() )
476 continue;
477
478 if( !entry.contains( "width" ) || !entry.contains( "gap" )
479 || !entry.contains( "via_gap" ) )
480 continue;
481
482 int width = pcbIUScale.mmToIU( entry["width"].get<double>() );
483 int gap = pcbIUScale.mmToIU( entry["gap"].get<double>() );
484 int via_gap = pcbIUScale.mmToIU( entry["via_gap"].get<double>() );
485
486 m_DiffPairDimensionsList.emplace_back(
487 DIFF_PAIR_DIMENSION( width, gap, via_gap ) );
488 }
489 },
490 {} ) );
491
492 // Handle options for teardrops (targets and some others):
493 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "teardrop_options",
494 [&]() -> nlohmann::json
495 {
496 nlohmann::json js = nlohmann::json::array();
497 nlohmann::json entry = {};
498
499 entry["td_onvia"] = m_TeardropParamsList.m_TargetVias;
500 entry["td_onpthpad"] = m_TeardropParamsList.m_TargetPTHPads;
501 entry["td_onsmdpad"] = m_TeardropParamsList.m_TargetSMDPads;
502 entry["td_ontrackend"] = m_TeardropParamsList.m_TargetTrack2Track;
503 entry["td_onroundshapesonly"] = m_TeardropParamsList.m_UseRoundShapesOnly;
504
505 js.push_back( entry );
506
507 return js;
508 },
509 [&]( const nlohmann::json& aObj )
510 {
511 if( !aObj.is_array() )
512 return;
513
514 for( const nlohmann::json& entry : aObj )
515 {
516 if( entry.empty() || !entry.is_object() )
517 continue;
518
519 if( entry.contains( "td_onvia" ) )
520 m_TeardropParamsList.m_TargetVias = entry["td_onvia"].get<bool>();
521
522 if( entry.contains( "td_onpthpad" ) )
523 m_TeardropParamsList.m_TargetPTHPads = entry["td_onpthpad"].get<bool>();
524
525 if( entry.contains( "td_onsmdpad" ) )
526 m_TeardropParamsList.m_TargetSMDPads = entry["td_onsmdpad"].get<bool>();
527
528 if( entry.contains( "td_ontrackend" ) )
529 m_TeardropParamsList.m_TargetTrack2Track = entry["td_ontrackend"].get<bool>();
530
531 if( entry.contains( "td_onroundshapesonly" ) )
532 m_TeardropParamsList.m_UseRoundShapesOnly = entry["td_onroundshapesonly"].get<bool>();
533
534 // Legacy settings
535 for( int ii = 0; ii < 3; ++ii )
536 {
538
539 if( entry.contains( "td_allow_use_two_tracks" ) )
540 td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
541
542 if( entry.contains( "td_curve_segcount" ) )
543 {
544 if( entry["td_curve_segcount"].get<int>() > 0 )
545 td_prm->m_CurvedEdges = true;
546 }
547
548 if( entry.contains( "td_on_pad_in_zone" ) )
549 td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
550 }
551 }
552 },
553 {} ) );
554
555 // Handle parameters (sizes, shape) for each type of teardrop:
556 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "teardrop_parameters",
557 [&]() -> nlohmann::json
558 {
559 nlohmann::json js = nlohmann::json::array();
560
561 for( size_t ii = 0; ii < m_TeardropParamsList.GetParametersCount(); ii++ )
562 {
563 nlohmann::json entry = {};
565
566 entry["td_target_name"] = GetTeardropTargetCanonicalName( (TARGET_TD)ii );
567 entry["td_maxlen"] = pcbIUScale.IUTomm( td_prm->m_TdMaxLen );
568 entry["td_maxheight"] = pcbIUScale.IUTomm( td_prm->m_TdMaxWidth );
569 entry["td_length_ratio"] = td_prm->m_BestLengthRatio;
570 entry["td_height_ratio"] = td_prm->m_BestWidthRatio;
571 entry["td_curve_segcount"] = td_prm->m_CurvedEdges ? 1 : 0;
572 entry["td_width_to_size_filter_ratio"] = td_prm->m_WidthtoSizeFilterRatio;
573 entry["td_allow_use_two_tracks"] = td_prm->m_AllowUseTwoTracks;
574 entry["td_on_pad_in_zone"] = td_prm->m_TdOnPadsInZones;
575
576 js.push_back( entry );
577 }
578
579 return js;
580 },
581 [&]( const nlohmann::json& aObj )
582 {
583 if( !aObj.is_array() )
584 return;
585
586 for( const nlohmann::json& entry : aObj )
587 {
588 if( entry.empty() || !entry.is_object() )
589 continue;
590
591 if( !entry.contains( "td_target_name" ) )
592 continue;
593
594 int idx = GetTeardropTargetTypeFromCanonicalName( entry["td_target_name"].get<std::string>() );
595
596 if( idx >= 0 && idx < 3 )
597 {
599
600 if( entry.contains( "td_maxlen" ) )
601 td_prm->m_TdMaxLen = pcbIUScale.mmToIU( entry["td_maxlen"].get<double>() );
602
603 if( entry.contains( "td_maxheight" ) )
604 td_prm->m_TdMaxWidth = pcbIUScale.mmToIU( entry["td_maxheight"].get<double>() );
605
606 if( entry.contains( "td_length_ratio" ) )
607 td_prm->m_BestLengthRatio = entry["td_length_ratio"].get<double>();
608
609 if( entry.contains( "td_height_ratio" ) )
610 td_prm->m_BestWidthRatio = entry["td_height_ratio"].get<double>();
611
612 if( entry.contains( "td_curve_segcount" ) )
613 {
614 if( entry["td_curve_segcount"].get<int>() > 0 )
615 td_prm->m_CurvedEdges = true;
616 }
617
618 if( entry.contains( "td_width_to_size_filter_ratio" ) )
619 td_prm->m_WidthtoSizeFilterRatio = entry["td_width_to_size_filter_ratio"].get<double>();
620
621 if( entry.contains( "td_allow_use_two_tracks" ) )
622 td_prm->m_AllowUseTwoTracks = entry["td_allow_use_two_tracks"].get<bool>();
623
624 if( entry.contains( "td_on_pad_in_zone" ) )
625 td_prm->m_TdOnPadsInZones = entry["td_on_pad_in_zone"].get<bool>();
626 }
627 }
628 },
629 {} ) );
630
631 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "tuning_pattern_settings",
632 [&]() -> nlohmann::json
633 {
634 nlohmann::json js = {};
635
636 auto make_settings =
637 []( const PNS::MEANDER_SETTINGS& aSettings )
638 {
639 nlohmann::json entry = {};
640
641 entry["min_amplitude"] = pcbIUScale.IUTomm( aSettings.m_minAmplitude );
642 entry["max_amplitude"] = pcbIUScale.IUTomm( aSettings.m_maxAmplitude );
643 entry["spacing"] = pcbIUScale.IUTomm( aSettings.m_spacing );
644 entry["corner_style"] = aSettings.m_cornerStyle == PNS::MEANDER_STYLE_CHAMFER ? 0 : 1;
645 entry["corner_radius_percentage"] = aSettings.m_cornerRadiusPercentage;
646 entry["single_sided"] = aSettings.m_singleSided;
647
648 return entry;
649 };
650
651 js["single_track_defaults"] = make_settings( m_SingleTrackMeanderSettings );
652 js["diff_pair_defaults"] = make_settings( m_DiffPairMeanderSettings );
653 js["diff_pair_skew_defaults"] = make_settings( m_SkewMeanderSettings );
654
655 return js;
656 },
657 [&]( const nlohmann::json& aObj )
658 {
659 auto read_settings =
660 []( const nlohmann::json& entry ) -> PNS::MEANDER_SETTINGS
661 {
662 PNS::MEANDER_SETTINGS settings;
663
664 if( entry.contains( "min_amplitude" ) )
665 settings.m_minAmplitude = pcbIUScale.mmToIU( entry["min_amplitude"].get<double>() );
666
667 if( entry.contains( "max_amplitude" ) )
668 settings.m_maxAmplitude = pcbIUScale.mmToIU( entry["max_amplitude"].get<double>() );
669
670 if( entry.contains( "spacing" ) )
671 settings.m_spacing = pcbIUScale.mmToIU( entry["spacing"].get<double>() );
672
673 if( entry.contains( "corner_style" ) )
674 {
675 settings.m_cornerStyle = entry["corner_style"] == 0 ? PNS::MEANDER_STYLE_CHAMFER
677 }
678
679 if( entry.contains( "corner_radius_percentage" ) )
680 settings.m_cornerRadiusPercentage = entry["corner_radius_percentage"].get<int>();
681
682 if( entry.contains( "single_sided" ) )
683 settings.m_singleSided = entry["single_sided"].get<bool>();
684
685 return settings;
686 };
687
688 if( aObj.contains( "single_track_defaults" ) )
689 m_SingleTrackMeanderSettings = read_settings( aObj["single_track_defaults"] );
690
691 if( aObj.contains( "diff_pair_defaults" ) )
692 m_DiffPairMeanderSettings = read_settings( aObj["diff_pair_defaults"] );
693
694 if( aObj.contains( "diff_pair_skew_defaults" ) )
695 m_SkewMeanderSettings = read_settings( aObj["diff_pair_skew_defaults"] );
696 },
697 {} ) );
698
699 int minTextSize = pcbIUScale.mmToIU( TEXT_MIN_SIZE_MM );
700 int maxTextSize = pcbIUScale.mmToIU( TEXT_MAX_SIZE_MM );
701 int minStroke = 1;
702 int maxStroke = pcbIUScale.mmToIU( 100 );
703
704 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_line_width",
706 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
707
708 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_v",
710 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
711
712 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_size_h",
714 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
715
716 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.silk_text_thickness",
718 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
719
720 m_params.emplace_back( new PARAM<bool>( "defaults.silk_text_italic",
721 &m_TextItalic[LAYER_CLASS_SILK], false ) );
722
723 m_params.emplace_back( new PARAM<bool>( "defaults.silk_text_upright",
724 &m_TextUpright[ LAYER_CLASS_SILK ], true ) );
725
726 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_line_width",
728 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
729
730 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_v",
732 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
733
734 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_size_h",
736 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
737
738 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.copper_text_thickness",
740 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
741
742 m_params.emplace_back( new PARAM<bool>( "defaults.copper_text_italic",
743 &m_TextItalic[LAYER_CLASS_COPPER], false ) );
744
745 m_params.emplace_back( new PARAM<bool>( "defaults.copper_text_upright",
747
748 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.board_outline_line_width",
750 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
751
752 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.courtyard_line_width",
754 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
755
756 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_line_width",
758 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
759
760 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_v",
762 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
763
764 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_size_h",
766 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
767
768 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.fab_text_thickness",
770 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
771
772 m_params.emplace_back( new PARAM<bool>( "defaults.fab_text_italic",
773 &m_TextItalic[LAYER_CLASS_FAB], false ) );
774
775 m_params.emplace_back( new PARAM<bool>( "defaults.fab_text_upright",
776 &m_TextUpright[LAYER_CLASS_FAB], true ) );
777
778 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_line_width",
780 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
781
782 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_v",
784 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
785
786 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_size_h",
788 minTextSize, maxTextSize, pcbIUScale.MM_PER_IU ) );
789
790 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.other_text_thickness",
792 minStroke, maxStroke, pcbIUScale.MM_PER_IU ) );
793
794 m_params.emplace_back( new PARAM<bool>( "defaults.other_text_italic",
795 &m_TextItalic[LAYER_CLASS_OTHERS], false ) );
796
797 m_params.emplace_back( new PARAM<bool>( "defaults.other_text_upright",
799
800 m_params.emplace_back( new PARAM_ENUM<DIM_UNITS_MODE>( "defaults.dimension_units",
801 &m_DimensionUnitsMode, DIM_UNITS_MODE::AUTOMATIC, DIM_UNITS_MODE::INCHES,
802 DIM_UNITS_MODE::AUTOMATIC ) );
803
804 m_params.emplace_back( new PARAM_ENUM<DIM_PRECISION>( "defaults.dimension_precision",
805 &m_DimensionPrecision, DIM_PRECISION::X_XXXX, DIM_PRECISION::X, DIM_PRECISION::V_VVVVV ) );
806
807 m_params.emplace_back( new PARAM_ENUM<DIM_UNITS_FORMAT>( "defaults.dimensions.units_format",
808 &m_DimensionUnitsFormat, DIM_UNITS_FORMAT::NO_SUFFIX, DIM_UNITS_FORMAT::NO_SUFFIX,
809 DIM_UNITS_FORMAT::PAREN_SUFFIX ) );
810
811 m_params.emplace_back( new PARAM<bool>( "defaults.dimensions.suppress_zeroes",
812 &m_DimensionSuppressZeroes, true ) );
813
814 // NOTE: excluding DIM_TEXT_POSITION::MANUAL from the valid range here
815 m_params.emplace_back( new PARAM_ENUM<DIM_TEXT_POSITION>( "defaults.dimensions.text_position",
816 &m_DimensionTextPosition, DIM_TEXT_POSITION::OUTSIDE, DIM_TEXT_POSITION::OUTSIDE,
817 DIM_TEXT_POSITION::INLINE ) );
818
819 m_params.emplace_back( new PARAM<bool>( "defaults.dimensions.keep_text_aligned",
821
822 m_params.emplace_back( new PARAM<int>( "defaults.dimensions.arrow_length",
825
826 m_params.emplace_back( new PARAM<int>( "defaults.dimensions.extension_offset",
829
830 m_params.emplace_back( new PARAM<bool>( "defaults.apply_defaults_to_fp_fields",
831 &m_StyleFPFields, false ) );
832 m_params.emplace_back( new PARAM<bool>( "defaults.apply_defaults_to_fp_text",
833 &m_StyleFPText, false ) );
834 m_params.emplace_back( new PARAM<bool>( "defaults.apply_defaults_to_fp_shapes",
835 &m_StyleFPShapes, false ) );
836
837 m_params.emplace_back( new PARAM_SCALED<int>( "defaults.zones.min_clearance",
840
841 m_params.emplace_back( new PARAM_LAMBDA<nlohmann::json>( "defaults.pads",
842 [&]() -> nlohmann::json
843 {
844 nlohmann::json ret =
845 {
846 { "width", pcbIUScale.IUTomm( m_Pad_Master->GetSize( PADSTACK::ALL_LAYERS ).x ) },
847 { "height", pcbIUScale.IUTomm( m_Pad_Master->GetSize( PADSTACK::ALL_LAYERS ).y ) },
848 { "drill", pcbIUScale.IUTomm( m_Pad_Master->GetDrillSize().x ) }
849 };
850
851 return ret;
852 },
853 [&]( const nlohmann::json& aJson )
854 {
855 if( aJson.contains( "width" ) && aJson.contains( "height" )
856 && aJson.contains( "drill" ) )
857 {
858 VECTOR2I sz;
859 sz.x = pcbIUScale.mmToIU( aJson["width"].get<double>() );
860 sz.y = pcbIUScale.mmToIU( aJson["height"].get<double>() );
861
862 m_Pad_Master->SetSize( PADSTACK::ALL_LAYERS, sz );
863
864 int drill = pcbIUScale.mmToIU( aJson["drill"].get<double>() );
865
866 m_Pad_Master->SetDrillSize( VECTOR2I( drill, drill ) );
867 }
868 }, {} ) );
869
870 m_params.emplace_back( new PARAM_SCALED<int>( "rules.max_error",
872
873 m_params.emplace_back( new PARAM_SCALED<int>( "rules.solder_mask_to_copper_clearance",
876
877 m_params.emplace_back( new PARAM<bool>( "zones_allow_external_fillets",
878 &m_ZoneKeepExternalFillets, false ) );
879
881
882 registerMigration( 1, 2,
883 [&]() -> bool
884 {
885 // Schema 1 to 2: move mask and paste margin settings back to board.
886 // The parameters are removed, so we just have to manually load them here and
887 // they will get saved with the board
888 if( std::optional<double> optval = Get<double>( "rules.solder_mask_clearance" ) )
889 m_SolderMaskExpansion = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
890
891 if( std::optional<double> optval = Get<double>( "rules.solder_mask_min_width" ) )
892 m_SolderMaskMinWidth = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
893
894 if( std::optional<double> optval = Get<double>( "rules.solder_paste_clearance" ) )
895 m_SolderPasteMargin = static_cast<int>( *optval * pcbIUScale.IU_PER_MM );
896
897 if( std::optional<double> optval = Get<double>( "rules.solder_paste_margin_ratio" ) )
898 m_SolderPasteMarginRatio = *optval;
899
900 try
901 {
902 At( "rules" ).erase( "solder_mask_clearance" );
903 At( "rules" ).erase( "solder_mask_min_width" );
904 At( "rules" ).erase( "solder_paste_clearance" );
905 At( "rules" ).erase( "solder_paste_margin_ratio" );
906 }
907 catch( ... )
908 {}
909
910 return true;
911 } );
912}
913
914
916{
917 if( m_parent )
918 {
920 m_parent = nullptr;
921 }
922}
923
924
926 NESTED_SETTINGS( "board_design_settings", bdsSchemaVersion, aOther.m_parent,
927 aOther.m_path ),
928 m_Pad_Master( nullptr )
929{
930 initFromOther( aOther );
931}
932
933
935{
936 initFromOther( aOther );
937 return *this;
938}
939
940
942{
943 // Copy of NESTED_SETTINGS around is not allowed, so let's just update the params.
952 m_MinConn = aOther.m_MinConn;
970 m_MaxError = aOther.m_MaxError;
981
982 std::copy( std::begin( aOther.m_LineThickness ), std::end( aOther.m_LineThickness ),
983 std::begin( m_LineThickness ) );
984
985 std::copy( std::begin( aOther.m_TextSize ), std::end( aOther.m_TextSize ),
986 std::begin( m_TextSize ) );
987
988 std::copy( std::begin( aOther.m_TextThickness ), std::end( aOther.m_TextThickness ),
989 std::begin( m_TextThickness ) );
990
991 std::copy( std::begin( aOther.m_TextItalic ), std::end( aOther.m_TextItalic ),
992 std::begin( m_TextItalic ) );
993
994 std::copy( std::begin( aOther.m_TextUpright ), std::end( aOther.m_TextUpright ),
995 std::begin( m_TextUpright ) );
996
1005
1006 m_auxOrigin = aOther.m_auxOrigin;
1007 m_gridOrigin = aOther.m_gridOrigin;
1008 m_HasStackup = aOther.m_HasStackup;
1010
1023 m_stackup = aOther.m_stackup;
1025 m_Pad_Master = std::make_unique<PAD>( *aOther.m_Pad_Master );
1027
1031}
1032
1033
1035{
1036 if( m_TrackWidthList != aOther.m_TrackWidthList ) return false;
1037 if( m_ViasDimensionsList != aOther.m_ViasDimensionsList ) return false;
1038 if( m_DiffPairDimensionsList != aOther.m_DiffPairDimensionsList ) return false;
1039 if( m_CurrentViaType != aOther.m_CurrentViaType ) return false;
1040 if( m_UseConnectedTrackWidth != aOther.m_UseConnectedTrackWidth ) return false;
1041 if( m_TempOverrideTrackWidth != aOther.m_TempOverrideTrackWidth ) return false;
1042 if( m_MinClearance != aOther.m_MinClearance ) return false;
1043 if( m_MinGrooveWidth != aOther.m_MinGrooveWidth ) return false;
1044 if( m_MinConn != aOther.m_MinConn ) return false;
1045 if( m_TrackMinWidth != aOther.m_TrackMinWidth ) return false;
1046 if( m_ViasMinAnnularWidth != aOther.m_ViasMinAnnularWidth ) return false;
1047 if( m_ViasMinSize != aOther.m_ViasMinSize ) return false;
1048 if( m_MinThroughDrill != aOther.m_MinThroughDrill ) return false;
1049 if( m_MicroViasMinSize != aOther.m_MicroViasMinSize ) return false;
1050 if( m_MicroViasMinDrill != aOther.m_MicroViasMinDrill ) return false;
1051 if( m_CopperEdgeClearance != aOther.m_CopperEdgeClearance ) return false;
1052 if( m_HoleClearance != aOther.m_HoleClearance ) return false;
1053 if( m_HoleToHoleMin != aOther.m_HoleToHoleMin ) return false;
1054 if( m_SilkClearance != aOther.m_SilkClearance ) return false;
1055 if( m_MinResolvedSpokes != aOther.m_MinResolvedSpokes ) return false;
1056 if( m_MinSilkTextHeight != aOther.m_MinSilkTextHeight ) return false;
1057 if( m_MinSilkTextThickness != aOther.m_MinSilkTextThickness ) return false;
1058 if( m_DRCSeverities != aOther.m_DRCSeverities ) return false;
1059 if( m_DrcExclusions != aOther.m_DrcExclusions ) return false;
1060 if( m_DrcExclusionComments != aOther.m_DrcExclusionComments ) return false;
1061 if( m_ZoneKeepExternalFillets != aOther.m_ZoneKeepExternalFillets ) return false;
1062 if( m_MaxError != aOther.m_MaxError ) return false;
1063 if( m_SolderMaskExpansion != aOther.m_SolderMaskExpansion ) return false;
1064 if( m_SolderMaskMinWidth != aOther.m_SolderMaskMinWidth ) return false;
1066 if( m_SolderPasteMargin != aOther.m_SolderPasteMargin ) return false;
1067 if( m_SolderPasteMarginRatio != aOther.m_SolderPasteMarginRatio ) return false;
1069 if( m_TentViasFront != aOther.m_TentViasFront ) return false;
1070 if( m_TentViasBack != aOther.m_TentViasBack ) return false;
1071 if( m_DefaultFPTextItems != aOther.m_DefaultFPTextItems ) return false;
1072 if( m_UserLayerNames != aOther.m_UserLayerNames ) return false;
1073
1074 if( !std::equal( std::begin( m_LineThickness ), std::end( m_LineThickness ),
1075 std::begin( aOther.m_LineThickness ) ) )
1076 return false;
1077
1078 if( !std::equal( std::begin( m_TextSize ), std::end( m_TextSize ),
1079 std::begin( aOther.m_TextSize ) ) )
1080 return false;
1081
1082 if( !std::equal( std::begin( m_TextThickness ), std::end( m_TextThickness ),
1083 std::begin( aOther.m_TextThickness ) ) )
1084 return false;
1085
1086 if( !std::equal( std::begin( m_TextItalic ), std::end( m_TextItalic ),
1087 std::begin( aOther.m_TextItalic ) ) )
1088 return false;
1089
1090 if( !std::equal( std::begin( m_TextUpright ), std::end( m_TextUpright ),
1091 std::begin( aOther.m_TextUpright ) ) )
1092 return false;
1093
1094 if( m_DimensionUnitsMode != aOther.m_DimensionUnitsMode ) return false;
1095 if( m_DimensionPrecision != aOther.m_DimensionPrecision ) return false;
1096 if( m_DimensionUnitsFormat != aOther.m_DimensionUnitsFormat ) return false;
1097 if( m_DimensionSuppressZeroes != aOther.m_DimensionSuppressZeroes ) return false;
1098 if( m_DimensionTextPosition != aOther.m_DimensionTextPosition ) return false;
1099 if( m_DimensionKeepTextAligned != aOther.m_DimensionKeepTextAligned ) return false;
1100 if( m_DimensionArrowLength != aOther.m_DimensionArrowLength ) return false;
1101 if( m_DimensionExtensionOffset != aOther.m_DimensionExtensionOffset ) return false;
1102 if( m_auxOrigin != aOther.m_auxOrigin ) return false;
1103 if( m_gridOrigin != aOther.m_gridOrigin ) return false;
1104 if( m_HasStackup != aOther.m_HasStackup ) return false;
1105 if( m_UseHeightForLengthCalcs != aOther.m_UseHeightForLengthCalcs ) return false;
1106 if( m_trackWidthIndex != aOther.m_trackWidthIndex ) return false;
1107 if( m_viaSizeIndex != aOther.m_viaSizeIndex ) return false;
1108 if( m_diffPairIndex != aOther.m_diffPairIndex ) return false;
1109 if( m_useCustomTrackVia != aOther.m_useCustomTrackVia ) return false;
1110 if( m_customTrackWidth != aOther.m_customTrackWidth ) return false;
1111 if( m_customViaSize != aOther.m_customViaSize ) return false;
1112 if( m_useCustomDiffPair != aOther.m_useCustomDiffPair ) return false;
1113 if( m_customDiffPair != aOther.m_customDiffPair ) return false;
1114 if( m_copperLayerCount != aOther.m_copperLayerCount ) return false;
1115 if( m_enabledLayers != aOther.m_enabledLayers ) return false;
1116 if( m_boardThickness != aOther.m_boardThickness ) return false;
1117 if( m_currentNetClassName != aOther.m_currentNetClassName ) return false;
1118 if( m_stackup != aOther.m_stackup ) return false;
1119 if( *m_NetSettings != *aOther.m_NetSettings ) return false;
1120 if( *m_Pad_Master != *aOther.m_Pad_Master ) return false;
1121 if( m_defaultZoneSettings != aOther.m_defaultZoneSettings ) return false;
1122
1123 if( m_StyleFPFields != aOther.m_StyleFPFields ) return false;
1124 if( m_StyleFPText != aOther.m_StyleFPText ) return false;
1125 if( m_StyleFPShapes != aOther.m_StyleFPShapes ) return false;
1126
1127 return true;
1128}
1129
1130
1132{
1150 std::string units_ptr( "defaults.dimension_units" );
1151 std::string precision_ptr( "defaults.dimension_precision" );
1152
1153 if( !( Contains( units_ptr ) && Contains( precision_ptr ) &&
1154 At( units_ptr ).is_number_integer() &&
1155 At( precision_ptr ).is_number_integer() ) )
1156 {
1157 // if either is missing or invalid, migration doesn't make sense
1158 return true;
1159 }
1160
1161 int units = *Get<int>( units_ptr );
1162 int precision = *Get<int>( precision_ptr );
1163
1164 // The enum maps directly to precision if the units is mils
1165 int extraDigits = 0;
1166
1167 switch( units )
1168 {
1169 case 0: extraDigits = 3; break;
1170 case 2: extraDigits = 2; break;
1171 default: break;
1172 }
1173
1174 precision += extraDigits;
1175
1176 Set( precision_ptr, precision );
1177
1178 return true;
1179}
1180
1181
1182bool BOARD_DESIGN_SETTINGS::LoadFromFile( const wxString& aDirectory )
1183{
1184 bool ret = NESTED_SETTINGS::LoadFromFile( aDirectory );
1185
1186 // A number of things won't have been translated by the PROJECT_FILE migration because of
1187 // descoped objects required to decode this data. So, it will be in the legacy.pcbnew
1188 // section and needs to be pulled out here
1189
1190 PROJECT_FILE* project = dynamic_cast<PROJECT_FILE*>( GetParent() );
1191
1192 if( !project )
1193 return ret;
1194
1195 bool migrated = false;
1196
1197 auto drcName =
1198 []( int aCode ) -> std::string
1199 {
1200 std::shared_ptr<DRC_ITEM> item = DRC_ITEM::Create( aCode );
1201 wxString name = item->GetSettingsKey();
1202 return std::string( name.ToUTF8() );
1203 };
1204
1205 const std::string rs = "rule_severities.";
1206 const std::string no_courtyard_key = "legacy_no_courtyard_defined";
1207 const std::string courtyard_overlap_key = "legacy_courtyards_overlap";
1208
1209 try
1210 {
1211 nlohmann::json& severities =
1212 project->Internals()->at( "/board/design_settings/rule_severities"_json_pointer );
1213
1214 if( severities.contains( no_courtyard_key ) )
1215 {
1216 if( severities[no_courtyard_key].get<bool>() )
1217 Set( rs + drcName( DRCE_MISSING_COURTYARD ), "error" );
1218 else
1219 Set( rs + drcName( DRCE_MISSING_COURTYARD ), "ignore" );
1220
1221 severities.erase( no_courtyard_key );
1222 migrated = true;
1223 }
1224
1225 if( severities.contains( courtyard_overlap_key ) )
1226 {
1227 if( severities[courtyard_overlap_key].get<bool>() )
1228 Set( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ), "error" );
1229 else
1230 Set( rs + drcName( DRCE_OVERLAPPING_FOOTPRINTS ), "ignore" );
1231
1232 severities.erase( courtyard_overlap_key );
1233 migrated = true;
1234 }
1235 }
1236 catch( ... )
1237 {
1238 }
1239 if( Contains( "legacy" ) )
1240 {
1241 // This defaults to false for new boards, but version 5.1.x and prior kept the fillets
1242 // so we do the same for legacy boards.
1244
1245 project->At( "legacy" ).erase( "pcbnew" );
1246 }
1247
1248 // Now that we have everything, we need to load again
1249 if( migrated )
1250 Load();
1251
1252 return ret;
1253}
1254
1255
1257{
1258 return m_DRCSeverities[ aDRCErrorCode ];
1259}
1260
1261
1262bool BOARD_DESIGN_SETTINGS::Ignore( int aDRCErrorCode )
1263{
1264 return m_DRCSeverities[ aDRCErrorCode ] == RPT_SEVERITY_IGNORE;
1265}
1266
1267
1269{
1270 int biggest = std::max( m_MinClearance, m_HoleClearance );
1271 DRC_CONSTRAINT constraint;
1272
1273 biggest = std::max( biggest, m_HoleToHoleMin );
1274 biggest = std::max( biggest, m_CopperEdgeClearance );
1275
1276 if( m_DRCEngine )
1277 {
1278 m_DRCEngine->QueryWorstConstraint( CLEARANCE_CONSTRAINT, constraint );
1279 biggest = std::max( biggest, constraint.Value().Min() );
1280
1281 m_DRCEngine->QueryWorstConstraint( PHYSICAL_CLEARANCE_CONSTRAINT, constraint );
1282 biggest = std::max( biggest, constraint.Value().Min() );
1283
1284 m_DRCEngine->QueryWorstConstraint( HOLE_CLEARANCE_CONSTRAINT, constraint );
1285 biggest = std::max( biggest, constraint.Value().Min() );
1286
1287 m_DRCEngine->QueryWorstConstraint( EDGE_CLEARANCE_CONSTRAINT, constraint );
1288 biggest = std::max( biggest, constraint.Value().Min() );
1289
1290 m_DRCEngine->QueryWorstConstraint( HOLE_TO_HOLE_CONSTRAINT, constraint );
1291 biggest = std::max( biggest, constraint.Value().Min() );
1292 }
1293
1294 return biggest;
1295}
1296
1297
1299{
1300 int clearance = m_NetSettings->GetDefaultNetclass()->GetClearance();
1301
1302 for( const auto& [name, netclass] : m_NetSettings->GetNetclasses() )
1303 clearance = std::min( clearance, netclass->GetClearance() );
1304
1305 return clearance;
1306}
1307
1308
1310{
1311 m_viaSizeIndex = std::min( aIndex, (unsigned) m_ViasDimensionsList.size() );
1312 m_useCustomTrackVia = false;
1313}
1314
1315
1317{
1320 else if( m_viaSizeIndex == 0 )
1321 return m_NetSettings->GetDefaultNetclass()->GetViaDiameter();
1322 else
1323 return m_ViasDimensionsList[ m_viaSizeIndex ].m_Diameter;
1324}
1325
1326
1328{
1329 int drill;
1330
1332 drill = m_customViaSize.m_Drill;
1333 else if( m_viaSizeIndex == 0 )
1334 drill = m_NetSettings->GetDefaultNetclass()->GetViaDrill();
1335 else
1336 drill = m_ViasDimensionsList[ m_viaSizeIndex ].m_Drill;
1337
1338 return drill > 0 ? drill : -1;
1339}
1340
1341
1343{
1344 m_trackWidthIndex = std::min( aIndex, (unsigned) m_TrackWidthList.size() );
1345 m_useCustomTrackVia = false;
1346}
1347
1348
1350{
1352 return m_customTrackWidth;
1353 else if( m_trackWidthIndex == 0 )
1354 return m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1355 else
1357}
1358
1359
1361{
1362 if( !m_DiffPairDimensionsList.empty() )
1363 {
1364 m_diffPairIndex = std::min( aIndex,
1365 static_cast<unsigned>( m_DiffPairDimensionsList.size() ) - 1 );
1366 }
1367
1368 m_useCustomDiffPair = false;
1369}
1370
1371
1373{
1375 {
1377 }
1378 else if( m_diffPairIndex == 0 )
1379 {
1380 if( m_NetSettings->GetDefaultNetclass()->HasDiffPairWidth() )
1381 return m_NetSettings->GetDefaultNetclass()->GetDiffPairWidth();
1382 else
1383 return m_NetSettings->GetDefaultNetclass()->GetTrackWidth();
1384 }
1385 else
1386 {
1388 }
1389}
1390
1391
1393{
1395 {
1396 return m_customDiffPair.m_Gap;
1397 }
1398 else if( m_diffPairIndex == 0 )
1399 {
1400 if( m_NetSettings->GetDefaultNetclass()->HasDiffPairGap() )
1401 return m_NetSettings->GetDefaultNetclass()->GetDiffPairGap();
1402 else
1403 return m_NetSettings->GetDefaultNetclass()->GetClearance();
1404 }
1405 else
1406 {
1408 }
1409}
1410
1411
1413{
1415 {
1417 }
1418 else if( m_diffPairIndex == 0 )
1419 {
1420 if( m_NetSettings->GetDefaultNetclass()->HasDiffPairViaGap() )
1421 return m_NetSettings->GetDefaultNetclass()->GetDiffPairViaGap();
1422 else
1423 return GetCurrentDiffPairGap();
1424 }
1425 else
1426 {
1428 }
1429}
1430
1431
1433{
1434 m_copperLayerCount = aNewLayerCount;
1435
1436 // Update only enabled copper layers mask
1438
1439 if( aNewLayerCount > 0 )
1440 m_enabledLayers |= LSET::AllCuMask( aNewLayerCount );
1441}
1442
1443
1445{
1446 // Ensures mandatory back and front layers are always enabled
1447 // regardless of board file configuration.
1448 aMask.set( B_Cu ).set( F_Cu )
1449 .set( B_CrtYd ).set( F_CrtYd )
1450 .set( Edge_Cuts ).set( Margin );
1451
1452 m_enabledLayers = aMask;
1453
1454 // update m_CopperLayerCount to ensure its consistency with m_EnabledLayers
1455 m_copperLayerCount = aMask.ClearNonCopperLayers().count();
1456}
1457
1458
1459// Return the layer class index { silk, copper, edges & courtyards, fab, others } of the
1460// given layer.
1462{
1463 if( aLayer == F_SilkS || aLayer == B_SilkS )
1464 return LAYER_CLASS_SILK;
1465 else if( IsCopperLayer( aLayer ) )
1466 return LAYER_CLASS_COPPER;
1467 else if( aLayer == Edge_Cuts )
1468 return LAYER_CLASS_EDGES;
1469 else if( aLayer == F_CrtYd || aLayer == B_CrtYd )
1470 return LAYER_CLASS_COURTYARD;
1471 else if( aLayer == F_Fab || aLayer == B_Fab )
1472 return LAYER_CLASS_FAB;
1473 else
1474 return LAYER_CLASS_OTHERS;
1475}
1476
1477
1479{
1480 return pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_DRCEpsilon );
1481}
1482
1483
1485{
1486 return pcbIUScale.mmToIU( ADVANCED_CFG::GetCfg().m_HoleWallThickness );
1487}
1488
1489
1491{
1492 return m_LineThickness[ GetLayerClass( aLayer ) ];
1493}
1494
1495
1497{
1498 return m_TextSize[ GetLayerClass( aLayer ) ];
1499}
1500
1501
1503{
1504 return m_TextThickness[ GetLayerClass( aLayer ) ];
1505}
1506
1507
1509{
1510 return m_TextItalic[ GetLayerClass( aLayer ) ];
1511}
1512
1513
1515{
1516 return m_TextUpright[ GetLayerClass( aLayer ) ];
1517}
1518
1520{
1521 m_Pad_Master.get()->SetSizeX( pcbIUScale.mmToIU( DEFAULT_PAD_WIDTH_MM ) );
1523 m_Pad_Master.get()->SetDrillShape( PAD_DRILL_SHAPE::CIRCLE );
1524 m_Pad_Master.get()->SetDrillSize(
1526 m_Pad_Master.get()->SetShape( PADSTACK::ALL_LAYERS, PAD_SHAPE::ROUNDRECT );
1527 m_Pad_Master.get()->SetRoundRectCornerRadius(
1530}
const char * name
Definition: DXF_plotter.cpp:59
constexpr int ARC_HIGH_DEF
Definition: base_units.h:120
constexpr EDA_IU_SCALE pcbIUScale
Definition: base_units.h:108
const int bdsSchemaVersion
#define DEFAULT_MICROVIASMINDRILL
#define DEFAULT_SOLDERPASTE_CLEARANCE
#define DEFAULT_SOLDERPASTE_RATIO
#define DEFAULT_CUSTOMDPAIRWIDTH
#define DEFAULT_DP_MEANDER_SPACING
#define DEFAULT_PAD_WIDTH_MM
#define DEFAULT_VIASMINSIZE
#define DEFAULT_PAD_DRILL_DIAMETER_MM
#define DEFAULT_TEXT_WIDTH
#define DEFAULT_COPPER_TEXT_WIDTH
#define DEFAULT_CUSTOMDPAIRGAP
#define DEFAULT_MINCLEARANCE
#define DEFAULT_HOLECLEARANCE
#define DEFAULT_SOLDERMASK_EXPANSION
#define DEFAULT_SOLDERMASK_MIN_WIDTH
#define DEFAULT_DIMENSION_EXTENSION_OFFSET
#define DEFAULT_PAD_REACT_RADIUS
#define DEFAULT_COPPEREDGECLEARANCE
#define DEFAULT_PAD_HEIGTH_MM
#define DEFAULT_DIMENSION_ARROW_LENGTH
#define DEFAULT_TRACKMINWIDTH
#define DEFAULT_MINTHROUGHDRILL
#define DEFAULT_SILK_TEXT_SIZE
#define DEFAULT_HOLETOHOLEMIN
#define DEFAULT_MINCONNECTION
#define DEFAULT_COPPER_LINE_WIDTH
#define DEFAULT_SILK_LINE_WIDTH
#define DEFAULT_SILKCLEARANCE
#define DEFAULT_MICROVIASMINSIZE
@ LAYER_CLASS_OTHERS
@ LAYER_CLASS_FAB
@ LAYER_CLASS_COURTYARD
@ LAYER_CLASS_SILK
@ LAYER_CLASS_COPPER
@ LAYER_CLASS_EDGES
#define DEFAULT_SILK_TEXT_WIDTH
#define DEFAULT_MINGROOVEWIDTH
#define DEFAULT_TEXT_SIZE
#define DEFAULT_EDGE_WIDTH
#define DEFAULT_CUSTOMTRACKWIDTH
#define DEFAULT_CUSTOMDPAIRVIAGAP
#define DEFAULT_COPPER_TEXT_SIZE
#define DEFAULT_SOLDERMASK_TO_COPPER_CLEARANCE
#define DEFAULT_LINE_WIDTH
#define DEFAULT_MEANDER_SPACING
#define DEFAULT_COURTYARD_WIDTH
#define DEFAULT_BOARD_THICKNESS_MM
#define DEFAULT_MINRESOLVEDSPOKES
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
BASE_SET & set(size_t pos)
Definition: base_set.h:116
Container for design settings for a BOARD object.
DIM_PRECISION m_DimensionPrecision
Number of digits after the decimal.
std::vector< TEXT_ITEM_INFO > m_DefaultFPTextItems
int GetHolePlatingThickness() const
Pad & via drills are finish size.
VIATYPE m_CurrentViaType
(VIA_BLIND_BURIED, VIA_THROUGH, VIA_MICROVIA)
void SetDiffPairIndex(unsigned aIndex)
std::shared_ptr< NET_SETTINGS > m_NetSettings
bool operator==(const BOARD_DESIGN_SETTINGS &aOther) const
std::map< wxString, wxString > m_DrcExclusionComments
DIM_UNITS_FORMAT m_DimensionUnitsFormat
void initFromOther(const BOARD_DESIGN_SETTINGS &aOther)
bool GetTextUpright(PCB_LAYER_ID aLayer) const
std::map< int, SEVERITY > m_DRCSeverities
VECTOR2I m_gridOrigin
origin for grid offsets
int GetTextThickness(PCB_LAYER_ID aLayer) const
Return the default text thickness from the layer class for the given layer.
VECTOR2I m_auxOrigin
origin for plot exports
bool m_TextUpright[LAYER_CLASS_COUNT]
BOARD_DESIGN_SETTINGS(JSON_SETTINGS *aParent, const std::string &aPath)
bool GetTextItalic(PCB_LAYER_ID aLayer) const
wxString m_currentNetClassName
Current net class name used to display netclass info.
std::shared_ptr< DRC_ENGINE > m_DRCEngine
void SetEnabledLayers(LSET aMask)
Change the bit-mask of enabled layers to aMask.
std::vector< DIFF_PAIR_DIMENSION > m_DiffPairDimensionsList
std::set< wxString > m_DrcExclusions
bool Ignore(int aDRCErrorCode)
Return true if the DRC error code's severity is SEVERITY_IGNORE.
std::map< std::string, wxString > m_UserLayerNames
std::unique_ptr< PAD > m_Pad_Master
void SetTrackWidthIndex(unsigned aIndex)
Set the current track width list index to aIndex.
TEARDROP_PARAMETERS_LIST m_TeardropParamsList
The parameters of teardrops for the different teardrop targets (via/pad, track end).
void SetViaSizeIndex(unsigned aIndex)
Set the current via size list index to aIndex.
int GetDRCEpsilon() const
Return an epsilon which accounts for rounding errors, etc.
int GetLayerClass(PCB_LAYER_ID aLayer) const
PNS::MEANDER_SETTINGS m_DiffPairMeanderSettings
int m_boardThickness
Board thickness for 3D viewer.
int m_copperLayerCount
Number of copper layers for this design.
bool LoadFromFile(const wxString &aDirectory="") override
Loads the backing file from disk and then calls Load()
PNS::MEANDER_SETTINGS m_SingleTrackMeanderSettings
int m_TextThickness[LAYER_CLASS_COUNT]
ZONE_SETTINGS m_defaultZoneSettings
The default settings that will be used for new zones.
SEVERITY GetSeverity(int aDRCErrorCode)
std::vector< int > m_TrackWidthList
DIFF_PAIR_DIMENSION m_customDiffPair
int m_LineThickness[LAYER_CLASS_COUNT]
VECTOR2I GetTextSize(PCB_LAYER_ID aLayer) const
Return the default text size from the layer class for the given layer.
int GetLineThickness(PCB_LAYER_ID aLayer) const
Return the default graphic segment thickness from the layer class for the given layer.
bool m_UseHeightForLengthCalcs
Enable inclusion of stackup height in track length measurements and length tuning.
VECTOR2I m_TextSize[LAYER_CLASS_COUNT]
PNS::MEANDER_SETTINGS m_SkewMeanderSettings
LSET m_enabledLayers
Bit-mask for layer enabling.
bool m_TextItalic[LAYER_CLASS_COUNT]
void SetCopperLayerCount(int aNewLayerCount)
Set the copper layer count to aNewLayerCount.
DIM_TEXT_POSITION m_DimensionTextPosition
BOARD_STACKUP m_stackup
The description of layers stackup, for board fabrication only physical layers are in layers stackup.
DIM_UNITS_MODE m_DimensionUnitsMode
std::vector< VIA_DIMENSION > m_ViasDimensionsList
BOARD_DESIGN_SETTINGS & operator=(const BOARD_DESIGN_SETTINGS &aOther)
MINOPTMAX< int > & Value()
Definition: drc_rule.h:153
static std::vector< std::reference_wrapper< RC_ITEM > > GetItemsWithSeverities(bool aIncludeDeprecated=false)
Definition: drc_item.h:133
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
Definition: drc_item.cpp:395
void Set(const std::string &aPath, ValueType aVal)
Stores a value into the JSON document Will throw an exception if ValueType isn't something that the l...
bool Contains(const std::string &aPath) const
virtual void Load()
Updates the parameters of this object based on the current JSON document contents.
std::vector< PARAM_BASE * > m_params
The list of parameters (owned by this object)
void registerMigration(int aOldSchemaVersion, int aNewSchemaVersion, std::function< bool(void)> aMigrator)
Registers a migration from one schema version to another.
nlohmann::json & At(const std::string &aPath)
Wrappers for the underlying JSON API so that most consumers don't need json.hpp All of these function...
void ReleaseNestedSettings(NESTED_SETTINGS *aSettings)
Saves and frees a nested settings object, if it exists within this one.
bool m_resetParamsIfMissing
Whether or not to set parameters to their default value if missing from JSON on Load()
LSET is a set of PCB_LAYER_IDs.
Definition: lset.h:37
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Definition: lset.cpp:564
LSET & ClearNonCopperLayers()
Clear the non-copper layers in this set.
Definition: lset.cpp:905
LSET & ClearCopperLayers()
Clear the copper layers in this set.
Definition: lset.cpp:896
T Min() const
Definition: minoptmax.h:33
NESTED_SETTINGS is a JSON_SETTINGS that lives inside a JSON_SETTINGS.
JSON_SETTINGS * GetParent()
JSON_SETTINGS * m_parent
A pointer to the parent object to load and store from.
bool LoadFromFile(const wxString &aDirectory="") override
Loads the JSON document from the parent and then calls Load()
static constexpr PCB_LAYER_ID ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
Definition: padstack.h:144
Stores an enum as an integer.
Definition: parameters.h:228
Like a normal param, but with custom getter and setter functions.
Definition: parameters.h:295
Represents a parameter that has a scaling factor between the value in the file and the value used int...
Definition: parameters.h:392
Dimensions for the meandering algorithm.
Definition: pns_meander.h:68
int m_minAmplitude
Maximum meandering amplitude.
Definition: pns_meander.h:83
int m_cornerRadiusPercentage
Place meanders on one side.
Definition: pns_meander.h:109
bool m_singleSided
Initial side when placing meanders at segment.
Definition: pns_meander.h:112
MEANDER_STYLE m_cornerStyle
Rounding percentage (0 - 100).
Definition: pns_meander.h:106
int m_maxAmplitude
Meandering period/spacing (see dialog picture for explanation).
Definition: pns_meander.h:86
int m_spacing
Amplitude/spacing adjustment step.
Definition: pns_meander.h:89
The backing store for a PROJECT, in JSON format.
Definition: project_file.h:72
A holder for a rule check item, DRC in Pcbnew or ERC in Eeschema.
Definition: rc_item.h:79
bool m_UseRoundShapesOnly
True to create teardrops for round shapes only.
bool m_TargetVias
True to create teardrops for vias.
bool m_TargetPTHPads
True to create teardrops for pads with holes.
bool m_TargetTrack2Track
True to create teardrops at the end of a track connected to the end of another track having a differe...
TEARDROP_PARAMETERS * GetParameters(TARGET_TD aTdType)
bool m_TargetSMDPads
True to create teardrops for pads SMD, edge connectors,.
TEARDROP_PARAMETARS is a helper class to handle parameters needed to build teardrops for a board thes...
double m_BestWidthRatio
The height of a teardrop as ratio between height and size of pad/via.
int m_TdMaxLen
max allowed length for teardrops in IU. <= 0 to disable
bool m_AllowUseTwoTracks
True to create teardrops using 2 track segments if the first in too small.
int m_TdMaxWidth
max allowed height for teardrops in IU. <= 0 to disable
double m_BestLengthRatio
The length of a teardrop as ratio between length and size of pad/via.
double m_WidthtoSizeFilterRatio
The ratio (H/D) between the via/pad size and the track width max value to create a teardrop 1....
bool m_TdOnPadsInZones
A filter to exclude pads inside zone fills.
bool m_CurvedEdges
True if the teardrop should be curved.
@ DRCE_SILK_EDGE_CLEARANCE
Definition: drc_item.h:98
@ DRCE_FOOTPRINT_FILTERS
Definition: drc_item.h:79
@ DRCE_PADSTACK
Definition: drc_item.h:62
@ DRCE_MIRRORED_TEXT_ON_FRONT_LAYER
Definition: drc_item.h:109
@ DRCE_LIB_FOOTPRINT_ISSUES
Definition: drc_item.h:82
@ DRCE_OVERLAPPING_FOOTPRINTS
Definition: drc_item.h:65
@ DRCE_OVERLAPPING_SILK
Definition: drc_item.h:101
@ DRCE_MISSING_COURTYARD
Definition: drc_item.h:66
@ DRCE_ISOLATED_COPPER
Definition: drc_item.h:48
@ DRCE_DRILLED_HOLES_TOO_CLOSE
Definition: drc_item.h:52
@ DRCE_COPPER_SLIVER
Definition: drc_item.h:92
@ DRCE_PTH_IN_COURTYARD
Definition: drc_item.h:69
@ DRCE_FIRST
Definition: drc_item.h:38
@ DRCE_DANGLING_VIA
Definition: drc_item.h:50
@ DRCE_FOOTPRINT_TYPE_MISMATCH
Definition: drc_item.h:81
@ DRCE_NONMIRRORED_TEXT_ON_BACK_LAYER
Definition: drc_item.h:110
@ DRCE_DUPLICATE_FOOTPRINT
Definition: drc_item.h:75
@ DRCE_DANGLING_TRACK
Definition: drc_item.h:51
@ DRCE_TEXT_HEIGHT
Definition: drc_item.h:99
@ DRCE_DRILLED_HOLES_COLOCATED
Definition: drc_item.h:53
@ DRCE_EXTRA_FOOTPRINT
Definition: drc_item.h:76
@ DRCE_SILK_CLEARANCE
Definition: drc_item.h:96
@ DRCE_LAST
Definition: drc_item.h:112
@ DRCE_LIB_FOOTPRINT_MISMATCH
Definition: drc_item.h:83
@ DRCE_NET_CONFLICT
Definition: drc_item.h:77
@ DRCE_MISSING_FOOTPRINT
Definition: drc_item.h:74
@ DRCE_TEXT_THICKNESS
Definition: drc_item.h:100
@ DRCE_NPTH_IN_COURTYARD
Definition: drc_item.h:70
@ DRCE_CONNECTION_WIDTH
Definition: drc_item.h:59
@ DRCE_SCHEMATIC_PARITY
Definition: drc_item.h:78
@ EDGE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:53
@ CLEARANCE_CONSTRAINT
Definition: drc_rule.h:49
@ HOLE_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:51
@ PHYSICAL_CLEARANCE_CONSTRAINT
Definition: drc_rule.h:74
@ HOLE_TO_HOLE_CONSTRAINT
Definition: drc_rule.h:52
#define TEXT_MIN_SIZE_MM
Minimum text size (1 micron).
Definition: eda_text.h:47
#define TEXT_MAX_SIZE_MM
Maximum text size in mm (~10 inches)
Definition: eda_text.h:48
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
Definition: layer_ids.h:617
PCB_LAYER_ID
A quick note on layer IDs:
Definition: layer_ids.h:60
@ F_CrtYd
Definition: layer_ids.h:116
@ Edge_Cuts
Definition: layer_ids.h:112
@ B_Cu
Definition: layer_ids.h:65
@ F_Fab
Definition: layer_ids.h:119
@ Margin
Definition: layer_ids.h:113
@ F_SilkS
Definition: layer_ids.h:100
@ B_CrtYd
Definition: layer_ids.h:115
@ B_SilkS
Definition: layer_ids.h:101
@ F_Cu
Definition: layer_ids.h:64
@ B_Fab
Definition: layer_ids.h:118
@ MEANDER_STYLE_ROUND
Definition: pns_meander.h:52
@ MEANDER_STYLE_CHAMFER
Definition: pns_meander.h:53
SEVERITY
@ RPT_SEVERITY_WARNING
@ RPT_SEVERITY_ERROR
@ RPT_SEVERITY_IGNORE
Container to handle a stock of specific differential pairs each with unique track width,...
constexpr double IUTomm(int iu) const
Definition: base_units.h:86
const double IU_PER_MM
Definition: base_units.h:76
const double MM_PER_IU
Definition: base_units.h:78
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
constexpr int mmToIU(double mm) const
Definition: base_units.h:88
Container to handle a stock of specific vias each with unique diameter and drill sizes in the BOARD c...
std::string GetTeardropTargetCanonicalName(TARGET_TD aTdType)
TARGET_TD GetTeardropTargetTypeFromCanonicalName(const std::string &aTargetName)
int clearance
wxString SeverityToString(const SEVERITY &aSeverity)
Definition: ui_common.cpp:66
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
#define ZONE_CLEARANCE_MM
Definition: zones.h:37