Commit 0c67e26e authored by Maciej Suminski's avatar Maciej Suminski

Added the dynamic ratsnest for the tracks that are currently routed with the PNS router.

parent 3e2e11fb
......@@ -705,12 +705,9 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem )
if( net < 1 ) // do not process unconnected items
return;
// Get list of nodes responding to the item
std::list<RN_NODE_PTR> nodes = m_nets[net].GetNodes( item );
std::list<RN_NODE_PTR>::iterator it, itEnd;
for( it = nodes.begin(), itEnd = nodes.end(); it != itEnd; ++it )
m_nets[net].AddSimpleNode( *it );
// Add all nodes belonging to the item
BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) )
m_nets[net].AddSimpleNode( node );
}
else if( aItem->Type() == PCB_MODULE_T )
{
......@@ -726,6 +723,46 @@ void RN_DATA::AddSimple( const BOARD_ITEM* aItem )
}
void RN_DATA::AddBlocked( const BOARD_ITEM* aItem )
{
int net;
if( aItem->IsConnected() )
{
const BOARD_CONNECTED_ITEM* item = static_cast<const BOARD_CONNECTED_ITEM*>( aItem );
net = item->GetNet();
if( net < 1 ) // do not process unconnected items
return;
// Block all nodes belonging to the item
BOOST_FOREACH( RN_NODE_PTR node, m_nets[net].GetNodes( item ) )
m_nets[net].AddBlockedNode( node );
}
else if( aItem->Type() == PCB_MODULE_T )
{
const MODULE* module = static_cast<const MODULE*>( aItem );
for( const D_PAD* pad = module->Pads().GetFirst(); pad; pad = pad->Next() )
AddBlocked( pad );
return;
}
else
return;
}
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_NET::processZones()
{
BOOST_FOREACH( std::deque<RN_EDGE_PTR>& edges, m_zoneConnections | boost::adaptors::map_values )
......@@ -773,17 +810,6 @@ void RN_NET::processZones()
}
void RN_DATA::updateNet( int aNetCode )
{
assert( aNetCode < (int) m_nets.size() );
if( aNetCode < 1 )
return;
m_nets[aNetCode].ClearSimple();
m_nets[aNetCode].Update();
}
void RN_DATA::Add( const BOARD_ITEM* aItem )
{
int net;
......@@ -946,3 +972,14 @@ void RN_DATA::Recalculate( int aNet )
updateNet( aNet );
}
}
void RN_DATA::updateNet( int aNetCode )
{
assert( aNetCode < (int) m_nets.size() );
if( aNetCode < 1 )
return;
m_nets[aNetCode].ClearSimple();
m_nets[aNetCode].Update();
}
......@@ -284,7 +284,7 @@ public:
/**
* Function MarkDirty()
* Marks ratsnest for given net as 'dirty', ie. requiring recomputation.
* Marks ratsnest for given net as 'dirty', i.e. requiring recomputation.
*/
void MarkDirty()
{
......@@ -432,7 +432,7 @@ public:
/**
* Function GetEdges()
* Returns pointer to the vector of edges that makes ratsnest for a given net.
* @return Pointer to the vector of edges that makes ratsnest for a given net
* @return Pointer to the vector of edges that makes ratsnest for a given net.
*/
const std::vector<RN_EDGE_PTR>* GetEdges() const
{
......@@ -441,8 +441,8 @@ public:
/**
* Function AddSimpleNode()
* Changes drawing mode for a node to simple (ie. one ratsnest line per node).
* @param aNode is a node that changes its drawing mode..
* Changes drawing mode for a node to simple (i.e. one ratsnest line per node).
* @param aNode is a node that changes its drawing mode.
*/
void AddSimpleNode( RN_NODE_PTR& aNode )
{
......@@ -450,9 +450,21 @@ public:
aNode->SetFlag( true );
}
/**
* Function AddBlockedNode()
* Specifies a node as not suitable as a ratsnest line target (i.e. ratsnest lines will not
* target the node). The status is cleared after calling ClearSimple().
* @param aNode is the node that is not going to be used as a ratsnest line target.
*/
void AddBlockedNode( RN_NODE_PTR& aNode )
{
m_blockedNodes.push_back( aNode );
aNode->SetFlag( true );
}
/**
* Function GetSimpleNodes()
* Returns list of nodes for which ratsnest is drawn in simple mode (ie. one
* Returns list of nodes for which ratsnest is drawn in simple mode (i.e. one
* ratsnest line per node).
* @return list of nodes for which ratsnest is drawn in simple mode.
*/
......@@ -470,11 +482,15 @@ public:
BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes )
node->SetFlag( false );
BOOST_FOREACH( const RN_NODE_PTR& node, m_blockedNodes )
node->SetFlag( false );
m_simpleNodes.clear();
m_blockedNodes.clear();
}
protected:
///> Validates edge, ie. modifies source and target nodes for an edge
///> Validates edge, i.e. modifies source and target nodes for an edge
///> to make sure that they are not ones with the flag set.
void validateEdge( RN_EDGE_PTR& aEdge );
......@@ -496,6 +512,9 @@ protected:
///> List of nodes for which ratsnest is drawn in simple mode.
std::deque<RN_NODE_PTR> m_simpleNodes;
///> List of nodes which should be used as ratsnest target nodes..
std::deque<RN_NODE_PTR> m_blockedNodes;
///> Flag indicating necessity of recalculation of ratsnest for a net.
bool m_dirty;
......@@ -556,12 +575,30 @@ public:
/**
* Function AddSimple()
* Sets an item to be drawn in simple mode (ie. one line per node, instead of full ratsnest).
* Sets an item to be drawn in simple mode (i.e. one line per node, instead of full ratsnest).
* It is used for drawing quick, temporary ratsnest, eg. while moving an item.
* @param aItem is an item to be drawn in simple node.
*/
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
* target its node(s)). The status is cleared after calling ClearSimple().
* @param aItem is the item of which node(s) are not going to be used as a ratsnest line target.
*/
void AddBlocked( const BOARD_ITEM* aItem );
/**
* Function ClearSimple()
* Clears the list of nodes for which ratsnest is drawn in simple mode (one line per node).
......
......@@ -63,14 +63,11 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
for( int i = 1; i < m_data->GetNetCount(); ++i )
{
const RN_NET& net = m_data->GetNet( i );
RN_NET& net = m_data->GetNet( i );
if( !net.IsVisible() )
continue;
// Avoid duplicate destinations for ratsnest lines by storing already used nodes
boost::unordered_set<RN_NODE_PTR> usedDestinations;
// Set brighter color for the temporary ratsnest
aGal->SetStrokeColor( color.Brightened( 0.8 ) );
......@@ -79,13 +76,15 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
{
RN_NODE_PTR dest = net.GetClosestNode( node, WITHOUT_FLAG() );
if( dest && usedDestinations.find( dest ) == usedDestinations.end() )
if( dest )
{
VECTOR2D origin( node->GetX(), node->GetY() );
VECTOR2D end( dest->GetX(), dest->GetY() );
aGal->DrawLine( origin, end );
usedDestinations.insert( dest );
// Avoid duplicate destinations for ratsnest lines by storing already used nodes
net.AddBlockedNode( dest );
}
}
......
......@@ -139,15 +139,20 @@ public:
const VECTOR2I SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplitsSegment );
/**
* Returns the last changes introduced by the router. After calling the method the list of
* changes is cleared, so only the latest changes are stored.
* Returns the last changes introduced by the router (since the last time ClearLastChanges()
* was called or a new track has been started).
*/
PICKED_ITEMS_LIST GetLastChanges()
const PICKED_ITEMS_LIST& GetLastChanges() const
{
PICKED_ITEMS_LIST copy = m_undoBuffer;
m_undoBuffer.ClearItemsList(); // TODO and delete?
return m_undoBuffer;
}
return copy;
/**
* Clears the list of recent changes, saved to be stored in the undo buffer.
*/
void ClearLastChanges()
{
m_undoBuffer.ClearItemsList();
}
private:
......
......@@ -32,6 +32,8 @@
#include <tool/context_menu.h>
#include <ratsnest_data.h>
#include "router_tool.h"
#include "pns_segment.h"
#include "pns_router.h"
......@@ -282,6 +284,30 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent )
ctls->ForceCursorPosition( false );
}
// Draw ratsnest for the currently routed track
RN_DATA* ratsnest = getModel<BOARD>( PCB_T )->GetRatsnest();
ratsnest->ClearSimple();
if( ( m_endItem == NULL || m_endItem == m_startItem ) && m_startItem->GetNet() > 0 )
{
// The ending node has to be first, so the line for the track is drawn first
ratsnest->AddSimple( m_endSnapPoint, m_startItem->GetNet() );
// Those nodes are added just to force ratsnest not to drawn
// lines to already routed parts of the track
const PICKED_ITEMS_LIST& changes = m_router->GetLastChanges();
for( unsigned int i = 0; i < changes.GetCount(); ++i )
{
// Block the new tracks, do not handle tracks that were moved
// (moved tracks are saved in the undo buffer with UR_DELETED status instead)
if( changes.GetPickedItemStatus( i ) == UR_NEW )
ratsnest->AddBlocked( static_cast<BOARD_CONNECTED_ITEM*>( changes.GetPickedItem( i ) ) );
}
// Also the origin of the new track should be skipped in the ratsnest shown for the routed track
ratsnest->AddBlocked( static_cast<BOARD_ITEM*>( m_startItem->GetParent() ) );
}
if( m_endItem )
TRACE( 0, "%s, layer : %d", m_endItem->GetKindStr().c_str() %
m_endItem->GetLayers().Start() );
......@@ -382,6 +408,7 @@ void ROUTER_TOOL::startRouting()
// Save the recent changes in the undo buffer
getEditFrame<PCB_EDIT_FRAME>()->SaveCopyInUndoList( m_router->GetLastChanges(),
UR_UNSPECIFIED );
m_router->ClearLastChanges();
getEditFrame<PCB_EDIT_FRAME>()->OnModify();
}
else
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment