We must check clearance on all layers of multi-layer items.

(One layer may have a custom rule.)

Fixes https://gitlab.com/kicad/code/kicad/issues/12733
This commit is contained in:
Jeff Young 2022-10-24 00:13:05 +01:00
parent c8261d13a5
commit 2dec37f806
2 changed files with 41 additions and 15 deletions

View File

@ -387,26 +387,36 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a
return it->second; return it->second;
PNS::CONSTRAINT constraint; PNS::CONSTRAINT constraint;
int rv = 0; int rv = 0;
int layer; LAYER_RANGE layers;
if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() ) if( !aB )
layer = aA->Layer(); layers = aA->Layers();
else if( isEdge( aA ) )
layers = aB->Layers();
else if( isEdge( aB ) )
layers = aA->Layers();
else else
layer = aB->Layer(); layers = aA->Layers().Intersection( aB->Layers() );
if( isCopper( aA ) && ( !aB || isCopper( aB ) ) ) for( int layer = layers.Start(); layer <= layers.End(); ++layer )
{ {
if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) ) if( isCopper( aA ) && ( !aB || isCopper( aB ) ) )
rv = constraint.m_Value.Min();
}
if( isEdge( aA ) || ( aB && isEdge( aB ) ) )
{
if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) )
{ {
if( constraint.m_Value.Min() > rv ) if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) )
rv = constraint.m_Value.Min(); {
if( constraint.m_Value.Min() > rv )
rv = constraint.m_Value.Min();
}
}
if( isEdge( aA ) || ( aB && isEdge( aB ) ) )
{
if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) )
{
if( constraint.m_Value.Min() > rv )
rv = constraint.m_Value.Min();
}
} }
} }

View File

@ -105,6 +105,22 @@ public:
m_end = aOther.m_end; m_end = aOther.m_end;
} }
LAYER_RANGE Intersection( const LAYER_RANGE& aOther ) const
{
LAYER_RANGE overlap;
overlap.m_start = std::max( m_start, aOther.m_start );
if( m_end < 0 )
overlap.m_end = aOther.m_end;
else if( aOther.m_end < 0 )
overlap.m_end = m_end;
else
overlap.m_end = std::min( m_end, aOther.m_end );
return overlap;
}
///< Shortcut for comparisons/overlap tests ///< Shortcut for comparisons/overlap tests
static LAYER_RANGE All() static LAYER_RANGE All()
{ {