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 )
787 && ( ( ( !ac ) ^ ( !bc ) )
790 || ( ( footprints[0] == footprints[1] )
793 && !b_is_non_copper )
800 for(
int ii = 0; ii < 2; ++ii )
803 if( !footprints[ii] || !alt_items[ii] )
806 const std::set<int>& netcodes = footprints[ii]->
GetNetTieCache( child_items[ii] );
808 auto it = netcodes.find( alt_items[ii]->GetNetCode() );
810 if( it != netcodes.end() )
813 REPORT( wxString::Format(
_(
"Net tie on %s; clearance: 0." ),
814 EscapeHTML( footprints[ii]->GetItemDescription(
this,
true ) ) ) )
816 constraint.
SetName(
_(
"net tie" ) );
826 int override_val = 0;
827 std::optional<int> overrideA;
828 std::optional<int> overrideB;
830 if( ac && !b_is_non_copper )
833 if( bc && !a_is_non_copper )
836 if( overrideA.has_value() || overrideB.has_value() )
840 if( overrideA.has_value() )
843 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
850 if( overrideB.has_value() )
853 REPORT( wxString::Format(
_(
"Local override on %s; clearance: %s." ),
857 if( overrideB > override_val )
865 if( override_val < m_designSettings->m_MinClearance )
868 msg =
_(
"board minimum" );
871 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
877 if( override_val < m_designSettings->m_HoleClearance )
880 msg =
_(
"board minimum hole" );
883 REPORT( wxString::Format(
_(
"Board minimum hole clearance: %s." ),
896 if(
pad &&
pad->GetLocalZoneConnection() != ZONE_CONNECTION::INHERITED )
902 REPORT( wxString::Format(
_(
"Local override on %s; zone connection: %s." ),
913 if(
pad &&
pad->GetLocalThermalGapOverride(
nullptr ) > 0 )
916 int gap_override =
pad->GetLocalThermalGapOverride( &msg );
919 REPORT( wxString::Format(
_(
"Local override on %s; thermal relief gap: %s." ),
930 if(
pad &&
pad->GetLocalSpokeWidthOverride(
nullptr ) > 0 )
933 int spoke_override =
pad->GetLocalSpokeWidthOverride( &msg );
936 REPORT( wxString::Format(
_(
"Local override on %s; thermal spoke width: %s." ),
945 REPORT( wxString::Format(
_(
"%s min thickness: %s." ),
959 REPORT( wxString::Format(
_(
"Checking assertion \"%s\"." ),
960 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
962 if( c->constraint.m_Test->EvaluateFor( a, b, c->constraint.m_Type, aLayer,
965 REPORT(
_(
"Assertion passed." ) )
973 auto processConstraint =
976 bool implicit = c->parentRule && c->parentRule->m_Implicit;
980 switch( c->constraint.m_Type )
989 REPORT( wxString::Format(
_(
"Checking %s clearance: %s." ),
994 REPORT( wxString::Format(
_(
"Checking %s creepage: %s." ),
999 REPORT( wxString::Format(
_(
"Checking %s max uncoupled length: %s." ),
1005 REPORT( wxString::Format(
_(
"Checking %s max skew: %s." ),
1011 REPORT( wxString::Format(
_(
"Checking %s gap: %s." ),
1017 REPORT( wxString::Format(
_(
"Checking %s thermal spoke width: %s." ),
1023 REPORT( wxString::Format(
_(
"Checking %s min spoke count: %s." ),
1026 c->constraint.m_Value.Min() ) ) )
1030 REPORT( wxString::Format(
_(
"Checking %s zone connection: %s." ),
1048 wxString min = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1049 wxString opt = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1050 wxString max = wxT(
"<i>" ) +
_(
"undefined" ) + wxT(
"</i>" );
1057 switch( c->constraint.m_Type )
1060 if( c->constraint.m_Value.HasOpt() )
1062 REPORT( wxString::Format(
_(
"Checking %s track width: opt %s." ),
1066 else if( c->constraint.m_Value.HasMin() )
1068 REPORT( wxString::Format(
_(
"Checking %s track width: min %s." ),
1076 REPORT( wxString::Format(
_(
"Checking %s annular width: min %s." ),
1082 if( c->constraint.m_Value.HasOpt() )
1084 REPORT( wxString::Format(
_(
"Checking %s via diameter: opt %s." ),
1088 else if( c->constraint.m_Value.HasMin() )
1090 REPORT( wxString::Format(
_(
"Checking %s via diameter: min %s." ),
1097 if( c->constraint.m_Value.HasOpt() )
1099 REPORT( wxString::Format(
_(
"Checking %s hole size: opt %s." ),
1103 else if( c->constraint.m_Value.HasMin() )
1105 REPORT( wxString::Format(
_(
"Checking %s hole size: min %s." ),
1115 REPORT( wxString::Format(
_(
"Checking %s: min %s." ),
1121 if( c->constraint.m_Value.HasOpt() )
1123 REPORT( wxString::Format(
_(
"Checking %s diff pair gap: opt %s." ),
1127 else if( c->constraint.m_Value.HasMin() )
1129 REPORT( wxString::Format(
_(
"Checking %s clearance: min %s." ),
1137 REPORT( wxString::Format(
_(
"Checking %s hole to hole: min %s." ),
1143 REPORT( wxString::Format(
_(
"Checking %s." ),
1149 if( c->constraint.m_Value.HasMin() )
1152 if( c->constraint.m_Value.HasOpt() )
1155 if( c->constraint.m_Value.HasMax() )
1158 REPORT( wxString::Format(
_(
"Checking %s: min %s; opt %s; max %s." ),
1169 REPORT( wxString::Format(
_(
"Checking %s." ),
1175 if( a_is_non_copper || b_is_non_copper )
1179 REPORT(
_(
"Netclass clearances apply only between copper items." ) )
1181 else if( a_is_non_copper )
1183 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1186 else if( b_is_non_copper )
1188 REPORT( wxString::Format(
_(
"%s contains no copper. Rule ignored." ),
1207 switch(
static_cast<const PCB_VIA*
>( a )->GetViaType() )
1230 if(
static_cast<const ZONE*
>( a )->IsTeardropArea() )
1238 default: mask = 0;
break;
1242 if( ( c->constraint.m_DisallowFlags & mask ) == 0 )
1245 REPORT(
_(
"Keepout constraint not met." ) )
1247 REPORT(
_(
"Disallow constraint not met." ) )
1265 if( !( c->layerTest & itemLayers ).any() )
1269 REPORT(
_(
"Keepout layer(s) not matched." ) )
1271 else if( c->parentRule )
1273 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1274 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1278 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1290 REPORT(
_(
"Constraint layer not matched." ) )
1292 else if( c->parentRule )
1294 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1295 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1299 REPORT(
_(
"Rule layer not matched; rule ignored." ) )
1306 REPORT( wxString::Format(
_(
"%s is not a drilled hole; rule ignored." ),
1309 else if( !c->condition || c->condition->GetExpression().IsEmpty() )
1315 REPORT(
_(
"Unconditional constraint applied." ) )
1319 REPORT(
_(
"Unconditional rule applied." ) )
1324 REPORT(
_(
"Unconditional rule applied; overrides previous constraints." ) )
1328 applyConstraint( c );
1338 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1339 EscapeHTML( c->condition->GetExpression() ) ) )
1342 if( c->condition->EvaluateFor( a, b, c->constraint.m_Type, aLayer, aReporter ) )
1348 REPORT(
_(
"Constraint applied." ) )
1352 REPORT(
_(
"Rule applied." ) )
1357 REPORT(
_(
"Rule applied; overrides previous constraints." ) )
1361 applyConstraint( c );
1365 REPORT( implicit ?
_(
"Membership not satisfied; constraint ignored." )
1366 :
_(
"Condition not satisfied; rule ignored." ) )
1373 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1376 processConstraint( rule );
1391 REPORT( wxString::Format(
_(
"Inheriting from parent: %s." ),
1395 a = parentFootprint;
1397 b = parentFootprint;
1401 std::vector<DRC_ENGINE_CONSTRAINT*>* ruleset =
m_constraintMap[ aConstraintType ];
1404 processConstraint( rule );
1418 bool needBlankLine =
true;
1427 needBlankLine =
false;
1430 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1451 needBlankLine =
false;
1454 REPORT( wxString::Format(
_(
"Local clearance on %s: %s." ),
1468 if( !a_is_non_copper && !b_is_non_copper )
1473 needBlankLine =
false;
1476 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1479 if( clearance < m_designSettings->m_MinClearance )
1482 constraint.
SetName(
_(
"board minimum" ) );
1492 REPORT( wxString::Format(
_(
"Board minimum clearance: %s." ),
1498 constraint.
SetName(
_(
"board minimum" ) );
1506 if(
pad && parentFootprint )
1510 if( local != ZONE_CONNECTION::INHERITED )
1513 REPORT( wxString::Format(
_(
"%s zone connection: %s." ),
1518 constraint.
SetName(
_(
"footprint" ) );
1529 REPORT( wxString::Format(
_(
"%s pad connection: %s." ),
1546 REPORT( wxString::Format(
_(
"%s thermal relief gap: %s." ),
1563 REPORT( wxString::Format(
_(
"%s thermal spoke width: %s." ),
1593 auto testAssertion =
1596 REPORT( wxString::Format(
_(
"Checking rule assertion \"%s\"." ),
1597 EscapeHTML( c->constraint.m_Test->GetExpression() ) ) )
1599 if( c->constraint.m_Test->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1602 REPORT(
_(
"Assertion passed." ) )
1607 aFailureHandler( &c->constraint );
1611 auto processConstraint =
1615 REPORT( wxString::Format(
_(
"Checking %s." ), c->constraint.GetName() ) )
1619 REPORT( wxString::Format(
_(
"Rule layer '%s' not matched; rule ignored." ),
1620 EscapeHTML( c->parentRule->m_LayerSource ) ) )
1623 if( !c->condition || c->condition->GetExpression().IsEmpty() )
1625 REPORT(
_(
"Unconditional rule applied." ) )
1630 REPORT( wxString::Format(
_(
"Checking rule condition \"%s\"." ),
1631 EscapeHTML( c->condition->GetExpression() ) ) )
1633 if( c->condition->EvaluateFor( a,
nullptr, c->constraint.m_Type,
1636 REPORT(
_(
"Rule applied." ) )
1641 REPORT(
_(
"Condition not satisfied; rule ignored." ) )
1650 for(
int ii = 0; ii < (int) ruleset->size(); ++ii )
1651 processConstraint( ruleset->at( ii ) );
1661 assert( error_code >= 0 && error_code <=
DRCE_LAST );
1669 static std::mutex globalLock;
1675 std::lock_guard<std::mutex> guard( globalLock );
1681 wxString msg = wxString::Format( wxT(
"Test '%s': %s (code %d)" ),
1682 aItem->GetViolatingTest()->GetName(),
1683 aItem->GetErrorMessage(),
1684 aItem->GetErrorCode() );
1686 DRC_RULE* rule = aItem->GetViolatingRule();
1689 msg += wxString::Format( wxT(
", violating rule: '%s'" ), rule->
m_Name );
1693 wxString violatingItemsStr = wxT(
"Violating items: " );
1695 m_reporter->
Report( wxString::Format( wxT(
" |- violating position (%d, %d)" ),
1751 wxSafeYield(
nullptr,
true );
1780 int current = c->constraint.GetValue().Min();
1782 if( current > worst )
1785 aConstraint = c->constraint;
1796 std::set<int> distinctMinimums;
1801 distinctMinimums.emplace( c->constraint.GetValue().Min() );
1804 return distinctMinimums;
1810 wxString& aBaseDpName )
1815 for(
auto it = aNetName.rbegin(); it != aNetName.rend() && rv == 0; ++it, ++count )
1819 if( ( ch >=
'0' && ch <=
'9' ) || ch ==
'_' )
1823 else if( ch ==
'+' )
1825 aComplementNet = wxT(
"-" );
1828 else if( ch ==
'-' )
1830 aComplementNet = wxT(
"+" );
1833 else if( ch ==
'N' )
1835 aComplementNet = wxT(
"P" );
1838 else if ( ch ==
'P' )
1840 aComplementNet = wxT(
"N" );
1849 if( rv != 0 && count >= 1 )
1851 aBaseDpName = aNetName.Left( aNetName.Length() - count );
1852 aComplementNet = wxString( aBaseDpName ) << aComplementNet << aNetName.Right( count - 1 );
1862 wxString
dummy, coupledNetName;
1898 if( parentFootprint && parentFootprint->
IsNetTie() )
1905 if( padToNetTieGroupMap[
pad->GetNumber() ] >= 0 && aTrackNetCode ==
pad->GetNetCode() )
1907 if(
pad->GetEffectiveShape( aTrackLayer )->Collide( aCollisionPos,
epsilon ) )
1921 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.
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
const LSET & GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
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)
void SetOptionsFromOther(const DRC_CONSTRAINT &aOther)
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 const LSET & FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static const 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)
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.