A rule zone is not really a BOARD_CONNECTED_ITEM.
Or at least it shouldn't always be treated as one. Fixes https://gitlab.com/kicad/code/kicad/issues/6382
This commit is contained in:
parent
b227d2b910
commit
1ce1e493d6
|
@ -107,16 +107,20 @@ static const wxString formatOpName( int op )
|
|||
return "???";
|
||||
}
|
||||
|
||||
|
||||
bool VALUE::EqualTo( const VALUE* b ) const
|
||||
{
|
||||
if( m_type == VT_UNDEFINED || b->m_type == VT_UNDEFINED )
|
||||
return false;
|
||||
|
||||
if( m_type == VT_NUMERIC && b->m_type == VT_NUMERIC )
|
||||
{
|
||||
return m_valueDbl == b->m_valueDbl;
|
||||
}
|
||||
else if( m_type == VT_STRING && b->m_type == VT_STRING )
|
||||
{
|
||||
if( b->m_stringIsWildcard )
|
||||
{
|
||||
return WildCompareString( b->m_valueStr, m_valueStr, false );
|
||||
}
|
||||
else
|
||||
return !m_valueStr.CmpNoCase( b->m_valueStr );
|
||||
}
|
||||
|
@ -125,6 +129,15 @@ bool VALUE::EqualTo( const VALUE* b ) const
|
|||
}
|
||||
|
||||
|
||||
bool VALUE::NotEqualTo( const VALUE* b ) const
|
||||
{
|
||||
if( m_type == VT_UNDEFINED || b->m_type == VT_UNDEFINED )
|
||||
return false;
|
||||
|
||||
return !EqualTo( b );
|
||||
}
|
||||
|
||||
|
||||
wxString UOP::Format() const
|
||||
{
|
||||
wxString str;
|
||||
|
@ -1120,7 +1133,7 @@ void UOP::Exec( CONTEXT* ctx )
|
|||
result = arg1 && arg2 && arg1->EqualTo( arg2 ) ? 1 : 0;
|
||||
break;
|
||||
case TR_OP_NOT_EQUAL:
|
||||
result = arg1 && arg2 && arg1->EqualTo( arg2 ) ? 0 : 1;
|
||||
result = arg1 && arg2 && arg1->NotEqualTo( arg2 ) ? 1 : 0;
|
||||
break;
|
||||
case TR_OP_BOOL_AND:
|
||||
result = arg1Value != 0.0 && arg2Value != 0.0 ? 1 : 0;
|
||||
|
|
|
@ -218,6 +218,9 @@ public:
|
|||
|
||||
virtual bool EqualTo( const VALUE* b ) const;
|
||||
|
||||
// NB: this is not an inverse of EqualTo as they both return false for undefined values.
|
||||
virtual bool NotEqualTo( const VALUE* b ) const;
|
||||
|
||||
VAR_TYPE_T GetType() const { return m_type; };
|
||||
|
||||
void Set( double aValue )
|
||||
|
|
|
@ -277,7 +277,7 @@ protected:
|
|||
wxAny a = getter( aObject );
|
||||
|
||||
if ( !( std::is_enum<T>::value && a.CheckType<int>() ) && !a.CheckType<T>() )
|
||||
throw std::invalid_argument("Invalid requested type");
|
||||
throw std::invalid_argument( "Invalid requested type" );
|
||||
|
||||
return wxANY_AS(a, T);
|
||||
}
|
||||
|
|
|
@ -175,7 +175,7 @@ public:
|
|||
* Note: do NOT return a std::shared_ptr from this. It is used heavily in DRC, and the
|
||||
* std::shared_ptr stuff shows up large in performance profiling.
|
||||
*/
|
||||
NETCLASS* GetNetClass() const;
|
||||
virtual NETCLASS* GetNetClass() const;
|
||||
|
||||
/**
|
||||
* Function GetEffectiveNetclass
|
||||
|
@ -184,7 +184,7 @@ public:
|
|||
* Note: do NOT return a std::shared_ptr from this. It is used heavily in DRC, and the
|
||||
* std::shared_ptr stuff shows up large in performance profiling.
|
||||
*/
|
||||
NETCLASS* GetEffectiveNetclass() const;
|
||||
virtual NETCLASS* GetEffectiveNetclass() const;
|
||||
|
||||
/**
|
||||
* Function GetNetClassName
|
||||
|
@ -194,7 +194,7 @@ public:
|
|||
* (should not return a null pointer).
|
||||
* @return the Net Class name of this item
|
||||
*/
|
||||
wxString GetNetClassName() const;
|
||||
virtual wxString GetNetClassName() const;
|
||||
|
||||
void SetLocalRatsnestVisible( bool aVisible )
|
||||
{
|
||||
|
|
|
@ -706,10 +706,16 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
}
|
||||
}
|
||||
|
||||
const BOARD_CONNECTED_ITEM* connectedA = dynamic_cast<const BOARD_CONNECTED_ITEM*>( a );
|
||||
const BOARD_CONNECTED_ITEM* connectedB = dynamic_cast<const BOARD_CONNECTED_ITEM*>( b );
|
||||
const DRC_CONSTRAINT* constraintRef = nullptr;
|
||||
bool implicit = false;
|
||||
const BOARD_CONNECTED_ITEM* ac = a && a->IsConnected() ?
|
||||
static_cast<const BOARD_CONNECTED_ITEM*>( a ) : nullptr;
|
||||
const BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
|
||||
static_cast<const BOARD_CONNECTED_ITEM*>( b ) : nullptr;
|
||||
|
||||
bool a_is_unconnected = a && !ac;
|
||||
bool b_is_unconnected = b && !bc;
|
||||
|
||||
const DRC_CONSTRAINT* constraintRef = nullptr;
|
||||
bool implicit = false;
|
||||
|
||||
// Local overrides take precedence
|
||||
if( aConstraintId == CLEARANCE_CONSTRAINT )
|
||||
|
@ -717,9 +723,9 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
int overrideA = 0;
|
||||
int overrideB = 0;
|
||||
|
||||
if( connectedA && connectedA->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
if( ac && !b_is_unconnected && ac->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
{
|
||||
overrideA = connectedA->GetLocalClearanceOverrides( &m_msg );
|
||||
overrideA = ac->GetLocalClearanceOverrides( &m_msg );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
|
@ -727,9 +733,9 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
MessageTextFromValue( UNITS, overrideA ) ) )
|
||||
}
|
||||
|
||||
if( connectedB && connectedB->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
if( bc && !a_is_unconnected && bc->GetLocalClearanceOverrides( nullptr ) > 0 )
|
||||
{
|
||||
overrideB = connectedB->GetLocalClearanceOverrides( &m_msg );
|
||||
overrideB = bc->GetLocalClearanceOverrides( &m_msg );
|
||||
|
||||
REPORT( "" )
|
||||
REPORT( wxString::Format( _( "Local override on %s; clearance: %s." ),
|
||||
|
@ -794,9 +800,9 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
|
||||
if( aConstraintId == CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
if( implicit && ( isKeepoutZone( a ) || isKeepoutZone( b ) ) )
|
||||
if( implicit && ( a_is_unconnected || b_is_unconnected ) )
|
||||
{
|
||||
REPORT( _( "Board and netclass clearances not applied to keepout zones" ) );
|
||||
REPORT( _( "Board and netclass clearances apply only to connected items." ) );
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -956,8 +962,8 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
if( constraintRef && aConstraintId == CLEARANCE_CONSTRAINT && implicit )
|
||||
{
|
||||
int global = constraintRef->m_Value.Min();
|
||||
int localA = connectedA ? connectedA->GetLocalClearance( nullptr ) : 0;
|
||||
int localB = connectedB ? connectedB->GetLocalClearance( nullptr ) : 0;
|
||||
int localA = ac ? ac->GetLocalClearance( nullptr ) : 0;
|
||||
int localB = bc ? bc->GetLocalClearance( nullptr ) : 0;
|
||||
int clearance = global;
|
||||
|
||||
if( localA > 0 )
|
||||
|
@ -968,7 +974,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
MessageTextFromValue( UNITS, localA ) ) )
|
||||
|
||||
if( localA > clearance )
|
||||
clearance = connectedA->GetLocalClearance( &m_msg );
|
||||
clearance = ac->GetLocalClearance( &m_msg );
|
||||
}
|
||||
|
||||
if( localB > 0 )
|
||||
|
@ -979,7 +985,7 @@ DRC_CONSTRAINT DRC_ENGINE::EvalRulesForItems( DRC_CONSTRAINT_TYPE_T aConstraintI
|
|||
MessageTextFromValue( UNITS, localB ) ) )
|
||||
|
||||
if( localB > clearance )
|
||||
clearance = connectedB->GetLocalClearance( &m_msg );
|
||||
clearance = bc->GetLocalClearance( &m_msg );
|
||||
}
|
||||
|
||||
if( localA > global || localB > global )
|
||||
|
|
|
@ -544,7 +544,7 @@ LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
|
|||
// simplier "A.Via_Type == 'buried'" is perfectly clear. Instead, return an undefined
|
||||
// value when the property doesn't appear on a particular object.
|
||||
|
||||
return LIBEVAL::VALUE( "UNDEFINED" );
|
||||
return LIBEVAL::VALUE();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -564,7 +564,10 @@ LIBEVAL::VALUE PCB_EXPR_VAR_REF::GetValue( LIBEVAL::CONTEXT* aCtx )
|
|||
any.GetAs<wxString>( &str );
|
||||
}
|
||||
|
||||
return LIBEVAL::VALUE( str );
|
||||
if( str == "UNDEFINED" )
|
||||
return LIBEVAL::VALUE();
|
||||
else
|
||||
return LIBEVAL::VALUE( str );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,10 +213,13 @@ void PCB_INSPECTION_TOOL::reportClearance( DRC_CONSTRAINT_TYPE_T aClearanceType,
|
|||
|
||||
if( aClearanceType == CLEARANCE_CONSTRAINT )
|
||||
{
|
||||
auto edgeConstraint = drcEngine.EvalRulesForItems( EDGE_CLEARANCE_CONSTRAINT, aA, aB,
|
||||
aLayer, r );
|
||||
if( ( aA && aA->GetLayer() == Edge_Cuts ) || ( aB && aB->GetLayer() == Edge_Cuts ) )
|
||||
{
|
||||
auto edgeConstraint = drcEngine.EvalRulesForItems( EDGE_CLEARANCE_CONSTRAINT, aA, aB,
|
||||
aLayer, r );
|
||||
|
||||
clearance = edgeConstraint.m_Value.HasMin() ? edgeConstraint.m_Value.Min() : 0;
|
||||
clearance = edgeConstraint.m_Value.HasMin() ? edgeConstraint.m_Value.Min() : 0;
|
||||
}
|
||||
}
|
||||
|
||||
auto constraint = drcEngine.EvalRulesForItems( aClearanceType, aA, aB, aLayer, r );
|
||||
|
@ -293,8 +296,12 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
wxString s = aItem->GetSelectMenuText( r->GetUnits() );
|
||||
|
||||
if( auto* cItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( aItem ) )
|
||||
s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ), cItem->GetNetClassName() );
|
||||
if( aItem->IsConnected() )
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* cItem = static_cast<BOARD_CONNECTED_ITEM*>( aItem );
|
||||
s += wxS( " " ) + wxString::Format( _( "[netclass %s]" ),
|
||||
cItem->GetNetClassName() );
|
||||
}
|
||||
|
||||
return s;
|
||||
};
|
||||
|
@ -333,8 +340,10 @@ int PCB_INSPECTION_TOOL::InspectClearance( const TOOL_EVENT& aEvent )
|
|||
getItemDescription( a ),
|
||||
getItemDescription( b ) ) );
|
||||
|
||||
BOARD_CONNECTED_ITEM* ac = dynamic_cast<BOARD_CONNECTED_ITEM*>( a );
|
||||
BOARD_CONNECTED_ITEM* bc = dynamic_cast<BOARD_CONNECTED_ITEM*>( b );
|
||||
BOARD_CONNECTED_ITEM* ac = a && a->IsConnected() ?
|
||||
static_cast<BOARD_CONNECTED_ITEM*>( a ) : nullptr;
|
||||
BOARD_CONNECTED_ITEM* bc = b && b->IsConnected() ?
|
||||
static_cast<BOARD_CONNECTED_ITEM*>( b ) : nullptr;
|
||||
|
||||
if( ac && bc && ac->GetNetCode() > 0 && ac->GetNetCode() == bc->GetNetCode() )
|
||||
{
|
||||
|
|
|
@ -77,6 +77,29 @@ public:
|
|||
return aItem && aItem->Type() == PCB_ZONE_T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Not all ZONEs are *really* BOARD_CONNECTED_ITEMs....
|
||||
*/
|
||||
bool IsConnected() const override
|
||||
{
|
||||
return !GetIsRuleArea();
|
||||
}
|
||||
|
||||
NETCLASS* GetNetClass() const override
|
||||
{
|
||||
if( GetIsRuleArea() )
|
||||
return nullptr;
|
||||
|
||||
return BOARD_CONNECTED_ITEM::GetNetClass();
|
||||
}
|
||||
|
||||
wxString GetNetClassName() const override
|
||||
{
|
||||
if( GetIsRuleArea() )
|
||||
return "UNDEFINED";
|
||||
|
||||
return BOARD_CONNECTED_ITEM::GetNetClassName();
|
||||
}
|
||||
/**
|
||||
* Copy aZone data to me
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue