Ratsnest algorithm distinguishes layers (GAL).

This commit is contained in:
Maciej Suminski 2015-06-04 14:54:08 +02:00
parent 42215f2388
commit c23adc47b7
3 changed files with 75 additions and 13 deletions

View File

@ -47,6 +47,7 @@
#include <limits> #include <limits>
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/make_shared.hpp> #include <boost/make_shared.hpp>
#include <class_board_connected_item.h>
using namespace hed; using namespace hed;
@ -55,6 +56,15 @@ using namespace hed;
#endif #endif
void NODE::updateLayers()
{
assert( m_layers.none() );
BOOST_FOREACH( const BOARD_CONNECTED_ITEM* item, m_parents )
m_layers |= item->GetLayerSet();
}
//#define DEBUG_HE //#define DEBUG_HE
#ifdef DEBUG_HE #ifdef DEBUG_HE
#include <iostream> #include <iostream>

View File

@ -52,6 +52,9 @@
#include <ttl/ttl_util.h> #include <ttl/ttl_util.h>
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp> #include <boost/weak_ptr.hpp>
#include <layers_id_colors_and_visibility.h>
class BOARD_CONNECTED_ITEM;
namespace ttl namespace ttl
{ {
@ -106,6 +109,15 @@ protected:
/// Reference count /// Reference count
unsigned int m_refCount; unsigned int m_refCount;
/// List of board items that share this node
std::list<const BOARD_CONNECTED_ITEM*> m_parents;
/// Layers that are occupied by this node
LSET m_layers;
/// Recomputes the layers used by this node
void updateLayers();
public: public:
/// Constructor /// Constructor
NODE( int aX = 0, int aY = 0 ) : NODE( int aX = 0, int aY = 0 ) :
@ -117,6 +129,7 @@ public:
#endif #endif
m_x( aX ), m_y( aY ), m_tag( -1 ), m_refCount( 0 ) m_x( aX ), m_y( aY ), m_tag( -1 ), m_refCount( 0 )
{ {
m_layers.reset();
} }
/// Destructor /// Destructor
@ -182,6 +195,26 @@ public:
{ {
return m_refCount; return m_refCount;
} }
inline void AddParent( const BOARD_CONNECTED_ITEM* aParent )
{
m_parents.push_back( aParent );
m_layers.reset(); // mark as needs updating
}
inline void RemoveParent( const BOARD_CONNECTED_ITEM* aParent )
{
m_parents.remove( aParent );
m_layers.reset(); // mark as needs updating
}
const LSET& GetLayers()
{
if( m_layers.none() )
updateLayers();
return m_layers;
}
}; };

View File

@ -408,7 +408,9 @@ void RN_NET::Update()
void RN_NET::AddItem( const D_PAD* aPad ) void RN_NET::AddItem( const D_PAD* aPad )
{ {
m_pads[aPad] = m_links.AddNode( aPad->GetPosition().x, aPad->GetPosition().y ); RN_NODE_PTR node = m_links.AddNode( aPad->GetPosition().x, aPad->GetPosition().y );
node->AddParent( aPad );
m_pads[aPad] = node;
m_dirty = true; m_dirty = true;
} }
@ -416,7 +418,9 @@ void RN_NET::AddItem( const D_PAD* aPad )
void RN_NET::AddItem( const VIA* aVia ) void RN_NET::AddItem( const VIA* aVia )
{ {
m_vias[aVia] = m_links.AddNode( aVia->GetPosition().x, aVia->GetPosition().y ); RN_NODE_PTR node = m_links.AddNode( aVia->GetPosition().x, aVia->GetPosition().y );
node->AddParent( aVia );
m_vias[aVia] = node;
m_dirty = true; m_dirty = true;
} }
@ -429,6 +433,8 @@ void RN_NET::AddItem( const TRACK* aTrack )
if( start != end ) if( start != end )
{ {
start->AddParent( aTrack );
end->AddParent( aTrack );
m_tracks[aTrack] = m_links.AddConnection( start, end ); m_tracks[aTrack] = m_links.AddConnection( start, end );
m_dirty = true; m_dirty = true;
} }
@ -455,8 +461,10 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
if( point.end_contour ) if( point.end_contour )
{ {
m_zones[aZone].m_Polygons.push_back( RN_POLY( &polyPoints[idxStart], &point, RN_POLY poly = RN_POLY( &polyPoints[idxStart], &point,
m_links, BOX2I( origin, end - origin ) ) ); m_links, BOX2I( origin, end - origin ) );
poly.GetNode()->AddParent( aZone );
m_zones[aZone].m_Polygons.push_back( poly );
idxStart = i + 1; idxStart = i + 1;
@ -492,6 +500,7 @@ void RN_NET::RemoveItem( const D_PAD* aPad )
try try
{ {
RN_NODE_PTR node = m_pads.at( aPad ); RN_NODE_PTR node = m_pads.at( aPad );
node->RemoveParent( aPad );
if( m_links.RemoveNode( node ) ) if( m_links.RemoveNode( node ) )
clearNode( node ); clearNode( node );
@ -511,6 +520,7 @@ void RN_NET::RemoveItem( const VIA* aVia )
try try
{ {
RN_NODE_PTR node = m_vias.at( aVia ); RN_NODE_PTR node = m_vias.at( aVia );
node->RemoveParent( aVia );
if( m_links.RemoveNode( node ) ) if( m_links.RemoveNode( node ) )
clearNode( node ); clearNode( node );
@ -532,17 +542,20 @@ void RN_NET::RemoveItem( const TRACK* aTrack )
RN_EDGE_MST_PTR& edge = m_tracks.at( aTrack ); RN_EDGE_MST_PTR& edge = m_tracks.at( aTrack );
// Save nodes, so they can be cleared later // Save nodes, so they can be cleared later
RN_NODE_PTR aBegin = edge->GetSourceNode(); RN_NODE_PTR start = edge->GetSourceNode();
RN_NODE_PTR aEnd = edge->GetTargetNode(); start->RemoveParent( aTrack );
RN_NODE_PTR end = edge->GetTargetNode();
end->RemoveParent( aTrack );
m_links.RemoveConnection( edge ); m_links.RemoveConnection( edge );
// Remove nodes associated with the edge. It is done in a safe way, there is a check // Remove nodes associated with the edge. It is done in a safe way, there is a check
// if nodes are not used by other edges. // if nodes are not used by other edges.
if( m_links.RemoveNode( aBegin ) ) if( m_links.RemoveNode( start ) )
clearNode( aBegin ); clearNode( start );
if( m_links.RemoveNode( aEnd ) ) if( m_links.RemoveNode( end ) )
clearNode( aEnd ); clearNode( end );
m_tracks.erase( aTrack ); m_tracks.erase( aTrack );
@ -562,7 +575,8 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
std::deque<RN_POLY>& polygons = m_zones.at( aZone ).m_Polygons; std::deque<RN_POLY>& polygons = m_zones.at( aZone ).m_Polygons;
BOOST_FOREACH( RN_POLY& polygon, polygons ) BOOST_FOREACH( RN_POLY& polygon, polygons )
{ {
const RN_NODE_PTR node = polygon.GetNode(); RN_NODE_PTR node = polygon.GetNode();
node->RemoveParent( aZone );
if( m_links.RemoveNode( node ) ) if( m_links.RemoveNode( node ) )
clearNode( node ); clearNode( node );
@ -962,13 +976,17 @@ bool RN_DATA::AreConnected( const BOARD_CONNECTED_ITEM* aItem, const BOARD_CONNE
void RN_NET::processZones() void RN_NET::processZones()
{ {
BOOST_FOREACH( RN_ZONE_DATA& zoneData, m_zones | boost::adaptors::map_values ) for( ZONE_DATA_MAP::iterator it = m_zones.begin(); it != m_zones.end(); ++it )
{ {
const ZONE_CONTAINER* zone = it->first;
RN_ZONE_DATA& zoneData = it->second;
// Reset existing connections // Reset existing connections
BOOST_FOREACH( RN_EDGE_MST_PTR edge, zoneData.m_Edges ) BOOST_FOREACH( RN_EDGE_MST_PTR edge, zoneData.m_Edges )
m_links.RemoveConnection( edge ); m_links.RemoveConnection( edge );
zoneData.m_Edges.clear(); zoneData.m_Edges.clear();
LSET layers = zone->GetLayerSet();
// Compute new connections // Compute new connections
RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes(); RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
@ -988,7 +1006,8 @@ void RN_NET::processZones()
while( point != pointEnd ) while( point != pointEnd )
{ {
if( *point != node && poly->HitTest( *point ) ) if( *point != node && ( (*point)->GetLayers() & layers ).any()
&& poly->HitTest( *point ) )
{ {
RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point ); RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
zoneData.m_Edges.push_back( connection ); zoneData.m_Edges.push_back( connection );