56#define ERROR_LIMIT 199
57#define EXTENDED_ERROR_LIMIT 499
74 if( wxGetEnv( wxT(
"DRC_DEBUG" ), &valueStr ) )
76 int setLevel = wxAtoi( valueStr );
78 if( level <= setLevel )
79 printf(
"%-30s:%d | %s\n", function, line, (
const char *) msg.c_str() );
122 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
149 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
152 rule->SetImplicitSource( aImplicitSource );
163 wxString expr, expr2, ncName;
167 std::shared_ptr<DRC_RULE> rule =
172 rule->AddConstraint( widthConstraint );
176 rule->AddConstraint( connectionConstraint );
180 rule->AddConstraint( drillConstraint );
184 rule->AddConstraint( annulusConstraint );
188 rule->AddConstraint( diameterConstraint );
192 rule->AddConstraint( holeToHoleConstraint );
198 rule->AddConstraint( thermalSpokeCountConstraint );
204 rule->AddConstraint( silkClearanceConstraint );
211 rule->AddConstraint( silkTextHeightConstraint );
218 rule->AddConstraint( silkTextThicknessConstraint );
223 rule->AddConstraint( holeClearanceConstraint );
228 rule->AddConstraint( edgeClearanceConstraint );
233 rule->AddConstraint( courtyardClearanceConstraint );
237 std::shared_ptr<DRC_RULE> uViaRule =
244 uViaRule->AddConstraint( uViaDrillConstraint );
248 uViaRule->AddConstraint( uViaDiameterConstraint );
252 std::shared_ptr<DRC_RULE> barcodeRule =
256 barcodeRule->AddConstraint( barcodeSeparationConstraint );
261 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
262 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
264 auto makeNetclassRules =
265 [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
267 ncName = nc->GetName();
268 ncName.Replace(
"'",
"\\'" );
270 if( nc->HasClearance() )
272 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
273 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
274 nc->GetClearanceParent()->GetHumanReadableName() );
277 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
279 netclassClearanceRules.push_back( netclassRule );
283 netclassRule->AddConstraint( constraint );
291 if( nc->HasTrackWidth() )
293 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
294 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
295 nc->GetTrackWidthParent()->GetHumanReadableName() );
298 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
300 netclassClearanceRules.push_back( netclassRule );
305 netclassRule->AddConstraint( constraint );
308 if( nc->HasDiffPairWidth() )
310 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
311 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
312 nc->GetDiffPairWidthParent()->GetHumanReadableName() );
315 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.inDiffPair('*')" ), ncName );
317 netclassItemSpecificRules.push_back( netclassRule );
321 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
322 netclassRule->AddConstraint( constraint );
325 if( nc->HasDiffPairGap() )
327 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
328 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
329 nc->GetDiffPairGapParent()->GetHumanReadableName() );
332 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
334 netclassItemSpecificRules.push_back( netclassRule );
339 netclassRule->AddConstraint( constraint );
342 if( nc->GetDiffPairGap() < nc->GetClearance() )
344 netclassRule = std::make_shared<DRC_RULE>();
345 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
346 nc->GetDiffPairGapParent()->GetHumanReadableName() );
349 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && AB.isCoupledDiffPair()" ), ncName );
351 netclassItemSpecificRules.push_back( netclassRule );
354 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
355 netclassRule->AddConstraint( min_clearanceConstraint );
361 if( nc->HasViaDiameter() )
363 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
364 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
365 nc->GetViaDiameterParent()->GetHumanReadableName() );
368 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
370 netclassItemSpecificRules.push_back( netclassRule );
375 netclassRule->AddConstraint( constraint );
378 if( nc->HasViaDrill() )
380 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
381 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
382 nc->GetViaDrillParent()->GetHumanReadableName() );
385 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
387 netclassItemSpecificRules.push_back( netclassRule );
392 netclassRule->AddConstraint( constraint );
395 if( nc->HasuViaDiameter() )
397 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
398 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
399 nc->GetuViaDiameterParent()->GetHumanReadableName() );
402 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
404 netclassItemSpecificRules.push_back( netclassRule );
408 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
409 netclassRule->AddConstraint( constraint );
412 if( nc->HasuViaDrill() )
414 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
415 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
416 nc->GetuViaDrillParent()->GetHumanReadableName() );
419 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
421 netclassItemSpecificRules.push_back( netclassRule );
426 netclassRule->AddConstraint( constraint );
430 m_board->SynchronizeNetsAndNetClasses(
false );
434 makeNetclassRules( netclass,
false );
437 makeNetclassRules( netclass,
false );
444 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
445 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
447 return lhs->m_Constraints[0].m_Value.Min()
448 < rhs->m_Constraints[0].m_Value.Min();
451 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
454 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
458 auto addTuningSingleRule =
460 const wxString& aNetclassName )
465 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
467 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
470 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s'" ),
479 tuningRule->AddConstraint( constraint );
484 auto addTuningDifferentialRules =
491 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
493 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
496 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
497 aNetclass->GetName(),
505 tuningRule->AddConstraint( constraint );
509 std::shared_ptr<DRC_RULE> tuningRule2 = std::make_shared<DRC_RULE>();
511 tuningRule2->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
514 expr2 = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
515 aNetclass->GetName(),
523 tuningRule2->AddConstraint( constraint2 );
530 std::shared_ptr<DRC_RULE> diffPairClearanceRule = std::make_shared<DRC_RULE>();
532 diffPairClearanceRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
535 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
536 aNetclass->GetName(),
542 diffPairClearanceRule->AddConstraint( min_clearanceConstraint );
544 addRule( diffPairClearanceRule );
550 std::shared_ptr<TUNING_PROFILES> tuningParams =
project->GetProjectFile().TuningProfileParameters();
552 auto addNetclassTuningProfileRules =
553 [&tuningParams, &addTuningSingleRule, &addTuningDifferentialRules](
NETCLASS* aNetclass )
555 if( aNetclass->HasTuningProfile() )
557 const wxString delayProfileName = aNetclass->GetTuningProfile();
558 const TUNING_PROFILE& profile = tuningParams->GetTuningProfile( delayProfileName );
566 addTuningSingleRule( entry, delayProfileName, aNetclass->GetName() );
568 addTuningDifferentialRules( entry, delayProfileName, aNetclass );
576 addNetclassTuningProfileRules( netclass.get() );
579 addNetclassTuningProfileRules( netclass.get() );
583 auto addKeepoutZoneRule =
593 wxString::Format(
_(
"keepout area of %s" ),
DescribeRef( parentFP->GetReference() ) ),
617 rule->m_ImplicitItemId = zone->
m_Uuid;
619 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
624 int disallowFlags = 0;
643 rule->AddConstraint( disallowConstraint );
649 addKeepoutZoneRule( zone,
nullptr );
654 for(
ZONE* zone : footprint->Zones() )
657 addKeepoutZoneRule( zone, footprint );
665 if(
m_board && aPath.FileExists() )
667 std::vector<std::shared_ptr<DRC_RULE>> rules;
669 if( FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) ) )
674 std::function<bool( wxString* )>
resolver =
675 [&]( wxString* token ) ->
bool
677 return m_board->ResolveTextVar( token, 0 );
680 while(
char* line = lineReader.
ReadLine() )
682 wxString str( line );
683 str =
m_board->ConvertCrossReferencesToKIIDs( str );
686 rulesText << str <<
'\n';
696 for( std::shared_ptr<DRC_RULE>& rule : rules )
709 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
713 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
715 condition = rule->m_Condition;
716 condition->
Compile( &error_semaphore );
721 TO_UTF8( rule->m_Condition->GetExpression() ), 0, 0 );
728 ruleVec =
new std::vector<DRC_ENGINE_CONSTRAINT*>();
732 engineConstraint->
layerTest = rule->m_LayerCondition;
736 ruleVec->push_back( engineConstraint );
747 if( c->parentRule && !c->parentRule->IsImplicit() )
766 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
768 provider->SetDRCEngine(
this );
793 throw original_parse_error;
810 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
812 provider->SetDRCEngine(
this );
857 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
860 throw original_parse_error;
897 if( !cacheGenerator.
Run() )
901 m_board->GetComponentClassManager().ForceComponentClassRecalculation();
903 int timestamp =
m_board->GetTimeStamp();
908 m_logReporter->Report( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
910 if( !provider->RunTests( aUnits ) )
919 wxASSERT( timestamp ==
m_board->GetTimeStamp() );
923#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
931 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
939 pad =
static_cast<const PAD*
>( a );
941 pad =
static_cast<const PAD*
>( b );
949 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
975 const ZONE* zone =
nullptr;
976 const FOOTPRINT* parentFootprint =
nullptr;
986 pad =
static_cast<const PAD*
>( a );
988 zone =
static_cast<const ZONE*
>( a );
991 pad =
static_cast<const PAD*
>( b );
993 zone =
static_cast<const ZONE*
>( b );
996 parentFootprint =
pad->GetParentFootprint();
1000 constraint.
m_Type = aConstraintType;
1002 auto applyConstraint =
1005 if( c->constraint.m_Value.HasMin() )
1007 if( c->parentRule && c->parentRule->IsImplicit() )
1013 if( c->constraint.m_Value.HasOpt() )
1016 if( c->constraint.m_Value.HasMax() )
1019 switch( c->constraint.m_Type )
1054 && ( ( ( !ac ) ^ ( !bc ) )
1057 || ( ( footprints[0] == footprints[1] )
1058 && footprints[0] ) )
1060 && !b_is_non_copper )
1067 for(
int ii = 0; ii < 2; ++ii )
1070 if( !footprints[ii] || !alt_items[ii] )
1073 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
1075 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
1077 if( it != netcodes.end() )
1080 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
1081 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
1083 constraint.
SetName(
_(
"net tie" ) );
1093 int override_val = 0;
1094 std::optional<int> overrideA;
1095 std::optional<int> overrideB;
1097 if( ac && !b_is_non_copper )
1100 if( bc && !a_is_non_copper )
1103 if( overrideA.has_value() || overrideB.has_value() )
1107 if( overrideA.has_value() )
1110 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1117 if( overrideB.has_value() )
1120 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1124 if( overrideB > override_val )
1132 if( override_val < m_designSettings->m_MinClearance )
1135 msg =
_(
"board minimum" );
1138 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1144 if( override_val < m_designSettings->m_HoleClearance )
1147 msg =
_(
"board minimum hole" );
1150 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
1169 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
1180 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
1183 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
1186 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
1197 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
1200 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
1203 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
1212 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
1224 std::optional<int>
override;
1228 override =
pad->GetLocalSolderMaskMargin();
1230 override =
static_cast<const PCB_SHAPE*
>( a )->GetLocalSolderMaskMargin();
1234 if( !
override.has_value() &&
pad )
1236 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1238 override = overrideFootprint->GetLocalSolderMaskMargin();
1239 overrideItem = overrideFootprint;
1246 REPORT( wxString::Format(
_(
"Local override on %s; solder mask expansion: %s." ),
1256 std::optional<int>
override;
1260 override =
pad->GetLocalSolderPasteMargin();
1262 if( !
override.has_value() &&
pad )
1264 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1266 override = overrideFootprint->GetLocalSolderPasteMargin();
1267 overrideItem = overrideFootprint;
1274 REPORT( wxString::Format(
_(
"Local override on %s; solder paste absolute clearance: %s." ),
1284 std::optional<double> overrideRatio;
1288 overrideRatio =
pad->GetLocalSolderPasteMarginRatio();
1290 if( !overrideRatio.has_value() &&
pad )
1292 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1294 overrideRatio = overrideFootprint->GetLocalSolderPasteMarginRatio();
1295 overrideItem = overrideFootprint;
1302 REPORT( wxString::Format(
_(
"Local override on %s; solder paste relative clearance: %s." ),
1311 auto testAssertion =
1314 REPORT( wxString::Format(
_(
"Checking assertion '%s'." ),
1315 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1317 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1318 REPORT(
_(
"Assertion passed." ) )
1323 auto processConstraint =
1326 bool implicit = c->parentRule && c->parentRule->IsImplicit();
1330 switch( c->constraint.m_Type )
1339 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
1344 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
1349 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1355 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1361 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1367 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1373 REPORT( wxString::Format(
_(
"Checking %s solder mask expansion: %s." ),
1379 REPORT( wxString::Format(
_(
"Checking %s solder paste absolute clearance: %s." ),
1385 REPORT( wxString::Format(
_(
"Checking %s solder paste relative clearance: %s." ),
1391 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1397 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1415 switch( c->constraint.m_Type )
1418 if( c->constraint.m_Value.HasOpt() )
1420 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1424 else if( c->constraint.m_Value.HasMin() )
1426 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1434 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1440 if( c->constraint.m_Value.HasOpt() )
1442 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1446 else if( c->constraint.m_Value.HasMin() )
1448 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1455 if( c->constraint.m_Value.HasOpt() )
1457 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1461 else if( c->constraint.m_Value.HasMin() )
1463 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1473 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1479 if( c->constraint.m_Value.HasOpt() )
1481 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1485 else if( c->constraint.m_Value.HasMin() )
1487 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1495 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1501 REPORT( wxString::Format(
_(
"Checking %s." ),
1507 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1509 c->constraint.m_Value.HasMin()
1511 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1512 c->constraint.m_Value.HasOpt()
1514 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1515 c->constraint.m_Value.HasMax()
1517 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ) ) )
1523 REPORT( wxString::Format(
_(
"Checking %s." ),
1529 if( a_is_non_copper || b_is_non_copper )
1533 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1535 else if( a_is_non_copper )
1537 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1540 else if( b_is_non_copper )
1542 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1561 if(
via->IsMicroVia() )
1563 else if(
via->IsBlindVia() )
1565 else if(
via->IsBuriedVia() )
1587 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1595 default: mask = 0;
break;
1599 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1602 REPORT(
_(
"Keepout constraint not met." ) )
1604 REPORT(
_(
"Disallow constraint not met." ) )
1622 if( !( c->layerTest & itemLayers ).any() )
1626 REPORT(
_(
"Keepout layer(s) not matched." ) )
1628 else if( c->parentRule )
1630 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1631 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1635 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1642 if( (
IsPcbLayer( aLayer ) && !c->layerTest.test( aLayer ) )
1643 || (
m_board->GetEnabledLayers() & c->layerTest ).count() == 0 )
1647 REPORT(
_(
"Constraint layer not matched." ) )
1649 else if( c->parentRule )
1651 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1652 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1656 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1663 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1666 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1672 REPORT(
_(
"Unconditional constraint applied." ) )
1676 REPORT(
_(
"Unconditional rule applied." ) )
1681 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1685 applyConstraint( c );
1695 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
1696 EscapeHTML( c->condition->GetExpression() ) ) )
1699 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1705 REPORT(
_(
"Constraint applied." ) )
1709 REPORT(
_(
"Rule applied." ) )
1714 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1718 applyConstraint( c );
1722 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1723 :
_(
"Condition not satisfied; rule ignored." ) )
1734 && ( !b || !b_is_non_copper ) )
1759 if( !ncNameA.empty() || !ncNameB.empty() )
1763 if( !ncNameA.empty() )
1771 if( !ncNameB.empty() )
1793 processConstraint( rule );
1811 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1815 a = parentFootprint;
1817 b = parentFootprint;
1824 processConstraint( rule );
1834 constraint.
SetName(
_(
"board setup" ) );
1841 constraint.
SetName(
_(
"board setup" ) );
1848 constraint.
SetName(
_(
"board setup" ) );
1861 bool needBlankLine =
true;
1870 needBlankLine =
false;
1873 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1894 needBlankLine =
false;
1897 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1911 if( !a_is_non_copper && !b_is_non_copper )
1916 needBlankLine =
false;
1919 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1925 constraint.
SetName(
_(
"board minimum" ) );
1935 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1941 constraint.
SetName(
_(
"board minimum" ) );
1949 if(
pad && parentFootprint )
1956 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1961 constraint.
SetName(
_(
"footprint" ) );
1972 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1989 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
2006 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
2071 auto testAssertion =
2074 REPORT( wxString::Format(
_(
"Checking rule assertion '%s'." ),
2075 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
2077 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2080 REPORT(
_(
"Assertion passed." ) )
2085 aFailureHandler( &c->constraint );
2089 auto processConstraint =
2093 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
2097 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
2098 EscapeHTML( c->parentRule->m_LayerSource ) ) )
2101 if( !c->condition || c->condition->GetExpression().IsEmpty() )
2103 REPORT(
_(
"Unconditional rule applied." ) )
2108 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
2109 EscapeHTML( c->condition->GetExpression() ) ) )
2111 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2114 REPORT(
_(
"Rule applied." ) )
2119 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
2128 for(
int ii = 0; ii < (int) it->second->size(); ++ii )
2129 processConstraint( it->second->at( ii ) );
2139 assert( error_code >= 0 && error_code <=
DRCE_LAST );
2146 int aMarkerLayer,
const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
2155 static std::mutex handlerLock;
2156 std::lock_guard<std::mutex> guard( handlerLock );
2162 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
2163 aItem->GetViolatingTest()->GetName(),
2164 aItem->GetErrorMessage(
false ),
2165 aItem->GetErrorCode() );
2167 DRC_RULE* rule = aItem->GetViolatingRule();
2170 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
2174 wxString violatingItemsStr = wxT(
"Violating items: " );
2176 m_logReporter->Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
2223 wxSafeYield(
nullptr,
true );
2252 if( current > worst )
2266 std::set<int> distinctMinimums;
2275 return distinctMinimums;
2281 wxString& aBaseDpName )
2286 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
2290 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
2294 else if( ch ==
'+' )
2296 aComplementNet = wxT(
"-" );
2299 else if( ch ==
'-' )
2301 aComplementNet = wxT(
"+" );
2304 else if( ch ==
'N' )
2306 aComplementNet = wxT(
"P" );
2309 else if ( ch ==
'P' )
2311 aComplementNet = wxT(
"N" );
2320 if( rv != 0 && count >= 1 )
2322 aBaseDpName = aNetName.Left( aNetName.Length() - count );
2323 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
2333 wxString
dummy, coupledNetName;
2369 if( parentFootprint && parentFootprint->
IsNetTie() )
2376 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
2378 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
2392 if(
name == prov->GetName() )
2404 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2405 wxS(
"[ShowMatches] engine enter: expr='%s', constraint=%d" ), aExpression, (
int) aConstraint );
2406 std::vector<BOARD_ITEM*> matches;
2415 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine: compile failed" ) );
2422 if(
auto connectivity =
m_board->GetConnectivity() )
2424 if(
auto ftCache = connectivity->GetFromToCache() )
2429 size_t totalItems = 0;
2430 size_t skippedItems = 0;
2431 size_t noLayerItems = 0;
2432 size_t checkedItems = 0;
2434 for(
auto& [kiid, item] :
m_board->GetItemByIdCache() )
2439 switch( item->Type() )
2451 LSET itemLayers = item->GetLayerSet();
2453 if( itemLayers.none() )
2460 bool matched =
false;
2464 if( condition.
EvaluateFor( item,
nullptr,
static_cast<int>( aConstraint ), layer,
2467 matches.push_back( item );
2468 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2469 wxS(
"[ShowMatches] engine: match type=%d kiid=%s layer=%d" ),
2470 (
int) item->Type(), kiid.AsString(), (
int) layer );
2477 if( !matched && matches.size() == 0 && checkedItems <= 5 )
2479 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2480 wxS(
"[ShowMatches] engine: no-match sample type=%d kiid=%s layers=%s" ),
2481 (
int) item->Type(), kiid.AsString(), itemLayers.
FmtHex() );
2485 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2486 wxS(
"[ShowMatches] engine stats: total=%zu skipped=%zu noLayer=%zu checked=%zu" ),
2487 totalItems, skippedItems, noLayerItems, checkedItems );
2489 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine exit: total=%zu" ), matches.size() );
2518 const PAD*
pad =
static_cast<const PAD*
>( aItem );
2533 *aSource = constraint.
GetName();
2559 if( it->first.m_uuid == aUuid )
2584 using CLEARANCE_MAP = std::unordered_map<DRC_OWN_CLEARANCE_CACHE_KEY, int>;
2588 std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>> itemsToProcess;
2589 size_t estimatedPads = 0;
2592 estimatedPads += footprint->Pads().size();
2594 itemsToProcess.reserve(
m_board->Tracks().size() + estimatedPads * 2 );
2601 itemsToProcess.emplace_back( track, layer );
2605 itemsToProcess.emplace_back( track, track->GetLayer() );
2611 for(
PAD*
pad : footprint->Pads() )
2614 itemsToProcess.emplace_back(
pad, layer );
2618 if( itemsToProcess.empty() )
2628 auto processItems = [
this](
size_t aStart,
size_t aEnd,
2629 const std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>>& aItems )
2632 CLEARANCE_MAP localCache;
2634 for(
size_t i = aStart; i < aEnd; ++i )
2643 const PAD*
pad =
static_cast<const PAD*
>( item );
2662 auto results =
tp.submit_blocks( 0, itemsToProcess.size(),
2663 [&](
size_t aStart,
size_t aEnd ) -> CLEARANCE_MAP
2665 return processItems( aStart, aEnd, itemsToProcess );
2672 std::vector<CLEARANCE_MAP> collectedResults;
2673 collectedResults.reserve( results.size() );
2675 for(
size_t i = 0; i < results.size(); ++i )
2677 if( results[i].valid() )
2678 collectedResults.push_back( results[i].get() );
2685 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)
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
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 ...
bool QueryWorstConstraint(DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint)
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 & 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 LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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