diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index 42b666d37f..9997dc300b 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -213,6 +213,13 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem ) } +void CN_CONNECTIVITY_ALGO::RemoveInvalidRefs() +{ + for( CN_ITEM* item : m_itemList ) + item->RemoveInvalidRefs(); +} + + void CN_CONNECTIVITY_ALGO::searchConnections() { #ifdef PROFILE @@ -221,13 +228,12 @@ void CN_CONNECTIVITY_ALGO::searchConnections() std::vector garbage; garbage.reserve( 1024 ); - m_itemList.RemoveInvalidItems( garbage ); + m_parentConnectivityData->RemoveInvalidRefs(); if( m_isLocal ) - { - for( CN_ITEM* item : m_globalConnectivity->m_itemList ) - item->RemoveInvalidRefs(); - } + m_globalConnectivityData->RemoveInvalidRefs(); + + m_itemList.RemoveInvalidItems( garbage ); for( CN_ITEM* item : garbage ) delete item; @@ -559,11 +565,11 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) } -void CN_CONNECTIVITY_ALGO::LocalBuild( std::shared_ptr aGlobalConnectivity, +void CN_CONNECTIVITY_ALGO::LocalBuild( std::shared_ptr aGlobalConnectivity, const std::vector& aLocalItems ) { m_isLocal = true; - m_globalConnectivity = aGlobalConnectivity; + m_globalConnectivityData = aGlobalConnectivity; for( BOARD_ITEM* item : aLocalItems ) { diff --git a/pcbnew/connectivity/connectivity_algo.h b/pcbnew/connectivity/connectivity_algo.h index 09b4b39350..862e81050d 100644 --- a/pcbnew/connectivity/connectivity_algo.h +++ b/pcbnew/connectivity/connectivity_algo.h @@ -92,6 +92,15 @@ public: void SetSourceNode( const std::shared_ptr& aNode ) { m_source = aNode; } void SetTargetNode( const std::shared_ptr& aNode ) { m_target = aNode; } + void RemoveInvalidRefs() + { + if( m_source && !m_source->Valid() ) + m_source.reset(); + + if( m_target && !m_target->Valid() ) + m_target.reset(); + } + void SetWeight( unsigned weight ) { m_weight = weight; } unsigned GetWeight() const { return m_weight; } @@ -158,7 +167,8 @@ public: std::list m_items; }; - CN_CONNECTIVITY_ALGO() : + CN_CONNECTIVITY_ALGO( CONNECTIVITY_DATA* aParentConnectivityData ) : + m_parentConnectivityData( aParentConnectivityData ), m_isLocal( false ) {} @@ -208,7 +218,7 @@ public: } void Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter = nullptr ); - void LocalBuild( std::shared_ptr aGlobalConnectivity, + void LocalBuild( std::shared_ptr aGlobalConnectivity, const std::vector& aLocalItems ); void Clear(); @@ -258,6 +268,8 @@ public: } void MarkNetAsDirty( int aNet ); + void RemoveInvalidRefs(); + void SetProgressReporter( PROGRESS_REPORTER* aReporter ); private: @@ -276,6 +288,7 @@ private: void markItemNetAsDirty( const BOARD_ITEM* aItem ); private: + CONNECTIVITY_DATA* m_parentConnectivityData; CN_LIST m_itemList; std::unordered_map m_itemMap; @@ -284,7 +297,7 @@ private: std::vector m_dirtyNets; bool m_isLocal; - std::shared_ptr m_globalConnectivity; + std::shared_ptr m_globalConnectivityData; PROGRESS_REPORTER* m_progressReporter = nullptr; }; diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index af67663412..57022eb587 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -47,7 +47,7 @@ CONNECTIVITY_DATA::CONNECTIVITY_DATA() : m_skipRatsnestUpdate( false ) { - m_connAlgo.reset( new CN_CONNECTIVITY_ALGO ); + m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) ); m_progressReporter = nullptr; m_fromToCache.reset( new FROM_TO_CACHE ); } @@ -112,7 +112,7 @@ bool CONNECTIVITY_DATA::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter ) std::shared_ptr& netSettings = aBoard->GetDesignSettings().m_NetSettings; - m_connAlgo.reset( new CN_CONNECTIVITY_ALGO ); + m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) ); m_connAlgo->Build( aBoard, aReporter ); m_netclassMap.clear(); @@ -151,8 +151,8 @@ void CONNECTIVITY_DATA::Build( std::shared_ptr& aGlobalConnec if( !lock ) return; - m_connAlgo.reset( new CN_CONNECTIVITY_ALGO ); - m_connAlgo->LocalBuild( aGlobalConnectivity->GetConnectivityAlgo(), aLocalItems ); + m_connAlgo.reset( new CN_CONNECTIVITY_ALGO( this ) ); + m_connAlgo->LocalBuild( aGlobalConnectivity, aLocalItems ); internalRecalculateRatsnest(); } @@ -932,6 +932,15 @@ void CONNECTIVITY_DATA::MarkItemNetAsDirty( BOARD_ITEM *aItem ) } +void CONNECTIVITY_DATA::RemoveInvalidRefs() +{ + m_connAlgo->RemoveInvalidRefs(); + + for( RN_NET* rnNet : m_nets ) + rnNet->RemoveInvalidRefs(); +} + + void CONNECTIVITY_DATA::SetProgressReporter( PROGRESS_REPORTER* aReporter ) { m_progressReporter = aReporter; diff --git a/pcbnew/connectivity/connectivity_data.h b/pcbnew/connectivity/connectivity_data.h index 45f35c9fbb..008fc49126 100644 --- a/pcbnew/connectivity/connectivity_data.h +++ b/pcbnew/connectivity/connectivity_data.h @@ -268,6 +268,8 @@ public: KISPINLOCK& GetLock() { return m_lock; } void MarkItemNetAsDirty( BOARD_ITEM* aItem ); + void RemoveInvalidRefs(); + void SetProgressReporter( PROGRESS_REPORTER* aReporter ); const std::map& GetNetclassMap() const { return m_netclassMap; } diff --git a/pcbnew/connectivity/connectivity_items.cpp b/pcbnew/connectivity/connectivity_items.cpp index 70c789c9f3..021f5428e7 100644 --- a/pcbnew/connectivity/connectivity_items.cpp +++ b/pcbnew/connectivity/connectivity_items.cpp @@ -288,9 +288,6 @@ void CN_LIST::RemoveInvalidItems( std::vector& aGarbage ) m_items.resize( lastItem - m_items.begin() ); - for( CN_ITEM* item : m_items ) - item->RemoveInvalidRefs(); - for( CN_ITEM* item : aGarbage ) m_index.Remove( item ); diff --git a/pcbnew/ratsnest/ratsnest_data.cpp b/pcbnew/ratsnest/ratsnest_data.cpp index 7cc2cc03e2..b71c6cba5a 100644 --- a/pcbnew/ratsnest/ratsnest_data.cpp +++ b/pcbnew/ratsnest/ratsnest_data.cpp @@ -456,6 +456,16 @@ void RN_NET::UpdateNet() } +void RN_NET::RemoveInvalidRefs() +{ + for( CN_EDGE& edge : m_rnEdges ) + edge.RemoveInvalidRefs(); + + for( CN_EDGE& edge : m_boardEdges ) + edge.RemoveInvalidRefs(); +} + + void RN_NET::Clear() { m_rnEdges.clear(); diff --git a/pcbnew/ratsnest/ratsnest_data.h b/pcbnew/ratsnest/ratsnest_data.h index 3553e3909f..955458de3b 100644 --- a/pcbnew/ratsnest/ratsnest_data.h +++ b/pcbnew/ratsnest/ratsnest_data.h @@ -77,6 +77,8 @@ public: */ void UpdateNet(); + void RemoveInvalidRefs(); + /** * Find optimal ends of RNEdges. The MST will have found the closest anchors, but when * zones are involved we might have points closer than the anchors. diff --git a/pcbnew/ratsnest/ratsnest_view_item.cpp b/pcbnew/ratsnest/ratsnest_view_item.cpp index a9fc679f7d..76341be370 100644 --- a/pcbnew/ratsnest/ratsnest_view_item.cpp +++ b/pcbnew/ratsnest/ratsnest_view_item.cpp @@ -198,12 +198,13 @@ void RATSNEST_VIEW_ITEM::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const const std::shared_ptr& sourceNode = edge.GetSourceNode(); const std::shared_ptr& targetNode = edge.GetTargetNode(); - const VECTOR2I source( sourceNode->Pos() ); - const VECTOR2I target( targetNode->Pos() ); - if( !sourceNode->Valid() || !targetNode->Valid() ) + if( !sourceNode || !sourceNode->Valid() || !targetNode || !targetNode->Valid() ) continue; + const VECTOR2I source( sourceNode->Pos() ); + const VECTOR2I target( targetNode->Pos() ); + bool enable = !sourceNode->GetNoLine() && !targetNode->GetNoLine(); bool show;