58#define ERROR_LIMIT 199
59#define EXTENDED_ERROR_LIMIT 499
76 if( wxGetEnv( wxT(
"DRC_DEBUG" ), &valueStr ) )
78 int setLevel = wxAtoi( valueStr );
80 if( level <= setLevel )
81 printf(
"%-30s:%d | %s\n", function, line, (
const char *) msg.c_str() );
124 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
151 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
154 rule->SetImplicitSource( aImplicitSource );
165 wxString expr, expr2, ncName;
169 std::shared_ptr<DRC_RULE> rule =
174 rule->AddConstraint( widthConstraint );
178 rule->AddConstraint( connectionConstraint );
182 rule->AddConstraint( drillConstraint );
186 rule->AddConstraint( annulusConstraint );
190 rule->AddConstraint( diameterConstraint );
194 rule->AddConstraint( holeToHoleConstraint );
200 rule->AddConstraint( thermalSpokeCountConstraint );
206 rule->AddConstraint( silkClearanceConstraint );
213 rule->AddConstraint( silkTextHeightConstraint );
220 rule->AddConstraint( silkTextThicknessConstraint );
225 rule->AddConstraint( holeClearanceConstraint );
230 rule->AddConstraint( edgeClearanceConstraint );
235 rule->AddConstraint( courtyardClearanceConstraint );
239 std::shared_ptr<DRC_RULE> uViaRule =
246 uViaRule->AddConstraint( uViaDrillConstraint );
250 uViaRule->AddConstraint( uViaDiameterConstraint );
254 std::shared_ptr<DRC_RULE> barcodeRule =
258 barcodeRule->AddConstraint( barcodeSeparationConstraint );
263 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
264 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
266 auto makeNetclassRules =
267 [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
269 ncName = nc->GetName();
270 ncName.Replace(
"'",
"\\'" );
272 if( nc->HasClearance() )
274 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
275 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
276 nc->GetClearanceParent()->GetHumanReadableName() );
279 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
281 netclassClearanceRules.push_back( netclassRule );
285 netclassRule->AddConstraint( constraint );
293 if( nc->HasTrackWidth() )
295 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
296 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
297 nc->GetTrackWidthParent()->GetHumanReadableName() );
300 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
302 netclassClearanceRules.push_back( netclassRule );
307 netclassRule->AddConstraint( constraint );
310 if( nc->HasDiffPairWidth() )
312 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
313 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
314 nc->GetDiffPairWidthParent()->GetHumanReadableName() );
317 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.inDiffPair('*')" ), ncName );
319 netclassItemSpecificRules.push_back( netclassRule );
323 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
324 netclassRule->AddConstraint( constraint );
327 if( nc->HasDiffPairGap() )
329 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
330 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
331 nc->GetDiffPairGapParent()->GetHumanReadableName() );
334 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
336 netclassItemSpecificRules.push_back( netclassRule );
341 netclassRule->AddConstraint( constraint );
344 if( nc->GetDiffPairGap() < nc->GetClearance() )
346 netclassRule = std::make_shared<DRC_RULE>();
347 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
348 nc->GetDiffPairGapParent()->GetHumanReadableName() );
351 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && AB.isCoupledDiffPair()" ), ncName );
353 netclassItemSpecificRules.push_back( netclassRule );
356 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
357 netclassRule->AddConstraint( min_clearanceConstraint );
363 if( nc->HasViaDiameter() )
365 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
366 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
367 nc->GetViaDiameterParent()->GetHumanReadableName() );
370 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
372 netclassItemSpecificRules.push_back( netclassRule );
377 netclassRule->AddConstraint( constraint );
380 if( nc->HasViaDrill() )
382 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
383 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
384 nc->GetViaDrillParent()->GetHumanReadableName() );
387 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
389 netclassItemSpecificRules.push_back( netclassRule );
394 netclassRule->AddConstraint( constraint );
397 if( nc->HasuViaDiameter() )
399 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
400 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
401 nc->GetuViaDiameterParent()->GetHumanReadableName() );
404 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
406 netclassItemSpecificRules.push_back( netclassRule );
410 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
411 netclassRule->AddConstraint( constraint );
414 if( nc->HasuViaDrill() )
416 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
417 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
418 nc->GetuViaDrillParent()->GetHumanReadableName() );
421 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
423 netclassItemSpecificRules.push_back( netclassRule );
428 netclassRule->AddConstraint( constraint );
432 m_board->SynchronizeNetsAndNetClasses(
false );
436 makeNetclassRules( netclass,
false );
439 makeNetclassRules( netclass,
false );
446 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
447 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
449 return lhs->m_Constraints[0].m_Value.Min()
450 < rhs->m_Constraints[0].m_Value.Min();
453 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
456 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
460 auto addTuningSingleRule =
462 const wxString& aNetclassName )
467 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
469 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
472 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s'" ),
481 tuningRule->AddConstraint( constraint );
486 auto addTuningDifferentialRules =
493 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
495 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
498 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
499 aNetclass->GetName(),
507 tuningRule->AddConstraint( constraint );
511 std::shared_ptr<DRC_RULE> tuningRule2 = std::make_shared<DRC_RULE>();
513 tuningRule2->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
516 expr2 = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
517 aNetclass->GetName(),
525 tuningRule2->AddConstraint( constraint2 );
532 std::shared_ptr<DRC_RULE> diffPairClearanceRule = std::make_shared<DRC_RULE>();
534 diffPairClearanceRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
537 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
538 aNetclass->GetName(),
544 diffPairClearanceRule->AddConstraint( min_clearanceConstraint );
546 addRule( diffPairClearanceRule );
552 std::shared_ptr<TUNING_PROFILES> tuningParams =
project->GetProjectFile().TuningProfileParameters();
554 auto addNetclassTuningProfileRules =
555 [&tuningParams, &addTuningSingleRule, &addTuningDifferentialRules](
NETCLASS* aNetclass )
557 if( aNetclass->HasTuningProfile() )
559 const wxString delayProfileName = aNetclass->GetTuningProfile();
560 const TUNING_PROFILE& profile = tuningParams->GetTuningProfile( delayProfileName );
568 addTuningSingleRule( entry, delayProfileName, aNetclass->GetName() );
570 addTuningDifferentialRules( entry, delayProfileName, aNetclass );
578 addNetclassTuningProfileRules( netclass.get() );
581 addNetclassTuningProfileRules( netclass.get() );
585 auto addKeepoutZoneRule =
595 wxString::Format(
_(
"keepout area of %s" ),
DescribeRef( parentFP->GetReference() ) ),
619 rule->m_ImplicitItemId = zone->
m_Uuid;
621 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
626 int disallowFlags = 0;
645 rule->AddConstraint( disallowConstraint );
651 addKeepoutZoneRule( zone,
nullptr );
656 for(
ZONE* zone : footprint->Zones() )
659 addKeepoutZoneRule( zone, footprint );
667 if(
m_board && aPath.FileExists() )
669 std::vector<std::shared_ptr<DRC_RULE>> rules;
671 if( FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) ) )
676 std::function<bool( wxString* )>
resolver =
677 [&]( wxString* token ) ->
bool
679 return m_board->ResolveTextVar( token, 0 );
682 while(
char* line = lineReader.
ReadLine() )
684 wxString str( line );
685 str =
m_board->ConvertCrossReferencesToKIIDs( str );
688 rulesText << str <<
'\n';
698 for( std::shared_ptr<DRC_RULE>& rule : rules )
711 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
715 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
717 condition = rule->m_Condition;
718 condition->
Compile( &error_semaphore );
723 TO_UTF8( rule->m_Condition->GetExpression() ), 0, 0 );
730 ruleVec =
new std::vector<DRC_ENGINE_CONSTRAINT*>();
734 engineConstraint->
layerTest = rule->m_LayerCondition;
738 ruleVec->push_back( engineConstraint );
750 if( c->parentRule && !c->parentRule->IsImplicit() )
759 && c->condition->HasGeometryDependentFunctions() )
776 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
778 provider->SetDRCEngine(
this );
803 throw original_parse_error;
820 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
822 provider->SetDRCEngine(
this );
867 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
870 throw original_parse_error;
907 if( !cacheGenerator.
Run() )
911 m_board->GetComponentClassManager().ForceComponentClassRecalculation();
913 int timestamp =
m_board->GetTimeStamp();
918 m_logReporter->Report( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
922 if( !provider->RunTests( aUnits ) )
925 providerTimer.
Stop();
927 provider->GetName(), providerTimer.
msecs() );
935 wxASSERT( timestamp ==
m_board->GetTimeStamp() );
939#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
947 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
955 pad =
static_cast<const PAD*
>( a );
957 pad =
static_cast<const PAD*
>( b );
965 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
991 const ZONE* zone =
nullptr;
992 const FOOTPRINT* parentFootprint =
nullptr;
1002 pad =
static_cast<const PAD*
>( a );
1004 zone =
static_cast<const ZONE*
>( a );
1007 pad =
static_cast<const PAD*
>( b );
1009 zone =
static_cast<const ZONE*
>( b );
1012 parentFootprint =
pad->GetParentFootprint();
1016 constraint.
m_Type = aConstraintType;
1018 auto applyConstraint =
1021 if( c->constraint.m_Value.HasMin() )
1023 if( c->parentRule && c->parentRule->IsImplicit() )
1029 if( c->constraint.m_Value.HasOpt() )
1032 if( c->constraint.m_Value.HasMax() )
1035 switch( c->constraint.m_Type )
1070 && ( ( ( !ac ) ^ ( !bc ) )
1073 || ( ( footprints[0] == footprints[1] )
1074 && footprints[0] ) )
1076 && !b_is_non_copper )
1083 for(
int ii = 0; ii < 2; ++ii )
1086 if( !footprints[ii] || !alt_items[ii] )
1089 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
1091 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
1093 if( it != netcodes.end() )
1096 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
1097 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
1099 constraint.
SetName(
_(
"net tie" ) );
1109 int override_val = 0;
1110 std::optional<int> overrideA;
1111 std::optional<int> overrideB;
1113 if( ac && !b_is_non_copper )
1116 if( bc && !a_is_non_copper )
1119 if( overrideA.has_value() || overrideB.has_value() )
1123 if( overrideA.has_value() )
1126 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1133 if( overrideB.has_value() )
1136 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1140 if( overrideB > override_val )
1148 if( override_val < m_designSettings->m_MinClearance )
1151 msg =
_(
"board minimum" );
1154 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1160 if( override_val < m_designSettings->m_HoleClearance )
1163 msg =
_(
"board minimum hole" );
1166 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
1185 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
1196 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
1199 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
1202 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
1213 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
1216 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
1219 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
1228 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
1240 std::optional<int>
override;
1244 override =
pad->GetLocalSolderMaskMargin();
1246 override =
static_cast<const PCB_SHAPE*
>( a )->GetLocalSolderMaskMargin();
1250 if( !
override.has_value() &&
pad )
1252 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1254 override = overrideFootprint->GetLocalSolderMaskMargin();
1255 overrideItem = overrideFootprint;
1262 REPORT( wxString::Format(
_(
"Local override on %s; solder mask expansion: %s." ),
1272 std::optional<int>
override;
1276 override =
pad->GetLocalSolderPasteMargin();
1278 if( !
override.has_value() &&
pad )
1280 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1282 override = overrideFootprint->GetLocalSolderPasteMargin();
1283 overrideItem = overrideFootprint;
1290 REPORT( wxString::Format(
_(
"Local override on %s; solder paste absolute clearance: %s." ),
1300 std::optional<double> overrideRatio;
1304 overrideRatio =
pad->GetLocalSolderPasteMarginRatio();
1306 if( !overrideRatio.has_value() &&
pad )
1308 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1310 overrideRatio = overrideFootprint->GetLocalSolderPasteMarginRatio();
1311 overrideItem = overrideFootprint;
1318 REPORT( wxString::Format(
_(
"Local override on %s; solder paste relative clearance: %s." ),
1327 auto testAssertion =
1330 REPORT( wxString::Format(
_(
"Checking assertion '%s'." ),
1331 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1333 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1334 REPORT(
_(
"Assertion passed." ) )
1339 auto processConstraint =
1342 bool implicit = c->parentRule && c->parentRule->IsImplicit();
1346 switch( c->constraint.m_Type )
1355 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
1360 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
1365 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1371 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1377 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1383 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1389 REPORT( wxString::Format(
_(
"Checking %s solder mask expansion: %s." ),
1395 REPORT( wxString::Format(
_(
"Checking %s solder paste absolute clearance: %s." ),
1401 REPORT( wxString::Format(
_(
"Checking %s solder paste relative clearance: %s." ),
1407 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1413 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1431 switch( c->constraint.m_Type )
1434 if( c->constraint.m_Value.HasOpt() )
1436 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1440 else if( c->constraint.m_Value.HasMin() )
1442 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1450 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1456 if( c->constraint.m_Value.HasOpt() )
1458 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1462 else if( c->constraint.m_Value.HasMin() )
1464 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1471 if( c->constraint.m_Value.HasOpt() )
1473 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1477 else if( c->constraint.m_Value.HasMin() )
1479 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1489 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1495 if( c->constraint.m_Value.HasOpt() )
1497 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1501 else if( c->constraint.m_Value.HasMin() )
1503 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1511 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1517 REPORT( wxString::Format(
_(
"Checking %s." ),
1523 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1525 c->constraint.m_Value.HasMin()
1527 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1528 c->constraint.m_Value.HasOpt()
1530 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1531 c->constraint.m_Value.HasMax()
1533 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ) ) )
1539 REPORT( wxString::Format(
_(
"Checking %s." ),
1545 if( a_is_non_copper || b_is_non_copper )
1549 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1551 else if( a_is_non_copper )
1553 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1556 else if( b_is_non_copper )
1558 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1577 if(
via->IsMicroVia() )
1579 else if(
via->IsBlindVia() )
1581 else if(
via->IsBuriedVia() )
1603 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1611 default: mask = 0;
break;
1615 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1618 REPORT(
_(
"Keepout constraint not met." ) )
1620 REPORT(
_(
"Disallow constraint not met." ) )
1638 if( !( c->layerTest & itemLayers ).any() )
1642 REPORT(
_(
"Keepout layer(s) not matched." ) )
1644 else if( c->parentRule )
1646 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1647 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1651 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1658 if( (
IsPcbLayer( aLayer ) && !c->layerTest.test( aLayer ) )
1659 || (
m_board->GetEnabledLayers() & c->layerTest ).count() == 0 )
1663 REPORT(
_(
"Constraint layer not matched." ) )
1665 else if( c->parentRule )
1667 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1668 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1672 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1679 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1682 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1688 REPORT(
_(
"Unconditional constraint applied." ) )
1692 REPORT(
_(
"Unconditional rule applied." ) )
1697 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1701 applyConstraint( c );
1711 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
1712 EscapeHTML( c->condition->GetExpression() ) ) )
1715 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1721 REPORT(
_(
"Constraint applied." ) )
1725 REPORT(
_(
"Rule applied." ) )
1730 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1734 applyConstraint( c );
1738 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1739 :
_(
"Condition not satisfied; rule ignored." ) )
1750 && ( !b || !b_is_non_copper ) )
1775 if( !ncNameA.empty() || !ncNameB.empty() )
1779 if( !ncNameA.empty() )
1787 if( !ncNameB.empty() )
1809 processConstraint( rule );
1827 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1831 a = parentFootprint;
1833 b = parentFootprint;
1840 processConstraint( rule );
1850 constraint.
SetName(
_(
"board setup" ) );
1857 constraint.
SetName(
_(
"board setup" ) );
1864 constraint.
SetName(
_(
"board setup" ) );
1877 bool needBlankLine =
true;
1886 needBlankLine =
false;
1889 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1910 needBlankLine =
false;
1913 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1927 if( !a_is_non_copper && !b_is_non_copper )
1932 needBlankLine =
false;
1935 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1941 constraint.
SetName(
_(
"board minimum" ) );
1951 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1957 constraint.
SetName(
_(
"board minimum" ) );
1965 if(
pad && parentFootprint )
1972 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1977 constraint.
SetName(
_(
"footprint" ) );
1988 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
2005 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
2022 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
2087 auto testAssertion =
2090 REPORT( wxString::Format(
_(
"Checking rule assertion '%s'." ),
2091 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
2093 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2096 REPORT(
_(
"Assertion passed." ) )
2101 aFailureHandler( &c->constraint );
2105 auto processConstraint =
2109 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
2113 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
2114 EscapeHTML( c->parentRule->m_LayerSource ) ) )
2117 if( !c->condition || c->condition->GetExpression().IsEmpty() )
2119 REPORT(
_(
"Unconditional rule applied." ) )
2124 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
2125 EscapeHTML( c->condition->GetExpression() ) ) )
2127 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2130 REPORT(
_(
"Rule applied." ) )
2135 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
2144 for(
int ii = 0; ii < (int) it->second->size(); ++ii )
2145 processConstraint( it->second->at( ii ) );
2155 assert( error_code >= 0 && error_code <=
DRCE_LAST );
2162 int aMarkerLayer,
const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
2171 static std::mutex handlerLock;
2172 std::lock_guard<std::mutex> guard( handlerLock );
2178 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
2179 aItem->GetViolatingTest()->GetName(),
2180 aItem->GetErrorMessage(
false ),
2181 aItem->GetErrorCode() );
2183 DRC_RULE* rule = aItem->GetViolatingRule();
2186 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
2190 wxString violatingItemsStr = wxT(
"Violating items: " );
2192 m_logReporter->Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
2256 bool aUnconditionalOnly )
2265 if( aUnconditionalOnly && c->
condition )
2270 if( current > worst )
2284 std::set<int> distinctMinimums;
2293 return distinctMinimums;
2299 wxString& aBaseDpName )
2304 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
2308 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
2312 else if( ch ==
'+' )
2314 aComplementNet = wxT(
"-" );
2317 else if( ch ==
'-' )
2319 aComplementNet = wxT(
"+" );
2322 else if( ch ==
'N' )
2324 aComplementNet = wxT(
"P" );
2327 else if ( ch ==
'P' )
2329 aComplementNet = wxT(
"N" );
2338 if( rv != 0 && count >= 1 )
2340 aBaseDpName = aNetName.Left( aNetName.Length() - count );
2341 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
2351 wxString
dummy, coupledNetName;
2387 if( parentFootprint && parentFootprint->
IsNetTie() )
2394 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
2396 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
2410 if(
name == prov->GetName() )
2422 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2423 wxS(
"[ShowMatches] engine enter: expr='%s', constraint=%d" ), aExpression, (
int) aConstraint );
2424 std::vector<BOARD_ITEM*> matches;
2433 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine: compile failed" ) );
2440 if(
auto connectivity =
m_board->GetConnectivity() )
2442 if(
auto ftCache = connectivity->GetFromToCache() )
2447 size_t totalItems = 0;
2448 size_t skippedItems = 0;
2449 size_t noLayerItems = 0;
2450 size_t checkedItems = 0;
2452 for(
auto& [kiid, item] :
m_board->GetItemByIdCache() )
2457 switch( item->Type() )
2469 LSET itemLayers = item->GetLayerSet();
2471 if( itemLayers.none() )
2478 bool matched =
false;
2482 if( condition.
EvaluateFor( item,
nullptr,
static_cast<int>( aConstraint ), layer,
2485 matches.push_back( item );
2486 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2487 wxS(
"[ShowMatches] engine: match type=%d kiid=%s layer=%d" ),
2488 (
int) item->Type(), kiid.AsString(), (
int) layer );
2495 if( !matched && matches.size() == 0 && checkedItems <= 5 )
2497 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2498 wxS(
"[ShowMatches] engine: no-match sample type=%d kiid=%s layers=%s" ),
2499 (
int) item->Type(), kiid.AsString(), itemLayers.
FmtHex() );
2503 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2504 wxS(
"[ShowMatches] engine stats: total=%zu skipped=%zu noLayer=%zu checked=%zu" ),
2505 totalItems, skippedItems, noLayerItems, checkedItems );
2507 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine exit: total=%zu" ), matches.size() );
2536 const PAD*
pad =
static_cast<const PAD*
>( aItem );
2551 *aSource = constraint.
GetName();
2585 if( it->first.m_uuid == aUuid )
2611 using CLEARANCE_MAP = std::unordered_map<DRC_OWN_CLEARANCE_CACHE_KEY, int>;
2615 std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>> itemsToProcess;
2616 size_t estimatedPads = 0;
2619 estimatedPads += footprint->Pads().size();
2621 itemsToProcess.reserve(
m_board->Tracks().size() + estimatedPads * 2 );
2628 itemsToProcess.emplace_back( track, layer );
2632 itemsToProcess.emplace_back( track, track->GetLayer() );
2638 for(
PAD*
pad : footprint->Pads() )
2641 itemsToProcess.emplace_back(
pad, layer );
2645 if( itemsToProcess.empty() )
2655 auto processItems = [
this](
size_t aStart,
size_t aEnd,
2656 const std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>>& aItems )
2659 CLEARANCE_MAP localCache;
2661 for(
size_t i = aStart; i < aEnd; ++i )
2670 const PAD*
pad =
static_cast<const PAD*
>( item );
2689 auto results =
tp.submit_blocks( 0, itemsToProcess.size(),
2690 [&](
size_t aStart,
size_t aEnd ) -> CLEARANCE_MAP
2692 return processItems( aStart, aEnd, itemsToProcess );
2699 std::vector<CLEARANCE_MAP> collectedResults;
2700 collectedResults.reserve( results.size() );
2702 for(
size_t i = 0; i < results.size(); ++i )
2704 if( results[i].valid() )
2705 collectedResults.push_back( results[i].get() );
2712 for(
const auto& localCache : collectedResults )
constexpr EDA_IU_SCALE pcbIUScale
std::set< BOARD_ITEM *, CompareByUuid > BOARD_ITEM_SET
Set of BOARD_ITEMs ordered by UUID.
#define MAXIMUM_CLEARANCE
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
std::string FmtHex() const
Return a hex string showing contents of this set.
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
virtual std::optional< int > GetClearanceOverrides(wxString *aSource) const
Return any clearance overrides set in the "classic" (ie: pre-rule) system.
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
virtual std::optional< int > GetLocalClearance() const
Return any local clearances set in the "classic" (ie: pre-rule) system.
Container for design settings for a BOARD object.
std::shared_ptr< NET_SETTINGS > m_NetSettings
int m_CopperEdgeClearance
std::map< int, SEVERITY > m_DRCSeverities
int m_MinSilkTextThickness
int GetDRCEpsilon() const
Return an epsilon which accounts for rounding errors, etc.
int m_ViasMinAnnularWidth
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual bool HasDrilledHole() const
virtual bool IsOnCopperLayer() const
Information pertinent to a Pcbnew printed circuit board.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Represents a single line in a time domain profile track propagation setup.
int GetDiffPairGap() const
PCB_LAYER_ID GetSignalLayer() const
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
void SetParentRule(DRC_RULE *aParentRule)
MINOPTMAX< int > & Value()
const MINOPTMAX< int > & GetValue() const
ZONE_CONNECTION m_ZoneConnection
void SetName(const wxString &aName)
void SetOptionsFromOther(const DRC_CONSTRAINT &aOther)
DRC_RULE * GetParentRule() const
std::map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
DRC_CLEARANCE_BATCH EvalClearanceBatch(const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer)
Evaluate all clearance-related constraints in a single batch call.
std::shared_ptr< DRC_RULE > createImplicitRule(const wxString &name, DRC_IMPLICIT_SOURCE aImplicitSource)
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
std::unordered_map< DRC_OWN_CLEARANCE_CACHE_KEY, int > m_ownClearanceCache
bool m_hasDiffPairClearanceOverrides
void addRule(std::shared_ptr< DRC_RULE > &rule)
PROGRESS_REPORTER * m_progressReporter
void ClearClearanceCache()
Clear the entire clearance cache.
void loadRules(const wxFileName &aPath)
Load and parse a rule set from an sexpr text file.
std::vector< DRC_TEST_PROVIDER * > m_testProviders
std::map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > > m_explicitConstraints
std::set< int > QueryDistinctConstraints(DRC_CONSTRAINT_T aConstraintId)
bool m_hasGeometryDependentRules
DS_PROXY_VIEW_ITEM * m_drawingSheet
NETLIST * m_schematicNetlist
std::shared_mutex m_clearanceCacheMutex
bool KeepRefreshing(bool aWait=false)
int GetCachedOwnClearance(const BOARD_ITEM *aItem, PCB_LAYER_ID aLayer, wxString *aSource=nullptr)
Get the cached own clearance for an item on a specific layer.
bool m_reportAllTrackErrors
bool ReportProgress(double aProgress)
DRC_TEST_PROVIDER * GetTestProvider(const wxString &name) const
bool HasRulesForConstraintType(DRC_CONSTRAINT_T constraintID)
BOARD_DESIGN_SETTINGS * GetDesignSettings() const
void SetMaxProgress(int aSize)
DRC_ENGINE(BOARD *aBoard=nullptr, BOARD_DESIGN_SETTINGS *aSettings=nullptr)
bool m_hasExplicitClearanceRules
std::vector< int > m_errorLimits
bool IsErrorLimitExceeded(int error_code)
void ProcessAssertions(const BOARD_ITEM *a, std::function< void(const DRC_CONSTRAINT *)> aFailureHandler, REPORTER *aReporter=nullptr)
DRC_VIOLATION_HANDLER m_violationHandler
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
std::vector< std::shared_ptr< DRC_RULE > > m_rules
bool QueryWorstConstraint(DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint, bool aUnconditionalOnly=false)
std::unordered_map< wxString, int > m_netclassClearances
static bool IsNetADiffPair(BOARD *aBoard, NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
bool IsNetTieExclusion(int aTrackNetCode, PCB_LAYER_ID aTrackLayer, const VECTOR2I &aCollisionPos, BOARD_ITEM *aCollidingItem)
Check if the given collision between a track and another item occurs during the track's entry into a ...
std::vector< BOARD_ITEM * > GetItemsMatchingCondition(const wxString &aExpression, DRC_CONSTRAINT_T aConstraint=ASSERTION_CONSTRAINT, REPORTER *aReporter=nullptr)
Evaluate a DRC condition against all board items and return matches.
void InitEngine(const wxFileName &aRulePath)
Initialize the DRC engine.
DRC_CONSTRAINT EvalZoneConnection(const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
static int MatchDpSuffix(const wxString &aNetName, wxString &aComplementNet, wxString &aBaseDpName)
Check if the given net is a diff pair, returning its polarity and complement if so.
bool ReportPhase(const wxString &aMessage)
void InitializeClearanceCache()
Initialize the clearance cache for all items on the board.
void InvalidateClearanceCache(const KIID &aUuid)
Invalidate the clearance cache for a specific item.
BOARD_DESIGN_SETTINGS * m_designSettings
void ReportViolation(const std::shared_ptr< DRC_ITEM > &aItem, const VECTOR2I &aPos, int aMarkerLayer, const std::function< void(PCB_MARKER *)> &aPathGenerator={})
std::mutex m_errorLimitsMutex
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
bool EvaluateFor(const BOARD_ITEM *aItemA, const BOARD_ITEM *aItemB, int aConstraint, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
std::vector< DRC_TEST_PROVIDER * > GetShowMatchesProviders() const
static DRC_SHOWMATCHES_PROVIDER_REGISTRY & Instance()
std::vector< DRC_TEST_PROVIDER * > GetTestProviders() const
static DRC_TEST_PROVIDER_REGISTRY & Instance()
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
void SetDRCEngine(DRC_ENGINE *engine)
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM_FLAGS GetFlags() const
A LINE_READER that reads from an open file.
char * ReadLine() override
Read a line of text into the buffer and increments the line number counter.
wxString AsString() const
LSET is a set of PCB_LAYER_IDs.
static const LSET & FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static wxString Name(PCB_LAYER_ID aLayerId)
Return the fixed name association with aLayerId.
A collection of nets and the parameters used to route or test these nets.
const wxString GetName() const
Gets the name of this (maybe aggregate) netclass in a format for internal usage or for export to exte...
Handle the data for a net.
const wxString & GetNetname() const
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetCompositeNetclasses() const
Gets all composite (multiple assignment / missing defaults) netclasses.
const std::map< wxString, std::shared_ptr< NETCLASS > > & GetNetclasses() const
Gets all netclasses.
std::shared_ptr< NETCLASS > GetDefaultNetclass()
Gets the default netclass for the project.
std::optional< int > GetLocalSolderMaskMargin() const
A small class to help profiling.
void Stop()
Save the time when this function was called, and set the counter stane to stop.
double msecs(bool aSinceLast=false)
Container for project specific data.
A pure virtual class used to derive REPORTER objects from.
virtual bool HasMessageOfSeverity(int aSeverityMask) const
Returns true if the reporter has one or more messages matching the specified severity mask.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
const EDA_IU_SCALE & GetIuScale() const
wxString MessageTextFromUnscaledValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
UNITS_PROVIDER(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits)
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
void SetUserUnits(EDA_UNITS aUnits)
Handle a list of polygons defining a copper zone.
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
bool GetDoNotAllowVias() const
bool GetDoNotAllowPads() const
bool GetDoNotAllowTracks() const
const wxString & GetZoneName() const
int GetMinThickness() const
ZONE_CONNECTION GetPadConnection() const
int GetThermalReliefSpokeWidth() const
bool GetDoNotAllowFootprints() const
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
bool HasKeepoutParametersSet() const
Accessor to determine if any keepout parameters are set.
bool GetDoNotAllowZoneFills() const
int GetThermalReliefGap() const
wxString ExpandTextVars(const wxString &aSource, const PROJECT *aProject, int aFlags)
wxString DescribeRef(const wxString &aRef)
Returns a user-visible HTML string describing a footprint reference designator.
void drcPrintDebugMessage(int level, const wxString &msg, const char *function, int line)
#define EXTENDED_ERROR_LIMIT
static bool isKeepoutZone(const BOARD_ITEM *aItem, bool aCheckFlags)
@ DRCE_TUNING_PROFILE_IMPLICIT_RULES
@ DRC_DISALLOW_BURIED_VIAS
@ DRC_DISALLOW_BLIND_VIAS
@ DRC_DISALLOW_THROUGH_VIAS
@ DRC_DISALLOW_FOOTPRINTS
@ DRC_DISALLOW_MICRO_VIAS
@ ANNULAR_WIDTH_CONSTRAINT
@ COURTYARD_CLEARANCE_CONSTRAINT
@ VIA_DIAMETER_CONSTRAINT
@ ZONE_CONNECTION_CONSTRAINT
@ DIFF_PAIR_GAP_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
@ CONNECTION_WIDTH_CONSTRAINT
@ THERMAL_RELIEF_GAP_CONSTRAINT
@ MAX_UNCOUPLED_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_ABS_MARGIN_CONSTRAINT
@ SOLDER_MASK_EXPANSION_CONSTRAINT
@ PHYSICAL_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_REL_MARGIN_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
constexpr int DRC_DISALLOW_VIAS
#define HOLE_PROXY
Indicates the BOARD_ITEM is a proxy for its hole.
static FILENAME_RESOLVER * resolver
static const wxChar * traceDrcProfile
Flag to enable DRC profile timing logging.
#define THROW_PARSE_ERROR(aProblem, aSource, aInputLine, aLineNumber, aByteIndex)
bool IsPcbLayer(int aLayer)
Test whether a layer is a valid layer for Pcbnew.
PCB_LAYER_ID
A quick note on layer IDs:
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ PTH
Plated through hole pad.
std::vector< FAB_LAYER_COLOR > dummy
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
#define TO_UTF8(wxstring)
Convert a wxString to a UTF8 encoded C string for all wxWidgets build modes.
Batch result for clearance-related constraints to reduce per-query overhead during PNS routing.
std::shared_ptr< DRC_RULE > parentRule
DRC_RULE_CONDITION * condition
DRC_CONSTRAINT constraint
Cache key for own clearance lookups, combining item UUID and layer.
A filename or source description, a problem input line, a line number, a byte offset,...
Represents a single line in the tuning profile configuration grid.
std::vector< DELAY_PROFILE_TRACK_PROPAGATION_ENTRY > m_TrackPropagationEntries
wxString result
Test unit parsing edge cases and error handling.
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::priority_thread_pool thread_pool
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_GENERATOR_T
class PCB_GENERATOR, generator on a layer
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_GROUP_T
class PCB_GROUP, a set of BOARD_ITEMs
@ PCB_TEXTBOX_T
class PCB_TEXTBOX, wrapped text on a layer
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_TEXT_T
class PCB_TEXT, text on a layer
@ PCB_FIELD_T
class PCB_FIELD, text associated with a footprint property
@ PCB_BARCODE_T
class PCB_BARCODE, a barcode (graphic item)
@ PCB_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_NETINFO_T
class NETINFO_ITEM, a description of a net
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I
wxString PrintZoneConnection(ZONE_CONNECTION aConnection)
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ FULL
pads are covered by copper