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 )
118 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
144 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
147 rule->m_Implicit =
true;
157 ReportAux( wxString::Format( wxT(
"Building implicit rules (per-item/class overrides, etc...)" ) ) );
167 rule->AddConstraint( widthConstraint );
171 rule->AddConstraint( connectionConstraint );
175 rule->AddConstraint( drillConstraint );
179 rule->AddConstraint( annulusConstraint );
183 rule->AddConstraint( diameterConstraint );
187 rule->AddConstraint( holeToHoleConstraint );
192 rule->AddConstraint( thermalSpokeCountConstraint );
198 rule->AddConstraint( silkClearanceConstraint );
204 rule->AddConstraint( silkTextHeightConstraint );
210 rule->AddConstraint( silkTextThicknessConstraint );
215 rule->AddConstraint( holeClearanceConstraint );
220 rule->AddConstraint( edgeClearanceConstraint );
225 rule->AddConstraint( courtyardClearanceConstraint );
229 std::shared_ptr<DRC_RULE> uViaRule =
createImplicitRule(
_(
"board setup micro-via constraints" ) );
235 uViaRule->AddConstraint( uViaDrillConstraint );
239 uViaRule->AddConstraint( uViaDiameterConstraint );
243 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
244 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
246 auto makeNetclassRules =
247 [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
249 wxString ncName = nc->GetVariableSubstitutionName();
250 wxString friendlyName = nc->GetName();
253 ncName.Replace(
"'",
"\\'" );
255 if( nc->HasClearance())
257 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
258 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
259 nc->GetClearanceParent()->GetName() );
260 netclassRule->m_Implicit =
true;
262 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
264 netclassClearanceRules.push_back( netclassRule );
268 netclassRule->AddConstraint( constraint );
271 if( nc->HasTrackWidth() )
273 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
274 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
275 nc->GetTrackWidthParent()->GetName() );
276 netclassRule->m_Implicit =
true;
278 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
280 netclassClearanceRules.push_back( netclassRule );
285 netclassRule->AddConstraint( constraint );
288 if( nc->HasDiffPairWidth() )
290 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
291 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
292 nc->GetDiffPairWidthParent()->GetName() );
293 netclassRule->m_Implicit =
true;
295 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.inDiffPair('*')" ),
298 netclassItemSpecificRules.push_back( netclassRule );
302 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
303 netclassRule->AddConstraint( constraint );
306 if( nc->HasDiffPairGap() )
308 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
309 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
310 nc->GetDiffPairGapParent()->GetName() );
311 netclassRule->m_Implicit =
true;
313 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
315 netclassItemSpecificRules.push_back( netclassRule );
320 netclassRule->AddConstraint( constraint );
323 if( nc->GetDiffPairGap() < nc->GetClearance() )
325 netclassRule = std::make_shared<DRC_RULE>();
326 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
327 nc->GetDiffPairGapParent()->GetName() );
328 netclassRule->m_Implicit =
true;
330 expr = wxString::Format( wxT(
"A.NetClass == '%s' && AB.isCoupledDiffPair()" ),
333 netclassItemSpecificRules.push_back( netclassRule );
336 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
337 netclassRule->AddConstraint( min_clearanceConstraint );
341 if( nc->HasViaDiameter() )
343 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
344 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
345 nc->GetViaDiameterParent()->GetName() );
346 netclassRule->m_Implicit =
true;
348 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ),
351 netclassItemSpecificRules.push_back( netclassRule );
356 netclassRule->AddConstraint( constraint );
359 if( nc->HasViaDrill() )
361 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
362 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
363 nc->GetViaDrillParent()->GetName() );
364 netclassRule->m_Implicit =
true;
366 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ),
369 netclassItemSpecificRules.push_back( netclassRule );
374 netclassRule->AddConstraint( constraint );
377 if( nc->HasuViaDiameter() )
379 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
380 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
381 nc->GetuViaDiameterParent()->GetName() );
382 netclassRule->m_Implicit =
true;
384 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ),
387 netclassItemSpecificRules.push_back( netclassRule );
391 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
392 netclassRule->AddConstraint( constraint );
395 if( nc->HasuViaDrill() )
397 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
398 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
399 nc->GetuViaDrillParent()->GetName() );
400 netclassRule->m_Implicit =
true;
402 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ),
405 netclassItemSpecificRules.push_back( netclassRule );
410 netclassRule->AddConstraint( constraint );
415 makeNetclassRules( bds.
m_NetSettings->GetDefaultNetclass(),
true );
418 makeNetclassRules( netclass,
false );
420 for(
const auto& [
name, netclass] : bds.
m_NetSettings->GetCompositeNetclasses() )
421 makeNetclassRules( netclass,
false );
428 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
429 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
431 return lhs->m_Constraints[0].m_Value.Min()
432 < rhs->m_Constraints[0].m_Value.Min();
435 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
438 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
443 std::vector<ZONE*> keepoutZones;
448 keepoutZones.push_back( zone );
453 for(
ZONE* zone : footprint->Zones() )
456 keepoutZones.push_back( zone );
460 for(
ZONE* zone : keepoutZones )
462 wxString
name = zone->GetZoneName();
469 rule->m_ImplicitItemId = zone->m_Uuid;
471 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
472 zone->m_Uuid.AsString() ) );
474 rule->m_LayerCondition = zone->GetLayerSet();
476 int disallowFlags = 0;
478 if( zone->GetDoNotAllowTracks() )
481 if( zone->GetDoNotAllowVias() )
484 if( zone->GetDoNotAllowPads() )
487 if( zone->GetDoNotAllowCopperPour() )
490 if( zone->GetDoNotAllowFootprints() )
495 rule->AddConstraint( disallowConstraint );
498 ReportAux( wxString::Format( wxT(
"Building %d implicit netclass rules" ),
499 (
int) netclassClearanceRules.size() ) );
505 if( aPath.FileExists() )
507 std::vector<std::shared_ptr<DRC_RULE>> rules;
509 FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) );
520 for( std::shared_ptr<DRC_RULE>& rule : rules )
528 ReportAux( wxString::Format( wxT(
"Compiling Rules (%d rules): " ), (
int)
m_rules.size() ) );
530 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
534 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
536 condition = rule->m_Condition;
547 engineConstraint->
layerTest = rule->m_LayerCondition;
563 ReportAux( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
564 provider->SetDRCEngine(
this );
597 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
600 throw original_parse_error;
637 if( !cacheGenerator.
Run() )
644 ReportAux( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
645 provider->SetCommit( aCommit );
647 if( !provider->RunTests( aUnits ) )
660#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
668 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
676 pad =
static_cast<const PAD*
>( a );
678 pad =
static_cast<const PAD*
>( b );
680 if(
pad &&
pad->GetAttribute() == PAD_ATTRIB::PTH )
686 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
714 const ZONE* zone =
nullptr;
715 const FOOTPRINT* parentFootprint =
nullptr;
722 pad =
static_cast<const PAD*
>( a );
724 zone =
static_cast<const ZONE*
>( a );
727 pad =
static_cast<const PAD*
>( b );
729 zone =
static_cast<const ZONE*
>( b );
732 parentFootprint =
pad->GetParentFootprint();
736 constraint.
m_Type = aConstraintType;
738 auto applyConstraint =
741 if( c->constraint.m_Value.HasMin() )
743 if( c->parentRule && c->parentRule->m_Implicit )
749 if( c->constraint.m_Value.HasOpt() )
752 if( c->constraint.m_Value.HasMax() )
753 constraint .m_Value.SetMax( c->constraint.m_Value.Max() );
766 if( aConstraintType ==
CLEARANCE_CONSTRAINT && ( ac || bc ) && !a_is_non_copper && !b_is_non_copper )
775 for(
int ii = 0; ii < 2; ++ii )
778 if( !footprints[ii] || !alt_items[ii] )
781 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
783 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
785 if( it != netcodes.end() )
788 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
789 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
791 constraint.
SetName(
_(
"net tie" ) );
801 int override_val = 0;
802 std::optional<int> overrideA;
803 std::optional<int> overrideB;
805 if( ac && !b_is_non_copper )
808 if( bc && !a_is_non_copper )
811 if( overrideA.has_value() || overrideB.has_value() )
815 if( overrideA.has_value() )
818 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
825 if( overrideB.has_value() )
828 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
832 if( overrideB > override_val )
840 if( override_val < m_designSettings->m_MinClearance )
843 msg =
_(
"board minimum" );
846 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
852 if( override_val < m_designSettings->m_HoleClearance )
855 msg =
_(
"board minimum hole" );
858 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
871 if(
pad &&
pad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED )
877 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
888 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
891 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
894 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
905 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
908 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
911 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
920 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
934 REPORT( wxString::Format(
_(
"Checking assertion \"%s\"." ),
935 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
937 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
940 REPORT(
_(
"Assertion passed." ) )
948 auto processConstraint =
951 bool implicit = c->parentRule && c->parentRule->m_Implicit;
955 switch( c->constraint.m_Type )
964 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
969 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
974 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
980 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
986 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
992 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
998 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1001 c->constraint.m_Value.Min() ) ) )
1005 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1023 wxString min = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1024 wxString opt = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1025 wxString max = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1032 switch( c->constraint.m_Type )
1035 if( c->constraint.m_Value.HasOpt() )
1037 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1041 else if( c->constraint.m_Value.HasMin() )
1043 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1051 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1057 if( c->constraint.m_Value.HasOpt() )
1059 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1063 else if( c->constraint.m_Value.HasMin() )
1065 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1072 if( c->constraint.m_Value.HasOpt() )
1074 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1078 else if( c->constraint.m_Value.HasMin() )
1080 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1090 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1096 if( c->constraint.m_Value.HasOpt() )
1098 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1102 else if( c->constraint.m_Value.HasMin() )
1104 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1112 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1118 REPORT( wxString::Format(
_(
"Checking %s." ),
1124 if( c->constraint.m_Value.HasMin() )
1127 if( c->constraint.m_Value.HasOpt() )
1130 if( c->constraint.m_Value.HasMax() )
1133 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1144 REPORT( wxString::Format(
_(
"Checking %s." ),
1150 if( a_is_non_copper || b_is_non_copper )
1154 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1156 else if( a_is_non_copper )
1158 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1161 else if( b_is_non_copper )
1163 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1182 switch(
static_cast<const PCB_VIA*
>( a )->GetViaType() )
1205 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1213 default: mask = 0;
break;
1217 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1220 REPORT(
_(
"Keepout constraint not met." ) )
1222 REPORT(
_(
"Disallow constraint not met." ) )
1240 if( !( c->layerTest & itemLayers ).any() )
1244 REPORT(
_(
"Keepout layer(s) not matched." ) )
1246 else if( c->parentRule )
1248 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1249 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1253 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1265 REPORT(
_(
"Constraint layer not matched." ) )
1267 else if( c->parentRule )
1269 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1270 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1274 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1281 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1284 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1290 REPORT(
_(
"Unconditional constraint applied." ) )
1294 REPORT(
_(
"Unconditional rule applied." ) )
1299 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1303 applyConstraint( c );
1313 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1314 EscapeHTML( c->condition->GetExpression() ) ) )
1317 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1323 REPORT(
_(
"Constraint applied." ) )
1327 REPORT(
_(
"Rule applied." ) )
1332 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1336 applyConstraint( c );
1340 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1341 :
_(
"Condition not satisfied; rule ignored." ) )
1348 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1350 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1351 processConstraint( ruleset->at( ii ) );
1366 a = parentFootprint;
1368 b = parentFootprint;
1372 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1374 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1375 processConstraint( ruleset->at( ii ) );
1388 int clearance = global;
1389 bool needBlankLine =
true;
1398 needBlankLine =
false;
1401 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1405 if( localA > clearance )
1422 needBlankLine =
false;
1425 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1429 if( localB > clearance )
1439 if( !a_is_non_copper && !b_is_non_copper )
1444 needBlankLine =
false;
1447 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1450 if( clearance < m_designSettings->m_MinClearance )
1453 constraint.
SetName(
_(
"board minimum" ) );
1463 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1469 constraint.
SetName(
_(
"board minimum" ) );
1477 if(
pad && parentFootprint )
1481 if( local != ZONE_CONNECTION::INHERITED )
1484 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1489 constraint.
SetName(
_(
"footprint" ) );
1500 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1517 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
1534 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
1564 auto testAssertion =
1567 REPORT( wxString::Format(
_(
"Checking rule assertion \"%s\"." ),
1568 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1570 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1573 REPORT(
_(
"Assertion passed." ) )
1578 aFailureHandler( &c->constraint );
1582 auto processConstraint =
1586 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
1590 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1591 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1594 if( !c->condition || c->condition->GetExpression().IsEmpty() )
1596 REPORT(
_(
"Unconditional rule applied." ) )
1601 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1602 EscapeHTML( c->condition->GetExpression() ) ) )
1604 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1607 REPORT(
_(
"Rule applied." ) )
1612 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
1621 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1622 processConstraint( ruleset->at( ii ) );
1632 assert( error_code >= 0 && error_code <=
DRCE_LAST );
1640 static std::mutex globalLock;
1646 std::lock_guard<std::mutex> guard( globalLock );
1652 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
1653 aItem->GetViolatingTest()->GetName(),
1654 aItem->GetErrorMessage(),
1655 aItem->GetErrorCode() );
1657 DRC_RULE* rule = aItem->GetViolatingRule();
1660 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
1664 wxString violatingItemsStr = wxT(
"Violating items: " );
1666 m_reporter->
Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
1749 int current = c->constraint.GetValue().Min();
1751 if( current > worst )
1754 aConstraint = c->constraint;
1765 std::set<int> distinctMinimums;
1770 distinctMinimums.emplace( c->constraint.GetValue().Min() );
1773 return distinctMinimums;
1779 wxString& aBaseDpName )
1784 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
1788 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
1792 else if( ch ==
'+' )
1794 aComplementNet = wxT(
"-" );
1797 else if( ch ==
'-' )
1799 aComplementNet = wxT(
"+" );
1802 else if( ch ==
'N' )
1804 aComplementNet = wxT(
"P" );
1807 else if ( ch ==
'P' )
1809 aComplementNet = wxT(
"N" );
1818 if( rv != 0 && count >= 1 )
1820 aBaseDpName = aNetName.Left( aNetName.Length() - count );
1821 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
1831 wxString
dummy, coupledNetName;
1867 if( parentFootprint && parentFootprint->
IsNetTie() )
1874 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
1876 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
1890 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
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 ClearGraphicsHandler()
void RunTests(EDA_UNITS aUnits, bool aReportAllTrackErrors, bool aTestFootprints, BOARD_COMMIT *aCommit=nullptr)
Run the DRC tests.
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 ReportViolation(const std::shared_ptr< DRC_ITEM > &aItem, const VECTOR2I &aPos, int aMarkerLayer)
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)
@ 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.