From 37242f67e0189d5d1d1836a8ef918c7cd013719e Mon Sep 17 00:00:00 2001 From: Jon Evans Date: Sun, 21 Mar 2021 15:31:15 -0400 Subject: [PATCH] Connectivity: just pick the most popular net to update conflicting clusters CHANGED: when pad net assignments are changed in a conflicting way (i.e., tracks exist that short out more than one net after the change, track nets will be updated to the net with the most pads). Fixes https://gitlab.com/kicad/code/kicad/-/issues/7929 --- pcbnew/connectivity/connectivity_algo.cpp | 20 ++++++++-------- pcbnew/connectivity/connectivity_items.cpp | 27 ++++++++++++++++++---- pcbnew/connectivity/connectivity_items.h | 9 ++++---- 3 files changed, 38 insertions(+), 18 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 3ed63ee4e5..e4fe163974 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -481,17 +481,19 @@ void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit ) { for( const auto& cluster : m_connClusters ) { - if( cluster->IsConflicting() ) + if( cluster->IsOrphaned() ) { - wxLogTrace( "CN", "Conflicting nets in cluster %p\n", cluster.get() ); - } - else if( cluster->IsOrphaned() ) - { - wxLogTrace( "CN", "Skipping orphaned cluster %p [net: %s]\n", cluster.get(), + wxLogTrace( "CN", "Skipping orphaned cluster %p [net: %s]", cluster.get(), (const char*) cluster->OriginNetName().c_str() ); } else if( cluster->HasValidNet() ) { + if( cluster->IsConflicting() ) + { + wxLogTrace( "CN", "Conflicting nets in cluster %p; chose %d (%s)", cluster.get(), + cluster->OriginNet(), cluster->OriginNetName() ); + } + // normal cluster: just propagate from the pads int n_changed = 0; @@ -515,15 +517,15 @@ void CN_CONNECTIVITY_ALGO::propagateConnections( BOARD_COMMIT* aCommit ) if( n_changed ) { - wxLogTrace( "CN", "Cluster %p : net : %d %s\n", cluster.get(), + wxLogTrace( "CN", "Cluster %p : net : %d %s", cluster.get(), cluster->OriginNet(), (const char*) cluster->OriginNetName().c_str() ); } else - wxLogTrace( "CN", "Cluster %p : nothing to propagate\n", cluster.get() ); + wxLogTrace( "CN", "Cluster %p : nothing to propagate", cluster.get() ); } else { - wxLogTrace( "CN", "Cluster %p : connected to unused net\n", cluster.get() ); + wxLogTrace( "CN", "Cluster %p : connected to unused net", cluster.get() ); } } } diff --git a/pcbnew/connectivity/connectivity_items.cpp b/pcbnew/connectivity/connectivity_items.cpp index 6190c9d479..0c168c321b 100644 --- a/pcbnew/connectivity/connectivity_items.cpp +++ b/pcbnew/connectivity/connectivity_items.cpp @@ -472,20 +472,37 @@ void CN_CLUSTER::Add( CN_ITEM* item ) { m_items.push_back( item ); - if( item->Net() <= 0 ) + int netCode = item->Net(); + + if( netCode <= 0 ) return; if( m_originNet <= 0 ) { - m_originNet = item->Net(); + m_originNet = netCode; } if( item->Parent()->Type() == PCB_PAD_T ) { - if( !m_originPad ) + if( m_netRanks.count( netCode ) ) { - m_originPad = item; - m_originNet = item->Net(); + m_netRanks[netCode]++; + + if( m_netRanks.count( m_originNet ) && m_netRanks[netCode] > m_netRanks[m_originNet] ) + { + m_originPad = item; + m_originNet = netCode; + } + } + else + { + m_netRanks[netCode] = 1; + + if( !m_originPad ) + { + m_originPad = item; + m_originNet = netCode; + } } if( m_originPad && item->Net() != m_originNet ) diff --git a/pcbnew/connectivity/connectivity_items.h b/pcbnew/connectivity/connectivity_items.h index 82b733cedc..c036d398d6 100644 --- a/pcbnew/connectivity/connectivity_items.h +++ b/pcbnew/connectivity/connectivity_items.h @@ -451,10 +451,11 @@ private: class CN_CLUSTER { private: - bool m_conflicting; - int m_originNet; - CN_ITEM* m_originPad; - std::vector m_items; + bool m_conflicting; + int m_originNet; + CN_ITEM* m_originPad; + std::vector m_items; + std::unordered_map m_netRanks; public: CN_CLUSTER();