From b442d769fd9d472e681aa6dee7e06fe101988222 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Tue, 23 May 2023 14:08:53 +0100 Subject: [PATCH] Don't allow collisions with self. The previous test didn't handle is-self-tests between a hole and its override in a different NODE. When calculating the pushout force we don't remove the via (and its hole) from the current node until after the calculation, so we end up checking for collisions between the new (cloned) via's hole and the original hole in the root node. Fixes https://gitlab.com/kicad/code/kicad/-/issues/14795 --- pcbnew/router/pns_hole.h | 2 +- pcbnew/router/pns_item.cpp | 4 ++-- pcbnew/router/pns_item.h | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/pcbnew/router/pns_hole.h b/pcbnew/router/pns_hole.h index 9e05c2def0..8794b7796c 100644 --- a/pcbnew/router/pns_hole.h +++ b/pcbnew/router/pns_hole.h @@ -69,7 +69,7 @@ public: const SHAPE* Shape() const override { return m_holeShape; } void SetParentPadVia( ITEM* aParent ) { m_parentPadVia = aParent; } - ITEM* ParentPadVia() const { return m_parentPadVia; } + ITEM* ParentPadVia() const override { return m_parentPadVia; } BOARD_ITEM* BoardItem() const override { diff --git a/pcbnew/router/pns_item.cpp b/pcbnew/router/pns_item.cpp index ec5e93a4b2..a82bc16925 100644 --- a/pcbnew/router/pns_item.cpp +++ b/pcbnew/router/pns_item.cpp @@ -65,7 +65,7 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode, //printf( "h %p n %p t %p ctx %p\n", aHead, aNode, this, aCtx ); - if( this == aHead || this == holeH ) // we cannot be self-colliding + if( this == aHead ) // we cannot be self-colliding return false; // Special cases for "head" lines with vias attached at the end. Note that this does not @@ -86,7 +86,7 @@ bool ITEM::collideSimple( const ITEM* aHead, const NODE* aNode, // And a special case for the "head" via's hole. - if( holeH ) + if( holeH && !HasSameParentPadVia( holeH ) ) collisionsFound |= collideSimple( holeH, aNode, aCtx ); // Sadly collision routines ignore SHAPE_POLY_LINE widths so we have to pass them in as part diff --git a/pcbnew/router/pns_item.h b/pcbnew/router/pns_item.h index 5b1e9a2e78..ea0318ae81 100644 --- a/pcbnew/router/pns_item.h +++ b/pcbnew/router/pns_item.h @@ -250,6 +250,13 @@ public: void SetIsFreePad( bool aIsFreePad = true ) { m_isFreePad = aIsFreePad; } bool IsFreePad() const { return m_isFreePad; } + virtual ITEM* ParentPadVia() const { return nullptr; } + virtual bool HasSameParentPadVia( const ITEM* aOther ) const + { + return ParentPadVia() && aOther->ParentPadVia() + && ParentPadVia()->Parent() == aOther->ParentPadVia()->Parent(); + } + bool IsVirtual() const { return m_isVirtual;