50#define ERROR_LIMIT 199
51#define EXTENDED_ERROR_LIMIT 499
68 if( wxGetEnv( wxT(
"DRC_DEBUG" ), &valueStr ) )
70 int setLevel = wxAtoi( valueStr );
72 if( level <= setLevel )
73 printf(
"%-30s:%d | %s\n", function, line, (
const char *) msg.c_str() );
80 m_designSettings ( aSettings ),
82 m_drawingSheet( nullptr ),
83 m_schematicNetlist( nullptr ),
84 m_rulesValid( false ),
85 m_reportAllTrackErrors( false ),
86 m_testFootprints( false ),
87 m_reporter( nullptr ),
88 m_progressReporter( nullptr )
116 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
142 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
145 rule->m_Implicit =
true;
155 ReportAux( wxString::Format( wxT(
"Building implicit rules (per-item/class overrides, etc...)" ) ) );
165 rule->AddConstraint( widthConstraint );
169 rule->AddConstraint( connectionConstraint );
173 rule->AddConstraint( drillConstraint );
177 rule->AddConstraint( annulusConstraint );
181 rule->AddConstraint( diameterConstraint );
185 rule->AddConstraint( holeToHoleConstraint );
190 rule->AddConstraint( thermalSpokeCountConstraint );
196 rule->AddConstraint( silkClearanceConstraint );
202 rule->AddConstraint( silkTextHeightConstraint );
208 rule->AddConstraint( silkTextThicknessConstraint );
213 rule->AddConstraint( holeClearanceConstraint );
218 rule->AddConstraint( edgeClearanceConstraint );
223 rule->AddConstraint( courtyardClearanceConstraint );
227 std::shared_ptr<DRC_RULE> uViaRule =
createImplicitRule(
_(
"board setup micro-via constraints" ) );
233 uViaRule->AddConstraint( uViaDrillConstraint );
237 uViaRule->AddConstraint( uViaDiameterConstraint );
241 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
242 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
244 auto makeNetclassRules = [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
246 wxString ncName = nc->GetName();
249 ncName.Replace(
"'",
"\\'" );
251 if( nc->HasClearance() )
253 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
254 netclassRule->m_Name = wxString::Format(
255 _(
"netclass '%s'" ), nc->GetClearanceParent()->GetHumanReadableName() );
256 netclassRule->m_Implicit =
true;
258 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
260 netclassClearanceRules.push_back( netclassRule );
264 netclassRule->AddConstraint( constraint );
267 if( nc->HasTrackWidth() )
269 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
270 netclassRule->m_Name = wxString::Format(
271 _(
"netclass '%s'" ), nc->GetTrackWidthParent()->GetHumanReadableName() );
272 netclassRule->m_Implicit =
true;
274 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
276 netclassClearanceRules.push_back( netclassRule );
281 netclassRule->AddConstraint( constraint );
284 if( nc->HasDiffPairWidth() )
286 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
287 netclassRule->m_Name =
288 wxString::Format(
_(
"netclass '%s' (diff pair)" ),
289 nc->GetDiffPairWidthParent()->GetHumanReadableName() );
290 netclassRule->m_Implicit =
true;
292 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.inDiffPair('*')" ), ncName );
294 netclassItemSpecificRules.push_back( netclassRule );
298 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
299 netclassRule->AddConstraint( constraint );
302 if( nc->HasDiffPairGap() )
304 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
305 netclassRule->m_Name =
306 wxString::Format(
_(
"netclass '%s' (diff pair)" ),
307 nc->GetDiffPairGapParent()->GetHumanReadableName() );
308 netclassRule->m_Implicit =
true;
310 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
312 netclassItemSpecificRules.push_back( netclassRule );
317 netclassRule->AddConstraint( constraint );
320 if( nc->GetDiffPairGap() < nc->GetClearance() )
322 netclassRule = std::make_shared<DRC_RULE>();
323 netclassRule->m_Name =
324 wxString::Format(
_(
"netclass '%s' (diff pair)" ),
325 nc->GetDiffPairGapParent()->GetHumanReadableName() );
326 netclassRule->m_Implicit =
true;
328 expr = wxString::Format( wxT(
"A.NetClass == '%s' && AB.isCoupledDiffPair()" ),
331 netclassItemSpecificRules.push_back( netclassRule );
334 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
335 netclassRule->AddConstraint( min_clearanceConstraint );
339 if( nc->HasViaDiameter() )
341 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
342 netclassRule->m_Name = wxString::Format(
343 _(
"netclass '%s'" ), nc->GetViaDiameterParent()->GetHumanReadableName() );
344 netclassRule->m_Implicit =
true;
346 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ), ncName );
348 netclassItemSpecificRules.push_back( netclassRule );
353 netclassRule->AddConstraint( constraint );
356 if( nc->HasViaDrill() )
358 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
359 netclassRule->m_Name = wxString::Format(
360 _(
"netclass '%s'" ), nc->GetViaDrillParent()->GetHumanReadableName() );
361 netclassRule->m_Implicit =
true;
363 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ), ncName );
365 netclassItemSpecificRules.push_back( netclassRule );
370 netclassRule->AddConstraint( constraint );
373 if( nc->HasuViaDiameter() )
375 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
376 netclassRule->m_Name =
377 wxString::Format(
_(
"netclass '%s' (uvia)" ),
378 nc->GetuViaDiameterParent()->GetHumanReadableName() );
379 netclassRule->m_Implicit =
true;
381 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ), ncName );
383 netclassItemSpecificRules.push_back( netclassRule );
387 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
388 netclassRule->AddConstraint( constraint );
391 if( nc->HasuViaDrill() )
393 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
394 netclassRule->m_Name = wxString::Format(
395 _(
"netclass '%s' (uvia)" ), nc->GetuViaDrillParent()->GetHumanReadableName() );
396 netclassRule->m_Implicit =
true;
398 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ), ncName );
400 netclassItemSpecificRules.push_back( netclassRule );
405 netclassRule->AddConstraint( constraint );
410 makeNetclassRules( bds.
m_NetSettings->GetDefaultNetclass(),
true );
413 makeNetclassRules( netclass,
false );
415 for(
const auto& [
name, netclass] : bds.
m_NetSettings->GetCompositeNetclasses() )
416 makeNetclassRules( netclass,
false );
423 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
424 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
426 return lhs->m_Constraints[0].m_Value.Min()
427 < rhs->m_Constraints[0].m_Value.Min();
430 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
433 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
438 std::vector<ZONE*> keepoutZones;
443 keepoutZones.push_back( zone );
448 for(
ZONE* zone : footprint->Zones() )
451 keepoutZones.push_back( zone );
455 for(
ZONE* zone : keepoutZones )
457 wxString
name = zone->GetZoneName();
464 rule->m_ImplicitItemId = zone->m_Uuid;
466 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
467 zone->m_Uuid.AsString() ) );
469 rule->m_LayerCondition = zone->GetLayerSet();
471 int disallowFlags = 0;
473 if( zone->GetDoNotAllowTracks() )
476 if( zone->GetDoNotAllowVias() )
479 if( zone->GetDoNotAllowPads() )
482 if( zone->GetDoNotAllowCopperPour() )
485 if( zone->GetDoNotAllowFootprints() )
490 rule->AddConstraint( disallowConstraint );
493 ReportAux( wxString::Format( wxT(
"Building %d implicit netclass rules" ),
494 (
int) netclassClearanceRules.size() ) );
500 if( aPath.FileExists() )
502 std::vector<std::shared_ptr<DRC_RULE>> rules;
504 FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) );
515 for( std::shared_ptr<DRC_RULE>& rule : rules )
523 ReportAux( wxString::Format( wxT(
"Compiling Rules (%d rules): " ), (
int)
m_rules.size() ) );
525 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
529 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
531 condition = rule->m_Condition;
542 engineConstraint->
layerTest = rule->m_LayerCondition;
558 ReportAux( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
559 provider->SetDRCEngine(
this );
592 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
595 throw original_parse_error;
632 if( !cacheGenerator.
Run() )
639 ReportAux( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
641 if( !provider->RunTests( aUnits ) )
654#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
662 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
670 pad =
static_cast<const PAD*
>( a );
672 pad =
static_cast<const PAD*
>( b );
674 if(
pad &&
pad->GetAttribute() == PAD_ATTRIB::PTH )
680 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
708 const ZONE* zone =
nullptr;
709 const FOOTPRINT* parentFootprint =
nullptr;
716 pad =
static_cast<const PAD*
>( a );
718 zone =
static_cast<const ZONE*
>( a );
721 pad =
static_cast<const PAD*
>( b );
723 zone =
static_cast<const ZONE*
>( b );
726 parentFootprint =
pad->GetParentFootprint();
730 constraint.
m_Type = aConstraintType;
732 auto applyConstraint =
735 if( c->constraint.m_Value.HasMin() )
737 if( c->parentRule && c->parentRule->m_Implicit )
743 if( c->constraint.m_Value.HasOpt() )
746 if( c->constraint.m_Value.HasMax() )
747 constraint .m_Value.SetMax( c->constraint.m_Value.Max() );
760 if( aConstraintType ==
CLEARANCE_CONSTRAINT && ( ac || bc ) && !a_is_non_copper && !b_is_non_copper )
769 for(
int ii = 0; ii < 2; ++ii )
772 if( !footprints[ii] || !alt_items[ii] )
775 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
777 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
779 if( it != netcodes.end() )
782 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
783 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
785 constraint.
SetName(
_(
"net tie" ) );
795 int override_val = 0;
796 std::optional<int> overrideA;
797 std::optional<int> overrideB;
799 if( ac && !b_is_non_copper )
802 if( bc && !a_is_non_copper )
805 if( overrideA.has_value() || overrideB.has_value() )
809 if( overrideA.has_value() )
812 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
819 if( overrideB.has_value() )
822 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
826 if( overrideB > override_val )
834 if( override_val < m_designSettings->m_MinClearance )
837 msg =
_(
"board minimum" );
840 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
846 if( override_val < m_designSettings->m_HoleClearance )
849 msg =
_(
"board minimum hole" );
852 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
865 if(
pad &&
pad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED )
871 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
882 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
885 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
888 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
899 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
902 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
905 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
914 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
928 REPORT( wxString::Format(
_(
"Checking assertion \"%s\"." ),
929 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
931 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
934 REPORT(
_(
"Assertion passed." ) )
942 auto processConstraint =
945 bool implicit = c->parentRule && c->parentRule->m_Implicit;
949 switch( c->constraint.m_Type )
958 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
963 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
968 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
974 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
980 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
986 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
992 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
995 c->constraint.m_Value.Min() ) ) )
999 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1017 wxString min = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1018 wxString opt = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1019 wxString max = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1026 switch( c->constraint.m_Type )
1029 if( c->constraint.m_Value.HasOpt() )
1031 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1035 else if( c->constraint.m_Value.HasMin() )
1037 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1045 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1051 if( c->constraint.m_Value.HasOpt() )
1053 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1057 else if( c->constraint.m_Value.HasMin() )
1059 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1066 if( c->constraint.m_Value.HasOpt() )
1068 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1072 else if( c->constraint.m_Value.HasMin() )
1074 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1084 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1090 if( c->constraint.m_Value.HasOpt() )
1092 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1096 else if( c->constraint.m_Value.HasMin() )
1098 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1106 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1112 REPORT( wxString::Format(
_(
"Checking %s." ),
1118 if( c->constraint.m_Value.HasMin() )
1121 if( c->constraint.m_Value.HasOpt() )
1124 if( c->constraint.m_Value.HasMax() )
1127 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1138 REPORT( wxString::Format(
_(
"Checking %s." ),
1144 if( a_is_non_copper || b_is_non_copper )
1148 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1150 else if( a_is_non_copper )
1152 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1155 else if( b_is_non_copper )
1157 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1176 switch(
static_cast<const PCB_VIA*
>( a )->GetViaType() )
1199 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1207 default: mask = 0;
break;
1211 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1214 REPORT(
_(
"Keepout constraint not met." ) )
1216 REPORT(
_(
"Disallow constraint not met." ) )
1234 if( !( c->layerTest & itemLayers ).any() )
1238 REPORT(
_(
"Keepout layer(s) not matched." ) )
1240 else if( c->parentRule )
1242 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1243 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1247 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1259 REPORT(
_(
"Constraint layer not matched." ) )
1261 else if( c->parentRule )
1263 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1264 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1268 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1275 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1278 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1284 REPORT(
_(
"Unconditional constraint applied." ) )
1288 REPORT(
_(
"Unconditional rule applied." ) )
1293 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1297 applyConstraint( c );
1307 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1308 EscapeHTML( c->condition->GetExpression() ) ) )
1311 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1317 REPORT(
_(
"Constraint applied." ) )
1321 REPORT(
_(
"Rule applied." ) )
1326 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1330 applyConstraint( c );
1334 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1335 :
_(
"Condition not satisfied; rule ignored." ) )
1342 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1344 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1345 processConstraint( ruleset->at( ii ) );
1360 a = parentFootprint;
1362 b = parentFootprint;
1366 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1368 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1369 processConstraint( ruleset->at( ii ) );
1382 int clearance = global;
1383 bool needBlankLine =
true;
1392 needBlankLine =
false;
1395 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1399 if( localA > clearance )
1416 needBlankLine =
false;
1419 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1423 if( localB > clearance )
1433 if( !a_is_non_copper && !b_is_non_copper )
1438 needBlankLine =
false;
1441 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1444 if( clearance < m_designSettings->m_MinClearance )
1447 constraint.
SetName(
_(
"board minimum" ) );
1457 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1463 constraint.
SetName(
_(
"board minimum" ) );
1471 if(
pad && parentFootprint )
1475 if( local != ZONE_CONNECTION::INHERITED )
1478 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1483 constraint.
SetName(
_(
"footprint" ) );
1494 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1511 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
1528 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
1558 auto testAssertion =
1561 REPORT( wxString::Format(
_(
"Checking rule assertion \"%s\"." ),
1562 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1564 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1567 REPORT(
_(
"Assertion passed." ) )
1572 aFailureHandler( &c->constraint );
1576 auto processConstraint =
1580 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
1584 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1585 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1588 if( !c->condition || c->condition->GetExpression().IsEmpty() )
1590 REPORT(
_(
"Unconditional rule applied." ) )
1595 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1596 EscapeHTML( c->condition->GetExpression() ) ) )
1598 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1601 REPORT(
_(
"Rule applied." ) )
1606 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
1615 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1616 processConstraint( ruleset->at( ii ) );
1626 assert( error_code >= 0 && error_code <=
DRCE_LAST );
1634 static std::mutex globalLock;
1640 std::lock_guard<std::mutex> guard( globalLock );
1646 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
1647 aItem->GetViolatingTest()->GetName(),
1648 aItem->GetErrorMessage(),
1649 aItem->GetErrorCode() );
1651 DRC_RULE* rule = aItem->GetViolatingRule();
1654 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
1658 wxString violatingItemsStr = wxT(
"Violating items: " );
1660 m_reporter->
Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
1716 wxSafeYield(
nullptr,
true );
1745 int current = c->constraint.GetValue().Min();
1747 if( current > worst )
1750 aConstraint = c->constraint;
1761 std::set<int> distinctMinimums;
1766 distinctMinimums.emplace( c->constraint.GetValue().Min() );
1769 return distinctMinimums;
1775 wxString& aBaseDpName )
1780 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
1784 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
1788 else if( ch ==
'+' )
1790 aComplementNet = wxT(
"-" );
1793 else if( ch ==
'-' )
1795 aComplementNet = wxT(
"+" );
1798 else if( ch ==
'N' )
1800 aComplementNet = wxT(
"P" );
1803 else if ( ch ==
'P' )
1805 aComplementNet = wxT(
"N" );
1814 if( rv != 0 && count >= 1 )
1816 aBaseDpName = aNetName.Left( aNetName.Length() - count );
1817 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
1827 wxString
dummy, coupledNetName;
1863 if( parentFootprint && parentFootprint->
IsNetTie() )
1870 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
1872 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
1886 if(
name == prov->GetName() )
constexpr EDA_IU_SCALE pcbIUScale
constexpr EDA_IU_SCALE unityScale
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 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
int m_MinSilkTextThickness
bool Ignore(int aDRCErrorCode)
Return true if the DRC error code's severity is SEVERITY_IGNORE.
int GetDRCEpsilon() const
Return an epsilon which accounts for rounding errors, etc.
int m_ViasMinAnnularWidth
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual bool IsConnected() const
Returns information if the object is derived from BOARD_CONNECTED_ITEM.
FOOTPRINT * GetParentFootprint() const
virtual LSET GetLayerSet() const
Return a std::bitset of all layers on which the item physically resides.
virtual bool HasDrilledHole() const
virtual bool IsOnCopperLayer() const
Information pertinent to a Pcbnew printed circuit board.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
const ZONES & Zones() const
void SynchronizeNetsAndNetClasses(bool aResetTrackAndViaSizes)
Copy NETCLASS info to each NET, based on NET membership in a NETCLASS.
void IncrementTimeStamp()
const FOOTPRINTS & Footprints() const
BOARD_DESIGN_SETTINGS & GetDesignSettings() 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()
ZONE_CONNECTION m_ZoneConnection
void SetName(const wxString &aName)
DRC_RULE * GetParentRule() const
std::map< DRC_CONSTRAINT_T, std::vector< DRC_ENGINE_CONSTRAINT * > * > m_constraintMap
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
void ReportViolation(const std::shared_ptr< DRC_ITEM > &aItem, const VECTOR2I &aPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
void addRule(std::shared_ptr< DRC_RULE > &rule)
PROGRESS_REPORTER * m_progressReporter
void loadRules(const wxFileName &aPath)
Load and parse a rule set from an sexpr text file.
std::vector< DRC_TEST_PROVIDER * > m_testProviders
std::set< int > QueryDistinctConstraints(DRC_CONSTRAINT_T aConstraintId)
bool KeepRefreshing(bool aWait=false)
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)
void ReportAux(const wxString &aStr)
DRC_ENGINE(BOARD *aBoard=nullptr, BOARD_DESIGN_SETTINGS *aSettings=nullptr)
std::vector< int > m_errorLimits
bool IsErrorLimitExceeded(int error_code)
void ProcessAssertions(const BOARD_ITEM *a, std::function< void(const DRC_CONSTRAINT *)> aFailureHandler, REPORTER *aReporter=nullptr)
DRC_VIOLATION_HANDLER m_violationHandler
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
std::vector< std::shared_ptr< DRC_RULE > > m_rules
std::shared_ptr< DRC_RULE > createImplicitRule(const wxString &name)
static bool IsNetADiffPair(BOARD *aBoard, NETINFO_ITEM *aNet, int &aNetP, int &aNetN)
bool IsNetTieExclusion(int aTrackNetCode, PCB_LAYER_ID aTrackLayer, const VECTOR2I &aCollisionPos, BOARD_ITEM *aCollidingItem)
Check if the given collision between a track and another item occurs during the track's entry into a ...
bool QueryWorstConstraint(DRC_CONSTRAINT_T aRuleId, DRC_CONSTRAINT &aConstraint)
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)
BOARD_DESIGN_SETTINGS * m_designSettings
void Parse(std::vector< std::shared_ptr< DRC_RULE > > &aRules, REPORTER *aReporter)
bool Compile(REPORTER *aReporter, int aSourceLine=0, int aSourceOffset=0)
std::vector< DRC_TEST_PROVIDER * > GetTestProviders() const
static DRC_TEST_PROVIDER_REGISTRY & Instance()
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
void SetDRCEngine(DRC_ENGINE *engine)
virtual wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const
Return a user-visible description string of this item.
KICAD_T Type() const
Returns the type of object.
EDA_ITEM_FLAGS GetFlags() const
LSET is a set of PCB_LAYER_IDs.
static LSET FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static LSET BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
Handle the data for a net.
const wxString & GetNetname() 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)
virtual bool IsCancelled() const =0
virtual bool KeepRefreshing(bool aWait=false)=0
Update the UI (if any).
virtual void AdvancePhase()=0
Use the next available virtual zone of the dialog progress bar.
virtual void AdvanceProgress()=0
Increment the progress bar length (inside the current virtual zone).
virtual void SetCurrentProgress(double aProgress)=0
Set the progress value to aProgress (0..1).
virtual void SetMaxProgress(int aMaxProgress)=0
Fix the value that gives the 100 percent progress bar length (inside the current virtual zone).
A pure virtual class used to derive REPORTER objects from.
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)=0
Report a string with a given severity.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
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
int GetMinThickness() const
ZONE_CONNECTION GetPadConnection() const
int GetThermalReliefSpokeWidth() const
bool GetDoNotAllowFootprints() const
bool GetDoNotAllowCopperPour() const
bool HasKeepoutParametersSet() const
Accessor to determine if any keepout parameters are set.
int GetThermalReliefGap() const
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)
std::function< void(PCB_MARKER *aMarker)> DRC_CUSTOM_MARKER_HANDLER
@ DRC_DISALLOW_FOOTPRINTS
@ DRC_DISALLOW_MICRO_VIAS
@ ANNULAR_WIDTH_CONSTRAINT
@ COURTYARD_CLEARANCE_CONSTRAINT
@ VIA_DIAMETER_CONSTRAINT
@ ZONE_CONNECTION_CONSTRAINT
@ DIFF_PAIR_GAP_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ EDGE_CLEARANCE_CONSTRAINT
@ MIN_RESOLVED_SPOKES_CONSTRAINT
@ TEXT_THICKNESS_CONSTRAINT
@ PHYSICAL_HOLE_CLEARANCE_CONSTRAINT
@ THERMAL_SPOKE_WIDTH_CONSTRAINT
@ CONNECTION_WIDTH_CONSTRAINT
@ THERMAL_RELIEF_GAP_CONSTRAINT
@ MAX_UNCOUPLED_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ PHYSICAL_CLEARANCE_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
#define HOLE_PROXY
Indicates the BOARD_ITEM is a proxy for its hole.
static const wxChar * traceDrcProfile
Flag to enable DRC profile timing logging.
PCB_LAYER_ID
A quick note on layer IDs:
KICOMMON_API wxString MessageTextFromValue(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnits, double aValue, bool aAddUnitsText=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE)
A helper to convert the double length aValue to a string in inches, millimeters, or unscaled units.
std::vector< FAB_LAYER_COLOR > dummy
wxString EscapeHTML(const wxString &aString)
Return a new wxString escaped for embedding in HTML.
std::shared_ptr< DRC_RULE > parentRule
DRC_RULE_CONDITION * condition
DRC_CONSTRAINT constraint
A filename or source description, a problem input line, a line number, a byte offset,...
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ 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_FOOTPRINT_T
class FOOTPRINT, a footprint
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TABLE_T
class PCB_TABLE, table of PCB_TABLECELLs
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
wxString PrintZoneConnection(ZONE_CONNECTION aConnection)
ZONE_CONNECTION
How pads are covered by copper in zone.