diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index a2d30de54f..b6b087677f 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -179,37 +179,32 @@ void DRC_ENGINE::loadImplicitRules() // 3) per-netclass rules - int ruleCount = 0; + std::vector 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& 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 ) diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index 91b4165795..ca913d91a6 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -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( aItem ) ) + s += wxString::Format( _( " [netclass %s]" ), cItem->GetNetClassName() ); + + return s; + }; + r->Report( _( "Clearance resolution for:" ) ); - r->Report( wxString::Format( _( "
  • Layer %s
  • %s
  • %s
" ), + r->Report( wxString::Format( wxT( "
  • %s %s
  • %s
  • %s
" ), + _( "Layer" ), m_frame->GetBoard()->GetLayerName( layer ), - a->GetSelectMenuText( r->GetUnits() ), - b->GetSelectMenuText( r->GetUnits() ) ) ); + getItemDescription( a ), + getItemDescription( b ) ) ); BOARD_CONNECTED_ITEM* ac = dynamic_cast( a ); BOARD_CONNECTED_ITEM* bc = dynamic_cast( b );