From 2dec37f80681f346f10bb9498967341164aa88ba Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Mon, 24 Oct 2022 00:13:05 +0100 Subject: [PATCH] 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 --- pcbnew/router/pns_kicad_iface.cpp | 40 +++++++++++++++++++------------ pcbnew/router/pns_layerset.h | 16 +++++++++++++ 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/pcbnew/router/pns_kicad_iface.cpp b/pcbnew/router/pns_kicad_iface.cpp index c4d47468df..cbc0924b8c 100644 --- a/pcbnew/router/pns_kicad_iface.cpp +++ b/pcbnew/router/pns_kicad_iface.cpp @@ -387,26 +387,36 @@ int PNS_PCBNEW_RULE_RESOLVER::Clearance( const PNS::ITEM* aA, const PNS::ITEM* a return it->second; PNS::CONSTRAINT constraint; - int rv = 0; - int layer; + int rv = 0; + LAYER_RANGE layers; - if( !aA->Layers().IsMultilayer() || !aB || aB->Layers().IsMultilayer() ) - layer = aA->Layer(); + if( !aB ) + layers = aA->Layers(); + else if( isEdge( aA ) ) + layers = aB->Layers(); + else if( isEdge( aB ) ) + layers = aA->Layers(); 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 ) ) - rv = constraint.m_Value.Min(); - } - - if( isEdge( aA ) || ( aB && isEdge( aB ) ) ) - { - if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_EDGE_CLEARANCE, aA, aB, layer, &constraint ) ) + if( isCopper( aA ) && ( !aB || isCopper( aB ) ) ) { - if( constraint.m_Value.Min() > rv ) - rv = constraint.m_Value.Min(); + if( QueryConstraint( PNS::CONSTRAINT_TYPE::CT_CLEARANCE, aA, aB, layer, &constraint ) ) + { + 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(); + } } } diff --git a/pcbnew/router/pns_layerset.h b/pcbnew/router/pns_layerset.h index f3b9d3bb15..6f3343fadd 100644 --- a/pcbnew/router/pns_layerset.h +++ b/pcbnew/router/pns_layerset.h @@ -105,6 +105,22 @@ public: 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 static LAYER_RANGE All() {