diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index 7169b9536d..9fec20b0a0 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -315,8 +315,8 @@ std::shared_ptr<DRC_RULE> DRC_RULES_PARSER::parseDRC_RULE() case T_layer: if( rule->m_LayerCondition != LSET::AllLayersMask() ) reportError( _( "'layer' keyword already present." ) ); - rule->m_LayerSource = FromUTF8(); - rule->m_LayerCondition = parseLayer(); + + rule->m_LayerCondition = parseLayer( &rule->m_LayerSource ); break; case T_severity: @@ -765,7 +765,7 @@ void DRC_RULES_PARSER::parseValueWithUnits( const wxString& aExpr, int& aResult, } -LSET DRC_RULES_PARSER::parseLayer() +LSET DRC_RULES_PARSER::parseLayer( wxString* aSource ) { LSET retVal; int token = NextTok(); @@ -777,10 +777,12 @@ LSET DRC_RULES_PARSER::parseLayer() } else if( token == T_outer ) { + *aSource = GetTokenString( token ); retVal = LSET::ExternalCuMask(); } else if( token == T_inner ) { + *aSource = GetTokenString( token ); retVal = LSET::InternalCuMask(); } else @@ -793,7 +795,10 @@ LSET DRC_RULES_PARSER::parseLayer() wxPGChoiceEntry& entry = layerMap[ii]; if( entry.GetText().Matches( layerName ) ) + { + *aSource = layerName; retVal.set( ToLAYER_ID( entry.GetValue() ) ); + } } if( !retVal.any() ) diff --git a/pcbnew/drc/drc_rule_parser.h b/pcbnew/drc/drc_rule_parser.h index 294d5a801d..084de44fa1 100644 --- a/pcbnew/drc/drc_rule_parser.h +++ b/pcbnew/drc/drc_rule_parser.h @@ -56,7 +56,7 @@ private: void parseConstraint( DRC_RULE* aRule ); void parseValueWithUnits( const wxString& aExpr, int& aResult, bool aUnitless = false ); - LSET parseLayer(); + LSET parseLayer( wxString* aSource ); SEVERITY parseSeverity(); void parseUnknown(); diff --git a/pcbnew/tools/board_inspection_tool.cpp b/pcbnew/tools/board_inspection_tool.cpp index 2d6c566cdc..7b3f22fad2 100644 --- a/pcbnew/tools/board_inspection_tool.cpp +++ b/pcbnew/tools/board_inspection_tool.cpp @@ -1218,60 +1218,67 @@ int BOARD_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent ) r = dialog->AddHTMLPage( _( "Physical Clearances" ) ); - auto reportPhysicalClearance = - [&]( PCB_LAYER_ID aLayer ) + if( compileError ) + { + reportCompileError( r ); + } + else if( !drcEngine->HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) ) + { + r->Report( "" ); + r->Report( _( "No 'physical_clearance' constraints defined." ) ); + } + else + { + LSET reportLayers = layerIntersection; + bool reported = false; + + if( a->IsOnLayer( Edge_Cuts ) ) + { + LSET edgeInteractingLayers = bFP ? LSET( { F_CrtYd, B_CrtYd } ) + : LSET( b->GetLayerSet() & LSET::PhysicalLayersMask() ); + reportLayers |= edgeInteractingLayers; + } + + if( b->IsOnLayer( Edge_Cuts ) ) + { + LSET edgeInteractingLayers = aFP ? LSET( { F_CrtYd, B_CrtYd } ) + : LSET( a->GetLayerSet() & LSET::PhysicalLayersMask() ); + reportLayers |= edgeInteractingLayers; + } + + for( PCB_LAYER_ID layer : reportLayers ) + { + reported = true; + reportHeader( _( "Physical clearance resolution for:" ), a, b, layer, r ); + + constraint = drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, layer, r ); + clearance = constraint.m_Value.Min(); + + if( constraint.IsNull() ) { - reportHeader( _( "Physical clearance resolution for:" ), a, b, aLayer, r ); - - constraint = drcEngine->EvalRules( PHYSICAL_CLEARANCE_CONSTRAINT, a, b, aLayer, r ); - clearance = constraint.m_Value.Min(); - - if( compileError ) - { - reportCompileError( r ); - } - else if( !drcEngine->HasRulesForConstraintType( PHYSICAL_CLEARANCE_CONSTRAINT ) ) - { - r->Report( "" ); - r->Report( _( "No 'physical_clearance' constraints defined." ) ); - } - else - { - r->Report( "" ); - r->Report( wxString::Format( _( "Resolved min clearance: %s." ), - m_frame->StringFromValue( clearance, true ) ) ); - } - r->Report( "" ); + r->Report( wxString::Format( _( "No 'physical_clearance' constraints in effect on %s." ), + m_frame->GetBoard()->GetLayerName( layer ) ) ); + } + else + { r->Report( "" ); - r->Report( "" ); - }; + r->Report( wxString::Format( _( "Resolved min clearance: %s." ), + m_frame->StringFromValue( clearance, true ) ) ); + } - if( layerIntersection.any() ) - { - PCB_LAYER_ID layer = active; + r->Report( "" ); + r->Report( "" ); + r->Report( "" ); + } - if( !layerIntersection.test( layer ) ) - layer = layerIntersection.Seq().front(); - - reportPhysicalClearance( layer ); - } - - if( aFP && b->IsOnLayer( Edge_Cuts ) ) - { - if( !aFP->GetCourtyard( F_CrtYd ).IsEmpty() ) - reportPhysicalClearance( F_CrtYd ); - - if( !aFP->GetCourtyard( B_CrtYd ).IsEmpty() ) - reportPhysicalClearance( B_CrtYd ); - } - else if( bFP && a->IsOnLayer( Edge_Cuts ) ) - { - if( !bFP->GetCourtyard( F_CrtYd ).IsEmpty() ) - reportPhysicalClearance( F_CrtYd ); - - if( !bFP->GetCourtyard( B_CrtYd ).IsEmpty() ) - reportPhysicalClearance( B_CrtYd ); + if( !reported ) + { + reportHeader( _( "Physical clearance resolution for:" ), a, b, r ); + r->Report( "" ); + r->Report( _( "Items share no relevant layers. No 'physical_clearance' constraints will " + "be applied." ) ); + } } if( a->HasHole() || b->HasHole() )