Pull some fixes back from 7.0.
1) An earlier 6.0 fix to apply pad clearance overrides to NPTH pads got broken, so this replaces it. 2) Allow min/max/opt to be set by different rules. 3) Fixes a bug where board minimum enforcement over a local override didn't get the right message text.
This commit is contained in:
parent
4da0c897bc
commit
1e23ce1c95
|
@ -782,49 +782,69 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
bool a_is_non_copper = a && ( !a->IsOnCopperLayer() || isKeepoutZone( a, false ) );
|
||||
bool b_is_non_copper = b && ( !b->IsOnCopperLayer() || isKeepoutZone( b, false ) );
|
||||
|
||||
const DRC_CONSTRAINT* constraintRef = nullptr;
|
||||
bool implicit = false;
|
||||
DRC_CONSTRAINT constraint;
|
||||
constraint.m_Type = aConstraintType;
|
||||
|
||||
// Local overrides take precedence over everything *except* board min clearance
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT )
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT || aConstraintType == HOLE_CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
int overrideA = 0;
|
||||
int overrideB = 0;
|
||||
int override = 0;
|
||||
|
||||
if( ac && !b_is_non_copper && ac->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
if( ac && !b_is_non_copper )
|
||||
{
|
||||
overrideA = ac->GetLocalClearanceOverrides( &m_msg );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
EscapeHTML( a->GetSelectMenuText( UNITS ) ),
|
||||
REPORT_VALUE( overrideA ) ) )
|
||||
}
|
||||
|
||||
if( bc && !a_is_non_copper && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
{
|
||||
overrideB = bc->GetLocalClearanceOverrides( &m_msg );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
EscapeHTML( b->GetSelectMenuText( UNITS ) ),
|
||||
REPORT_VALUE( overrideB ) ) )
|
||||
}
|
||||
|
||||
if( overrideA || overrideB )
|
||||
{
|
||||
int override = std::max( overrideA, overrideB );
|
||||
|
||||
if( override < m_designSettings->m_MinClearance )
|
||||
if( int overrideA = ac->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
{
|
||||
override = m_designSettings->m_MinClearance;
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
|
||||
REPORT_VALUE( override ) ) )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
EscapeHTML( a->GetSelectMenuText( UNITS ) ),
|
||||
REPORT_VALUE( overrideA ) ) )
|
||||
|
||||
override = ac->GetLocalClearanceOverrides( &m_msg );
|
||||
}
|
||||
}
|
||||
|
||||
if( bc && !a_is_non_copper )
|
||||
{
|
||||
if( int overrideB = bc->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
{
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
EscapeHTML( b->GetSelectMenuText( UNITS ) ),
|
||||
EscapeHTML( REPORT_VALUE( overrideB ) ) ) )
|
||||
|
||||
if( overrideB > override )
|
||||
override = bc->GetLocalClearanceOverrides( &m_msg );
|
||||
}
|
||||
}
|
||||
|
||||
if( override )
|
||||
{
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
if( override < m_designSettings->m_MinClearance )
|
||||
{
|
||||
override = m_designSettings->m_MinClearance;
|
||||
m_msg = _( "board minimum" );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum clearance: %s." ),
|
||||
REPORT_VALUE( override ) ) )
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( override < m_designSettings->m_HoleClearance )
|
||||
{
|
||||
override = m_designSettings->m_HoleClearance;
|
||||
m_msg = _( "board minimum hole" );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Board minimum hole clearance: %s." ),
|
||||
REPORT_VALUE( override ) ) )
|
||||
}
|
||||
}
|
||||
|
||||
DRC_CONSTRAINT constraint( aConstraintType, m_msg );
|
||||
constraint.SetName( m_msg );
|
||||
constraint.m_Value.SetMin( override );
|
||||
return constraint;
|
||||
}
|
||||
|
@ -833,7 +853,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
auto processConstraint =
|
||||
[&]( const DRC_ENGINE_CONSTRAINT* c ) -> bool
|
||||
{
|
||||
implicit = c->parentRule && c->parentRule->m_Implicit;
|
||||
bool implicit = c->parentRule && c->parentRule->m_Implicit;
|
||||
|
||||
REPORT( "" )
|
||||
|
||||
|
@ -1021,7 +1041,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
REPORT( implicit ? _( "Unconditional constraint applied." )
|
||||
: _( "Unconditional rule applied." ) );
|
||||
|
||||
constraintRef = &c->constraint;
|
||||
constraint = c->constraint;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -1041,7 +1061,22 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
REPORT( implicit ? _( "Constraint applied." )
|
||||
: _( "Rule applied; overrides previous constraints." ) )
|
||||
|
||||
constraintRef = &c->constraint;
|
||||
if( c->constraint.m_Value.HasMin() )
|
||||
constraint.m_Value.SetMin( c->constraint.m_Value.Min() );
|
||||
|
||||
if( c->constraint.m_Value.HasOpt() )
|
||||
constraint.m_Value.SetOpt( c->constraint.m_Value.Opt() );
|
||||
|
||||
if( c->constraint.m_Value.HasMax() )
|
||||
constraint .m_Value.SetMax( c->constraint.m_Value.Max() );
|
||||
|
||||
// While the expectation would be to OR the disallow flags, we've already
|
||||
// masked them down to aItem's type -- so we're really only looking for a
|
||||
// boolean here.
|
||||
constraint.m_DisallowFlags = c->constraint.m_DisallowFlags;
|
||||
|
||||
constraint.SetParentRule( c->constraint.GetParentRule() );
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -1077,14 +1112,15 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
}
|
||||
}
|
||||
|
||||
bool explicitConstraintFound = constraintRef && !implicit;
|
||||
if( constraint.GetParentRule() && !constraint.GetParentRule()->m_Implicit )
|
||||
return constraint;
|
||||
|
||||
// Unfortunately implicit rules don't work for local clearances (such as zones) because
|
||||
// they have to be max'ed with netclass values (which are already implicit rules), and our
|
||||
// rule selection paradigm is "winner takes all".
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT && !explicitConstraintFound )
|
||||
if( aConstraintType == CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
int global = constraintRef ? constraintRef->m_Value.Min() : 0;
|
||||
int global = constraint.m_Value.Min();
|
||||
int localA = ac ? ac->GetLocalClearance( nullptr ) : 0;
|
||||
int localB = bc ? bc->GetLocalClearance( nullptr ) : 0;
|
||||
int clearance = global;
|
||||
|
@ -1113,16 +1149,20 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRules( DRC_CONSTRAINT_T aConstraintType, const BO
|
|||
|
||||
if( localA > global || localB > global )
|
||||
{
|
||||
DRC_CONSTRAINT constraint( CLEARANCE_CONSTRAINT, m_msg );
|
||||
constraint.SetName( m_msg );
|
||||
constraint.m_Value.SetMin( clearance );
|
||||
return constraint;
|
||||
}
|
||||
}
|
||||
else if( constraint.GetParentRule() )
|
||||
{
|
||||
return constraint;
|
||||
}
|
||||
|
||||
static DRC_CONSTRAINT nullConstraint( NULL_CONSTRAINT );
|
||||
nullConstraint.m_DisallowFlags = 0;
|
||||
constraint.m_Type = NULL_CONSTRAINT;
|
||||
constraint.m_DisallowFlags = 0;
|
||||
|
||||
return constraintRef ? *constraintRef : nullConstraint;
|
||||
return constraint;
|
||||
|
||||
#undef REPORT
|
||||
#undef UNITS
|
||||
|
|
|
@ -318,7 +318,7 @@ wxString DRC_ITEM::GetViolatingRuleDesc() const
|
|||
{
|
||||
if( m_violatingRule )
|
||||
return wxString::Format( _( "Rule: %s" ), m_violatingRule->m_Name );
|
||||
|
||||
return wxEmptyString;
|
||||
else
|
||||
return _("Local override" );
|
||||
}
|
||||
|
||||
|
|
|
@ -125,6 +125,8 @@ class DRC_CONSTRAINT
|
|||
void SetParentRule( DRC_RULE *aParentRule ) { m_parentRule = aParentRule; }
|
||||
DRC_RULE* GetParentRule() const { return m_parentRule; }
|
||||
|
||||
void SetName( const wxString& aName ) { m_name = aName; }
|
||||
|
||||
wxString GetName() const
|
||||
{
|
||||
if( m_parentRule )
|
||||
|
|
|
@ -688,7 +688,7 @@ int PAD::GetLocalClearanceOverrides( wxString* aSource ) const
|
|||
int PAD::GetLocalClearance( wxString* aSource ) const
|
||||
{
|
||||
if( aSource )
|
||||
*aSource = wxString::Format( _( "pad %s" ), GetName() );
|
||||
*aSource = _( "pad" );
|
||||
|
||||
return m_localClearance;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -101,7 +101,7 @@
|
|||
"allow_blind_buried_vias": false,
|
||||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.2032,
|
||||
"min_clearance": 0.17779999999999999,
|
||||
"min_copper_edge_clearance": 0.19999999999999998,
|
||||
"min_hole_clearance": 0.0,
|
||||
"min_hole_to_hole": 0.25,
|
||||
|
|
|
@ -110,7 +110,7 @@ BOOST_FIXTURE_TEST_CASE( DRCFalseNegativeRegressions, DRC_REGRESSION_TEST_FIXTUR
|
|||
{ "issue6945", 2 },
|
||||
{ "issue7241", 1 },
|
||||
{ "issue7267", 4 },
|
||||
{ "issue7325", 21 },
|
||||
{ "issue7325", 2 },
|
||||
{ "issue8003", 2 } };
|
||||
|
||||
for( const std::pair<wxString, int>& entry : tests )
|
||||
|
|
Loading…
Reference in New Issue