57#define ERROR_LIMIT 199
58#define EXTENDED_ERROR_LIMIT 499
75 if( wxGetEnv( wxT(
"DRC_DEBUG" ), &valueStr ) )
77 int setLevel = wxAtoi( valueStr );
79 if( level <= setLevel )
80 printf(
"%-30s:%d | %s\n", function, line, (
const char *) msg.c_str() );
123 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
150 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
153 rule->SetImplicitSource( aImplicitSource );
164 wxString expr, expr2, ncName;
173 rule->AddConstraint( widthConstraint );
177 rule->AddConstraint( connectionConstraint );
181 rule->AddConstraint( drillConstraint );
185 rule->AddConstraint( annulusConstraint );
189 rule->AddConstraint( diameterConstraint );
193 rule->AddConstraint( holeToHoleConstraint );
199 rule->AddConstraint( thermalSpokeCountConstraint );
205 rule->AddConstraint( silkClearanceConstraint );
212 rule->AddConstraint( silkTextHeightConstraint );
219 rule->AddConstraint( silkTextThicknessConstraint );
224 rule->AddConstraint( holeClearanceConstraint );
229 rule->AddConstraint( edgeClearanceConstraint );
234 rule->AddConstraint( courtyardClearanceConstraint );
238 std::shared_ptr<DRC_RULE> uViaRule =
createImplicitRule(
_(
"board setup constraints micro-via" ),
245 uViaRule->AddConstraint( uViaDrillConstraint );
249 uViaRule->AddConstraint( uViaDiameterConstraint );
253 std::shared_ptr<DRC_RULE> barcodeRule =
createImplicitRule(
_(
"barcode visual separation default" ),
257 barcodeRule->AddConstraint( barcodeSeparationConstraint );
262 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
263 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
265 auto makeNetclassRules =
266 [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
268 ncName = nc->GetName();
269 ncName.Replace(
"'",
"\\'" );
271 if( nc->HasClearance() )
273 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
274 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
275 nc->GetClearanceParent()->GetHumanReadableName() );
278 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
280 netclassClearanceRules.push_back( netclassRule );
284 netclassRule->AddConstraint( constraint );
292 if( nc->HasTrackWidth() )
294 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
295 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
296 nc->GetTrackWidthParent()->GetHumanReadableName() );
299 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
301 netclassClearanceRules.push_back( netclassRule );
306 netclassRule->AddConstraint( constraint );
309 if( nc->HasDiffPairWidth() )
311 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
312 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' diff pair" ),
313 nc->GetDiffPairWidthParent()->GetHumanReadableName() );
316 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.inDiffPair('*')" ), ncName );
318 netclassItemSpecificRules.push_back( netclassRule );
322 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
323 netclassRule->AddConstraint( constraint );
326 if( nc->HasDiffPairGap() )
328 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
329 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
330 nc->GetDiffPairGapParent()->GetHumanReadableName() );
333 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s')" ), ncName );
335 netclassItemSpecificRules.push_back( netclassRule );
340 netclassRule->AddConstraint( constraint );
343 if( nc->GetDiffPairGap() < nc->GetClearance() )
345 netclassRule = std::make_shared<DRC_RULE>();
346 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' diff pair" ),
347 nc->GetDiffPairGapParent()->GetHumanReadableName() );
350 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && AB.isCoupledDiffPair()" ), ncName );
352 netclassItemSpecificRules.push_back( netclassRule );
355 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
356 netclassRule->AddConstraint( min_clearanceConstraint );
362 if( nc->HasViaDiameter() )
364 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
365 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
366 nc->GetViaDiameterParent()->GetHumanReadableName() );
369 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
371 netclassItemSpecificRules.push_back( netclassRule );
376 netclassRule->AddConstraint( constraint );
379 if( nc->HasViaDrill() )
381 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
382 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
383 nc->GetViaDrillParent()->GetHumanReadableName() );
386 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type != 'Micro'" ), ncName );
388 netclassItemSpecificRules.push_back( netclassRule );
393 netclassRule->AddConstraint( constraint );
396 if( nc->HasuViaDiameter() )
398 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
399 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' uvia" ),
400 nc->GetuViaDiameterParent()->GetHumanReadableName() );
403 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
405 netclassItemSpecificRules.push_back( netclassRule );
409 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
410 netclassRule->AddConstraint( constraint );
413 if( nc->HasuViaDrill() )
415 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
416 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' uvia" ),
417 nc->GetuViaDrillParent()->GetHumanReadableName() );
420 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Via_Type == 'Micro'" ), ncName );
422 netclassItemSpecificRules.push_back( netclassRule );
427 netclassRule->AddConstraint( constraint );
431 m_board->SynchronizeNetsAndNetClasses(
false );
435 makeNetclassRules( netclass,
false );
438 makeNetclassRules( netclass,
false );
445 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
446 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
448 return lhs->m_Constraints[0].m_Value.Min() < 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(
536 wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && AB.isCoupledDiffPair()" ),
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;
618 rule->m_ImplicitItem = zone;
620 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
625 int disallowFlags = 0;
644 rule->AddConstraint( disallowConstraint );
650 addKeepoutZoneRule( zone,
nullptr );
655 for(
ZONE* zone : footprint->Zones() )
658 addKeepoutZoneRule( zone, footprint );
666 if(
m_board && aPath.FileExists() )
668 std::vector<std::shared_ptr<DRC_RULE>> rules;
670 if( FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) ) )
675 std::function<bool( wxString* )>
resolver =
676 [&]( wxString* token ) ->
bool
681 return m_board->ResolveTextVar( token, 0 );
684 while(
char* line = lineReader.
ReadLine() )
686 wxString str( line );
687 str =
m_board->ConvertCrossReferencesToKIIDs( str );
690 rulesText << str <<
'\n';
700 for( std::shared_ptr<DRC_RULE>& rule : rules )
713 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
717 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
719 condition = rule->m_Condition;
720 condition->
Compile( &error_semaphore );
731 ruleVec =
new std::vector<DRC_ENGINE_CONSTRAINT*>();
735 engineConstraint->
layerTest = rule->m_LayerCondition;
741 && rule->m_ImplicitItem && rule->m_ImplicitItem->Type() ==
PCB_ZONE_T )
748 ruleVec->push_back( engineConstraint );
760 if( c->parentRule && !c->parentRule->IsImplicit() )
769 && c->condition->HasGeometryDependentFunctions() )
786 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
788 provider->SetDRCEngine(
this );
824 throw original_parse_error;
841 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
843 provider->SetDRCEngine(
this );
899 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
902 throw original_parse_error;
939 if( !cacheGenerator.
Run() )
943 m_board->GetComponentClassManager().ForceComponentClassRecalculation();
945 int timestamp =
m_board->GetTimeStamp();
950 m_logReporter->Report( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
954 if( !provider->RunTests( aUnits ) )
957 providerTimer.
Stop();
958 wxLogTrace(
traceDrcProfile,
"DRC provider '%s' took %0.3f ms", provider->GetName(), providerTimer.
msecs() );
966 wxASSERT( timestamp ==
m_board->GetTimeStamp() );
970#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
978 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
986 pad =
static_cast<const PAD*
>( a );
988 pad =
static_cast<const PAD*
>( b );
996 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
1020 const PAD*
pad =
nullptr;
1021 const ZONE* zone =
nullptr;
1022 const FOOTPRINT* parentFootprint =
nullptr;
1032 pad =
static_cast<const PAD*
>( a );
1034 zone =
static_cast<const ZONE*
>( a );
1037 pad =
static_cast<const PAD*
>( b );
1039 zone =
static_cast<const ZONE*
>( b );
1042 parentFootprint =
pad->GetParentFootprint();
1046 constraint.
m_Type = aConstraintType;
1048 auto applyConstraint =
1051 if( c->constraint.m_Value.HasMin() )
1053 if( c->parentRule && c->parentRule->IsImplicit() )
1061 if( c->constraint.m_Value.HasOpt() )
1064 if( c->constraint.m_Value.HasMax() )
1067 switch( c->constraint.m_Type )
1102 && ( ( ( !ac ) ^ ( !bc ) )
1105 || ( ( footprints[0] == footprints[1] )
1106 && footprints[0] ) )
1108 && !b_is_non_copper )
1115 for(
int ii = 0; ii < 2; ++ii )
1118 if( !footprints[ii] || !alt_items[ii] )
1121 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
1123 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
1125 if( it != netcodes.end() )
1128 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
1129 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
1131 constraint.
SetName(
_(
"net tie" ) );
1141 int override_val = 0;
1142 std::optional<int> overrideA;
1143 std::optional<int> overrideB;
1145 if( ac && !b_is_non_copper )
1148 if( bc && !a_is_non_copper )
1151 if( overrideA.has_value() || overrideB.has_value() )
1155 if( overrideA.has_value() )
1158 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1165 if( overrideB.has_value() )
1168 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1172 if( overrideB > override_val )
1180 if( override_val < m_designSettings->m_MinClearance )
1183 msg =
_(
"board minimum" );
1186 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1192 if( override_val < m_designSettings->m_HoleClearance )
1195 msg =
_(
"board minimum hole" );
1198 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
1217 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
1228 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
1231 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
1234 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
1245 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
1248 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
1251 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
1260 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
1272 std::optional<int>
override;
1276 override =
pad->GetLocalSolderMaskMargin();
1278 override =
static_cast<const PCB_SHAPE*
>( a )->GetLocalSolderMaskMargin();
1282 if( !
override.has_value() &&
pad )
1284 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1286 override = overrideFootprint->GetLocalSolderMaskMargin();
1287 overrideItem = overrideFootprint;
1294 REPORT( wxString::Format(
_(
"Local override on %s; solder mask expansion: %s." ),
1304 std::optional<int>
override;
1308 override =
pad->GetLocalSolderPasteMargin();
1310 if( !
override.has_value() &&
pad )
1312 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1314 override = overrideFootprint->GetLocalSolderPasteMargin();
1315 overrideItem = overrideFootprint;
1322 REPORT( wxString::Format(
_(
"Local override on %s; solder paste absolute clearance: %s." ),
1332 std::optional<double> overrideRatio;
1336 overrideRatio =
pad->GetLocalSolderPasteMarginRatio();
1338 if( !overrideRatio.has_value() &&
pad )
1340 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1342 overrideRatio = overrideFootprint->GetLocalSolderPasteMarginRatio();
1343 overrideItem = overrideFootprint;
1350 REPORT( wxString::Format(
_(
"Local override on %s; solder paste relative clearance: %s." ),
1359 auto testAssertion =
1362 REPORT( wxString::Format(
_(
"Checking assertion '%s'." ),
1363 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1365 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1366 REPORT(
_(
"Assertion passed." ) )
1376 std::unordered_map<wxString, bool> conditionCache;
1378 auto reportConstraintHeader =
1383 bool implicit = c->parentRule && c->parentRule->IsImplicit();
1385 switch( c->constraint.m_Type )
1394 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
1399 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
1404 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1410 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1416 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1422 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1428 REPORT( wxString::Format(
_(
"Checking %s solder mask expansion: %s." ),
1434 REPORT( wxString::Format(
_(
"Checking %s solder paste absolute clearance: %s." ),
1440 REPORT( wxString::Format(
_(
"Checking %s solder paste relative clearance: %s." ),
1446 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1452 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1473 switch( c->constraint.m_Type )
1476 if( c->constraint.m_Value.HasOpt() )
1478 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1482 else if( c->constraint.m_Value.HasMin() )
1484 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1492 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1498 if( c->constraint.m_Value.HasOpt() )
1500 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1504 else if( c->constraint.m_Value.HasMin() )
1506 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1513 if( c->constraint.m_Value.HasOpt() )
1515 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1519 else if( c->constraint.m_Value.HasMin() )
1521 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1531 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1537 if( c->constraint.m_Value.HasOpt() )
1539 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1543 else if( c->constraint.m_Value.HasMin() )
1545 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1553 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1559 REPORT( wxString::Format(
_(
"Checking %s." ),
1565 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1567 c->constraint.m_Value.HasMin()
1569 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1570 c->constraint.m_Value.HasOpt()
1572 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1573 c->constraint.m_Value.HasMax()
1575 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ) ) )
1581 REPORT( wxString::Format(
_(
"Checking %s." ),
EscapeHTML( c->constraint.GetName() ) ) )
1585 auto checkCondition =
1588 bool condMatched =
false;
1597 auto it = conditionCache.find( expr );
1599 if( it != conditionCache.end() )
1601 condMatched = it->second;
1606 conditionCache[expr] = condMatched;
1613 auto processConstraint =
1622 if( a_is_non_copper || b_is_non_copper )
1624 reportConstraintHeader( c );
1625 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1630 if( !checkCondition( c,
nullptr ) )
1634 reportConstraintHeader( c );
1638 if( a_is_non_copper )
1640 REPORT( wxString::Format(
_(
"%s contains no copper. Constraint ignored." ),
1644 else if( b_is_non_copper )
1646 REPORT( wxString::Format(
_(
"%s contains no copper. Constraint ignored." ),
1657 REPORT(
_(
"Keepout belongs to the footprint under test; constraint ignored." ) )
1671 if(
via->IsMicroVia() )
1673 else if(
via->IsBlindVia() )
1675 else if(
via->IsBuriedVia() )
1697 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1705 default: mask = 0;
break;
1712 REPORT(
_(
"Keepout constraint not met." ) )
1714 REPORT(
_(
"Disallow constraint not met." ) )
1732 if( !( c->
layerTest & itemLayers ).any() )
1736 REPORT(
_(
"Keepout layer(s) not matched." ) )
1740 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1745 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1757 REPORT(
_(
"Constraint layer not matched." ) )
1761 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1766 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1777 REPORT( wxString::Format(
_(
"%s does not have a hole; rule ignored." ),
1786 REPORT(
_(
"Unconditional constraint applied." ) )
1790 REPORT(
_(
"Unconditional rule applied." ) )
1795 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1799 applyConstraint( c );
1822 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
1831 condMatched = checkCondition( c, aReporter );
1839 REPORT(
_(
"Constraint applied." ) )
1843 REPORT(
_(
"Rule applied." ) )
1848 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1852 applyConstraint( c );
1856 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1857 :
_(
"Condition not satisfied; rule ignored." ) )
1868 && ( !b || !b_is_non_copper ) )
1893 if( !ncNameA.empty() || !ncNameB.empty() )
1897 if( !ncNameA.empty() )
1905 if( !ncNameB.empty() )
1927 processConstraint( rule );
1936 REPORT( wxString::Format(
_(
"Resolved minimum clearance: %s." ),
1960 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1964 a = parentFootprint;
1966 b = parentFootprint;
1970 conditionCache.clear();
1977 processConstraint( rule );
1987 constraint.
SetName(
_(
"board setup" ) );
1994 constraint.
SetName(
_(
"board setup" ) );
2001 constraint.
SetName(
_(
"board setup" ) );
2014 bool needBlankLine =
true;
2023 needBlankLine =
false;
2026 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
2047 needBlankLine =
false;
2050 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
2064 if( !a_is_non_copper && !b_is_non_copper )
2069 needBlankLine =
false;
2072 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
2078 constraint.
SetName(
_(
"board minimum" ) );
2087 if(
pad && parentFootprint )
2094 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
2099 constraint.
SetName(
_(
"footprint" ) );
2110 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
2127 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
2144 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
2209 auto testAssertion =
2212 REPORT( wxString::Format(
_(
"Checking rule assertion '%s'." ),
2213 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
2215 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2218 REPORT(
_(
"Assertion passed." ) )
2223 aFailureHandler( &c->constraint );
2227 auto processConstraint =
2231 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
2235 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
2236 EscapeHTML( c->parentRule->m_LayerSource ) ) )
2239 if( !c->condition || c->condition->GetExpression().IsEmpty() )
2241 REPORT(
_(
"Unconditional rule applied." ) )
2246 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
2247 EscapeHTML( c->condition->GetExpression() ) ) )
2249 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2252 REPORT(
_(
"Rule applied." ) )
2257 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
2266 for(
int ii = 0; ii < (int) it->second->size(); ++ii )
2267 processConstraint( it->second->at( ii ) );
2277 assert( error_code >= 0 && error_code <=
DRCE_LAST );
2284 int aMarkerLayer,
const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
2301 static std::mutex handlerLock;
2302 std::lock_guard<std::mutex> guard( handlerLock );
2308 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
2309 aItem->GetViolatingTest()->GetName(),
2310 aItem->GetErrorMessage(
false ),
2311 aItem->GetErrorCode() );
2313 DRC_RULE* rule = aItem->GetViolatingRule();
2316 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
2320 wxString violatingItemsStr = wxT(
"Violating items: " );
2322 m_logReporter->Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
2386 bool aUnconditionalOnly )
2395 if( aUnconditionalOnly && c->
condition )
2400 if( current > worst )
2434 std::set<int> distinctMinimums;
2443 return distinctMinimums;
2453 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
2457 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
2461 else if( ch ==
'+' )
2463 aComplementNet = wxT(
"-" );
2466 else if( ch ==
'-' )
2468 aComplementNet = wxT(
"+" );
2471 else if( ch ==
'N' )
2473 aComplementNet = wxT(
"P" );
2476 else if ( ch ==
'P' )
2478 aComplementNet = wxT(
"N" );
2487 if( rv != 0 && count >= 1 )
2489 aBaseDpName = aNetName.Left( aNetName.Length() - count );
2490 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
2499 const wxString& refName = aNet->
GetNetname();
2500 wxString
dummy, coupledNetName;
2536 if( parentFootprint && parentFootprint->
IsNetTie() )
2543 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
2545 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
2557enum class SHOWMATCH_DOMAIN
2564 MASK_EXPANSION_ITEMS,
2577struct SHOWMATCH_DOMAIN_SPEC
2579 SHOWMATCH_DOMAIN primary;
2580 SHOWMATCH_DOMAIN secondary = SHOWMATCH_DOMAIN::ALL_ITEMS;
2581 bool hasSecondary =
false;
2582 bool secondaryUnary =
false;
2586bool isShowMatchSkippable(
const BOARD_ITEM* aItem )
2588 switch( aItem->
Type() )
2594 default:
return false;
2599bool matchesShowMatchDomain(
const BOARD_ITEM* aItem, SHOWMATCH_DOMAIN aDomain )
2601 if( !aItem || isShowMatchSkippable( aItem ) )
2606 case SHOWMATCH_DOMAIN::ALL_ITEMS:
return true;
2610 case SHOWMATCH_DOMAIN::EDGE_ITEMS:
2616 const PAD*
pad =
static_cast<const PAD*
>( aItem );
2624 case SHOWMATCH_DOMAIN::HOLE_ITEMS:
return aItem->
HasHole();
2626 case SHOWMATCH_DOMAIN::MASK_EXPANSION_ITEMS:
2627 switch( aItem->
Type() )
2636 default:
return false;
2641 case SHOWMATCH_DOMAIN::PADS:
return aItem->
Type() ==
PCB_PAD_T;
2647 case SHOWMATCH_DOMAIN::ROUTING_ITEMS:
2648 switch( aItem->
Type() )
2655 default:
return false;
2660 case SHOWMATCH_DOMAIN::SILK_TARGET_ITEMS:
2667 case SHOWMATCH_DOMAIN::TEXT_ITEMS:
2671 case SHOWMATCH_DOMAIN::VIAS:
return aItem->
Type() ==
PCB_VIA_T;
2678SHOWMATCH_DOMAIN_SPEC getShowMatchDomainSpec(
DRC_CONSTRAINT_T aConstraint )
2680 switch( aConstraint )
2697 return { SHOWMATCH_DOMAIN::SILK_ITEMS, SHOWMATCH_DOMAIN::SILK_TARGET_ITEMS,
true,
false };
2729 default:
return { SHOWMATCH_DOMAIN::ALL_ITEMS };
2734std::vector<BOARD_ITEM*> collectShowMatchCandidates(
BOARD* aBoard, SHOWMATCH_DOMAIN aDomain )
2736 std::vector<BOARD_ITEM*> items;
2743 if( matchesShowMatchDomain( item, aDomain ) )
2744 items.push_back( item );
2751std::vector<PCB_LAYER_ID> getShowMatchLayers(
const BOARD_ITEM* aItem )
2753 std::vector<PCB_LAYER_ID> layers;
2755 switch( aItem->
Type() )
2757 case PCB_PAD_T: layers =
static_cast<const PAD*
>( aItem )->Padstack().UniqueLayers();
break;
2759 case PCB_VIA_T: layers =
static_cast<const PCB_VIA*
>( aItem )->Padstack().UniqueLayers();
break;
2763 layers.push_back( layer );
2768 if( layers.empty() )
2778 bool testedLayer =
false;
2780 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItem ) )
2805std::vector<PCB_LAYER_ID> getShowMatchPairLayers(
const DRC_RULE& aRule,
const BOARD_ITEM* aItemA,
2808 std::vector<PCB_LAYER_ID> layers;
2809 std::set<int> seenLayers;
2817 if( seenLayers.insert(
static_cast<int>( aLayer ) ).second )
2818 layers.push_back( aLayer );
2821 switch( aConstraint )
2824 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemA ) )
2832 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemA ) )
2835 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemB ) )
2841 if( layers.empty() )
2851 for(
PCB_LAYER_ID layer : getShowMatchPairLayers( aRule, aItemA, aItemB, aConstraint ) )
2869 if(
name == prov->GetName() )
2881 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine enter: expr='%s', constraint=%d" ),
2882 aExpression, (
int) aConstraint );
2884 std::vector<BOARD_ITEM*> matches;
2893 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine: compile failed" ) );
2900 if( std::shared_ptr<CONNECTIVITY_DATA> connectivity =
m_board->GetConnectivity() )
2902 if( std::shared_ptr<FROM_TO_CACHE> ftCache = connectivity->GetFromToCache() )
2907 size_t totalItems = 0;
2908 size_t skippedItems = 0;
2909 size_t noLayerItems = 0;
2910 size_t checkedItems = 0;
2912 for(
auto& [kiid, item] :
m_board->GetItemByIdCache() )
2917 switch( item->Type() )
2930 LSET itemLayers = item->GetLayerSet();
2932 if( itemLayers.none() )
2939 bool matched =
false;
2943 if( condition.
EvaluateFor( item,
nullptr,
static_cast<int>( aConstraint ), layer,
2946 matches.push_back( item );
2947 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2948 wxS(
"[ShowMatches] engine: match type=%d kiid=%s layer=%d" ),
2949 (
int) item->Type(), kiid.AsString(), (
int) layer );
2956 if( !matched && matches.size() == 0 && checkedItems <= 5 )
2958 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2959 wxS(
"[ShowMatches] engine: no-match sample type=%d kiid=%s layers=%s" ),
2960 (
int) item->Type(), kiid.AsString(), itemLayers.
FmtHex() );
2964 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2965 wxS(
"[ShowMatches] engine stats: total=%zu skipped=%zu noLayer=%zu checked=%zu" ),
2966 totalItems, skippedItems, noLayerItems, checkedItems );
2968 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine exit: total=%zu" ), matches.size() );
2975 std::vector<BOARD_ITEM*> matches;
2980 const bool requiresPairwise = aRule->m_Condition && aRule->m_Condition->RequiresPairItems();
2981 std::set<BOARD_ITEM*> matchedItems;
2983 if( std::shared_ptr<CONNECTIVITY_DATA> connectivity =
m_board->GetConnectivity() )
2985 if( std::shared_ptr<FROM_TO_CACHE> ftCache = connectivity->GetFromToCache() )
2994 SHOWMATCH_DOMAIN_SPEC domainSpec = getShowMatchDomainSpec( constraint.
m_Type );
2995 std::vector<BOARD_ITEM*> primaryItems = collectShowMatchCandidates(
m_board, domainSpec.primary );
2996 std::vector<BOARD_ITEM*> secondaryItems;
2998 if( domainSpec.hasSecondary )
2999 secondaryItems = collectShowMatchCandidates(
m_board, domainSpec.secondary );
3001 if( requiresPairwise )
3003 if( secondaryItems.empty() )
3005 for(
size_t ii = 0; ii < primaryItems.size(); ++ii )
3009 for(
size_t jj = ii + 1; jj < primaryItems.size(); ++jj )
3013 if( ruleMatchesPair( *aRule, itemA, itemB, constraint.
m_Type,
3016 matchedItems.insert( itemA );
3017 matchedItems.insert( itemB );
3028 if( itemA == itemB )
3031 if( ruleMatchesPair( *aRule, itemA, itemB, constraint.
m_Type,
3034 matchedItems.insert( itemA );
3035 matchedItems.insert( itemB );
3045 if( ruleMatchesUnary( *aRule, item, constraint.
m_Type, aReporter ? aReporter :
m_logReporter ) )
3047 matchedItems.insert( item );
3051 if( domainSpec.hasSecondary && domainSpec.secondaryUnary )
3055 if( ruleMatchesUnary( *aRule, item, constraint.
m_Type, aReporter ? aReporter :
m_logReporter ) )
3057 matchedItems.insert( item );
3064 matches.assign( matchedItems.begin(), matchedItems.end() );
3094 const PAD*
pad =
static_cast<const PAD*
>( aItem );
3109 *aSource = constraint.
GetName();
3143 if( it->first.m_uuid == aUuid )
3169 using CLEARANCE_MAP = std::unordered_map<DRC_OWN_CLEARANCE_CACHE_KEY, int>;
3173 std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>> itemsToProcess;
3174 size_t estimatedPads = 0;
3177 estimatedPads += footprint->Pads().size();
3179 itemsToProcess.reserve(
m_board->Tracks().size() + estimatedPads * 2 );
3186 itemsToProcess.emplace_back( track, layer );
3190 itemsToProcess.emplace_back( track, track->GetLayer() );
3196 for(
PAD*
pad : footprint->Pads() )
3199 itemsToProcess.emplace_back(
pad, layer );
3203 if( itemsToProcess.empty() )
3214 [
this](
size_t aStart,
size_t aEnd,
const std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>>& aItems )
3217 CLEARANCE_MAP localCache;
3219 for(
size_t i = aStart; i < aEnd; ++i )
3228 const PAD*
pad =
static_cast<const PAD*
>( item );
3247 auto results =
tp.submit_blocks( 0, itemsToProcess.size(),
3248 [&](
size_t aStart,
size_t aEnd ) -> CLEARANCE_MAP
3250 return processItems( aStart, aEnd, itemsToProcess );
3257 std::vector<CLEARANCE_MAP> collectedResults;
3258 collectedResults.reserve( results.size() );
3260 for(
size_t i = 0; i < results.size(); ++i )
3262 if( results[i].valid() )
3263 collectedResults.push_back( results[i].get() );
3270 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.
virtual bool IsOnLayer(PCB_LAYER_ID aLayer) const
Test to see if this object is on the given layer.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual bool IsOnCopperLayer() const
virtual bool HasHole() const
Information pertinent to a Pcbnew printed circuit board.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
const std::unordered_map< KIID, BOARD_ITEM * > & GetItemByIdCache() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
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)
std::vector< BOARD_ITEM * > GetItemsMatchingRule(const std::shared_ptr< DRC_RULE > &aRule, REPORTER *aReporter=nullptr)
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
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)
static bool IsNetADiffPair(BOARD *aBoard, const NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
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
bool HasUserDefinedPhysicalConstraint()
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 SetViolatingRule(DRC_RULE *aRule)
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
wxString GetExpression() const
bool EvaluateFor(const BOARD_ITEM *aItemA, const BOARD_ITEM *aItemB, int aConstraint, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
DRC_RULE_CONDITION * m_Condition
DRC_IMPLICIT_SOURCE GetImplicitSource() const
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 const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
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() const
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
const BOX2I GetBoundingBox() const override
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
bool IsComponentClassSelector(const wxString &aToken)
${Class:X} inside a DRC rule is a component-class selector consumed by testFootprintSelector(),...
@ 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
@ NET_CHAIN_LENGTH_CONSTRAINT
@ SOLDER_MASK_SLIVER_CONSTRAINT
@ NET_CHAIN_STUB_LENGTH_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ TRACK_SEGMENT_LENGTH_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ NET_CHAIN_RETURN_PATH_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::deque< FOOTPRINT * > FOOTPRINTS
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.
ZONE * implicitKeepoutZone
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
static const long long MM
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
constexpr KICAD_T BaseType(const KICAD_T aType)
Return the underlying type of the given type.
@ PCB_CONSTRAINT_T
class PCB_CONSTRAINT, a geometric constraint between board items
@ 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_TABLECELL_T
class PCB_TABLECELL, PCB_TEXTBOX for use in tables
@ 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_DIMENSION_T
class PCB_DIMENSION_BASE: abstract dimension meta-type
@ 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