From 40abb013ec4bffb28e16ada170e3d6416b9f4744 Mon Sep 17 00:00:00 2001 From: Jeff Young <jeff@rokeby.ie> Date: Tue, 20 Jun 2023 18:12:55 +0100 Subject: [PATCH] Don't consider a group to be on a copper layer. Its members can be on copper layers, but the group itself isn't on any layer. Also fixes a bug where we were trying to clone TRIANGULATED_POLYGON::TRI shapes as indexable sub-shapes. (The TRI only has indexes into its parent, so cloning it will only result in segfaults down the line.) Also fixes a bug where we weren't including copper items inside groups when checking footprint net ties. Fixes https://gitlab.com/kicad/code/kicad/-/issues/15021 --- include/pcb_group.h | 6 ++++++ libs/kimath/include/geometry/shape_compound.h | 6 +++--- pcbnew/footprint.cpp | 10 ++++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/include/pcb_group.h b/include/pcb_group.h index b306b0da84..59aeea3beb 100644 --- a/include/pcb_group.h +++ b/include/pcb_group.h @@ -124,6 +124,12 @@ public: wxFAIL_MSG( wxT( "groups don't support layer SetLayer" ) ); } + bool IsOnCopperLayer() const override + { + // A group might have members on a copper layer, but isn't itself on any layer. + return false; + } + /** Set layer for all items within the group. * * To avoid freezes with circular references, the maximum depth is 20 by default. diff --git a/libs/kimath/include/geometry/shape_compound.h b/libs/kimath/include/geometry/shape_compound.h index c4c333cb03..0e26bd70ed 100644 --- a/libs/kimath/include/geometry/shape_compound.h +++ b/libs/kimath/include/geometry/shape_compound.h @@ -81,7 +81,7 @@ public: void AddShape( SHAPE* aShape ) { // Don't make clients deal with nested SHAPE_COMPOUNDs - if( aShape->HasIndexableSubshapes() ) + if( dynamic_cast<SHAPE_COMPOUND*>( aShape ) ) { std::vector<const SHAPE*> subshapes; aShape->GetIndexableSubshapes( subshapes ); @@ -102,7 +102,7 @@ public: void AddShape( std::shared_ptr<SHAPE> aShape ) { // Don't make clients deal with nested SHAPE_COMPOUNDs - if( aShape->HasIndexableSubshapes() ) + if( dynamic_cast<SHAPE_COMPOUND*>( aShape.get() ) ) { std::vector<const SHAPE*> subshapes; aShape->GetIndexableSubshapes( subshapes ); @@ -125,7 +125,7 @@ public: int Size() const { - return m_shapes.size(); + return (int) m_shapes.size(); } void Rotate( const EDA_ANGLE& aAngle, const VECTOR2I& aCenter = { 0, 0 } ) override; diff --git a/pcbnew/footprint.cpp b/pcbnew/footprint.cpp index e869ab3744..4c6a9fc636 100644 --- a/pcbnew/footprint.cpp +++ b/pcbnew/footprint.cpp @@ -2417,7 +2417,17 @@ void FOOTPRINT::CheckNetTies( const std::function<void( const BOARD_ITEM* aItem, for( BOARD_ITEM* item : m_drawings ) { if( item->IsOnCopperLayer() ) + { copperItems.push_back( item ); + } + else if( PCB_GROUP* group = dynamic_cast<PCB_GROUP*>( item ) ) + { + group->RunOnDescendants( [&]( BOARD_ITEM* descendent ) + { + if( descendent->IsOnCopperLayer() ) + copperItems.push_back( descendent ); + } ); + } } for( ZONE* zone : m_zones )