Commit 190af5d9 authored by Maciej Suminski's avatar Maciej Suminski

Added functions to resolve connectivity queries in ratsnest (GAL).

parent e6a10faa
......@@ -4,21 +4,21 @@
* Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
* Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern,
* 0314 Oslo, Norway.
*
* This file is part of TTL.
*
* TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
* License, or (at your option) any later version.
*
* TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public
......@@ -36,7 +36,7 @@
* disclosing the source code of your own applications.
*
* This file may be used in accordance with the terms contained in a
* written agreement between you and SINTEF ICT.
* written agreement between you and SINTEF ICT.
*/
#ifndef _HE_TRIANG_H_
......@@ -100,6 +100,9 @@ protected:
/// Node coordinates
int m_x, m_y;
/// Tag for quick connection resolution
int m_tag;
/// Reference count
unsigned int m_refCount;
......@@ -112,7 +115,7 @@ public:
#ifdef TTL_USE_NODE_ID
m_id( id_count++ ),
#endif
m_x( aX ), m_y( aY ), m_refCount( 0 )
m_x( aX ), m_y( aY ), m_tag( -1 ), m_refCount( 0 )
{
}
......@@ -120,20 +123,32 @@ public:
~NODE() {}
/// Returns the x-coordinate
int GetX() const
inline int GetX() const
{
return m_x;
}
/// Returns the y-coordinate
int GetY() const
inline int GetY() const
{
return m_y;
}
/// Returns tag, common identifier for connected nodes
inline int GetTag() const
{
return m_tag;
}
/// Sets tag, common identifier for connected nodes
inline void SetTag( int aTag )
{
m_tag = aTag;
}
#ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined)
int Id() const
inline int Id() const
{
return m_id;
}
......@@ -141,35 +156,35 @@ public:
#ifdef TTL_USE_NODE_FLAG
/// Sets the flag (TTL_USE_NODE_FLAG must be defined)
void SetFlag( bool aFlag )
inline void SetFlag( bool aFlag )
{
m_flag = aFlag;
}
/// Returns the flag (TTL_USE_NODE_FLAG must be defined)
const bool& GetFlag() const
inline const bool& GetFlag() const
{
return m_flag;
}
#endif
void IncRefCount()
inline void IncRefCount()
{
m_refCount++;
}
void DecRefCount()
inline void DecRefCount()
{
m_refCount--;
}
unsigned int GetRefCount() const
inline unsigned int GetRefCount() const
{
return m_refCount;
}
};
/**
* \class EDGE
* \brief \b %Edge class in the in the half-edge data structure.
......@@ -187,55 +202,65 @@ public:
{
}
/// Returns tag, common identifier for connected nodes
inline int GetTag() const
{
int tag = GetSourceNode()->GetTag();
if( tag >= 0 )
return tag;
return GetTargetNode()->GetTag();
}
/// Sets the source node
void SetSourceNode( const NODE_PTR& aNode )
inline void SetSourceNode( const NODE_PTR& aNode )
{
m_sourceNode = aNode;
}
/// Sets the next edge in face
void SetNextEdgeInFace( const EDGE_PTR& aEdge )
inline void SetNextEdgeInFace( const EDGE_PTR& aEdge )
{
m_nextEdgeInFace = aEdge;
}
/// Sets the twin edge
void SetTwinEdge( const EDGE_PTR& aEdge )
inline void SetTwinEdge( const EDGE_PTR& aEdge )
{
m_twinEdge = aEdge;
}
/// Sets the edge as a leading edge
void SetAsLeadingEdge( bool aLeading = true )
inline void SetAsLeadingEdge( bool aLeading = true )
{
m_isLeadingEdge = aLeading;
}
/// Checks if an edge is a leading edge
bool IsLeadingEdge() const
inline bool IsLeadingEdge() const
{
return m_isLeadingEdge;
}
/// Returns the twin edge
EDGE_PTR GetTwinEdge() const
inline EDGE_PTR GetTwinEdge() const
{
return m_twinEdge.lock();
}
void ClearTwinEdge()
inline void ClearTwinEdge()
{
m_twinEdge.reset();
}
/// Returns the next edge in face
const EDGE_PTR& GetNextEdgeInFace() const
inline const EDGE_PTR& GetNextEdgeInFace() const
{
return m_nextEdgeInFace;
}
/// Retuns the source node
const NODE_PTR& GetSourceNode() const
inline const NODE_PTR& GetSourceNode() const
{
return m_sourceNode;
}
......@@ -246,12 +271,12 @@ public:
return m_nextEdgeInFace->GetSourceNode();
}
void SetWeight( unsigned int weight )
inline void SetWeight( unsigned int weight )
{
m_weight = weight;
}
unsigned int GetWeight() const
inline unsigned int GetWeight() const
{
return m_weight;
}
......@@ -294,22 +319,17 @@ public:
m_weight = aWeight;
}
EDGE_MST( const EDGE& edge )
{
m_sourceNode = edge.GetSourceNode();
m_target = edge.GetTargetNode();
m_weight = edge.GetWeight();
}
~EDGE_MST()
{
}
/// @copydoc Edge::setSourceNode()
virtual const NODE_PTR& GetTargetNode() const
{
return m_target;
}
private:
EDGE_MST( const EDGE& aEdge )
{
assert( false );
}
};
class DART; // Forward declaration (class in this namespace)
......@@ -410,7 +430,7 @@ public:
/// Swaps the edge associated with diagonal
void SwapEdge( EDGE_PTR& aDiagonal );
/// Splits the triangle associated with edge into three new triangles joining at point
/// Splits the triangle associated with edge into three new triangles joining at point
EDGE_PTR SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint );
// Functions required by TTL for removing nodes in a Delaunay triangulation
......@@ -440,7 +460,7 @@ public:
std::list<EDGE_PTR>* GetEdges( bool aSkipBoundaryEdges = false ) const;
#ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes
/// Sets flag in all the nodes
void FlagNodes( bool aFlag ) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013-2015 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
......@@ -96,22 +96,26 @@ bool isEdgeConnectingNode( const RN_EDGE_PTR& aEdge, const RN_NODE_PTR& aNode )
}
std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
const std::vector<RN_NODE_PTR>& aNodes )
static std::vector<RN_EDGE_MST_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
std::vector<RN_NODE_PTR>& aNodes )
{
unsigned int nodeNumber = aNodes.size();
unsigned int mstExpectedSize = nodeNumber - 1;
unsigned int mstSize = 0;
bool ratsnestLines = false;
// The output
std::vector<RN_EDGE_PTR>* mst = new std::vector<RN_EDGE_PTR>;
std::vector<RN_EDGE_MST_PTR>* mst = new std::vector<RN_EDGE_MST_PTR>;
mst->reserve( mstExpectedSize );
// Set tags for marking cycles
boost::unordered_map<RN_NODE_PTR, int> tags;
unsigned int tag = 0;
BOOST_FOREACH( const RN_NODE_PTR& node, aNodes )
BOOST_FOREACH( RN_NODE_PTR& node, aNodes )
{
node->SetTag( tag );
tags[node] = tag++;
}
// Lists of nodes connected together (subtrees) to detect cycles in the graph
std::vector<std::list<int> > cycles( nodeNumber );
......@@ -123,27 +127,40 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
while( mstSize < mstExpectedSize && !aEdges.empty() )
{
RN_EDGE_PTR& dt = *aEdges.begin();
RN_EDGE_PTR& dt = aEdges.front();
int srcTag = tags[dt->GetSourceNode()];
int trgTag = tags[dt->GetTargetNode()];
// Because edges are sorted by their weight, first we always process connected
// items (weight == 0). Once we stumble upon an edge with non-zero weight,
// it means that the rest of the lines are ratsnest.
if( !ratsnestLines && dt->GetWeight() != 0 )
ratsnestLines = true;
// Check if by adding this edge we are going to join two different forests
if( srcTag != trgTag )
{
// Update tags
std::list<int>::iterator it, itEnd;
for( it = cycles[trgTag].begin(), itEnd = cycles[trgTag].end(); it != itEnd; ++it )
tags[aNodes[*it]] = srcTag;
// Move nodes that were marked with old tag to the list marked with the new tag
cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
if( dt->GetWeight() == 0 ) // Skip already existing connections (weight == 0)
if( ratsnestLines )
{
mstExpectedSize--;
for( it = cycles[trgTag].begin(), itEnd = cycles[trgTag].end(); it != itEnd; ++it )
tags[aNodes[*it]] = srcTag;
}
else
{
for( it = cycles[trgTag].begin(), itEnd = cycles[trgTag].end(); it != itEnd; ++it ) {
tags[aNodes[*it]] = srcTag;
aNodes[*it]->SetTag( srcTag );
}
}
// Move nodes that were marked with old tag to the list marked with the new tag
cycles[srcTag].splice( cycles[srcTag].end(), cycles[trgTag] );
if( ratsnestLines )
{
// Do a copy of edge, but make it RN_EDGE_MST. In contrary to RN_EDGE,
// RN_EDGE_MST saves both source and target node and does not require any other
......@@ -154,6 +171,11 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
mst->push_back( newEdge );
++mstSize;
}
else
{
// Processing a connection, decrease the expected size of the ratsnest MST
--mstExpectedSize;
}
}
// Remove the edge that was just processed
......@@ -167,7 +189,7 @@ std::vector<RN_EDGE_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
}
void RN_NET::validateEdge( RN_EDGE_PTR& aEdge )
void RN_NET::validateEdge( RN_EDGE_MST_PTR& aEdge )
{
RN_NODE_PTR source = aEdge->GetSourceNode();
RN_NODE_PTR target = aEdge->GetTargetNode();
......@@ -238,12 +260,13 @@ bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode )
}
const RN_EDGE_PTR& RN_LINKS::AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
unsigned int aDistance )
RN_EDGE_MST_PTR RN_LINKS::AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
unsigned int aDistance )
{
m_edges.push_back( boost::make_shared<RN_EDGE_MST>( aNode1, aNode2, aDistance ) );
RN_EDGE_MST_PTR edge = boost::make_shared<RN_EDGE_MST>( aNode1, aNode2, aDistance );
m_edges.push_back( edge );
return m_edges.back();
return edge;
}
......@@ -252,10 +275,10 @@ void RN_NET::compute()
const RN_LINKS::RN_NODE_SET& boardNodes = m_links.GetNodes();
const RN_LINKS::RN_EDGE_LIST& boardEdges = m_links.GetConnections();
// Special case that does need so complicated algorithm
if( boardNodes.size() == 2 )
// Special cases that does need so complicated algorithm
if( boardNodes.size() <= 2 )
{
m_rnEdges.reset( new std::vector<RN_EDGE_PTR>( 0 ) );
m_rnEdges.reset( new std::vector<RN_EDGE_MST_PTR>( 0 ) );
// Check if the only possible connection exists
if( boardEdges.size() == 0 )
......@@ -268,12 +291,6 @@ void RN_NET::compute()
return;
}
else if( boardNodes.size() <= 1 ) // This case is even simpler
{
m_rnEdges.reset( new std::vector<RN_EDGE_PTR>( 0 ) );
return;
}
// Move and sort (sorting speeds up) all nodes to a vector for the Delaunay triangulation
std::vector<RN_NODE_PTR> nodes( boardNodes.size() );
......@@ -301,7 +318,7 @@ void RN_NET::clearNode( const RN_NODE_PTR& aNode )
if( !m_rnEdges )
return;
std::vector<RN_EDGE_PTR>::iterator newEnd;
std::vector<RN_EDGE_MST_PTR>::iterator newEnd;
// Remove all ratsnest edges for associated with the node
newEnd = std::remove_if( m_rnEdges->begin(), m_rnEdges->end(),
......@@ -377,7 +394,7 @@ void RN_NET::Update()
compute();
BOOST_FOREACH( RN_EDGE_PTR& edge, *m_rnEdges )
BOOST_FOREACH( RN_EDGE_MST_PTR& edge, *m_rnEdges )
validateEdge( edge );
m_dirty = false;
......@@ -386,8 +403,7 @@ void RN_NET::Update()
void RN_NET::AddItem( const D_PAD* aPad )
{
RN_NODE_PTR nodePtr = m_links.AddNode( aPad->GetPosition().x, aPad->GetPosition().y );
m_pads[aPad] = nodePtr;
m_pads[aPad] = m_links.AddNode( aPad->GetPosition().x, aPad->GetPosition().y );
m_dirty = true;
}
......@@ -505,7 +521,7 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
{
try
{
RN_EDGE_PTR& edge = m_tracks.at( aTrack );
RN_EDGE_MST_PTR& edge = m_tracks.at( aTrack );
// Save nodes, so they can be cleared later
RN_NODE_PTR aBegin = edge->GetSourceNode();
......@@ -546,8 +562,8 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
polygons.clear();
// Remove all connections added by the zone
std::deque<RN_EDGE_PTR>& edges = m_zoneConnections.at( aZone );
BOOST_FOREACH( RN_EDGE_PTR& edge, edges )
std::deque<RN_EDGE_MST_PTR>& edges = m_zoneConnections.at( aZone );
BOOST_FOREACH( RN_EDGE_PTR edge, edges )
m_links.RemoveConnection( edge );
edges.clear();
......@@ -694,7 +710,7 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
case PCB_TRACE_T:
{
const TRACK* track = static_cast<const TRACK*>( aItem );
RN_EDGE_PTR edge = m_tracks.at( track );
const RN_EDGE_MST_PTR& edge = m_tracks.at( track );
nodes.push_back( edge->GetSourceNode() );
nodes.push_back( edge->GetTargetNode() );
......@@ -714,6 +730,76 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
}
void RN_NET::ClearSimple()
{
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();
}
void RN_NET::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
std::list<BOARD_CONNECTED_ITEM*>& aOutput,
RN_ITEM_TYPES aTypes ) const
{
std::list<RN_NODE_PTR> nodes = GetNodes( aItem );
assert( !nodes.empty() );
int tag = nodes.front()->GetTag();
assert( tag >= 0 );
if( aTypes & RN_PADS )
{
for( PAD_NODE_MAP::const_iterator it = m_pads.begin(); it != m_pads.end(); ++it )
{
if( it->second->GetTag() == tag )
aOutput.push_back( const_cast<D_PAD*>( it->first ) );
}
}
if( aTypes & RN_VIAS )
{
for( VIA_NODE_MAP::const_iterator it = m_vias.begin(); it != m_vias.end(); ++it )
{
if( it->second->GetTag() == tag )
aOutput.push_back( const_cast<VIA*>( it->first ) );
}
}
if( aTypes & RN_TRACKS )
{
for( TRACK_EDGE_MAP::const_iterator it = m_tracks.begin(); it != m_tracks.end(); ++it )
{
if( it->second->GetTag() == tag )
aOutput.push_back( const_cast<TRACK*>( it->first ) );
}
}
if( aTypes & RN_ZONES )
{
for( ZONE_EDGE_MAP::const_iterator it = m_zoneConnections.begin();
it != m_zoneConnections.end(); ++it )
{
const std::deque<RN_EDGE_MST_PTR>& edges = it->second;
BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, edges )
{
if( edge->GetTag() == tag )
{
aOutput.push_back( const_cast<ZONE_CONTAINER*>( it->first ) );
break;
}
}
}
}
}
void RN_DATA::AddSimple( const BOARD_ITEM* aItem )
{
int net;
......@@ -784,11 +870,46 @@ void RN_DATA::AddSimple( const VECTOR2I& aPosition, int aNetCode )
}
void RN_DATA::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
std::list<BOARD_CONNECTED_ITEM*>& aOutput,
RN_ITEM_TYPES aTypes ) const
{
int net = aItem->GetNetCode();
if( net < 1 )
return;
assert( net < (int) m_nets.size() );
m_nets[net].GetConnectedItems( aItem, aOutput, aTypes );
}
bool RN_DATA::AreConnected( const BOARD_CONNECTED_ITEM* aItem, const BOARD_CONNECTED_ITEM* aOther )
{
int net1 = aItem->GetNetCode();
int net2 = aOther->GetNetCode();
if( net1 < 1 || net2 < 1 || net1 != net2 )
return false;
assert( net1 < (int) m_nets.size() && net2 < (int) m_nets.size() );
// net1 == net2
std::list<RN_NODE_PTR> items1 = m_nets[net1].GetNodes( aItem );
std::list<RN_NODE_PTR> items2 = m_nets[net1].GetNodes( aOther );
assert( !items1.empty() && !items2.empty() );
return ( items1.front()->GetTag() == items2.front()->GetTag() );
}
void RN_NET::processZones()
{
BOOST_FOREACH( std::deque<RN_EDGE_PTR>& edges, m_zoneConnections | boost::adaptors::map_values )
BOOST_FOREACH( std::deque<RN_EDGE_MST_PTR>& edges, m_zoneConnections | boost::adaptors::map_values )
{
BOOST_FOREACH( RN_EDGE_PTR& edge, edges )
BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
m_links.RemoveConnection( edge );
edges.clear();
......@@ -814,7 +935,7 @@ void RN_NET::processZones()
{
if( poly->HitTest( *point ) )
{
const RN_EDGE_PTR& connection = m_links.AddConnection( poly->GetNode(), *point );
RN_EDGE_MST_PTR connection = m_links.AddConnection( poly->GetNode(), *point );
m_zoneConnections[poly->GetParent()].push_back( connection );
// This point already belongs to a polygon, we do not need to check it anymore
......
/*
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2013 CERN
* Copyright (C) 2013-2015 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
......@@ -49,6 +49,16 @@ class TRACK;
class ZONE_CONTAINER;
class CPolyPt;
///> Types of items that are handled by the class
enum RN_ITEM_TYPES
{
RN_PADS = 0x01,
RN_VIAS = 0x02,
RN_TRACKS = 0x04,
RN_ZONES = 0x08,
RN_ALL = 0xFF
};
// Preserve KiCad coding style policy
typedef hed::NODE RN_NODE;
typedef hed::NODE_PTR RN_NODE_PTR;
......@@ -157,8 +167,8 @@ public:
* @param aDistance is the distance of the connection (0 means that nodes are actually
* connected, >0 means a missing connection).
*/
const RN_EDGE_PTR& AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
unsigned int aDistance = 0 );
RN_EDGE_MST_PTR AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
unsigned int aDistance = 0 );
/**
* Function RemoveConnection()
......@@ -181,7 +191,7 @@ public:
}
protected:
///> Set of nodes that are used are expected to be connected together.
///> Set of nodes that are expected to be connected together (vias, tracks, pads).
RN_NODE_SET m_nodes;
///> List of edges that currently connect nodes.
......@@ -210,7 +220,6 @@ public:
return m_node;
}
/**
* Function GetParent()
* Returns pointer to zone that is the owner of subpolygon.
......@@ -307,7 +316,7 @@ public:
* Returns pointer to a vector of edges that makes ratsnest for a given net.
* @return Pointer to a vector of edges that makes ratsnest for a given net.
*/
const std::vector<RN_EDGE_PTR>* GetUnconnected() const
const std::vector<RN_EDGE_MST_PTR>* GetUnconnected() const
{
return m_rnEdges.get();
}
......@@ -429,22 +438,12 @@ public:
std::list<RN_NODE_PTR> GetClosestNodes( const RN_NODE_PTR& aNode,
const RN_NODE_FILTER& aFilter, int aNumber = -1 ) const;
/**
* 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.
*/
const std::vector<RN_EDGE_PTR>* GetEdges() const
{
return m_rnEdges.get();
}
/**
* Function AddSimpleNode()
* 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 )
inline void AddSimpleNode( RN_NODE_PTR& aNode )
{
m_simpleNodes.push_back( aNode );
aNode->SetFlag( true );
......@@ -456,7 +455,7 @@ public:
* 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 )
inline void AddBlockedNode( RN_NODE_PTR& aNode )
{
m_blockedNodes.push_back( aNode );
aNode->SetFlag( true );
......@@ -468,7 +467,7 @@ public:
* ratsnest line per node).
* @return list of nodes for which ratsnest is drawn in simple mode.
*/
const std::deque<RN_NODE_PTR>& GetSimpleNodes() const
inline const std::deque<RN_NODE_PTR>& GetSimpleNodes() const
{
return m_simpleNodes;
}
......@@ -477,22 +476,23 @@ public:
* Function ClearSimple()
* Removes all nodes and edges that are used for displaying ratsnest in simple mode.
*/
void ClearSimple()
{
BOOST_FOREACH( const RN_NODE_PTR& node, m_simpleNodes )
node->SetFlag( false );
BOOST_FOREACH( const RN_NODE_PTR& node, m_blockedNodes )
node->SetFlag( false );
void ClearSimple();
m_simpleNodes.clear();
m_blockedNodes.clear();
}
/**
* Function GetConnectedItems()
* Adds items that are connected together to a list.
* @param aItem is the reference item to find other connected items.
* @param aOutput is the list that will contain found items.
* @param aTypes allows to filter by item types.
*/
void GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
std::list<BOARD_CONNECTED_ITEM*>& aOutput,
RN_ITEM_TYPES aTypes = RN_ALL) const;
protected:
///> 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 );
void validateEdge( RN_EDGE_MST_PTR& aEdge );
///> Removes all ratsnest edges for a given node.
void clearNode( const RN_NODE_PTR& aNode );
......@@ -507,31 +507,37 @@ protected:
RN_LINKS m_links;
///> Vector of edges that makes ratsnest for a given net.
boost::shared_ptr< std::vector<RN_EDGE_PTR> > m_rnEdges;
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 should be used as ratsnest target nodes..
///> List of nodes which will not 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;
///> Helper typedefs
typedef boost::unordered_map<const D_PAD*, RN_NODE_PTR> PAD_NODE_MAP;
typedef boost::unordered_map<const VIA*, RN_NODE_PTR> VIA_NODE_MAP;
typedef boost::unordered_map<const TRACK*, RN_EDGE_MST_PTR> TRACK_EDGE_MAP;
typedef boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_POLY> > ZONE_POLY_MAP;
typedef boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_EDGE_MST_PTR> > ZONE_EDGE_MAP;
///> Map that associates nodes in the ratsnest model to respective nodes.
boost::unordered_map<const D_PAD*, RN_NODE_PTR> m_pads;
PAD_NODE_MAP m_pads;
///> Map that associates nodes in the ratsnest model to respective vias.
boost::unordered_map<const VIA*, RN_NODE_PTR> m_vias;
VIA_NODE_MAP m_vias;
///> Map that associates edges in the ratsnest model to respective tracks.
boost::unordered_map<const TRACK*, RN_EDGE_PTR> m_tracks;
TRACK_EDGE_MAP m_tracks;
///> Map that associates groups of subpolygons in the ratsnest model to their respective zones.
boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_POLY> > m_zonePolygons;
///> Map that associates groups of subpolygons in the ratsnest model to respective zones.
ZONE_POLY_MAP m_zonePolygons;
///> Map that associates groups of edges in the ratsnest model to their respective zones.
boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_EDGE_PTR> > m_zoneConnections;
///> Map that associates groups of edges in the ratsnest model to respective zones.
ZONE_EDGE_MAP m_zoneConnections;
///> Visibility flag.
bool m_visible;
......@@ -646,6 +652,26 @@ public:
return m_nets[aNetCode];
}
/**
* Function GetConnectedItems()
* Adds items that are connected together to a list.
* @param aItem is the reference item to find other connected items.
* @param aOutput is the list that will contain found items.
* @param aTypes allows to filter by item types.
*/
void GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
std::list<BOARD_CONNECTED_ITEM*>& aOutput,
RN_ITEM_TYPES aTypes = RN_ALL ) const;
/**
* Function AreConnected()
* Checks if two items are connected with copper.
* @param aThis is the first item.
* @param aOther is the second item.
* @return True if they are connected, false otherwise.
*/
bool AreConnected( const BOARD_CONNECTED_ITEM* aItem, const BOARD_CONNECTED_ITEM* aOther );
protected:
/**
* Function updateNet()
......
......@@ -72,7 +72,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
// Set brighter color for the temporary ratsnest
aGal->SetStrokeColor( color.Brightened( 0.8 ) );
// Draw the "dynamic" ratsnest (ie. for objects that may be currently being moved)
// 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() );
......@@ -93,11 +93,12 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
if( i != highlightedNet )
aGal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted
const std::vector<RN_EDGE_PTR>* edges = net.GetUnconnected();
const std::vector<RN_EDGE_MST_PTR>* edges = net.GetUnconnected();
if( edges == NULL )
continue;
BOOST_FOREACH( const RN_EDGE_PTR& edge, *edges )
BOOST_FOREACH( const RN_EDGE_MST_PTR& edge, *edges )
{
const RN_NODE_PTR& sourceNode = edge->GetSourceNode();
const RN_NODE_PTR& targetNode = edge->GetTargetNode();
......
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