Ratsnest algorithm handles items in pad areas (GAL).
This commit is contained in:
parent
24e7f961b9
commit
3cddf14e73
|
@ -251,6 +251,43 @@ void RN_NET::validateEdge( RN_EDGE_MST_PTR& aEdge )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RN_NET::removeNode( RN_NODE_PTR& aNode, const BOARD_CONNECTED_ITEM* aParent )
|
||||||
|
{
|
||||||
|
aNode->RemoveParent( aParent );
|
||||||
|
|
||||||
|
if( m_links.RemoveNode( aNode ) )
|
||||||
|
{
|
||||||
|
clearNode( aNode );
|
||||||
|
m_dirty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RN_NET::removeEdge( RN_EDGE_MST_PTR& aEdge, const BOARD_CONNECTED_ITEM* aParent )
|
||||||
|
{
|
||||||
|
// Save nodes, so they can be cleared later
|
||||||
|
RN_NODE_PTR start = aEdge->GetSourceNode();
|
||||||
|
RN_NODE_PTR end = aEdge->GetTargetNode();
|
||||||
|
|
||||||
|
start->RemoveParent( aParent );
|
||||||
|
end->RemoveParent( aParent );
|
||||||
|
|
||||||
|
// Connection has to be removed before running RemoveNode(),
|
||||||
|
// as RN_NODE influences the reference counter
|
||||||
|
m_links.RemoveConnection( aEdge );
|
||||||
|
|
||||||
|
// 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( m_links.RemoveNode( start ) )
|
||||||
|
clearNode( start );
|
||||||
|
|
||||||
|
if( m_links.RemoveNode( end ) )
|
||||||
|
clearNode( end );
|
||||||
|
|
||||||
|
m_dirty = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
const RN_NODE_PTR& RN_LINKS::AddNode( int aX, int aY )
|
const RN_NODE_PTR& RN_LINKS::AddNode( int aX, int aY )
|
||||||
{
|
{
|
||||||
RN_NODE_SET::iterator node;
|
RN_NODE_SET::iterator node;
|
||||||
|
@ -276,7 +313,7 @@ bool RN_LINKS::RemoveNode( const RN_NODE_PTR& aNode )
|
||||||
|
|
||||||
|
|
||||||
RN_EDGE_MST_PTR RN_LINKS::AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
|
RN_EDGE_MST_PTR RN_LINKS::AddConnection( const RN_NODE_PTR& aNode1, const RN_NODE_PTR& aNode2,
|
||||||
unsigned int aDistance )
|
unsigned int aDistance )
|
||||||
{
|
{
|
||||||
assert( aNode1 != aNode2 );
|
assert( aNode1 != aNode2 );
|
||||||
RN_EDGE_MST_PTR edge = boost::make_shared<RN_EDGE_MST>( aNode1, aNode2, aDistance );
|
RN_EDGE_MST_PTR edge = boost::make_shared<RN_EDGE_MST>( aNode1, aNode2, aDistance );
|
||||||
|
@ -377,6 +414,7 @@ void RN_NET::Update()
|
||||||
{
|
{
|
||||||
// Add edges resulting from nodes being connected by zones
|
// Add edges resulting from nodes being connected by zones
|
||||||
processZones();
|
processZones();
|
||||||
|
processPads();
|
||||||
|
|
||||||
compute();
|
compute();
|
||||||
|
|
||||||
|
@ -391,7 +429,7 @@ void RN_NET::AddItem( const D_PAD* aPad )
|
||||||
{
|
{
|
||||||
RN_NODE_PTR node = 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 );
|
node->AddParent( aPad );
|
||||||
m_pads[aPad] = node;
|
m_pads[aPad].m_Node = node;
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
}
|
}
|
||||||
|
@ -442,73 +480,42 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
|
||||||
|
|
||||||
void RN_NET::RemoveItem( const D_PAD* aPad )
|
void RN_NET::RemoveItem( const D_PAD* aPad )
|
||||||
{
|
{
|
||||||
try
|
PAD_NODE_MAP::iterator it = m_pads.find( aPad );
|
||||||
{
|
|
||||||
RN_NODE_PTR node = m_pads.at( aPad );
|
|
||||||
node->RemoveParent( aPad );
|
|
||||||
|
|
||||||
if( m_links.RemoveNode( node ) )
|
if( it == m_pads.end() )
|
||||||
clearNode( node );
|
return;
|
||||||
|
|
||||||
m_pads.erase( aPad );
|
RN_PAD_DATA& pad_data = it->second;
|
||||||
|
removeNode( pad_data.m_Node, aPad );
|
||||||
|
|
||||||
m_dirty = true;
|
BOOST_FOREACH( RN_EDGE_MST_PTR& edge, pad_data.m_Edges )
|
||||||
}
|
removeEdge( edge, aPad );
|
||||||
catch( ... )
|
|
||||||
{
|
m_pads.erase( aPad );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RN_NET::RemoveItem( const VIA* aVia )
|
void RN_NET::RemoveItem( const VIA* aVia )
|
||||||
{
|
{
|
||||||
try
|
VIA_NODE_MAP::iterator it = m_vias.find( aVia );
|
||||||
{
|
|
||||||
RN_NODE_PTR node = m_vias.at( aVia );
|
|
||||||
node->RemoveParent( aVia );
|
|
||||||
|
|
||||||
if( m_links.RemoveNode( node ) )
|
if( it == m_vias.end() )
|
||||||
clearNode( node );
|
return;
|
||||||
|
|
||||||
m_vias.erase( aVia );
|
removeNode( it->second, aVia );
|
||||||
|
m_vias.erase( it );
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void RN_NET::RemoveItem( const TRACK* aTrack )
|
void RN_NET::RemoveItem( const TRACK* aTrack )
|
||||||
{
|
{
|
||||||
try
|
TRACK_EDGE_MAP::iterator it = m_tracks.find( aTrack );
|
||||||
{
|
|
||||||
RN_EDGE_MST_PTR& edge = m_tracks.at( aTrack );
|
|
||||||
|
|
||||||
// Save nodes, so they can be cleared later
|
if( it == m_tracks.end() )
|
||||||
RN_NODE_PTR start = edge->GetSourceNode();
|
return;
|
||||||
start->RemoveParent( aTrack );
|
|
||||||
RN_NODE_PTR end = edge->GetTargetNode();
|
|
||||||
end->RemoveParent( aTrack );
|
|
||||||
|
|
||||||
m_links.RemoveConnection( edge );
|
removeEdge( it->second, aTrack );
|
||||||
|
m_tracks.erase( it );
|
||||||
// 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( m_links.RemoveNode( start ) )
|
|
||||||
clearNode( start );
|
|
||||||
|
|
||||||
if( m_links.RemoveNode( end ) )
|
|
||||||
clearNode( end );
|
|
||||||
|
|
||||||
m_tracks.erase( aTrack );
|
|
||||||
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
|
||||||
catch( ... )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -524,24 +531,16 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
|
||||||
// Remove all subpolygons that make the zone
|
// Remove all subpolygons that make the zone
|
||||||
std::deque<RN_POLY>& polygons = zoneData.m_Polygons;
|
std::deque<RN_POLY>& polygons = zoneData.m_Polygons;
|
||||||
BOOST_FOREACH( RN_POLY& polygon, polygons )
|
BOOST_FOREACH( RN_POLY& polygon, polygons )
|
||||||
{
|
removeNode( polygon.GetNode(), aZone );
|
||||||
RN_NODE_PTR node = polygon.GetNode();
|
|
||||||
node->RemoveParent( aZone );
|
|
||||||
|
|
||||||
if( m_links.RemoveNode( node ) )
|
|
||||||
clearNode( node );
|
|
||||||
}
|
|
||||||
polygons.clear();
|
polygons.clear();
|
||||||
|
|
||||||
// Remove all connections added by the zone
|
// Remove all connections added by the zone
|
||||||
std::deque<RN_EDGE_MST_PTR>& edges = zoneData.m_Edges;
|
std::deque<RN_EDGE_MST_PTR>& edges = zoneData.m_Edges;
|
||||||
BOOST_FOREACH( RN_EDGE_PTR edge, edges )
|
BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
|
||||||
m_links.RemoveConnection( edge );
|
removeEdge( edge, aZone );
|
||||||
edges.clear();
|
edges.clear();
|
||||||
|
|
||||||
m_zones.erase( it );
|
m_zones.erase( it );
|
||||||
|
|
||||||
m_dirty = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -680,7 +679,7 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
|
||||||
case PCB_PAD_T:
|
case PCB_PAD_T:
|
||||||
{
|
{
|
||||||
const D_PAD* pad = static_cast<const D_PAD*>( aItem );
|
const D_PAD* pad = static_cast<const D_PAD*>( aItem );
|
||||||
nodes.push_back( m_pads.at( pad ) );
|
nodes.push_back( m_pads.at( pad ).m_Node );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -776,7 +775,7 @@ void RN_NET::GetConnectedItems( const BOARD_CONNECTED_ITEM* aItem,
|
||||||
{
|
{
|
||||||
for( PAD_NODE_MAP::const_iterator it = m_pads.begin(); it != m_pads.end(); ++it )
|
for( PAD_NODE_MAP::const_iterator it = m_pads.begin(); it != m_pads.end(); ++it )
|
||||||
{
|
{
|
||||||
if( it->second->GetTag() == tag )
|
if( it->second.m_Node->GetTag() == tag )
|
||||||
aOutput.push_back( const_cast<D_PAD*>( it->first ) );
|
aOutput.push_back( const_cast<D_PAD*>( it->first ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -972,6 +971,8 @@ void RN_NET::processZones()
|
||||||
if( *point != node && ( (*point)->GetLayers() & layers ).any()
|
if( *point != node && ( (*point)->GetLayers() & layers ).any()
|
||||||
&& poly->HitTest( *point ) )
|
&& poly->HitTest( *point ) )
|
||||||
{
|
{
|
||||||
|
//(*point)->AddParent( zone ); // do not assign parent for helper links
|
||||||
|
|
||||||
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 );
|
||||||
|
|
||||||
|
@ -989,6 +990,42 @@ void RN_NET::processZones()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RN_NET::processPads()
|
||||||
|
{
|
||||||
|
for( PAD_NODE_MAP::iterator it = m_pads.begin(); it != m_pads.end(); ++it )
|
||||||
|
{
|
||||||
|
const D_PAD* pad = it->first;
|
||||||
|
RN_NODE_PTR node = it->second.m_Node;
|
||||||
|
std::deque<RN_EDGE_MST_PTR>& edges = it->second.m_Edges;
|
||||||
|
|
||||||
|
// Reset existing connections
|
||||||
|
BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
|
||||||
|
m_links.RemoveConnection( edge );
|
||||||
|
|
||||||
|
LSET layers = pad->GetLayerSet();
|
||||||
|
RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
|
||||||
|
RN_LINKS::RN_NODE_SET::iterator point, pointEnd;
|
||||||
|
|
||||||
|
point = candidates.begin();
|
||||||
|
pointEnd = candidates.end();
|
||||||
|
|
||||||
|
while( point != pointEnd )
|
||||||
|
{
|
||||||
|
if( *point != node && ( (*point)->GetLayers() & layers ).any() &&
|
||||||
|
pad->HitTest( wxPoint( (*point)->GetX(), (*point)->GetY() ) ) )
|
||||||
|
{
|
||||||
|
//(*point)->AddParent( pad ); // do not assign parent for helper links
|
||||||
|
|
||||||
|
RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
|
||||||
|
edges.push_back( connection );
|
||||||
|
}
|
||||||
|
|
||||||
|
++point;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void RN_DATA::Add( const BOARD_ITEM* aItem )
|
void RN_DATA::Add( const BOARD_ITEM* aItem )
|
||||||
{
|
{
|
||||||
int net;
|
int net;
|
||||||
|
|
|
@ -279,6 +279,11 @@ public:
|
||||||
return m_node;
|
return m_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline RN_NODE_PTR& GetNode()
|
||||||
|
{
|
||||||
|
return m_node;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function HitTest()
|
* Function HitTest()
|
||||||
* Tests if selected node is located within polygon boundaries.
|
* Tests if selected node is located within polygon boundaries.
|
||||||
|
@ -545,12 +550,21 @@ protected:
|
||||||
///> 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_MST_PTR& aEdge );
|
void validateEdge( RN_EDGE_MST_PTR& aEdge );
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
void removeNode( RN_NODE_PTR& aNode, const BOARD_CONNECTED_ITEM* aParent );
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
void removeEdge( RN_EDGE_MST_PTR& aEdge, const BOARD_CONNECTED_ITEM* aParent );
|
||||||
|
|
||||||
///> 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 );
|
||||||
|
|
||||||
///> Adds appropriate edges for nodes that are connected by zones.
|
///> Adds appropriate edges for nodes that are connected by zones.
|
||||||
void processZones();
|
void processZones();
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
void processPads();
|
||||||
|
|
||||||
///> Recomputes ratsnset from scratch.
|
///> Recomputes ratsnset from scratch.
|
||||||
void compute();
|
void compute();
|
||||||
|
|
||||||
|
@ -569,6 +583,7 @@ protected:
|
||||||
///> 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;
|
||||||
|
|
||||||
|
// TODO
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
///> Subpolygons belonging to a zone
|
///> Subpolygons belonging to a zone
|
||||||
|
@ -578,8 +593,18 @@ protected:
|
||||||
std::deque<RN_EDGE_MST_PTR> m_Edges;
|
std::deque<RN_EDGE_MST_PTR> m_Edges;
|
||||||
} RN_ZONE_DATA;
|
} RN_ZONE_DATA;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
RN_NODE_PTR m_Node;
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
std::deque<RN_EDGE_MST_PTR> m_Edges;
|
||||||
|
} RN_PAD_DATA;
|
||||||
|
|
||||||
///> Helper typedefs
|
///> Helper typedefs
|
||||||
typedef boost::unordered_map<const D_PAD*, RN_NODE_PTR> PAD_NODE_MAP;
|
typedef boost::unordered_map<const D_PAD*, RN_PAD_DATA> PAD_NODE_MAP;
|
||||||
typedef boost::unordered_map<const VIA*, RN_NODE_PTR> VIA_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 TRACK*, RN_EDGE_MST_PTR> TRACK_EDGE_MAP;
|
||||||
typedef boost::unordered_map<const ZONE_CONTAINER*, RN_ZONE_DATA> ZONE_DATA_MAP;
|
typedef boost::unordered_map<const ZONE_CONTAINER*, RN_ZONE_DATA> ZONE_DATA_MAP;
|
||||||
|
|
Loading…
Reference in New Issue