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;
168 std::shared_ptr<DRC_RULE> rule =
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 =
245 uViaRule->AddConstraint( uViaDrillConstraint );
249 uViaRule->AddConstraint( uViaDiameterConstraint );
253 std::shared_ptr<DRC_RULE> barcodeRule =
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' (diff pair)" ),
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()
449 < rhs->m_Constraints[0].m_Value.Min();
452 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
455 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
459 auto addTuningSingleRule =
461 const wxString& aNetclassName )
466 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
468 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
471 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s'" ),
480 tuningRule->AddConstraint( constraint );
485 auto addTuningDifferentialRules =
492 std::shared_ptr<DRC_RULE> tuningRule = std::make_shared<DRC_RULE>();
494 tuningRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
497 expr = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
498 aNetclass->GetName(),
506 tuningRule->AddConstraint( constraint );
510 std::shared_ptr<DRC_RULE> tuningRule2 = std::make_shared<DRC_RULE>();
512 tuningRule2->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
515 expr2 = wxString::Format( wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && A.inDiffPair('*')" ),
516 aNetclass->GetName(),
524 tuningRule2->AddConstraint( constraint2 );
531 std::shared_ptr<DRC_RULE> diffPairClearanceRule = std::make_shared<DRC_RULE>();
533 diffPairClearanceRule->m_Name = wxString::Format(
_(
"tuning profile '%s'" ), aProfileName );
536 expr = wxString::Format(
537 wxT(
"A.hasExactNetclass('%s') && A.Layer == '%s' && AB.isCoupledDiffPair()" ),
543 diffPairClearanceRule->AddConstraint( min_clearanceConstraint );
545 addRule( diffPairClearanceRule );
551 std::shared_ptr<TUNING_PROFILES> tuningParams =
project->GetProjectFile().TuningProfileParameters();
553 auto addNetclassTuningProfileRules =
554 [&tuningParams, &addTuningSingleRule, &addTuningDifferentialRules](
NETCLASS* aNetclass )
556 if( aNetclass->HasTuningProfile() )
558 const wxString delayProfileName = aNetclass->GetTuningProfile();
559 const TUNING_PROFILE& profile = tuningParams->GetTuningProfile( delayProfileName );
567 addTuningSingleRule( entry, delayProfileName, aNetclass->GetName() );
569 addTuningDifferentialRules( entry, delayProfileName, aNetclass );
577 addNetclassTuningProfileRules( netclass.get() );
580 addNetclassTuningProfileRules( netclass.get() );
584 auto addKeepoutZoneRule =
594 wxString::Format(
_(
"keepout area of %s" ),
DescribeRef( parentFP->GetReference() ) ),
618 rule->m_ImplicitItemId = zone->
m_Uuid;
619 rule->m_ImplicitItem = zone;
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;
742 const auto& cache =
m_board->GetItemByIdCache();
743 auto it = cache.find( rule->m_ImplicitItemId );
745 if( it != cache.end() && it->second->Type() ==
PCB_ZONE_T )
749 ruleVec->push_back( engineConstraint );
761 if( c->parentRule && !c->parentRule->IsImplicit() )
770 && c->condition->HasGeometryDependentFunctions() )
787 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
789 provider->SetDRCEngine(
this );
825 throw original_parse_error;
842 m_logReporter->Report( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
844 provider->SetDRCEngine(
this );
900 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
903 throw original_parse_error;
940 if( !cacheGenerator.
Run() )
944 m_board->GetComponentClassManager().ForceComponentClassRecalculation();
946 int timestamp =
m_board->GetTimeStamp();
951 m_logReporter->Report( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
955 if( !provider->RunTests( aUnits ) )
958 providerTimer.
Stop();
960 provider->GetName(), providerTimer.
msecs() );
968 wxASSERT( timestamp ==
m_board->GetTimeStamp() );
972#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
980 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
988 pad =
static_cast<const PAD*
>( a );
990 pad =
static_cast<const PAD*
>( b );
998 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
1023 const PAD*
pad =
nullptr;
1024 const ZONE* zone =
nullptr;
1025 const FOOTPRINT* parentFootprint =
nullptr;
1035 pad =
static_cast<const PAD*
>( a );
1037 zone =
static_cast<const ZONE*
>( a );
1040 pad =
static_cast<const PAD*
>( b );
1042 zone =
static_cast<const ZONE*
>( b );
1045 parentFootprint =
pad->GetParentFootprint();
1049 constraint.
m_Type = aConstraintType;
1051 auto applyConstraint =
1054 if( c->constraint.m_Value.HasMin() )
1056 if( c->parentRule && c->parentRule->IsImplicit() )
1064 if( c->constraint.m_Value.HasOpt() )
1067 if( c->constraint.m_Value.HasMax() )
1070 switch( c->constraint.m_Type )
1105 && ( ( ( !ac ) ^ ( !bc ) )
1108 || ( ( footprints[0] == footprints[1] )
1109 && footprints[0] ) )
1111 && !b_is_non_copper )
1118 for(
int ii = 0; ii < 2; ++ii )
1121 if( !footprints[ii] || !alt_items[ii] )
1124 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
1126 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
1128 if( it != netcodes.end() )
1131 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
1132 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
1134 constraint.
SetName(
_(
"net tie" ) );
1144 int override_val = 0;
1145 std::optional<int> overrideA;
1146 std::optional<int> overrideB;
1148 if( ac && !b_is_non_copper )
1151 if( bc && !a_is_non_copper )
1154 if( overrideA.has_value() || overrideB.has_value() )
1158 if( overrideA.has_value() )
1161 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1168 if( overrideB.has_value() )
1171 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
1175 if( overrideB > override_val )
1183 if( override_val < m_designSettings->m_MinClearance )
1186 msg =
_(
"board minimum" );
1189 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1195 if( override_val < m_designSettings->m_HoleClearance )
1198 msg =
_(
"board minimum hole" );
1201 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
1220 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
1231 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
1234 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
1237 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
1248 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
1251 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
1254 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
1263 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
1275 std::optional<int>
override;
1279 override =
pad->GetLocalSolderMaskMargin();
1281 override =
static_cast<const PCB_SHAPE*
>( a )->GetLocalSolderMaskMargin();
1285 if( !
override.has_value() &&
pad )
1287 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1289 override = overrideFootprint->GetLocalSolderMaskMargin();
1290 overrideItem = overrideFootprint;
1297 REPORT( wxString::Format(
_(
"Local override on %s; solder mask expansion: %s." ),
1307 std::optional<int>
override;
1311 override =
pad->GetLocalSolderPasteMargin();
1313 if( !
override.has_value() &&
pad )
1315 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1317 override = overrideFootprint->GetLocalSolderPasteMargin();
1318 overrideItem = overrideFootprint;
1325 REPORT( wxString::Format(
_(
"Local override on %s; solder paste absolute clearance: %s." ),
1335 std::optional<double> overrideRatio;
1339 overrideRatio =
pad->GetLocalSolderPasteMarginRatio();
1341 if( !overrideRatio.has_value() &&
pad )
1343 if(
FOOTPRINT* overrideFootprint =
pad->GetParentFootprint() )
1345 overrideRatio = overrideFootprint->GetLocalSolderPasteMarginRatio();
1346 overrideItem = overrideFootprint;
1353 REPORT( wxString::Format(
_(
"Local override on %s; solder paste relative clearance: %s." ),
1362 auto testAssertion =
1365 REPORT( wxString::Format(
_(
"Checking assertion '%s'." ),
1366 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1368 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1369 REPORT(
_(
"Assertion passed." ) )
1379 std::unordered_map<wxString, bool> conditionCache;
1381 auto processConstraint =
1384 bool implicit = c->parentRule && c->parentRule->IsImplicit();
1388 switch( c->constraint.m_Type )
1397 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
1402 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
1407 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1413 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1419 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1425 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1431 REPORT( wxString::Format(
_(
"Checking %s solder mask expansion: %s." ),
1437 REPORT( wxString::Format(
_(
"Checking %s solder paste absolute clearance: %s." ),
1443 REPORT( wxString::Format(
_(
"Checking %s solder paste relative clearance: %s." ),
1449 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1455 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1476 switch( c->constraint.m_Type )
1479 if( c->constraint.m_Value.HasOpt() )
1481 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1485 else if( c->constraint.m_Value.HasMin() )
1487 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1495 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1501 if( c->constraint.m_Value.HasOpt() )
1503 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1507 else if( c->constraint.m_Value.HasMin() )
1509 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1516 if( c->constraint.m_Value.HasOpt() )
1518 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1522 else if( c->constraint.m_Value.HasMin() )
1524 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1534 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1540 if( c->constraint.m_Value.HasOpt() )
1542 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1546 else if( c->constraint.m_Value.HasMin() )
1548 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1556 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1562 REPORT( wxString::Format(
_(
"Checking %s." ),
1568 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1570 c->constraint.m_Value.HasMin()
1572 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1573 c->constraint.m_Value.HasOpt()
1575 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ),
1576 c->constraint.m_Value.HasMax()
1578 : wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" ) ) )
1584 REPORT( wxString::Format(
_(
"Checking %s." ),
1590 if( a_is_non_copper || b_is_non_copper )
1594 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1596 else if( a_is_non_copper )
1598 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1601 else if( b_is_non_copper )
1603 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1622 if(
via->IsMicroVia() )
1624 else if(
via->IsBlindVia() )
1626 else if(
via->IsBuriedVia() )
1648 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1656 default: mask = 0;
break;
1660 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1663 REPORT(
_(
"Keepout constraint not met." ) )
1665 REPORT(
_(
"Disallow constraint not met." ) )
1683 if( !( c->layerTest & itemLayers ).any() )
1687 REPORT(
_(
"Keepout layer(s) not matched." ) )
1689 else if( c->parentRule )
1691 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1692 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1696 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1703 if( (
IsPcbLayer( aLayer ) && !c->layerTest.test( aLayer ) )
1704 || (
m_board->GetEnabledLayers() & c->layerTest ).count() == 0 )
1708 REPORT(
_(
"Constraint layer not matched." ) )
1710 else if( c->parentRule )
1712 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1713 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1717 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1728 REPORT( wxString::Format(
_(
"%s does not have a hole; rule ignored." ),
1731 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1737 REPORT(
_(
"Unconditional constraint applied." ) )
1741 REPORT(
_(
"Unconditional rule applied." ) )
1746 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1750 applyConstraint( c );
1758 if( c->implicitKeepoutZone && !aReporter )
1761 BOX2I zoneBBox = c->implicitKeepoutZone->GetBoundingBox();
1773 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
1774 EscapeHTML( c->condition->GetExpression() ) ) )
1777 bool condMatched =
false;
1781 condMatched = c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
1786 const wxString& expr = c->condition->GetExpression();
1787 auto it = conditionCache.find( expr );
1789 if( it != conditionCache.end() )
1791 condMatched = it->second;
1795 condMatched = c->condition->EvaluateFor( a, b, c->constraint.m_Type,
1797 conditionCache[expr] = condMatched;
1807 REPORT(
_(
"Constraint applied." ) )
1811 REPORT(
_(
"Rule applied." ) )
1816 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1820 applyConstraint( c );
1824 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1825 :
_(
"Condition not satisfied; rule ignored." ) )
1836 && ( !b || !b_is_non_copper ) )
1861 if( !ncNameA.empty() || !ncNameB.empty() )
1865 if( !ncNameA.empty() )
1873 if( !ncNameB.empty() )
1895 processConstraint( rule );
1913 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1917 a = parentFootprint;
1919 b = parentFootprint;
1923 conditionCache.clear();
1930 processConstraint( rule );
1940 constraint.
SetName(
_(
"board setup" ) );
1947 constraint.
SetName(
_(
"board setup" ) );
1954 constraint.
SetName(
_(
"board setup" ) );
1967 bool needBlankLine =
true;
1976 needBlankLine =
false;
1979 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
2000 needBlankLine =
false;
2003 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
2017 if( !a_is_non_copper && !b_is_non_copper )
2022 needBlankLine =
false;
2025 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
2031 constraint.
SetName(
_(
"board minimum" ) );
2041 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
2047 constraint.
SetName(
_(
"board minimum" ) );
2055 if(
pad && parentFootprint )
2062 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
2067 constraint.
SetName(
_(
"footprint" ) );
2078 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
2095 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
2112 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
2177 auto testAssertion =
2180 REPORT( wxString::Format(
_(
"Checking rule assertion '%s'." ),
2181 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
2183 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2186 REPORT(
_(
"Assertion passed." ) )
2191 aFailureHandler( &c->constraint );
2195 auto processConstraint =
2199 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
2203 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
2204 EscapeHTML( c->parentRule->m_LayerSource ) ) )
2207 if( !c->condition || c->condition->GetExpression().IsEmpty() )
2209 REPORT(
_(
"Unconditional rule applied." ) )
2214 REPORT( wxString::Format(
_(
"Checking rule condition '%s'." ),
2215 EscapeHTML( c->condition->GetExpression() ) ) )
2217 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
2220 REPORT(
_(
"Rule applied." ) )
2225 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
2234 for(
int ii = 0; ii < (int) it->second->size(); ++ii )
2235 processConstraint( it->second->at( ii ) );
2245 assert( error_code >= 0 && error_code <=
DRCE_LAST );
2252 int aMarkerLayer,
const std::function<
void(
PCB_MARKER* )>& aPathGenerator )
2269 static std::mutex handlerLock;
2270 std::lock_guard<std::mutex> guard( handlerLock );
2276 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
2277 aItem->GetViolatingTest()->GetName(),
2278 aItem->GetErrorMessage(
false ),
2279 aItem->GetErrorCode() );
2281 DRC_RULE* rule = aItem->GetViolatingRule();
2284 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
2288 wxString violatingItemsStr = wxT(
"Violating items: " );
2290 m_logReporter->Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
2354 bool aUnconditionalOnly )
2363 if( aUnconditionalOnly && c->
condition )
2368 if( current > worst )
2404 std::set<int> distinctMinimums;
2413 return distinctMinimums;
2419 wxString& aBaseDpName )
2424 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
2428 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
2432 else if( ch ==
'+' )
2434 aComplementNet = wxT(
"-" );
2437 else if( ch ==
'-' )
2439 aComplementNet = wxT(
"+" );
2442 else if( ch ==
'N' )
2444 aComplementNet = wxT(
"P" );
2447 else if ( ch ==
'P' )
2449 aComplementNet = wxT(
"N" );
2458 if( rv != 0 && count >= 1 )
2460 aBaseDpName = aNetName.Left( aNetName.Length() - count );
2461 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
2471 wxString
dummy, coupledNetName;
2507 if( parentFootprint && parentFootprint->
IsNetTie() )
2514 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
2516 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
2528enum class SHOWMATCH_DOMAIN
2535 MASK_EXPANSION_ITEMS,
2548struct SHOWMATCH_DOMAIN_SPEC
2550 SHOWMATCH_DOMAIN primary;
2551 SHOWMATCH_DOMAIN secondary = SHOWMATCH_DOMAIN::ALL_ITEMS;
2552 bool hasSecondary =
false;
2553 bool secondaryUnary =
false;
2557bool isShowMatchSkippable(
const BOARD_ITEM* aItem )
2559 switch( aItem->
Type() )
2565 default:
return false;
2570bool matchesShowMatchDomain(
const BOARD_ITEM* aItem, SHOWMATCH_DOMAIN aDomain )
2572 if( !aItem || isShowMatchSkippable( aItem ) )
2577 case SHOWMATCH_DOMAIN::ALL_ITEMS:
return true;
2581 case SHOWMATCH_DOMAIN::EDGE_ITEMS:
2587 const PAD*
pad =
static_cast<const PAD*
>( aItem );
2595 case SHOWMATCH_DOMAIN::HOLE_ITEMS:
return aItem->
HasHole();
2597 case SHOWMATCH_DOMAIN::MASK_EXPANSION_ITEMS:
2598 switch( aItem->
Type() )
2607 default:
return false;
2612 case SHOWMATCH_DOMAIN::PADS:
return aItem->
Type() ==
PCB_PAD_T;
2618 case SHOWMATCH_DOMAIN::ROUTING_ITEMS:
2619 switch( aItem->
Type() )
2626 default:
return false;
2631 case SHOWMATCH_DOMAIN::SILK_TARGET_ITEMS:
2638 case SHOWMATCH_DOMAIN::TEXT_ITEMS:
2642 case SHOWMATCH_DOMAIN::VIAS:
return aItem->
Type() ==
PCB_VIA_T;
2649SHOWMATCH_DOMAIN_SPEC getShowMatchDomainSpec(
DRC_CONSTRAINT_T aConstraint )
2651 switch( aConstraint )
2668 return { SHOWMATCH_DOMAIN::SILK_ITEMS, SHOWMATCH_DOMAIN::SILK_TARGET_ITEMS,
true,
false };
2700 default:
return { SHOWMATCH_DOMAIN::ALL_ITEMS };
2705std::vector<BOARD_ITEM*> collectShowMatchCandidates(
BOARD* aBoard, SHOWMATCH_DOMAIN aDomain )
2707 std::vector<BOARD_ITEM*> items;
2714 if( matchesShowMatchDomain( item, aDomain ) )
2715 items.push_back( item );
2722std::vector<PCB_LAYER_ID> getShowMatchLayers(
const BOARD_ITEM* aItem )
2724 std::vector<PCB_LAYER_ID> layers;
2726 switch( aItem->
Type() )
2728 case PCB_PAD_T: layers =
static_cast<const PAD*
>( aItem )->Padstack().UniqueLayers();
break;
2730 case PCB_VIA_T: layers =
static_cast<const PCB_VIA*
>( aItem )->Padstack().UniqueLayers();
break;
2734 layers.push_back( layer );
2739 if( layers.empty() )
2749 bool testedLayer =
false;
2751 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItem ) )
2776std::vector<PCB_LAYER_ID> getShowMatchPairLayers(
const DRC_RULE& aRule,
const BOARD_ITEM* aItemA,
2779 std::vector<PCB_LAYER_ID> layers;
2780 std::set<int> seenLayers;
2787 if( seenLayers.insert(
static_cast<int>( aLayer ) ).second )
2788 layers.push_back( aLayer );
2791 switch( aConstraint )
2794 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemA ) )
2802 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemA ) )
2805 for(
PCB_LAYER_ID layer : getShowMatchLayers( aItemB ) )
2811 if( layers.empty() )
2821 for(
PCB_LAYER_ID layer : getShowMatchPairLayers( aRule, aItemA, aItemB, aConstraint ) )
2839 if(
name == prov->GetName() )
2851 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2852 wxS(
"[ShowMatches] engine enter: expr='%s', constraint=%d" ), aExpression, (
int) aConstraint );
2853 std::vector<BOARD_ITEM*> matches;
2862 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine: compile failed" ) );
2869 if(
auto connectivity =
m_board->GetConnectivity() )
2871 if(
auto ftCache = connectivity->GetFromToCache() )
2876 size_t totalItems = 0;
2877 size_t skippedItems = 0;
2878 size_t noLayerItems = 0;
2879 size_t checkedItems = 0;
2881 for(
auto& [kiid, item] :
m_board->GetItemByIdCache() )
2886 switch( item->Type() )
2898 LSET itemLayers = item->GetLayerSet();
2900 if( itemLayers.none() )
2907 bool matched =
false;
2911 if( condition.
EvaluateFor( item,
nullptr,
static_cast<int>( aConstraint ), layer,
2914 matches.push_back( item );
2915 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2916 wxS(
"[ShowMatches] engine: match type=%d kiid=%s layer=%d" ),
2917 (
int) item->Type(), kiid.AsString(), (
int) layer );
2924 if( !matched && matches.size() == 0 && checkedItems <= 5 )
2926 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2927 wxS(
"[ShowMatches] engine: no-match sample type=%d kiid=%s layers=%s" ),
2928 (
int) item->Type(), kiid.AsString(), itemLayers.
FmtHex() );
2932 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ),
2933 wxS(
"[ShowMatches] engine stats: total=%zu skipped=%zu noLayer=%zu checked=%zu" ),
2934 totalItems, skippedItems, noLayerItems, checkedItems );
2936 wxLogTrace( wxS(
"KI_TRACE_DRC_RULE_EDITOR" ), wxS(
"[ShowMatches] engine exit: total=%zu" ), matches.size() );
2943 std::vector<BOARD_ITEM*> matches;
2948 const wxString condition = aRule->m_Condition ? aRule->m_Condition->GetExpression() : wxString();
2949 const bool requiresPairwise = condition.Contains( wxS(
"B." ) );
2950 std::set<BOARD_ITEM*> matchedItems;
2952 if(
auto connectivity =
m_board->GetConnectivity() )
2954 if(
auto ftCache = connectivity->GetFromToCache() )
2963 SHOWMATCH_DOMAIN_SPEC domainSpec = getShowMatchDomainSpec( constraint.
m_Type );
2964 std::vector<BOARD_ITEM*> primaryItems = collectShowMatchCandidates(
m_board, domainSpec.primary );
2965 std::vector<BOARD_ITEM*> secondaryItems;
2967 if( domainSpec.hasSecondary )
2968 secondaryItems = collectShowMatchCandidates(
m_board, domainSpec.secondary );
2970 if( requiresPairwise )
2972 if( secondaryItems.empty() )
2974 for(
size_t ii = 0; ii < primaryItems.size(); ++ii )
2978 for(
size_t jj = ii + 1; jj < primaryItems.size(); ++jj )
2982 if( ruleMatchesPair( *aRule, itemA, itemB, constraint.
m_Type,
2985 matchedItems.insert( itemA );
2986 matchedItems.insert( itemB );
2997 if( itemA == itemB )
3000 if( ruleMatchesPair( *aRule, itemA, itemB, constraint.
m_Type,
3003 matchedItems.insert( itemA );
3004 matchedItems.insert( itemB );
3014 if( ruleMatchesUnary( *aRule, item, constraint.
m_Type, aReporter ? aReporter :
m_logReporter ) )
3016 matchedItems.insert( item );
3020 if( domainSpec.hasSecondary && domainSpec.secondaryUnary )
3024 if( ruleMatchesUnary( *aRule, item, constraint.
m_Type, aReporter ? aReporter :
m_logReporter ) )
3026 matchedItems.insert( item );
3033 matches.assign( matchedItems.begin(), matchedItems.end() );
3063 const PAD*
pad =
static_cast<const PAD*
>( aItem );
3078 *aSource = constraint.
GetName();
3112 if( it->first.m_uuid == aUuid )
3138 using CLEARANCE_MAP = std::unordered_map<DRC_OWN_CLEARANCE_CACHE_KEY, int>;
3142 std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>> itemsToProcess;
3143 size_t estimatedPads = 0;
3146 estimatedPads += footprint->Pads().size();
3148 itemsToProcess.reserve(
m_board->Tracks().size() + estimatedPads * 2 );
3155 itemsToProcess.emplace_back( track, layer );
3159 itemsToProcess.emplace_back( track, track->GetLayer() );
3165 for(
PAD*
pad : footprint->Pads() )
3168 itemsToProcess.emplace_back(
pad, layer );
3172 if( itemsToProcess.empty() )
3182 auto processItems = [
this](
size_t aStart,
size_t aEnd,
3183 const std::vector<std::pair<const BOARD_ITEM*, PCB_LAYER_ID>>& aItems )
3186 CLEARANCE_MAP localCache;
3188 for(
size_t i = aStart; i < aEnd; ++i )
3197 const PAD*
pad =
static_cast<const PAD*
>( item );
3216 auto results =
tp.submit_blocks( 0, itemsToProcess.size(),
3217 [&](
size_t aStart,
size_t aEnd ) -> CLEARANCE_MAP
3219 return processItems( aStart, aEnd, itemsToProcess );
3226 std::vector<CLEARANCE_MAP> collectedResults;
3227 collectedResults.reserve( results.size() );
3229 for(
size_t i = 0; i < results.size(); ++i )
3231 if( results[i].valid() )
3232 collectedResults.push_back( results[i].get() );
3239 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)
bool EvaluateFor(const BOARD_ITEM *aItemA, const BOARD_ITEM *aItemB, int aConstraint, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
DRC_RULE_CONDITION * m_Condition
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
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
@ 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_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