From 1936b45a0fa74e3e6493ccfe7eed61b7997c2885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20W=C5=82ostowski?= Date: Sat, 1 Jul 2017 23:54:17 +0200 Subject: [PATCH] Multiple connectivity algo crash fixes: - ratsnest crash on single-pad nets - connectivity crash on adding new net codes --- pcbnew/connectivity_algo.cpp | 15 ++++++++++----- pcbnew/connectivity_algo.h | 11 ++++++++--- pcbnew/ratsnest_data.cpp | 30 +++++++++++++++++++++--------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/pcbnew/connectivity_algo.cpp b/pcbnew/connectivity_algo.cpp index dbf74a7a5b..06a3616a31 100644 --- a/pcbnew/connectivity_algo.cpp +++ b/pcbnew/connectivity_algo.cpp @@ -203,7 +203,7 @@ void CN_CONNECTIVITY_ALGO::markItemNetAsDirty( const BOARD_ITEM* aItem ) if( aItem->IsConnected() ) { auto citem = static_cast( aItem ); - markNetAsDirty( citem->GetNetCode() ); + MarkNetAsDirty( citem->GetNetCode() ); } else { @@ -212,7 +212,7 @@ void CN_CONNECTIVITY_ALGO::markItemNetAsDirty( const BOARD_ITEM* aItem ) auto mod = static_cast ( aItem ); for( D_PAD* pad = mod->PadsList(); pad; pad = pad->Next() ) - markNetAsDirty( pad->GetNetCode() ); + MarkNetAsDirty( pad->GetNetCode() ); } } } @@ -224,6 +224,11 @@ bool CN_CONNECTIVITY_ALGO::Add( BOARD_ITEM* aItem ) switch( aItem->Type() ) { + case PCB_NETINFO_T: + { + MarkNetAsDirty( static_cast( aItem )->GetNet() ); + break; + } case PCB_MODULE_T: for( auto pad : static_cast( aItem ) -> Pads() ) { @@ -762,7 +767,7 @@ void CN_CONNECTIVITY_ALGO::propagateConnections() if( item->CanChangeNet() ) { item->Parent()->SetNetCode( cluster->OriginNet() ); - markNetAsDirty( cluster->OriginNet() ); + MarkNetAsDirty( cluster->OriginNet() ); n_changed++; } } @@ -826,9 +831,9 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS& CN_CONNECTIVITY_ALGO::GetClusters() } -void CN_CONNECTIVITY_ALGO::markNetAsDirty( int aNet ) +void CN_CONNECTIVITY_ALGO::MarkNetAsDirty( int aNet ) { - if( aNet <= 0 ) + if( aNet < 0 ) return; if( (int) m_dirtyNets.size() <= aNet ) diff --git a/pcbnew/connectivity_algo.h b/pcbnew/connectivity_algo.h index 31f4d83bce..38e7b5afb8 100644 --- a/pcbnew/connectivity_algo.h +++ b/pcbnew/connectivity_algo.h @@ -823,7 +823,6 @@ public: bool addConnectedItem( BOARD_CONNECTED_ITEM* aItem ); bool isDirty() const; - void markNetAsDirty( int aNet ); void markItemNetAsDirty( const BOARD_ITEM* aItem ); public: @@ -838,6 +837,9 @@ public: bool IsNetDirty( int aNet ) const { + if( aNet < 0 ) + return false; + return m_dirtyNets[ aNet ]; } @@ -883,8 +885,11 @@ public: CN_PAD_LIST& PadList() { return m_padList; } - void ForEachAnchor( std::function aFunc ); - void ForEachItem( std::function aFunc ); + void ForEachAnchor( std::function aFunc ); + void ForEachItem( std::function aFunc ); + + void MarkNetAsDirty( int aNet ); + }; bool operator<( const CN_ANCHOR_PTR a, const CN_ANCHOR_PTR b ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 3fa53c21fd..3e144d1ae2 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -235,18 +235,30 @@ public: for( int i = prevId; i < id; i++ ) anchorChains[prevId].push_back( m_allNodes[ i ] ); - - hed::TRIANGULATION triangulator; - triangulator.CreateDelaunay( triNodes.begin(), triNodes.end() ); - triangulator.GetEdges( triangEdges ); - - for( auto e : triangEdges ) + if( triNodes.size() == 1 ) { - auto src = m_allNodes[ e->GetSourceNode()->Id() ]; - auto dst = m_allNodes[ e->GetTargetNode()->Id() ]; - + return mstEdges; + } + else if( triNodes.size() == 2 ) + { + auto src = m_allNodes[ triNodes[0]->Id() ]; + auto dst = m_allNodes[ triNodes[1]->Id() ]; mstEdges.emplace_back( src, dst, getDistance( src, dst ) ); } + else + { + hed::TRIANGULATION triangulator; + triangulator.CreateDelaunay( triNodes.begin(), triNodes.end() ); + triangulator.GetEdges( triangEdges ); + + for( auto e : triangEdges ) + { + auto src = m_allNodes[ e->GetSourceNode()->Id() ]; + auto dst = m_allNodes[ e->GetTargetNode()->Id() ]; + + mstEdges.emplace_back( src, dst, getDistance( src, dst ) ); + } + } for( unsigned int i = 0; i < anchorChains.size(); i++ ) {