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

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

parent 3e2e11fb
Loading
Loading
Loading
Loading
+54 −17
Original line number Diff line number Diff line
@@ -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();
}
+44 −7
Original line number Diff line number Diff line
@@ -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).
+5 −6
Original line number Diff line number Diff line
@@ -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 );
            }
        }

+11 −6
Original line number Diff line number Diff line
@@ -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:
+27 −0
Original line number Diff line number Diff line
@@ -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