From 664bf1382d2686d1633e9d1b39aaafff8f195126 Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Mon, 11 Jul 2022 22:46:20 -0400 Subject: [PATCH] PNS: Fix IsLineCorner logic Handle segment width test in the case of locked segs Fix logic failure where vias on path cause crash Fixes https://gitlab.com/kicad/code/kicad/-/issues/11990 (cherry picked from commit 25123759887fb6a94c5eaebfbf2e7c065ef4d1e7) --- pcbnew/router/pns_joint.h | 42 +++++++++++++++++++++++---------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/pcbnew/router/pns_joint.h b/pcbnew/router/pns_joint.h index a1c32a84ab..3b10cc1889 100644 --- a/pcbnew/router/pns_joint.h +++ b/pcbnew/router/pns_joint.h @@ -102,7 +102,15 @@ public: */ bool IsLineCorner( bool aAllowLockedSegs = false ) const { - if( m_linkedItems.Size() != 2 || m_linkedItems.Count( SEGMENT_T | ARC_T ) != 2 ) + if( m_linkedItems.Size() == 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 ) + { + LINKED_ITEM* seg1 = static_cast( m_linkedItems[0] ); + LINKED_ITEM* seg2 = static_cast( m_linkedItems[1] ); + + // joints between segments of different widths are not considered trivial. + return seg1->Width() == seg2->Width(); + } + else if( m_linkedItems.Size() > 2 && m_linkedItems.Count( SEGMENT_T | ARC_T ) == 2 ) { if( !aAllowLockedSegs ) { @@ -113,8 +121,10 @@ public: else if( ( m_linkedItems.Size() - m_linkedItems.Count( SEGMENT_T | ARC_T ) ) == m_linkedItems.Count( VIA_T ) ) { - const VIA* via = nullptr; - bool hasNonVirtualVia = false; + const LINKED_ITEM* seg1 = nullptr; + const LINKED_ITEM* seg2 = nullptr; + const VIA* via = nullptr; + bool hasNonVirtualVia = false; for( const ITEM* item : m_linkedItems.CItems() ) { @@ -123,28 +133,26 @@ public: via = static_cast( item ); hasNonVirtualVia = !via->IsVirtual(); - - if( hasNonVirtualVia ) - break; + } + else if( item->Kind() == SEGMENT_T || item->Kind() == ARC_T ) + { + if( !seg1 ) + seg1 = static_cast( item ); + else + seg2 = static_cast( item ); } } - assert( via ); - if( !via || hasNonVirtualVia ) return false; - } - else - { - return false; + + assert ( seg1 && seg2 ); + + return seg1->Width() == seg2->Width(); } } - auto seg1 = static_cast( m_linkedItems[0] ); - auto seg2 = static_cast( m_linkedItems[1] ); - - // joints between segments of different widths are not considered trivial. - return seg1->Width() == seg2->Width(); + return false; } bool IsNonFanoutVia() const