From e59aaf05c6e9cfbfdecac8b1b68ceab577a8f4e8 Mon Sep 17 00:00:00 2001 From: Jeff Young Date: Sun, 6 Feb 2022 17:26:30 +0000 Subject: [PATCH] Make sure that GetConnectedItems searches from the root item. Fixes https://gitlab.com/kicad/code/kicad/issues/10583 --- pcbnew/connectivity/connectivity_algo.cpp | 10 +++---- pcbnew/connectivity/connectivity_algo.h | 2 +- pcbnew/connectivity/connectivity_data.cpp | 30 +++++++++++-------- .../dialogs/dialog_track_via_properties.cpp | 2 +- .../drc_test_provider_zone_connections.cpp | 7 +++-- 5 files changed, 29 insertions(+), 22 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index fe9553ec8b..76ab5d02b0 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -315,9 +315,9 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST } -const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, - const KICAD_T aTypes[], - int aSingleNet ) +const CN_CONNECTIVITY_ALGO::CLUSTERS +CN_CONNECTIVITY_ALGO::SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], + int aSingleNet, CN_ITEM* rootItem ) { bool withinAnyNet = ( aMode != CSM_PROPAGATE ); @@ -330,7 +330,7 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST searchConnections(); auto addToSearchList = - [&item_set, withinAnyNet, aSingleNet, aTypes]( CN_ITEM *aItem ) + [&item_set, withinAnyNet, aSingleNet, aTypes, rootItem ]( CN_ITEM *aItem ) { if( withinAnyNet && aItem->Net() <= 0 ) return; @@ -352,7 +352,7 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST } } - if( !found ) + if( !found && aItem != rootItem ) return; aItem->SetVisited( false ); diff --git a/pcbnew/connectivity/connectivity_algo.h b/pcbnew/connectivity/connectivity_algo.h index 51229e5951..3773e9ad50 100644 --- a/pcbnew/connectivity/connectivity_algo.h +++ b/pcbnew/connectivity/connectivity_algo.h @@ -214,7 +214,7 @@ public: bool Add( BOARD_ITEM* aItem ); const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode, const KICAD_T aTypes[], - int aSingleNet ); + int aSingleNet, CN_ITEM* rootItem = nullptr ); const CLUSTERS SearchClusters( CLUSTER_SEARCH_MODE aMode ); /** diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index cf7deb97bc..2b5f93537e 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -438,23 +438,29 @@ void CONNECTIVITY_DATA::Clear() } -const std::vector CONNECTIVITY_DATA::GetConnectedItems( - const BOARD_CONNECTED_ITEM* aItem, - const KICAD_T aTypes[], - bool aIgnoreNetcodes ) const +const std::vector +CONNECTIVITY_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem, const KICAD_T aTypes[], + bool aIgnoreNetcodes ) const { - std::vector rv; - const auto clusters = m_connAlgo->SearchClusters( - aIgnoreNetcodes ? - CN_CONNECTIVITY_ALGO::CSM_PROPAGATE : - CN_CONNECTIVITY_ALGO::CSM_CONNECTIVITY_CHECK, aTypes, - aIgnoreNetcodes ? -1 : aItem->GetNetCode() ); + constexpr KICAD_T types[] = { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_VIA_T, PCB_ZONE_T, + PCB_FOOTPRINT_T, EOT }; - for( auto cl : clusters ) + std::vector rv; + CN_CONNECTIVITY_ALGO::CLUSTER_SEARCH_MODE searchMode; + + if( aIgnoreNetcodes ) + searchMode = CN_CONNECTIVITY_ALGO::CSM_PROPAGATE; + else + searchMode = CN_CONNECTIVITY_ALGO::CSM_CONNECTIVITY_CHECK; + + const auto clusters = m_connAlgo->SearchClusters( searchMode, types, + aIgnoreNetcodes ? -1 : aItem->GetNetCode() ); + + for( const std::shared_ptr& cl : clusters ) { if( cl->Contains( aItem ) ) { - for( const auto item : *cl ) + for( const CN_ITEM* item : *cl ) { if( item->Valid() ) rv.push_back( item->Parent() ); diff --git a/pcbnew/dialogs/dialog_track_via_properties.cpp b/pcbnew/dialogs/dialog_track_via_properties.cpp index 1a0521aa37..1dac064309 100644 --- a/pcbnew/dialogs/dialog_track_via_properties.cpp +++ b/pcbnew/dialogs/dialog_track_via_properties.cpp @@ -672,7 +672,7 @@ bool DIALOG_TRACK_VIA_PROPERTIES::TransferDataFromWindow() for( EDA_ITEM* item : m_items ) { - const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_PAD_T, PCB_VIA_T, PCB_FOOTPRINT_T, EOT }; + const KICAD_T ourTypes[] = { PCB_TRACE_T, PCB_ARC_T, PCB_PAD_T, PCB_VIA_T, PCB_FOOTPRINT_T, EOT }; BOARD_CONNECTED_ITEM* boardItem = static_cast( item ); auto connectedItems = connectivity->GetConnectedItems( boardItem, ourTypes, true ); diff --git a/pcbnew/drc/drc_test_provider_zone_connections.cpp b/pcbnew/drc/drc_test_provider_zone_connections.cpp index 7b70232898..c8743aa17d 100644 --- a/pcbnew/drc/drc_test_provider_zone_connections.cpp +++ b/pcbnew/drc/drc_test_provider_zone_connections.cpp @@ -106,11 +106,11 @@ bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run() if( m_drcEngine->IsErrorLimitExceeded( DRCE_STARVED_THERMAL ) ) return true; - // Quick test for connected: + // Quick test for "connected": if( pad->GetNetCode() != zone->GetNetCode() || pad->GetNetCode() <= 0 ) continue; - // More thorough test for connected: + // More thorough test for "connected", but still not layer-specific: const KICAD_T type_zone[] = { PCB_ZONE_T, EOT }; if( !alg::contains( connectivity->GetConnectedItems( pad, type_zone ), zone ) ) @@ -156,7 +156,8 @@ bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run() } } - if( spokes < minCount ) + // Note that spokes > 0 is our final "connected" test. + if( spokes > 0 && spokes < minCount ) { std::shared_ptr drce = DRC_ITEM::Create( DRCE_STARVED_THERMAL );