From 6b7749658e4e8fd280f2ca9de56e885b71d05792 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Thu, 15 Oct 2020 20:18:49 +0100 Subject: [PATCH] Report all implicit rules for resolution reports. --- pcbnew/drc/drc_engine.cpp | 191 +++++++++++++++------------ pcbnew/tools/pcb_inspection_tool.cpp | 23 ++++ 2 files changed, 128 insertions(+), 86 deletions(-) diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index bb97952a5e..88f527ecb5 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -617,101 +617,120 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI } } + auto processConstraint = + [&]( const CONSTRAINT_WITH_CONDITIONS* c ) + { + implicit = c->parentRule && c->parentRule->m_Implicit; + + REPORT( "" ) + + if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE ) + { + int clearance = c->constraint.m_Value.Min(); + REPORT( wxString::Format( _( "Checking %s; clearance: %s." ), + c->constraint.GetName(), + MessageTextFromValue( UNITS, clearance ) ) ) + } + else if( aConstraintId == DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE ) + { + int clearance = c->constraint.m_Value.Min(); + REPORT( wxString::Format( _( "Checking %s; courtyard clearance: %s." ), + c->constraint.GetName(), + MessageTextFromValue( UNITS, clearance ) ) ) + } + else if( aConstraintId == DRC_CONSTRAINT_TYPE_SILK_CLEARANCE ) + { + int clearance = c->constraint.m_Value.Min(); + REPORT( wxString::Format( _( "Checking %s; silk clearance: %s." ), + c->constraint.GetName(), + MessageTextFromValue( UNITS, clearance ) ) ) + } + else if( aConstraintId == DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE ) + { + int clearance = c->constraint.m_Value.Min(); + REPORT( wxString::Format( _( "Checking %s; hole clearance: %s." ), + c->constraint.GetName(), + MessageTextFromValue( UNITS, clearance ) ) ) + } + else if( aConstraintId == DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) + { + int clearance = c->constraint.m_Value.Min(); + REPORT( wxString::Format( _( "Checking %s; edge clearance: %s." ), + c->constraint.GetName(), + MessageTextFromValue( UNITS, clearance ) ) ) + } + else + { + REPORT( wxString::Format( _( "Checking %s." ), + c->constraint.GetName() ) ) + } + + if( aLayer != UNDEFINED_LAYER && !c->layerTest.test( aLayer ) ) + { + if( c->parentRule ) + { + REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ), + c->parentRule->m_LayerSource ) ) + REPORT( "Rule ignored." ) + } + + return false; + } + + if( !c->condition || c->condition->GetExpression().IsEmpty() ) + { + REPORT( implicit ? _( "Unconditional constraint applied." ) + : _( "Unconditional rule applied." ) ); + + constraintRef = &c->constraint; + return true; + } + else + { + // Don't report on implicit rule conditions; they're synthetic. + if( !implicit ) + { + REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ), + c->condition->GetExpression() ) ) + } + + if( c->condition->EvaluateFor( a, b, aLayer, aReporter ) ) + { + REPORT( implicit ? _( "Constraint applied." ) + : _( "Rule applied; overrides previous constraints." ) ) + + constraintRef = &c->constraint; + return true; + } + else + { + REPORT( implicit ? _( "Membership not satisfied; constraint ignored." ) + : _( "Condition not satisfied; rule ignored." ) ) + + return false; + } + } + }; + if( m_constraintMap.count( aConstraintId ) ) { std::vector* ruleset = m_constraintMap[ aConstraintId ]; - // Last matching rule wins, so process in reverse order - for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii ) + if( aReporter ) { - const CONSTRAINT_WITH_CONDITIONS* rcons = ruleset->at( ii ); - implicit = rcons->parentRule && rcons->parentRule->m_Implicit; - - REPORT( "" ) - - if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE ) + // We want to see all results so process in "natural" order + for( int ii = 0; ii < (int) ruleset->size(); ++ii ) { - int clearance = rcons->constraint.m_Value.Min(); - REPORT( wxString::Format( _( "Checking %s; clearance: %s." ), - rcons->constraint.GetName(), - MessageTextFromValue( UNITS, clearance ) ) ) + processConstraint( ruleset->at( ii ) ); } - else if( aConstraintId == DRC_CONSTRAINT_TYPE_COURTYARD_CLEARANCE ) + } + else + { + // Last matching rule wins, so process in reverse order and quit when match found + for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii ) { - int clearance = rcons->constraint.m_Value.Min(); - REPORT( wxString::Format( _( "Checking %s; courtyard clearance: %s." ), - rcons->constraint.GetName(), - MessageTextFromValue( UNITS, clearance ) ) ) - } - else if( aConstraintId == DRC_CONSTRAINT_TYPE_SILK_CLEARANCE ) - { - int clearance = rcons->constraint.m_Value.Min(); - REPORT( wxString::Format( _( "Checking %s; silk clearance: %s." ), - rcons->constraint.GetName(), - MessageTextFromValue( UNITS, clearance ) ) ) - } - else if( aConstraintId == DRC_CONSTRAINT_TYPE_HOLE_CLEARANCE ) - { - int clearance = rcons->constraint.m_Value.Min(); - REPORT( wxString::Format( _( "Checking %s; hole clearance: %s." ), - rcons->constraint.GetName(), - MessageTextFromValue( UNITS, clearance ) ) ) - } - else if( aConstraintId == DRC_CONSTRAINT_TYPE_EDGE_CLEARANCE ) - { - int clearance = rcons->constraint.m_Value.Min(); - REPORT( wxString::Format( _( "Checking %s; edge clearance: %s." ), - rcons->constraint.GetName(), - MessageTextFromValue( UNITS, clearance ) ) ) - } - else - { - REPORT( wxString::Format( _( "Checking %s." ), - rcons->constraint.GetName() ) ) - } - - if( aLayer != UNDEFINED_LAYER && !rcons->layerTest.test( aLayer ) ) - { - if( rcons->parentRule ) - { - REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ), - rcons->parentRule->m_LayerSource ) ) - REPORT( "Rule ignored." ) - } - - continue; - } - - if( !rcons->condition || rcons->condition->GetExpression().IsEmpty() ) - { - REPORT( implicit ? _( "Unconditional constraint applied." ) - : _( "Unconditional rule applied." ) ) - - constraintRef = &rcons->constraint; - break; - } - else - { - // Don't report on implicit rule conditions; they're synthetic. - if( !implicit ) - { - REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ), - rcons->condition->GetExpression() ) ) - } - - if( rcons->condition->EvaluateFor( a, b, aLayer, aReporter ) ) - { - REPORT( implicit ? _( "Constraint applied." ) - : _( "Rule applied. (No further rules will be checked.)" ) ) - - constraintRef = &rcons->constraint; + if( processConstraint( ruleset->at( ii ) ) ) break; - } - else - { - REPORT( implicit ? _( "Membership not satisfied; constraint ignored." ) - : _( "Condition not satisfied; rule ignored." ) ) - } } } } diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index 757dc0aa99..82bd6674e3 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -253,6 +253,29 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent ) BOARD_ITEM* a = static_cast( selection.GetItem( 0 ) ); BOARD_ITEM* b = static_cast( selection.GetItem( 1 ) ); + if( a->Type() == PCB_TRACE_T || a->Type() == PCB_ARC_T ) + layer = a->GetLayer(); + else if( b->Type() == PCB_TRACE_T || b->Type() == PCB_ARC_T ) + layer = b->GetLayer(); + else if( a->Type() == PCB_PAD_T && static_cast( a )->GetAttribute() == PAD_ATTRIB_SMD ) + { + D_PAD* pad = static_cast( a ); + + if( pad->GetAttribute() == PAD_ATTRIB_SMD && pad->IsOnLayer( F_Cu ) ) + layer = F_Cu; + else + layer = B_Cu; + } + else if( b->Type() == PCB_PAD_T ) + { + D_PAD* pad = static_cast( b ); + + if( pad->GetAttribute() == PAD_ATTRIB_SMD && pad->IsOnLayer( F_Cu ) ) + layer = F_Cu; + else + layer = B_Cu; + } + if( a->Type() != PCB_ZONE_AREA_T && b->Type() == PCB_ZONE_AREA_T ) std::swap( a, b ); else if( !a->IsConnected() && b->IsConnected() )