diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 2682a21631..e59d5b82e7 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -42,7 +42,8 @@ CONNECTIVITY_DATA::CONNECTIVITY_DATA() } -CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector& aItems ) +CONNECTIVITY_DATA::CONNECTIVITY_DATA( const std::vector& aItems, bool aSkipRatsnest ) + : m_skipRatsnest( aSkipRatsnest ) { Build( aItems ); m_progressReporter = nullptr; @@ -187,7 +188,8 @@ void CONNECTIVITY_DATA::RecalculateRatsnest( BOARD_COMMIT* aCommit ) m_connAlgo->ClearDirtyFlags(); - updateRatsnest(); + if( !m_skipRatsnest ) + updateRatsnest(); } @@ -254,7 +256,7 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector& return ; } - CONNECTIVITY_DATA connData( aItems ); + CONNECTIVITY_DATA connData( aItems, true ); BlockRatsnestItems( aItems ); for( unsigned int nc = 1; nc < connData.m_nets.size(); nc++ ) @@ -278,27 +280,19 @@ void CONNECTIVITY_DATA::ComputeDynamicRatsnest( const std::vector& } } - for( auto net : connData.m_nets ) + const auto& edges = GetRatsnestForItems( aItems ); + + for( const auto& edge : edges ) { - if( !net ) - continue; + const auto& nodeA = edge.GetSourceNode(); + const auto& nodeB = edge.GetTargetNode(); + RN_DYNAMIC_LINE l; - const auto& edges = net->GetUnconnected(); - - if( edges.empty() ) - continue; - - for( const auto& edge : edges ) - { - const auto& nodeA = edge.GetSourceNode(); - const auto& nodeB = edge.GetTargetNode(); - RN_DYNAMIC_LINE l; - - l.a = nodeA->Pos(); - l.b = nodeB->Pos(); - l.netCode = 0; - m_dynamicRatsnest.push_back( l ); - } + // Use the parents' positions + l.a = nodeA->Parent()->GetPosition(); + l.b = nodeB->Parent()->GetPosition(); + l.netCode = 0; + m_dynamicRatsnest.push_back( l ); } } @@ -521,68 +515,6 @@ unsigned int CONNECTIVITY_DATA::GetPadCount( int aNet ) const } -const std::vector CONNECTIVITY_DATA::NearestUnconnectedTargets( - const BOARD_CONNECTED_ITEM* aRef, - const VECTOR2I& aPos, - int aNet ) -{ - CN_CLUSTER_PTR refCluster; - int refNet = -1; - - if( aRef ) - refNet = aRef->GetNetCode(); - - if( aNet >= 0 ) - refNet = aNet; - - if( aRef ) - { - for( auto cl : m_connAlgo->GetClusters() ) - { - if( cl->Contains( aRef ) ) - { - refCluster = cl; - break; - } - } - } - - std::set anchors; - - for( auto cl : m_connAlgo->GetClusters() ) - { - if( cl != refCluster ) - { - for( auto item : *cl ) - { - if( item->Valid() && item->Parent()->GetNetCode() == refNet - && item->Parent()->Type() != PCB_ZONE_AREA_T ) - { - for( auto anchor : item->Anchors() ) - { - anchors.insert( anchor->Pos() ); - } - } - } - } - } - - - std::vector rv; - - std::copy( anchors.begin(), anchors.end(), std::back_inserter( rv ) ); - std::sort( rv.begin(), rv.end(), [aPos] ( const VECTOR2I& a, const VECTOR2I& b ) - { - auto da = (a - aPos).EuclideanNorm(); - auto db = (b - aPos).EuclideanNorm(); - - return da < db; - } ); - - return rv; -} - - void CONNECTIVITY_DATA::GetUnconnectedEdges( std::vector& aEdges) const { for( auto rnNet : m_nets ) @@ -689,6 +621,56 @@ void CONNECTIVITY_DATA::SetProgressReporter( PROGRESS_REPORTER* aReporter ) } +const std::vector CONNECTIVITY_DATA::GetRatsnestForItems( std::vector aItems ) +{ + std::set nets; + std::vector edges; + std::set item_set( aItems.begin(), aItems.end() ); + + for( auto item : aItems ) + { + auto conn_item = static_cast( item ); + + if( item->Type() == PCB_MODULE_T ) + { + auto component = static_cast( item ); + + for( auto pad : component->Pads() ) + { + nets.insert( pad->GetNetCode() ); + item_set.insert( pad ); + } + } + else + { + nets.insert( conn_item->GetNetCode() ); + } + } + + for( const auto& netcode : nets ) + { + const auto& net = GetRatsnestForNet( netcode ); + + for( const auto& edge : net->GetEdges() ) + { + auto srcNode = edge.GetSourceNode(); + auto dstNode = edge.GetTargetNode(); + + auto srcParent = static_cast( srcNode->Parent() ); + auto dstParent = static_cast( dstNode->Parent() ); + + bool srcFound = ( item_set.find(srcParent) != item_set.end() ); + bool dstFound = ( item_set.find(dstParent) != item_set.end() ); + + if ( srcFound && dstFound ) + edges.push_back( edge ); + } + } + + return edges; +} + + const std::vector CONNECTIVITY_DATA::GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections ) { std::set nets; diff --git a/pcbnew/connectivity/connectivity_data.h b/pcbnew/connectivity/connectivity_data.h index c3ebb5939f..47e11cc9a6 100644 --- a/pcbnew/connectivity/connectivity_data.h +++ b/pcbnew/connectivity/connectivity_data.h @@ -83,7 +83,7 @@ public: CONNECTIVITY_DATA(); ~CONNECTIVITY_DATA(); - CONNECTIVITY_DATA( const std::vector& aItems ); + CONNECTIVITY_DATA( const std::vector& aItems, bool aSkipItems = false ); /** * Function Build() @@ -227,10 +227,6 @@ public: const std::vector GetNetItems( int aNetCode, const KICAD_T aTypes[] ) const; - const std::vector NearestUnconnectedTargets( const BOARD_CONNECTED_ITEM* aRef, - const VECTOR2I& aPos, - int aMaxCount = -1 ); - void BlockRatsnestItems( const std::vector& aItems ); std::shared_ptr GetConnectivityAlgo() const @@ -247,6 +243,8 @@ public: void SetProgressReporter( PROGRESS_REPORTER* aReporter ); #ifndef SWIG + const std::vector GetRatsnestForItems( const std::vector aItems ); + const std::vector GetRatsnestForComponent( MODULE* aComponent, bool aSkipInternalConnections = false ); #endif @@ -262,6 +260,8 @@ private: PROGRESS_REPORTER* m_progressReporter; + bool m_skipRatsnest = false; + std::mutex m_lock; };