Report all implicit rules for resolution reports.
This commit is contained in:
parent
19155edde0
commit
6b7749658e
|
@ -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 ) )
|
if( m_constraintMap.count( aConstraintId ) )
|
||||||
{
|
{
|
||||||
std::vector<CONSTRAINT_WITH_CONDITIONS*>* ruleset = m_constraintMap[ aConstraintId ];
|
std::vector<CONSTRAINT_WITH_CONDITIONS*>* ruleset = m_constraintMap[ aConstraintId ];
|
||||||
|
|
||||||
// Last matching rule wins, so process in reverse order
|
if( aReporter )
|
||||||
for( int ii = (int) ruleset->size() - 1; ii >= 0; --ii )
|
|
||||||
{
|
{
|
||||||
const CONSTRAINT_WITH_CONDITIONS* rcons = ruleset->at( ii );
|
// We want to see all results so process in "natural" order
|
||||||
implicit = rcons->parentRule && rcons->parentRule->m_Implicit;
|
for( int ii = 0; ii < (int) ruleset->size(); ++ii )
|
||||||
|
|
||||||
REPORT( "" )
|
|
||||||
|
|
||||||
if( aConstraintId == DRC_CONSTRAINT_TYPE_CLEARANCE )
|
|
||||||
{
|
{
|
||||||
int clearance = rcons->constraint.m_Value.Min();
|
processConstraint( ruleset->at( ii ) );
|
||||||
REPORT( wxString::Format( _( "Checking %s; clearance: %s." ),
|
|
||||||
rcons->constraint.GetName(),
|
|
||||||
MessageTextFromValue( UNITS, clearance ) ) )
|
|
||||||
}
|
}
|
||||||
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();
|
if( processConstraint( ruleset->at( ii ) ) )
|
||||||
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;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
REPORT( implicit ? _( "Membership not satisfied; constraint ignored." )
|
|
||||||
: _( "Condition not satisfied; rule ignored." ) )
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -253,6 +253,29 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
||||||
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
|
BOARD_ITEM* a = static_cast<BOARD_ITEM*>( selection.GetItem( 0 ) );
|
||||||
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( selection.GetItem( 1 ) );
|
BOARD_ITEM* b = static_cast<BOARD_ITEM*>( 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<D_PAD*>( a )->GetAttribute() == PAD_ATTRIB_SMD )
|
||||||
|
{
|
||||||
|
D_PAD* pad = static_cast<D_PAD*>( 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<D_PAD*>( 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 )
|
if( a->Type() != PCB_ZONE_AREA_T && b->Type() == PCB_ZONE_AREA_T )
|
||||||
std::swap( a, b );
|
std::swap( a, b );
|
||||||
else if( !a->IsConnected() && b->IsConnected() )
|
else if( !a->IsConnected() && b->IsConnected() )
|
||||||
|
|
Loading…
Reference in New Issue