Clearer dynamic ratsnest (for moved items).

This commit is contained in:
Maciej Suminski 2015-06-05 17:49:00 +02:00
parent 16db8e644b
commit fa421f15d8
4 changed files with 74 additions and 41 deletions

View File

@ -215,6 +215,9 @@ public:
return m_layers;
}
// Tag used for unconnected items.
static const int TAG_UNCONNECTED = -1;
};

View File

@ -719,6 +719,22 @@ std::list<RN_NODE_PTR> RN_NET::GetClosestNodes( const RN_NODE_PTR& aNode,
}
void RN_NET::AddSimple( const BOARD_CONNECTED_ITEM* aItem )
{
std::list<RN_NODE_PTR> 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_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) const
{
std::list<RN_NODE_PTR> nodes;
@ -802,16 +818,42 @@ void RN_NET::GetAllItems( std::list<BOARD_CONNECTED_ITEM*>& aOutput, RN_ITEM_TYP
}
boost::unordered_set<RN_NODE_PTR> RN_NET::GetSimpleNodes() const
{
boost::unordered_set<RN_NODE_PTR> nodes;
BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_simpleItems | boost::adaptors::map_values )
{
std::list<RN_NODE_PTR> 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<RN_NODE_PTR> 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<RN_NODE>( aPosition.x, aPosition.y );
m_nets[aNetCode].AddSimpleNode( newNode );
}
void RN_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
std::list<BOARD_CONNECTED_ITEM*>& aOutput,
RN_ITEM_TYPE aTypes ) const

View File

@ -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<RN_NODE_PTR>& GetSimpleNodes() const
{
return m_simpleNodes;
}
boost::unordered_set<RN_NODE_PTR> GetSimpleNodes() const;
/**
* Function ClearSimple()
@ -546,12 +555,12 @@ protected:
///> Vector of edges that makes ratsnest for a given net.
boost::shared_ptr< std::vector<RN_EDGE_MST_PTR> > m_rnEdges;
///> List of nodes for which ratsnest is drawn in simple mode.
std::deque<RN_NODE_PTR> m_simpleNodes;
///> List of nodes which will not be used as ratsnest target nodes.
std::deque<RN_NODE_PTR> m_blockedNodes;
///> Map that stores items to be computed in simple mode, keyed by their tags.
boost::unordered_map<int, const BOARD_CONNECTED_ITEM*> 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

View File

@ -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 )
{