Sort synthetic netclass rules by min clearance.
This way when 'A' and 'B' have different netclasses the largest will fire (rather than just a random one of the two). Fixes https://gitlab.com/kicad/code/kicad/issues/5926
This commit is contained in:
parent
38cef95da9
commit
6550e01318
|
@ -179,37 +179,32 @@ void DRC_ENGINE::loadImplicitRules()
|
|||
|
||||
// 3) per-netclass rules
|
||||
|
||||
int ruleCount = 0;
|
||||
std::vector<DRC_RULE*> netclassRules;
|
||||
|
||||
auto makeNetclassRule =
|
||||
[&]( const NETCLASSPTR& nc, bool isDefault )
|
||||
[&]( const NETCLASSPTR& netclass, bool isDefault )
|
||||
{
|
||||
wxString className = nc->GetName();
|
||||
wxString expr;
|
||||
// Only add rules for netclass clearances which are larger than board minimums.
|
||||
// That way board minimums will still enforce a global minimum.
|
||||
|
||||
if( !isDefault )
|
||||
if( netclass->GetClearance() > bds.m_MinClearance )
|
||||
{
|
||||
expr = wxString::Format( "A.NetClass == '%s' || B.NetClass == '%s'",
|
||||
className, className );
|
||||
}
|
||||
DRC_RULE* rule = new DRC_RULE;
|
||||
wxString name = netclass->GetName();
|
||||
|
||||
DRC_RULE_CONDITION* inNetclassCondition = new DRC_RULE_CONDITION ( expr );
|
||||
DRC_RULE* nc_rule = createImplicitRule( wxString::Format( _( "netclass '%s'" ),
|
||||
className ));
|
||||
rule->m_Name = wxString::Format( _( "netclass '%s'" ), name );
|
||||
rule->m_Implicit = true;
|
||||
|
||||
nc_rule->m_Condition = inNetclassCondition;
|
||||
wxString expr = wxString::Format( "A.NetClass == '%s'", name );
|
||||
DRC_RULE_CONDITION* condition = new DRC_RULE_CONDITION( expr );
|
||||
|
||||
// Only add netclass clearances if they're larger than board minimums. That way
|
||||
// board minimums will still enforce a global minimum.
|
||||
rule->m_Condition = condition;
|
||||
netclassRules.push_back( rule );
|
||||
|
||||
if( nc->GetClearance() > bds.m_MinClearance )
|
||||
{
|
||||
DRC_CONSTRAINT ncClearanceConstraint( DRC_CONSTRAINT_TYPE_CLEARANCE );
|
||||
ncClearanceConstraint.Value().SetMin( nc->GetClearance() );
|
||||
nc_rule->AddConstraint( ncClearanceConstraint );
|
||||
ncClearanceConstraint.Value().SetMin( netclass->GetClearance() );
|
||||
rule->AddConstraint( ncClearanceConstraint );
|
||||
}
|
||||
|
||||
ruleCount++;
|
||||
};
|
||||
|
||||
m_board->SynchronizeNetsAndNetClasses();
|
||||
|
@ -218,7 +213,20 @@ void DRC_ENGINE::loadImplicitRules()
|
|||
for( const std::pair<const wxString, NETCLASSPTR>& netclass : bds.GetNetClasses() )
|
||||
makeNetclassRule( netclass.second, false );
|
||||
|
||||
ReportAux( wxString::Format( "Building %d implicit netclass rules", ruleCount ) );
|
||||
// These have to be sorted by min clearance so the right one fires if 'A' and 'B' belong
|
||||
// to two different netclasses.
|
||||
|
||||
std::sort( netclassRules.begin(), netclassRules.end(),
|
||||
[]( DRC_RULE* lhs, DRC_RULE* rhs )
|
||||
{
|
||||
return lhs->m_Constraints[0].m_Value.Min()
|
||||
< rhs->m_Constraints[0].m_Value.Min();
|
||||
} );
|
||||
|
||||
for( DRC_RULE* netclassRule : netclassRules )
|
||||
addRule( netclassRule );
|
||||
|
||||
ReportAux( wxString::Format( "Building %d implicit netclass rules", netclassRules.size() ) );
|
||||
}
|
||||
|
||||
static wxString formatConstraint( const DRC_CONSTRAINT& constraint )
|
||||
|
|
|
@ -271,12 +271,24 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
else
|
||||
{
|
||||
auto getItemDescription =
|
||||
[&]( BOARD_ITEM* aItem )
|
||||
{
|
||||
wxString s = aItem->GetSelectMenuText( r->GetUnits() );
|
||||
|
||||
if( auto* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
|
||||
s += wxString::Format( _( " [netclass %s]" ), cItem->GetNetClassName() );
|
||||
|
||||
return s;
|
||||
};
|
||||
|
||||
r->Report( _( "<h7>Clearance resolution for:</h7>" ) );
|
||||
|
||||
r->Report( wxString::Format( _( "<ul><li>Layer %s</li><li>%s</li><li>%s</li></ul>" ),
|
||||
r->Report( wxString::Format( wxT( "<ul><li>%s %s</li><li>%s</li><li>%s</li></ul>" ),
|
||||
_( "Layer" ),
|
||||
m_frame->GetBoard()->GetLayerName( layer ),
|
||||
a->GetSelectMenuText( r->GetUnits() ),
|
||||
b->GetSelectMenuText( r->GetUnits() ) ) );
|
||||
getItemDescription( a ),
|
||||
getItemDescription( b ) ) );
|
||||
|
||||
BOARD_CONNECTED_ITEM* ac = dynamic_cast<BOARD_CONNECTED_ITEM*>( a );
|
||||
BOARD_CONNECTED_ITEM* bc = dynamic_cast<BOARD_CONNECTED_ITEM*>( b );
|
||||
|
|
Loading…
Reference in New Issue