diff --git a/pcbnew/drc/drc_engine.cpp b/pcbnew/drc/drc_engine.cpp index 81ffcb359c..cb934fe147 100644 --- a/pcbnew/drc/drc_engine.cpp +++ b/pcbnew/drc/drc_engine.cpp @@ -315,14 +315,14 @@ bool DRC_ENGINE::CompileRules() m_constraintMap[ id ]->provider = provider; - for( auto rule : m_rules ) + for( DRC_RULE* rule : m_rules ) { DRC_RULE_CONDITION* condition = nullptr; bool compileOk = false; std::vector matchingConstraints; drc_dbg(7, "Scan provider %s, rule %s", provider->GetName(), rule->m_Name ); - if( !rule->m_Condition->GetExpression().IsEmpty() ) + if( rule->m_Condition && !rule->m_Condition->GetExpression().IsEmpty() ) { condition = rule->m_Condition; compileOk = condition->Compile( nullptr, 0, 0 ); // fixme @@ -375,9 +375,8 @@ bool DRC_ENGINE::CompileRules() } -void DRC_ENGINE::RunTests( ) +void DRC_ENGINE::InitEngine() { - m_drcReport.reset( new DRC_REPORT ); m_testProviders = DRC_TEST_PROVIDER_REGISTRY::Instance().GetTestProviders(); for( auto provider : m_testProviders ) @@ -388,8 +387,16 @@ void DRC_ENGINE::RunTests( ) inferLegacyRules(); CompileRules(); +} - for( auto provider : m_testProviders ) + +void DRC_ENGINE::RunTests( ) +{ + InitEngine(); + + m_drcReport = std::make_shared(); + + for( DRC_TEST_PROVIDER* provider : m_testProviders ) { bool skipProvider = false; auto matchingConstraints = provider->GetMatchingConstraintIds(); @@ -419,8 +426,11 @@ void DRC_ENGINE::RunTests( ) DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintId, - BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer ) + BOARD_ITEM* a, BOARD_ITEM* b, PCB_LAYER_ID aLayer, + REPORTER* aReporter ) { +#define REPORT( s ) { if( aReporter ) { aReporter->Report( s ); } } + // Local overrides take precedence if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE ) { @@ -428,48 +438,77 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI : nullptr; BOARD_CONNECTED_ITEM* bc = b->IsConnected() ? static_cast( b ) : nullptr; - int clearance = 0; + int overrideA = 0; + int overrideB = 0; - if( ac && ac->GetLocalClearanceOverrides( nullptr ) > clearance ) - clearance = ac->GetLocalClearanceOverrides( &m_msg ); + if( ac && ac->GetLocalClearanceOverrides( nullptr ) > 0 ) + { + overrideA = ac->GetLocalClearanceOverrides( &m_msg ); - if( bc && bc->GetLocalClearanceOverrides( nullptr ) > clearance ) - clearance = bc->GetLocalClearanceOverrides( &m_msg ); + REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ), + a->GetSelectMenuText( aReporter->GetUnits() ), + StringFromValue( aReporter->GetUnits(), overrideA, true ) ) ); + } - if( clearance ) + if( bc && bc->GetLocalClearanceOverrides( nullptr ) > 0 ) + { + overrideB = bc->GetLocalClearanceOverrides( &m_msg ); + + REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ), + b->GetSelectMenuText( aReporter->GetUnits() ), + StringFromValue( aReporter->GetUnits(), overrideB, true ) ) ); + + // If both overridden, report on which wins + if( overrideA ) + { + REPORT( wxString::Format( _( "Clearance: %s." ), + std::max( overrideA, overrideB ) ) ); + } + } + + if( overrideA || overrideB ) { DRC_CONSTRAINT constraint( DRC_CONSTRAINT_TYPE_CLEARANCE, m_msg ); - constraint.m_Value.SetMin( clearance ); + constraint.m_Value.SetMin( std::max( overrideA, overrideB ) ); return constraint; } } auto ruleset = m_constraintMap[ aConstraintId ]; - for( const auto& rcond : ruleset->sortedConstraints ) + for( const CONSTRAINT_WITH_CONDITIONS* rcond : ruleset->sortedConstraints ) { + DRC_RULE* rule = rcond->parentRule; + REPORT( wxString::Format( _( "Checking rule \"%s\"." ), rule->m_Name ) ); + + if( aLayer != UNDEFINED_LAYER && !rule->m_LayerCondition.test( aLayer ) ) + { + REPORT( wxString::Format( _( "Rule layer \"%s\" not matched." ), + rule->m_LayerSource ) ); + REPORT( "Rule not applied." ); + + continue; + } + if( rcond->conditions.size() == 0 ) // uconditional { - drc_dbg( 8, " -> rule '%s' matches (unconditional)\n", - rcond->constraint.GetParentRule()->m_Name ); + REPORT( "No condition found; rule applied." ); + return rcond->constraint; } - for( const auto& condition : rcond->conditions ) + for( DRC_RULE_CONDITION* condition : rcond->conditions ) { - drc_dbg( 8, " -> check condition '%s'\n", - condition->GetExpression() ); + REPORT( wxString::Format( _( "Checking rule condition \"%s\"." ), + condition->GetExpression() ) ); - bool result = condition->EvaluateFor( a, b, aLayer ); + bool result = condition->EvaluateFor( a, b, aLayer, aReporter ); + + REPORT( result ? _( "Rule applied." ) + : _( "Condition not satisfied; rule not applied." ) ); if( result ) - { - drc_dbg( 8, " -> rule '%s' matches, triggered by condition '%s'\n", - rcond->constraint.GetParentRule()->m_Name, - condition->GetExpression() ); - return rcond->constraint; - } } } diff --git a/pcbnew/drc/drc_engine.h b/pcbnew/drc/drc_engine.h index 1279e473fe..9b146f2cc5 100644 --- a/pcbnew/drc/drc_engine.h +++ b/pcbnew/drc/drc_engine.h @@ -82,7 +82,7 @@ public: struct ENTRY { std::shared_ptr m_item; - ::MARKER_PCB* m_marker; + MARKER_PCB* m_marker; }; typedef std::vector ENTRIES; @@ -149,6 +149,8 @@ public: m_reporter = aReporter; } + void InitEngine(); + void RunTests(); void SetErrorLimit( int aLimit ); @@ -165,7 +167,8 @@ public: DRC_CONSTRAINT EvalRulesForItems( DRC_CONSTRAINT_TYPE_T ruleID, BOARD_ITEM* a, BOARD_ITEM* b = nullptr, - PCB_LAYER_ID aLayer = UNDEFINED_LAYER ); + PCB_LAYER_ID aLayer = UNDEFINED_LAYER, + REPORTER* aReporter = nullptr ); std::vector QueryConstraintsById( DRC_CONSTRAINT_TYPE_T ruleID ); diff --git a/pcbnew/drc/drc_rule.cpp b/pcbnew/drc/drc_rule.cpp index c832d9408a..c5158a1400 100644 --- a/pcbnew/drc/drc_rule.cpp +++ b/pcbnew/drc/drc_rule.cpp @@ -130,6 +130,7 @@ wxString DRC_CONSTRAINT::GetName() const DRC_RULE::DRC_RULE() : m_Unary( false ), m_LayerCondition( LSET::AllLayersMask() ), + m_Condition( nullptr ), m_Priority( 0 ), m_Severity( SEVERITY::RPT_SEVERITY_ERROR ) { diff --git a/pcbnew/drc/drc_rule_parser.cpp b/pcbnew/drc/drc_rule_parser.cpp index 3d7367c08f..8789245aa6 100644 --- a/pcbnew/drc/drc_rule_parser.cpp +++ b/pcbnew/drc/drc_rule_parser.cpp @@ -196,7 +196,7 @@ DRC_RULE* DRC_RULES_PARSER::parseDRC_RULE() if( IsSymbol( token ) ) { - rule->m_Condition->SetExpression( FromUTF8() ); + rule->m_Condition = new DRC_RULE_CONDITION( FromUTF8() ); rule->m_Condition->Compile( m_reporter, CurLineNumber(), CurOffset() ); } else diff --git a/pcbnew/tools/pcb_inspection_tool.cpp b/pcbnew/tools/pcb_inspection_tool.cpp index c54412a6bc..786963a970 100644 --- a/pcbnew/tools/pcb_inspection_tool.cpp +++ b/pcbnew/tools/pcb_inspection_tool.cpp @@ -31,6 +31,7 @@ #include #include #include +#include #include "pcb_inspection_tool.h" @@ -100,7 +101,7 @@ int PCB_INSPECTION_TOOL::ShowStatisticsDialog( const TOOL_EVENT& aEvent ) } -void reportZoneConnection( ZONE_CONTAINER* aZone, D_PAD* aPad, REPORTER* r ) +void PCB_INSPECTION_TOOL::reportZoneConnection( ZONE_CONTAINER* aZone, D_PAD* aPad, REPORTER* r ) { ENUM_MAP connectionEnum = ENUM_MAP::Instance(); wxString source; @@ -179,16 +180,28 @@ void reportZoneConnection( ZONE_CONTAINER* aZone, D_PAD* aPad, REPORTER* r ) } -void reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONNECTED_ITEM* aA, BOARD_ITEM* aB, - REPORTER* r ) +void PCB_INSPECTION_TOOL::reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONNECTED_ITEM* aA, + BOARD_ITEM* aB, REPORTER* r ) { wxString source; r->Report( "" ); + DRC_ENGINE drcEngine( m_frame->GetBoard(), &m_frame->GetBoard()->GetDesignSettings() ); + drcEngine.InitEngine(); + + auto constraint = drcEngine.EvalRulesForItems( DRC_CONSTRAINT_TYPE_CLEARANCE, aA, aB, aLayer ); + + if( r ) + { + wxString clearance = StringFromValue( r->GetUnits(), constraint.m_Value.Min(), true ); + r->Report( wxString::Format( _( "Clearance: %s." ), clearance ) ); + } + // JEY TODO: hook this up to new DRC engine to get "classic" sources as well; right now // we're just reporting on rules.... - aA->GetClearance( aLayer, aB, &source, r ); + // JEY TODO: retire this version + // aA->GetClearance( aLayer, aB, &source, r ); } diff --git a/pcbnew/tools/pcb_inspection_tool.h b/pcbnew/tools/pcb_inspection_tool.h index a25d190c61..5450c7c2ce 100644 --- a/pcbnew/tools/pcb_inspection_tool.h +++ b/pcbnew/tools/pcb_inspection_tool.h @@ -110,6 +110,11 @@ private: void onListNetsDialogClosed( wxCommandEvent& aEvent ); void onInspectClearanceDialogClosed( wxCommandEvent& aEvent ); + void reportZoneConnection( ZONE_CONTAINER* aZone, D_PAD* aPad, REPORTER* r ); + + void reportCopperClearance( PCB_LAYER_ID aLayer, BOARD_CONNECTED_ITEM* aA, BOARD_ITEM* aB, + REPORTER* r ); + private: PCB_EDIT_FRAME* m_frame; // Pointer to the currently used edit frame.