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->GetDoNotAllowZoneFills() )
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() )
642 ReportAux( wxString::Format( wxT(
"Run DRC provider: '%s'" ), provider->GetName() ) );
644 if( !provider->RunTests( aUnits ) )
657#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } }
665 REPORT( wxString::Format(
_(
"Resolved zone connection type: %s." ),
673 pad =
static_cast<const PAD*
>( a );
675 pad =
static_cast<const PAD*
>( b );
677 if(
pad &&
pad->GetAttribute() == PAD_ATTRIB::PTH )
683 REPORT( wxString::Format(
_(
"Pad is not a through hole pad; connection will be: %s." ),
711 const ZONE* zone =
nullptr;
712 const FOOTPRINT* parentFootprint =
nullptr;
719 pad =
static_cast<const PAD*
>( a );
721 zone =
static_cast<const ZONE*
>( a );
724 pad =
static_cast<const PAD*
>( b );
726 zone =
static_cast<const ZONE*
>( b );
729 parentFootprint =
pad->GetParentFootprint();
733 constraint.
m_Type = aConstraintType;
735 auto applyConstraint =
738 if( c->constraint.m_Value.HasMin() )
740 if( c->parentRule && c->parentRule->m_Implicit )
746 if( c->constraint.m_Value.HasOpt() )
749 if( c->constraint.m_Value.HasMax() )
750 constraint .m_Value.SetMax( c->constraint.m_Value.Max() );
752 switch( c->constraint.m_Type )
785 && ( ( ( !ac ) ^ ( !bc ) )
788 || ( ( footprints[0] == footprints[1] )
791 && !b_is_non_copper )
798 for(
int ii = 0; ii < 2; ++ii )
801 if( !footprints[ii] || !alt_items[ii] )
804 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
806 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
808 if( it != netcodes.end() )
811 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
812 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
814 constraint.
SetName(
_(
"net tie" ) );
824 int override_val = 0;
825 std::optional<int> overrideA;
826 std::optional<int> overrideB;
828 if( ac && !b_is_non_copper )
831 if( bc && !a_is_non_copper )
834 if( overrideA.has_value() || overrideB.has_value() )
838 if( overrideA.has_value() )
841 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
848 if( overrideB.has_value() )
851 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
855 if( overrideB > override_val )
863 if( override_val < m_designSettings->m_MinClearance )
866 msg =
_(
"board minimum" );
869 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
875 if( override_val < m_designSettings->m_HoleClearance )
878 msg =
_(
"board minimum hole" );
881 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
894 if(
pad &&
pad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED )
900 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
911 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
914 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
917 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
928 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
931 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
934 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
943 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
957 REPORT( wxString::Format(
_(
"Checking assertion \"%s\"." ),
958 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
960 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
963 REPORT(
_(
"Assertion passed." ) )
971 auto processConstraint =
974 bool implicit = c->parentRule && c->parentRule->m_Implicit;
978 switch( c->constraint.m_Type )
987 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
992 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
997 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1003 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1009 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1015 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1021 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1024 c->constraint.m_Value.Min() ) ) )
1028 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1046 wxString min = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1047 wxString opt = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1048 wxString max = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1055 switch( c->constraint.m_Type )
1058 if( c->constraint.m_Value.HasOpt() )
1060 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1064 else if( c->constraint.m_Value.HasMin() )
1066 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1074 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1080 if( c->constraint.m_Value.HasOpt() )
1082 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1086 else if( c->constraint.m_Value.HasMin() )
1088 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1095 if( c->constraint.m_Value.HasOpt() )
1097 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1101 else if( c->constraint.m_Value.HasMin() )
1103 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1113 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1119 if( c->constraint.m_Value.HasOpt() )
1121 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1125 else if( c->constraint.m_Value.HasMin() )
1127 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1135 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1141 REPORT( wxString::Format(
_(
"Checking %s." ),
1147 if( c->constraint.m_Value.HasMin() )
1150 if( c->constraint.m_Value.HasOpt() )
1153 if( c->constraint.m_Value.HasMax() )
1156 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1167 REPORT( wxString::Format(
_(
"Checking %s." ),
1173 if( a_is_non_copper || b_is_non_copper )
1177 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1179 else if( a_is_non_copper )
1181 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1184 else if( b_is_non_copper )
1186 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1205 switch(
static_cast<const PCB_VIA*
>( a )->GetViaType() )
1228 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1236 default: mask = 0;
break;
1240 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1243 REPORT(
_(
"Keepout constraint not met." ) )
1245 REPORT(
_(
"Disallow constraint not met." ) )
1263 if( !( c->layerTest & itemLayers ).any() )
1267 REPORT(
_(
"Keepout layer(s) not matched." ) )
1269 else if( c->parentRule )
1271 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1272 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1276 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1288 REPORT(
_(
"Constraint layer not matched." ) )
1290 else if( c->parentRule )
1292 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1293 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1297 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1304 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1307 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1313 REPORT(
_(
"Unconditional constraint applied." ) )
1317 REPORT(
_(
"Unconditional rule applied." ) )
1322 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1326 applyConstraint( c );
1336 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1337 EscapeHTML( c->condition->GetExpression() ) ) )
1340 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1346 REPORT(
_(
"Constraint applied." ) )
1350 REPORT(
_(
"Rule applied." ) )
1355 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1359 applyConstraint( c );
1363 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1364 :
_(
"Condition not satisfied; rule ignored." ) )
1371 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1374 processConstraint( rule );
1389 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1393 a = parentFootprint;
1395 b = parentFootprint;
1399 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1402 processConstraint( rule );
1416 bool needBlankLine =
true;
1425 needBlankLine =
false;
1428 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1449 needBlankLine =
false;
1452 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1466 if( !a_is_non_copper && !b_is_non_copper )
1471 needBlankLine =
false;
1474 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1477 if( clearance < m_designSettings->m_MinClearance )
1480 constraint.
SetName(
_(
"board minimum" ) );
1490 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1496 constraint.
SetName(
_(
"board minimum" ) );
1504 if(
pad && parentFootprint )
1508 if( local != ZONE_CONNECTION::INHERITED )
1511 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1516 constraint.
SetName(
_(
"footprint" ) );
1527 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1544 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
1561 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
1591 auto testAssertion =
1594 REPORT( wxString::Format(
_(
"Checking rule assertion \"%s\"." ),
1595 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1597 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1600 REPORT(
_(
"Assertion passed." ) )
1605 aFailureHandler( &c->constraint );
1609 auto processConstraint =
1613 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
1617 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1618 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1621 if( !c->condition || c->condition->GetExpression().IsEmpty() )
1623 REPORT(
_(
"Unconditional rule applied." ) )
1628 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1629 EscapeHTML( c->condition->GetExpression() ) ) )
1631 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1634 REPORT(
_(
"Rule applied." ) )
1639 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
1648 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1649 processConstraint( ruleset->at( ii ) );
1659 assert( error_code >= 0 && error_code <=
DRCE_LAST );
1667 static std::mutex globalLock;
1673 std::lock_guard<std::mutex> guard( globalLock );
1679 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
1680 aItem->GetViolatingTest()->GetName(),
1681 aItem->GetErrorMessage(),
1682 aItem->GetErrorCode() );
1684 DRC_RULE* rule = aItem->GetViolatingRule();
1687 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
1691 wxString violatingItemsStr = wxT(
"Violating items: " );
1693 m_reporter->
Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
1749 wxSafeYield(
nullptr,
true );
1778 int current = c->constraint.GetValue().Min();
1780 if( current > worst )
1783 aConstraint = c->constraint;
1794 std::set<int> distinctMinimums;
1799 distinctMinimums.emplace( c->constraint.GetValue().Min() );
1802 return distinctMinimums;
1808 wxString& aBaseDpName )
1813 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
1817 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
1821 else if( ch ==
'+' )
1823 aComplementNet = wxT(
"-" );
1826 else if( ch ==
'-' )
1828 aComplementNet = wxT(
"+" );
1831 else if( ch ==
'N' )
1833 aComplementNet = wxT(
"P" );
1836 else if ( ch ==
'P' )
1838 aComplementNet = wxT(
"N" );
1847 if( rv != 0 && count >= 1 )
1849 aBaseDpName = aNetName.Left( aNetName.Length() - count );
1850 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
1860 wxString
dummy, coupledNetName;
1896 if( parentFootprint && parentFootprint->
IsNetTie() )
1903 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
1905 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
1919 if(
name == prov->GetName() )
constexpr EDA_IU_SCALE pcbIUScale
constexpr EDA_IU_SCALE unityScale
#define MAXIMUM_CLEARANCE
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
COMPONENT_CLASS_MANAGER & GetComponentClassManager()
Gets the component class manager.
void ForceComponentClassRecalculation() const
Forces the component class for all footprints to be recalculated.
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 HasKeepoutParametersSet() const
Accessor to determine if any keepout parameters are set.
bool GetDoNotAllowZoneFills() const
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.