48#define ERROR_LIMIT 199
49#define EXTENDED_ERROR_LIMIT 499
56 if( wxGetEnv( wxT(
"DRC_DEBUG" ), &valueStr ) )
58 int setLevel = wxAtoi( valueStr );
60 if( level <= setLevel )
61 printf(
"%-30s:%d | %s\n", function, line, (
const char *) msg.c_str() );
68 m_designSettings ( aSettings ),
70 m_drawingSheet( nullptr ),
71 m_schematicNetlist( nullptr ),
72 m_rulesValid( false ),
73 m_reportAllTrackErrors( false ),
74 m_testFootprints( false ),
75 m_reporter( nullptr ),
76 m_progressReporter( nullptr )
106 const ZONE* zone =
static_cast<const ZONE*
>( aItem );
132 std::shared_ptr<DRC_RULE> rule = std::make_shared<DRC_RULE>();
135 rule->m_Implicit =
true;
145 ReportAux( wxString::Format( wxT(
"Building implicit rules (per-item/class overrides, etc...)" ) ) );
155 rule->AddConstraint( widthConstraint );
159 rule->AddConstraint( connectionConstraint );
163 rule->AddConstraint( drillConstraint );
167 rule->AddConstraint( annulusConstraint );
171 rule->AddConstraint( diameterConstraint );
175 rule->AddConstraint( holeToHoleConstraint );
180 rule->AddConstraint( thermalSpokeCountConstraint );
186 rule->AddConstraint( silkClearanceConstraint );
192 rule->AddConstraint( silkTextHeightConstraint );
198 rule->AddConstraint( silkTextThicknessConstraint );
203 rule->AddConstraint( holeClearanceConstraint );
208 rule->AddConstraint( edgeClearanceConstraint );
213 rule->AddConstraint( courtyardClearanceConstraint );
217 std::shared_ptr<DRC_RULE> uViaRule =
createImplicitRule(
_(
"board setup micro-via constraints" ) );
223 uViaRule->AddConstraint( uViaDrillConstraint );
227 uViaRule->AddConstraint( uViaDiameterConstraint );
231 std::vector<std::shared_ptr<DRC_RULE>> netclassClearanceRules;
232 std::vector<std::shared_ptr<DRC_RULE>> netclassItemSpecificRules;
234 auto makeNetclassRules =
235 [&](
const std::shared_ptr<NETCLASS>& nc,
bool isDefault )
237 wxString ncName = nc->GetVariableSubstitutionName();
238 wxString friendlyName = nc->GetName();
241 ncName.Replace(
"'",
"\\'" );
243 if( nc->HasClearance())
245 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
246 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
247 nc->GetClearanceParent()->GetName() );
248 netclassRule->m_Implicit =
true;
250 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
252 netclassClearanceRules.push_back( netclassRule );
256 netclassRule->AddConstraint( constraint );
259 if( nc->HasTrackWidth() )
261 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
262 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
263 nc->GetTrackWidthParent()->GetName() );
264 netclassRule->m_Implicit =
true;
266 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
268 netclassClearanceRules.push_back( netclassRule );
273 netclassRule->AddConstraint( constraint );
276 if( nc->HasDiffPairWidth() )
278 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
279 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
280 nc->GetDiffPairWidthParent()->GetName() );
281 netclassRule->m_Implicit =
true;
283 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.inDiffPair('*')" ),
286 netclassItemSpecificRules.push_back( netclassRule );
290 constraint.
Value().
SetOpt( nc->GetDiffPairWidth() );
291 netclassRule->AddConstraint( constraint );
294 if( nc->HasDiffPairGap() )
296 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
297 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
298 nc->GetDiffPairGapParent()->GetName() );
299 netclassRule->m_Implicit =
true;
301 expr = wxString::Format( wxT(
"A.NetClass == '%s'" ), ncName );
303 netclassItemSpecificRules.push_back( netclassRule );
308 netclassRule->AddConstraint( constraint );
311 if( nc->GetDiffPairGap() < nc->GetClearance() )
313 netclassRule = std::make_shared<DRC_RULE>();
314 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (diff pair)" ),
315 nc->GetDiffPairGapParent()->GetName() );
316 netclassRule->m_Implicit =
true;
318 expr = wxString::Format( wxT(
"A.NetClass == '%s' && AB.isCoupledDiffPair()" ),
321 netclassItemSpecificRules.push_back( netclassRule );
324 min_clearanceConstraint.
Value().
SetMin( nc->GetDiffPairGap() );
325 netclassRule->AddConstraint( min_clearanceConstraint );
329 if( nc->HasViaDiameter() )
331 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
332 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
333 nc->GetViaDiameterParent()->GetName() );
334 netclassRule->m_Implicit =
true;
336 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ),
339 netclassItemSpecificRules.push_back( netclassRule );
344 netclassRule->AddConstraint( constraint );
347 if( nc->HasViaDrill() )
349 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
350 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s'" ),
351 nc->GetViaDrillParent()->GetName() );
352 netclassRule->m_Implicit =
true;
354 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type != 'Micro'" ),
357 netclassItemSpecificRules.push_back( netclassRule );
362 netclassRule->AddConstraint( constraint );
365 if( nc->HasuViaDiameter() )
367 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
368 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
369 nc->GetuViaDiameterParent()->GetName() );
370 netclassRule->m_Implicit =
true;
372 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ),
375 netclassItemSpecificRules.push_back( netclassRule );
379 constraint.
Value().
SetMin( nc->GetuViaDiameter() );
380 netclassRule->AddConstraint( constraint );
383 if( nc->HasuViaDrill() )
385 std::shared_ptr<DRC_RULE> netclassRule = std::make_shared<DRC_RULE>();
386 netclassRule->m_Name = wxString::Format(
_(
"netclass '%s' (uvia)" ),
387 nc->GetuViaDrillParent()->GetName() );
388 netclassRule->m_Implicit =
true;
390 expr = wxString::Format( wxT(
"A.NetClass == '%s' && A.Via_Type == 'Micro'" ),
393 netclassItemSpecificRules.push_back( netclassRule );
398 netclassRule->AddConstraint( constraint );
403 makeNetclassRules( bds.
m_NetSettings->GetDefaultNetclass(),
true );
406 makeNetclassRules( netclass,
false );
408 for(
const auto& [
name, netclass] : bds.
m_NetSettings->GetCompositeNetclasses() )
409 makeNetclassRules( netclass,
false );
416 std::sort( netclassClearanceRules.begin(), netclassClearanceRules.end(),
417 [](
const std::shared_ptr<DRC_RULE>& lhs,
const std::shared_ptr<DRC_RULE>& rhs )
419 return lhs->m_Constraints[0].m_Value.Min()
420 < rhs->m_Constraints[0].m_Value.Min();
423 for( std::shared_ptr<DRC_RULE>& ncRule : netclassClearanceRules )
426 for( std::shared_ptr<DRC_RULE>& ncRule : netclassItemSpecificRules )
431 std::vector<ZONE*> keepoutZones;
436 keepoutZones.push_back( zone );
441 for(
ZONE* zone : footprint->Zones() )
444 keepoutZones.push_back( zone );
448 for(
ZONE* zone : keepoutZones )
450 wxString
name = zone->GetZoneName();
457 rule->m_ImplicitItemId = zone->m_Uuid;
459 rule->m_Condition =
new DRC_RULE_CONDITION( wxString::Format( wxT(
"A.intersectsArea('%s')" ),
460 zone->m_Uuid.AsString() ) );
462 rule->m_LayerCondition = zone->GetLayerSet();
464 int disallowFlags = 0;
466 if( zone->GetDoNotAllowTracks() )
469 if( zone->GetDoNotAllowVias() )
472 if( zone->GetDoNotAllowPads() )
475 if( zone->GetDoNotAllowCopperPour() )
478 if( zone->GetDoNotAllowFootprints() )
483 rule->AddConstraint( disallowConstraint );
486 ReportAux( wxString::Format( wxT(
"Building %d implicit netclass rules" ),
487 (
int) netclassClearanceRules.size() ) );
493 if( aPath.FileExists() )
495 std::vector<std::shared_ptr<DRC_RULE>> rules;
497 FILE* fp = wxFopen( aPath.GetFullPath(), wxT(
"rt" ) );
508 for( std::shared_ptr<DRC_RULE>& rule : rules )
516 ReportAux( wxString::Format( wxT(
"Compiling Rules (%d rules): " ), (
int)
m_rules.size() ) );
518 for( std::shared_ptr<DRC_RULE>& rule :
m_rules )
522 if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() )
524 condition = rule->m_Condition;
535 engineConstraint->
layerTest = rule->m_LayerCondition;
551 ReportAux( wxString::Format( wxT(
"Create DRC provider: '%s'" ), provider->GetName() ) );
552 provider->SetDRCEngine(
this );
585 wxFAIL_MSG( wxT(
"Compiling implicit rules failed." ) );
588 throw original_parse_error;
623 if( !cacheGenerator.
Run() )
630 ReportAux( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
631 provider->SetCommit( aCommit );
633 if( !provider->RunTests( aUnits ) )
643#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
651 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
659 pad =
static_cast<const PAD*
>( a );
661 pad =
static_cast<const PAD*
>( b );
663 if(
pad &&
pad->GetAttribute() == PAD_ATTRIB::PTH )
669 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
697 const ZONE* zone =
nullptr;
698 const FOOTPRINT* parentFootprint =
nullptr;
705 pad =
static_cast<const PAD*
>( a );
707 zone =
static_cast<const ZONE*
>( a );
710 pad =
static_cast<const PAD*
>( b );
712 zone =
static_cast<const ZONE*
>( b );
715 parentFootprint =
pad->GetParentFootprint();
719 constraint.
m_Type = aConstraintType;
721 auto applyConstraint =
724 if( c->constraint.m_Value.HasMin() )
726 if( c->parentRule && c->parentRule->m_Implicit )
732 if( c->constraint.m_Value.HasOpt() )
735 if( c->constraint.m_Value.HasMax() )
736 constraint .m_Value.SetMax( c->constraint.m_Value.Max() );
751 int override_val = 0;
752 std::optional<int> overrideA;
753 std::optional<int> overrideB;
755 if( ac && !b_is_non_copper )
758 if( bc && !a_is_non_copper )
761 if( overrideA.has_value() || overrideB.has_value() )
765 if( overrideA.has_value() )
768 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
775 if( overrideB.has_value() )
778 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
782 if( overrideB > override_val )
790 if( override_val < m_designSettings->m_MinClearance )
793 msg =
_(
"board minimum" );
796 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
802 if( override_val < m_designSettings->m_HoleClearance )
805 msg =
_(
"board minimum hole" );
808 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
821 if(
pad &&
pad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED )
827 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
838 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
841 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
844 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
855 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
858 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
861 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
870 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
884 REPORT( wxString::Format(
_(
"Checking assertion \"%s\"." ),
885 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
887 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
890 REPORT(
_(
"Assertion passed." ) )
898 auto processConstraint =
901 bool implicit = c->parentRule && c->parentRule->m_Implicit;
905 switch( c->constraint.m_Type )
914 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
919 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
924 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
930 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
936 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
942 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
948 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
951 c->constraint.m_Value.Min() ) ) )
955 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
973 wxString min = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
974 wxString opt = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
975 wxString max = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
982 switch( c->constraint.m_Type )
985 if( c->constraint.m_Value.HasOpt() )
987 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
991 else if( c->constraint.m_Value.HasMin() )
993 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1001 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1007 if( c->constraint.m_Value.HasOpt() )
1009 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1013 else if( c->constraint.m_Value.HasMin() )
1015 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1022 if( c->constraint.m_Value.HasOpt() )
1024 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1028 else if( c->constraint.m_Value.HasMin() )
1030 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1040 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1046 if( c->constraint.m_Value.HasOpt() )
1048 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1052 else if( c->constraint.m_Value.HasMin() )
1054 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1062 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1068 REPORT( wxString::Format(
_(
"Checking %s." ),
1074 if( c->constraint.m_Value.HasMin() )
1077 if( c->constraint.m_Value.HasOpt() )
1080 if( c->constraint.m_Value.HasMax() )
1083 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1094 REPORT( wxString::Format(
_(
"Checking %s." ),
1100 if( a_is_non_copper || b_is_non_copper )
1104 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1106 else if( a_is_non_copper )
1108 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1111 else if( b_is_non_copper )
1113 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1132 switch(
static_cast<const PCB_VIA*
>( a )->GetViaType() )
1155 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1163 default: mask = 0;
break;
1167 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1170 REPORT(
_(
"Keepout constraint not met." ) )
1172 REPORT(
_(
"Disallow constraint not met." ) )
1190 if( !( c->layerTest & itemLayers ).any() )
1194 REPORT(
_(
"Keepout layer(s) not matched." ) )
1196 else if( c->parentRule )
1198 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1199 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1203 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1215 REPORT(
_(
"Constraint layer not matched." ) )
1217 else if( c->parentRule )
1219 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1220 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1224 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1231 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1234 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1240 REPORT(
_(
"Unconditional constraint applied." ) )
1244 REPORT(
_(
"Unconditional rule applied." ) )
1249 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1253 applyConstraint( c );
1263 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1264 EscapeHTML( c->condition->GetExpression() ) ) )
1267 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1273 REPORT(
_(
"Constraint applied." ) )
1277 REPORT(
_(
"Rule applied." ) )
1282 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1286 applyConstraint( c );
1290 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1291 :
_(
"Condition not satisfied; rule ignored." ) )
1298 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1300 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1301 processConstraint( ruleset->at( ii ) );
1316 a = parentFootprint;
1318 b = parentFootprint;
1322 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1324 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1325 processConstraint( ruleset->at( ii ) );
1338 int clearance = global;
1339 bool needBlankLine =
true;
1348 needBlankLine =
false;
1351 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1355 if( localA > clearance )
1372 needBlankLine =
false;
1375 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1379 if( localB > clearance )
1389 if( !a_is_non_copper && !b_is_non_copper )
1394 needBlankLine =
false;
1397 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1400 if( clearance < m_designSettings->m_MinClearance )
1403 constraint.
SetName(
_(
"board minimum" ) );
1413 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1419 constraint.
SetName(
_(
"board minimum" ) );
1427 if(
pad && parentFootprint )
1431 if( local != ZONE_CONNECTION::INHERITED )
1434 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1439 constraint.
SetName(
_(
"footprint" ) );
1450 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1467 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
1484 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
1514 auto testAssertion =
1517 REPORT( wxString::Format(
_(
"Checking rule assertion \"%s\"." ),
1518 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1520 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1523 REPORT(
_(
"Assertion passed." ) )
1528 aFailureHandler( &c->constraint );
1532 auto processConstraint =
1536 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
1540 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1541 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1544 if( !c->condition || c->condition->GetExpression().IsEmpty() )
1546 REPORT(
_(
"Unconditional rule applied." ) )
1551 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1552 EscapeHTML( c->condition->GetExpression() ) ) )
1554 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1557 REPORT(
_(
"Rule applied." ) )
1562 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
1571 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1572 processConstraint( ruleset->at( ii ) );
1582 assert( error_code >= 0 && error_code <=
DRCE_LAST );
1590 static std::mutex globalLock;
1596 std::lock_guard<std::mutex> guard( globalLock );
1602 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
1603 aItem->GetViolatingTest()->GetName(),
1604 aItem->GetErrorMessage(),
1605 aItem->GetErrorCode() );
1607 DRC_RULE* rule = aItem->GetViolatingRule();
1610 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
1614 wxString violatingItemsStr = wxT(
"Violating items: " );
1616 m_reporter->
Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
1699 int current = c->constraint.GetValue().Min();
1701 if( current > worst )
1704 aConstraint = c->constraint;
1715 std::set<int> distinctMinimums;
1720 distinctMinimums.emplace( c->constraint.GetValue().Min() );
1723 return distinctMinimums;
1729 wxString& aBaseDpName )
1734 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
1738 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
1742 else if( ch ==
'+' )
1744 aComplementNet = wxT(
"-" );
1747 else if( ch ==
'-' )
1749 aComplementNet = wxT(
"+" );
1752 else if( ch ==
'N' )
1754 aComplementNet = wxT(
"P" );
1757 else if ( ch ==
'P' )
1759 aComplementNet = wxT(
"N" );
1768 if( rv != 0 && count >= 1 )
1770 aBaseDpName = aNetName.Left( aNetName.Length() - count );
1771 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
1781 wxString
dummy, coupledNetName;
1817 if( parentFootprint && parentFootprint->
IsNetTie() )
1824 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
1826 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
1840 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
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.
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.