diff --git a/pcbnew/class_board.cpp b/pcbnew/class_board.cpp index a56c226d63..c046fb70fd 100644 --- a/pcbnew/class_board.cpp +++ b/pcbnew/class_board.cpp @@ -867,26 +867,41 @@ BOARD_ITEM* BOARD::Remove( BOARD_ITEM* aBoardItem ) break; case PCB_ZONE_AREA_T: // this one uses a vector + { + ZONE_CONTAINER* zone = static_cast( aBoardItem ); + // find the item in the vector, then delete then erase it. - for( unsigned i = 0; iGetNets()[zone->GetNet()].RemoveItem( zone ); + } + break; case PCB_MODULE_T: + { + MODULE* module = static_cast( aBoardItem ); m_Modules.Remove( (MODULE*) aBoardItem ); - break; + + for( D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() ) + m_ratsnest->GetNets()[pad->GetNet()].RemoveItem( pad ); + } + break; case PCB_TRACE_T: case PCB_VIA_T: - m_Track.Remove( (TRACK*) aBoardItem ); - break; + { + TRACK* track = static_cast( aBoardItem ); + m_Track.Remove( track ); + m_ratsnest->GetNets()[track->GetNet()].RemoveItem( track ); + } + break; case PCB_ZONE_T: m_Zone.Remove( (SEGZONE*) aBoardItem ); diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index e66451b86b..a5f708e0fe 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -201,12 +201,18 @@ const RN_NODE_PTR& RN_LINKS::AddNode( int aX, int aY ) } -void RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode ) +bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode ) { aNode->DecRefCount(); // TODO use the shared_ptr use_count if( aNode->GetRefCount() == 0 ) + { m_nodes.erase( aNode ); + + return true; + } + + return false; } @@ -270,6 +276,9 @@ void RN_NET::compute() void RN_NET::clearNode( const RN_NODE_PTR& aNode ) { + if( !m_rnEdges ) + return; + std::vector::iterator newEnd; // Remove all ratsnest edges for associated with the node @@ -430,75 +439,92 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone ) void RN_NET::RemoveItem( const D_PAD* aPad ) { - RN_NODE_PTR& node = m_pads[aPad]; - if( !node ) - return; + try + { + RN_NODE_PTR node = m_pads.at( aPad ); - // Remove edges associated with the node - clearNode( node ); - m_links.RemoveNode( node ); + if( m_links.RemoveNode( node ) ) + clearNode( node ); - m_pads.erase( aPad ); + m_pads.erase( aPad ); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const SEGVIA* aVia ) { - RN_NODE_PTR& node = m_vias[aVia]; - if( !node ) - return; + try + { + RN_NODE_PTR node = m_vias.at( aVia ); - // Remove edges associated with the node - clearNode( node ); - m_links.RemoveNode( node ); + if( m_links.RemoveNode( node ) ) + clearNode( node ); - m_vias.erase( aVia ); + m_vias.erase( aVia ); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const TRACK* aTrack ) { - RN_EDGE_PTR& edge = m_tracks[aTrack]; - if( !edge ) - return; + try + { + RN_EDGE_PTR& edge = m_tracks.at( aTrack ); - // Save nodes, so they can be cleared later - const RN_NODE_PTR& aBegin = edge->getSourceNode(); - const RN_NODE_PTR& aEnd = edge->getTargetNode(); - m_links.RemoveConnection( edge ); + // Save nodes, so they can be cleared later + RN_NODE_PTR aBegin = edge->getSourceNode(); + RN_NODE_PTR aEnd = edge->getTargetNode(); + m_links.RemoveConnection( edge ); - // Remove nodes associated with the edge. It is done in a safe way, there is a check - // if nodes are not used by other edges. - clearNode( aBegin ); - clearNode( aEnd ); - m_links.RemoveNode( aBegin ); - m_links.RemoveNode( aEnd ); + // Remove nodes associated with the edge. It is done in a safe way, there is a check + // if nodes are not used by other edges. + if( m_links.RemoveNode( aBegin ) ) + clearNode( aBegin ); - m_tracks.erase( aTrack ); + if( m_links.RemoveNode( aEnd ) ) + clearNode( aEnd ); - m_dirty = true; + m_tracks.erase( aTrack ); + + m_dirty = true; + } + catch( ... ) + { + } } void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone ) { - // Remove all subpolygons that make the zone - std::deque& polygons = m_zonePolygons[aZone]; - BOOST_FOREACH( RN_POLY& polygon, polygons ) - m_links.RemoveNode( polygon.GetNode() ); - polygons.clear(); + try + { + // Remove all subpolygons that make the zone + std::deque& polygons = m_zonePolygons.at( aZone ); + BOOST_FOREACH( RN_POLY& polygon, polygons ) + m_links.RemoveNode( polygon.GetNode() ); + polygons.clear(); - // Remove all connections added by the zone - std::deque& edges = m_zoneConnections[aZone]; - BOOST_FOREACH( RN_EDGE_PTR& edge, edges ) - m_links.RemoveConnection( edge ); - edges.clear(); + // Remove all connections added by the zone + std::deque& edges = m_zoneConnections.at( aZone ); + BOOST_FOREACH( RN_EDGE_PTR& edge, edges ) + m_links.RemoveConnection( edge ); + edges.clear(); - m_dirty = true; + m_dirty = true; + } + catch( ... ) + { + } } @@ -832,6 +858,7 @@ void RN_DATA::Recalculate( int aNet ) // Start with net number 1, as 0 stand for not connected for( unsigned int i = 1; i < m_board->GetNetCount(); ++i ) { + // Recompute only nets that require it if( m_nets[i].IsDirty() ) updateNet( i ); } diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 6d0e7ee896..f8ffbf2406 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -129,8 +129,9 @@ public: * Function RemoveNode() * Removes a node described by a given node pointer. * @param aNode is a pointer to node to be removed. + * @return True if node was removed, false if there were other references, so it was kept. */ - void RemoveNode( const RN_NODE_PTR& aNode ); + bool RemoveNode( const RN_NODE_PTR& aNode ); /** * Function GetNodes() @@ -577,7 +578,7 @@ public: * Returns ratsnest grouped by net numbers. * @return Vector of ratsnest grouped by net numbers. */ - const std::vector& GetNets() const + std::vector& GetNets() { return m_nets; }