From fa421f15d87829c7d8f1b98c3cc78b4fac15d37f Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Fri, 5 Jun 2015 17:49:00 +0200 Subject: [PATCH] Clearer dynamic ratsnest (for moved items). --- include/ttl/halfedge/hetriang.h | 3 ++ pcbnew/ratsnest_data.cpp | 62 ++++++++++++++++++++++++--------- pcbnew/ratsnest_data.h | 47 ++++++++++++------------- pcbnew/ratsnest_viewitem.cpp | 3 +- 4 files changed, 74 insertions(+), 41 deletions(-) diff --git a/include/ttl/halfedge/hetriang.h b/include/ttl/halfedge/hetriang.h index 6a22c08faa..59cfdaccb9 100644 --- a/include/ttl/halfedge/hetriang.h +++ b/include/ttl/halfedge/hetriang.h @@ -215,6 +215,9 @@ public: return m_layers; } + + // Tag used for unconnected items. + static const int TAG_UNCONNECTED = -1; }; diff --git a/pcbnew/ratsnest_data.cpp b/pcbnew/ratsnest_data.cpp index 1dd1dd5852..e06079a6e9 100644 --- a/pcbnew/ratsnest_data.cpp +++ b/pcbnew/ratsnest_data.cpp @@ -719,6 +719,22 @@ std::list RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode, } +void RN_NET::AddSimple( const BOARD_CONNECTED_ITEM* aItem ) +{ + std::list nodes = GetNodes( aItem ); + + if( nodes.empty() ) + return; + + int tag = nodes.front()->GetTag(); + + if( m_simpleItems.count( tag ) ) + return; // we already have a simple item for this tag + + m_simpleItems[tag] = aItem; +} + + std::list RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) const { std::list nodes; @@ -802,16 +818,42 @@ void RN_NET::GetAllItems( std::list& aOutput, RN_ITEM_TYP } +boost::unordered_set RN_NET::GetSimpleNodes() const +{ + boost::unordered_set nodes; + + BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_simpleItems | boost::adaptors::map_values ) + { + std::list n = GetNodes( item ); + + if( n.empty() ) + return nodes; + + nodes.insert( n.front() ); // one node is enough, the rest belong to the same item + n.front()->SetFlag( true ); + } + + return nodes; +} + + void RN_NET::ClearSimple() { - BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes ) - node->SetFlag( false ); + BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_simpleItems | boost::adaptors::map_values ) + { + std::list n = GetNodes( item ); + + if( n.empty() ) + return; + + n.front()->SetFlag( false ); + } BOOST_FOREACH( const RN_NODE_PTR& node, m_blockedNodes ) node->SetFlag( false ); - m_simpleNodes.clear(); m_blockedNodes.clear(); + m_simpleItems.clear(); } @@ -881,9 +923,7 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem ) if( net < 1 ) // do not process unconnected items return; - // Add all nodes belonging to the item - BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) ) - m_nets[net].AddSimpleNode( node ); + m_nets[net].AddSimple( item ); } else if( aItem->Type() == PCB_MODULE_T ) { @@ -929,16 +969,6 @@ void RN_DATA::AddBlocked( const BOARD_ITEM* aItem ) } -void RN_DATA::AddSimple( const VECTOR2I& aPosition, int aNetCode ) -{ - assert( aNetCode > 0 ); - - RN_NODE_PTR newNode = boost::make_shared( aPosition.x, aPosition.y ); - - m_nets[aNetCode].AddSimpleNode( newNode ); -} - - void RN_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem, std::list& aOutput, RN_ITEM_TYPE aTypes ) const diff --git a/pcbnew/ratsnest_data.h b/pcbnew/ratsnest_data.h index 315563b9fd..82e1e71ed9 100644 --- a/pcbnew/ratsnest_data.h +++ b/pcbnew/ratsnest_data.h @@ -100,6 +100,22 @@ struct WITHOUT_FLAG : public RN_NODE_FILTER } }; +///> Filters out nodes with a specific tag +struct DIFFERENT_TAG : public RN_NODE_FILTER +{ + DIFFERENT_TAG( int aTag ) : + m_tag( aTag ) + {} + + bool operator()( const RN_NODE_PTR& aNode ) const + { + return aNode->GetTag() != m_tag; + } + + private: + int m_tag; +}; + struct RN_NODE_AND_FILTER : public RN_NODE_FILTER { RN_NODE_AND_FILTER( const RN_NODE_FILTER& aFilter1, const RN_NODE_FILTER& aFilter2 ) : @@ -476,15 +492,11 @@ public: const RN_NODE_FILTER& aFilter, int aNumber = -1 ) const; /** - * Function AddSimpleNode() - * Changes drawing mode for a node to simple (i.e. one ratsnest line per node). + * Function AddSimple() + * Changes drawing mode for an item to simple (i.e. one ratsnest line per node). * @param aNode is a node that changes its drawing mode. */ - inline void AddSimpleNode( RN_NODE_PTR& aNode ) - { - m_simpleNodes.push_back( aNode ); - aNode->SetFlag( true ); - } + void AddSimple( const BOARD_CONNECTED_ITEM* aItem ); /** * Function AddBlockedNode() @@ -504,10 +516,7 @@ public: * ratsnest line per node). * @return list of nodes for which ratsnest is drawn in simple mode. */ - inline const std::deque& GetSimpleNodes() const - { - return m_simpleNodes; - } + boost::unordered_set GetSimpleNodes() const; /** * Function ClearSimple() @@ -546,12 +555,12 @@ protected: ///> Vector of edges that makes ratsnest for a given net. boost::shared_ptr< std::vector > m_rnEdges; - ///> List of nodes for which ratsnest is drawn in simple mode. - std::deque m_simpleNodes; - ///> List of nodes which will not be used as ratsnest target nodes. std::deque m_blockedNodes; + ///> Map that stores items to be computed in simple mode, keyed by their tags. + boost::unordered_map m_simpleItems; + ///> Flag indicating necessity of recalculation of ratsnest for a net. bool m_dirty; @@ -630,16 +639,6 @@ public: */ void AddSimple( const BOARD_ITEM* aItem ); - /** - * Function AddSimple() - * Allows to draw a ratsnest line using a position expressed in world coordinates and a - * net code (so there is no need to have a real BOARD_ITEM to draw ratsnest line). - * It is used for drawing quick, temporary ratsnest, eg. while moving an item. - * @param aPosition is the point for which ratsnest line are going to be drawn. - * @param aNetCode determines the net code for which the ratsnest line are going to be drawn. - */ - void AddSimple( const VECTOR2I& aPosition, int aNetCode ); - /** * Function AddBlocked() * Specifies an item as not suitable as a ratsnest line target (i.e. ratsnest lines will not diff --git a/pcbnew/ratsnest_viewitem.cpp b/pcbnew/ratsnest_viewitem.cpp index 4c98dd615b..8dc26fafb0 100644 --- a/pcbnew/ratsnest_viewitem.cpp +++ b/pcbnew/ratsnest_viewitem.cpp @@ -75,7 +75,8 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const // Draw the "dynamic" ratsnest (i.e. for objects that may be currently being moved) BOOST_FOREACH( const RN_NODE_PTR& node, net.GetSimpleNodes() ) { - RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() ); + RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() && + DIFFERENT_TAG( RN_NODE::TAG_UNCONNECTED ) ); if( dest ) {