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 @@ ...@@ -4,21 +4,21 @@
* Copyright (C) 2013 CERN * Copyright (C) 2013 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* Contact information: E-mail: tor.dokken@sintef.no * Contact information: E-mail: tor.dokken@sintef.no
* SINTEF ICT, Department of Applied Mathematics, * SINTEF ICT, Department of Applied Mathematics,
* P.O. Box 124 Blindern, * P.O. Box 124 Blindern,
* 0314 Oslo, Norway. * 0314 Oslo, Norway.
* *
* This file is part of TTL. * This file is part of TTL.
* *
* TTL is free software: you can redistribute it and/or modify * TTL is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as * it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the * 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, * TTL is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details. * GNU Affero General Public License for more details.
* *
* You should have received a copy of the GNU Affero General Public * You should have received a copy of the GNU Affero General Public
...@@ -36,7 +36,7 @@ ...@@ -36,7 +36,7 @@
* disclosing the source code of your own applications. * disclosing the source code of your own applications.
* *
* This file may be used in accordance with the terms contained in a * 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_ #ifndef _HE_TRIANG_H_
...@@ -100,6 +100,9 @@ protected: ...@@ -100,6 +100,9 @@ protected:
/// Node coordinates /// Node coordinates
int m_x, m_y; int m_x, m_y;
/// Tag for quick connection resolution
int m_tag;
/// Reference count /// Reference count
unsigned int m_refCount; unsigned int m_refCount;
...@@ -112,7 +115,7 @@ public: ...@@ -112,7 +115,7 @@ public:
#ifdef TTL_USE_NODE_ID #ifdef TTL_USE_NODE_ID
m_id( id_count++ ), m_id( id_count++ ),
#endif #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: ...@@ -120,20 +123,32 @@ public:
~NODE() {} ~NODE() {}
/// Returns the x-coordinate /// Returns the x-coordinate
int GetX() const inline int GetX() const
{ {
return m_x; return m_x;
} }
/// Returns the y-coordinate /// Returns the y-coordinate
int GetY() const inline int GetY() const
{ {
return m_y; 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 #ifdef TTL_USE_NODE_ID
/// Returns the id (TTL_USE_NODE_ID must be defined) /// Returns the id (TTL_USE_NODE_ID must be defined)
int Id() const inline int Id() const
{ {
return m_id; return m_id;
} }
...@@ -141,35 +156,35 @@ public: ...@@ -141,35 +156,35 @@ public:
#ifdef TTL_USE_NODE_FLAG #ifdef TTL_USE_NODE_FLAG
/// Sets the flag (TTL_USE_NODE_FLAG must be defined) /// Sets the flag (TTL_USE_NODE_FLAG must be defined)
void SetFlag( bool aFlag ) inline void SetFlag( bool aFlag )
{ {
m_flag = aFlag; m_flag = aFlag;
} }
/// Returns the flag (TTL_USE_NODE_FLAG must be defined) /// Returns the flag (TTL_USE_NODE_FLAG must be defined)
const bool& GetFlag() const inline const bool& GetFlag() const
{ {
return m_flag; return m_flag;
} }
#endif #endif
void IncRefCount() inline void IncRefCount()
{ {
m_refCount++; m_refCount++;
} }
void DecRefCount() inline void DecRefCount()
{ {
m_refCount--; m_refCount--;
} }
unsigned int GetRefCount() const inline unsigned int GetRefCount() const
{ {
return m_refCount; return m_refCount;
} }
}; };
/** /**
* \class EDGE * \class EDGE
* \brief \b %Edge class in the in the half-edge data structure. * \brief \b %Edge class in the in the half-edge data structure.
...@@ -187,55 +202,65 @@ public: ...@@ -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 /// Sets the source node
void SetSourceNode( const NODE_PTR& aNode ) inline void SetSourceNode( const NODE_PTR& aNode )
{ {
m_sourceNode = aNode; m_sourceNode = aNode;
} }
/// Sets the next edge in face /// Sets the next edge in face
void SetNextEdgeInFace( const EDGE_PTR& aEdge ) inline void SetNextEdgeInFace( const EDGE_PTR& aEdge )
{ {
m_nextEdgeInFace = aEdge; m_nextEdgeInFace = aEdge;
} }
/// Sets the twin edge /// Sets the twin edge
void SetTwinEdge( const EDGE_PTR& aEdge ) inline void SetTwinEdge( const EDGE_PTR& aEdge )
{ {
m_twinEdge = aEdge; m_twinEdge = aEdge;
} }
/// Sets the edge as a leading edge /// Sets the edge as a leading edge
void SetAsLeadingEdge( bool aLeading = true ) inline void SetAsLeadingEdge( bool aLeading = true )
{ {
m_isLeadingEdge = aLeading; m_isLeadingEdge = aLeading;
} }
/// Checks if an edge is a leading edge /// Checks if an edge is a leading edge
bool IsLeadingEdge() const inline bool IsLeadingEdge() const
{ {
return m_isLeadingEdge; return m_isLeadingEdge;
} }
/// Returns the twin edge /// Returns the twin edge
EDGE_PTR GetTwinEdge() const inline EDGE_PTR GetTwinEdge() const
{ {
return m_twinEdge.lock(); return m_twinEdge.lock();
} }
void ClearTwinEdge() inline void ClearTwinEdge()
{ {
m_twinEdge.reset(); m_twinEdge.reset();
} }
/// Returns the next edge in face /// Returns the next edge in face
const EDGE_PTR& GetNextEdgeInFace() const inline const EDGE_PTR& GetNextEdgeInFace() const
{ {
return m_nextEdgeInFace; return m_nextEdgeInFace;
} }
/// Retuns the source node /// Retuns the source node
const NODE_PTR& GetSourceNode() const inline const NODE_PTR& GetSourceNode() const
{ {
return m_sourceNode; return m_sourceNode;
} }
...@@ -246,12 +271,12 @@ public: ...@@ -246,12 +271,12 @@ public:
return m_nextEdgeInFace->GetSourceNode(); return m_nextEdgeInFace->GetSourceNode();
} }
void SetWeight( unsigned int weight ) inline void SetWeight( unsigned int weight )
{ {
m_weight = weight; m_weight = weight;
} }
unsigned int GetWeight() const inline unsigned int GetWeight() const
{ {
return m_weight; return m_weight;
} }
...@@ -294,22 +319,17 @@ public: ...@@ -294,22 +319,17 @@ public:
m_weight = aWeight; 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() /// @copydoc Edge::setSourceNode()
virtual const NODE_PTR& GetTargetNode() const virtual const NODE_PTR& GetTargetNode() const
{ {
return m_target; return m_target;
} }
private:
EDGE_MST( const EDGE& aEdge )
{
assert( false );
}
}; };
class DART; // Forward declaration (class in this namespace) class DART; // Forward declaration (class in this namespace)
...@@ -410,7 +430,7 @@ public: ...@@ -410,7 +430,7 @@ public:
/// Swaps the edge associated with diagonal /// Swaps the edge associated with diagonal
void SwapEdge( EDGE_PTR& aDiagonal ); 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 ); EDGE_PTR SplitTriangle( EDGE_PTR& aEdge, const NODE_PTR& aPoint );
// Functions required by TTL for removing nodes in a Delaunay triangulation // Functions required by TTL for removing nodes in a Delaunay triangulation
...@@ -440,7 +460,7 @@ public: ...@@ -440,7 +460,7 @@ public:
std::list<EDGE_PTR>* GetEdges( bool aSkipBoundaryEdges = false ) const; std::list<EDGE_PTR>* GetEdges( bool aSkipBoundaryEdges = false ) const;
#ifdef TTL_USE_NODE_FLAG #ifdef TTL_USE_NODE_FLAG
/// Sets flag in all the nodes /// Sets flag in all the nodes
void FlagNodes( bool aFlag ) const; void FlagNodes( bool aFlag ) const;
/// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node. /// Returns a list of nodes. This function requires TTL_USE_NODE_FLAG to be defined. \see Node.
......
This diff is collapsed.
/* /*
* This program source code file is part of KICAD, a free EDA CAD application. * 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> * @author Maciej Suminski <maciej.suminski@cern.ch>
* *
* This program is free software; you can redistribute it and/or * This program is free software; you can redistribute it and/or
...@@ -49,6 +49,16 @@ class TRACK; ...@@ -49,6 +49,16 @@ class TRACK;
class ZONE_CONTAINER; class ZONE_CONTAINER;
class CPolyPt; 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 // Preserve KiCad coding style policy
typedef hed::NODE RN_NODE; typedef hed::NODE RN_NODE;
typedef hed::NODE_PTR RN_NODE_PTR; typedef hed::NODE_PTR RN_NODE_PTR;
...@@ -157,8 +167,8 @@ public: ...@@ -157,8 +167,8 @@ public:
* @param aDistance is the distance of the connection (0 means that nodes are actually * @param aDistance is the distance of the connection (0 means that nodes are actually
* connected, >0 means a missing connection). * connected, >0 means a missing connection).
*/ */
const RN_EDGE_PTR& AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2, RN_EDGE_MST_PTR AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
unsigned int aDistance = 0 ); unsigned int aDistance = 0 );
/** /**
* Function RemoveConnection() * Function RemoveConnection()
...@@ -181,7 +191,7 @@ public: ...@@ -181,7 +191,7 @@ public:
} }
protected: 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; RN_NODE_SET m_nodes;
///> List of edges that currently connect nodes. ///> List of edges that currently connect nodes.
...@@ -210,7 +220,6 @@ public: ...@@ -210,7 +220,6 @@ public:
return m_node; return m_node;
} }
/** /**
* Function GetParent() * Function GetParent()
* Returns pointer to zone that is the owner of subpolygon. * Returns pointer to zone that is the owner of subpolygon.
...@@ -307,7 +316,7 @@ public: ...@@ -307,7 +316,7 @@ public:
* Returns pointer to a vector of edges that makes ratsnest for a given net. * 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. * @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(); return m_rnEdges.get();
} }
...@@ -429,22 +438,12 @@ public: ...@@ -429,22 +438,12 @@ public:
std::list<RN_NODE_PTR> GetClosestNodes( const RN_NODE_PTR& aNode, std::list<RN_NODE_PTR> GetClosestNodes( const RN_NODE_PTR& aNode,
const RN_NODE_FILTER& aFilter, int aNumber = -1 ) const; 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() * Function AddSimpleNode()
* Changes drawing mode for a node to simple (i.e. one ratsnest line per node). * 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. * @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 ); m_simpleNodes.push_back( aNode );
aNode->SetFlag( true ); aNode->SetFlag( true );
...@@ -456,7 +455,7 @@ public: ...@@ -456,7 +455,7 @@ public:
* target the node). The status is cleared after calling ClearSimple(). * 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. * @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 ); m_blockedNodes.push_back( aNode );
aNode->SetFlag( true ); aNode->SetFlag( true );
...@@ -468,7 +467,7 @@ public: ...@@ -468,7 +467,7 @@ public:
* ratsnest line per node). * ratsnest line per node).
* @return list of nodes for which ratsnest is drawn in simple mode. * @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; return m_simpleNodes;
} }
...@@ -477,22 +476,23 @@ public: ...@@ -477,22 +476,23 @@ public:
* Function ClearSimple() * Function ClearSimple()
* Removes all nodes and edges that are used for displaying ratsnest in simple mode. * Removes all nodes and edges that are used for displaying ratsnest in simple mode.
*/ */
void ClearSimple() 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 );
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: protected:
///> Validates edge, i.e. 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. ///> 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. ///> Removes all ratsnest edges for a given node.
void clearNode( const RN_NODE_PTR& aNode ); void clearNode( const RN_NODE_PTR& aNode );
...@@ -507,31 +507,37 @@ protected: ...@@ -507,31 +507,37 @@ protected:
RN_LINKS m_links; RN_LINKS m_links;
///> Vector of edges that makes ratsnest for a given net. ///> 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. ///> List of nodes for which ratsnest is drawn in simple mode.
std::deque<RN_NODE_PTR> m_simpleNodes; 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; std::deque<RN_NODE_PTR> m_blockedNodes;
///> Flag indicating necessity of recalculation of ratsnest for a net. ///> Flag indicating necessity of recalculation of ratsnest for a net.
bool m_dirty; 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. ///> 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. ///> 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. ///> 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. ///> Map that associates groups of subpolygons in the ratsnest model to respective zones.
boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_POLY> > m_zonePolygons; ZONE_POLY_MAP m_zonePolygons;
///> Map that associates groups of edges in the ratsnest model to their respective zones. ///> Map that associates groups of edges in the ratsnest model to respective zones.
boost::unordered_map<const ZONE_CONTAINER*, std::deque<RN_EDGE_PTR> > m_zoneConnections; ZONE_EDGE_MAP m_zoneConnections;
///> Visibility flag. ///> Visibility flag.
bool m_visible; bool m_visible;
...@@ -646,6 +652,26 @@ public: ...@@ -646,6 +652,26 @@ public:
return m_nets[aNetCode]; 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: protected:
/** /**
* Function updateNet() * Function updateNet()
......
...@@ -72,7 +72,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const ...@@ -72,7 +72,7 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
// Set brighter color for the temporary ratsnest // Set brighter color for the temporary ratsnest
aGal->SetStrokeColor( color.Brightened( 0.8 ) ); 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() ) 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() );
...@@ -93,11 +93,12 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const ...@@ -93,11 +93,12 @@ void RATSNEST_VIEWITEM::ViewDraw( int aLayer, GAL* aGal ) const
if( i != highlightedNet ) if( i != highlightedNet )
aGal->SetStrokeColor( color ); // using the default ratsnest color for not highlighted 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 ) if( edges == NULL )
continue; 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& sourceNode = edge->GetSourceNode();
const RN_NODE_PTR& targetNode = edge->GetTargetNode(); 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