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 )
|
||||
{
|
||||
RN_NODE_SET::iterator node;
|
||||
|
@ -377,6 +414,7 @@ void RN_NET::Update()
|
|||
{
|
||||
// Add edges resulting from nodes being connected by zones
|
||||
processZones();
|
||||
processPads();
|
||||
|
||||
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 );
|
||||
node->AddParent( aPad );
|
||||
m_pads[aPad] = node;
|
||||
m_pads[aPad].m_Node = node;
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
|
@ -442,73 +480,42 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
|
|||
|
||||
void RN_NET::RemoveItem( const D_PAD* aPad )
|
||||
{
|
||||
try
|
||||
{
|
||||
RN_NODE_PTR node = m_pads.at( aPad );
|
||||
node->RemoveParent( aPad );
|
||||
PAD_NODE_MAP::iterator it = m_pads.find( aPad );
|
||||
|
||||
if( m_links.RemoveNode( node ) )
|
||||
clearNode( node );
|
||||
if( it == m_pads.end() )
|
||||
return;
|
||||
|
||||
RN_PAD_DATA& pad_data = it->second;
|
||||
removeNode( pad_data.m_Node, aPad );
|
||||
|
||||
BOOST_FOREACH( RN_EDGE_MST_PTR& edge, pad_data.m_Edges )
|
||||
removeEdge( edge, aPad );
|
||||
|
||||
m_pads.erase( aPad );
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RN_NET::RemoveItem( const VIA* aVia )
|
||||
{
|
||||
try
|
||||
{
|
||||
RN_NODE_PTR node = m_vias.at( aVia );
|
||||
node->RemoveParent( aVia );
|
||||
VIA_NODE_MAP::iterator it = m_vias.find( aVia );
|
||||
|
||||
if( m_links.RemoveNode( node ) )
|
||||
clearNode( node );
|
||||
if( it == m_vias.end() )
|
||||
return;
|
||||
|
||||
m_vias.erase( aVia );
|
||||
|
||||
m_dirty = true;
|
||||
}
|
||||
catch( ... )
|
||||
{
|
||||
}
|
||||
removeNode( it->second, aVia );
|
||||
m_vias.erase( it );
|
||||
}
|
||||
|
||||
|
||||
void RN_NET::RemoveItem( const TRACK* aTrack )
|
||||
{
|
||||
try
|
||||
{
|
||||
RN_EDGE_MST_PTR& edge = m_tracks.at( aTrack );
|
||||
TRACK_EDGE_MAP::iterator it = m_tracks.find( aTrack );
|
||||
|
||||
// Save nodes, so they can be cleared later
|
||||
RN_NODE_PTR start = edge->GetSourceNode();
|
||||
start->RemoveParent( aTrack );
|
||||
RN_NODE_PTR end = edge->GetTargetNode();
|
||||
end->RemoveParent( aTrack );
|
||||
if( it == m_tracks.end() )
|
||||
return;
|
||||
|
||||
m_links.RemoveConnection( edge );
|
||||
|
||||
// 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( ... )
|
||||
{
|
||||
}
|
||||
removeEdge( it->second, aTrack );
|
||||
m_tracks.erase( it );
|
||||
}
|
||||
|
||||
|
||||
|
@ -524,24 +531,16 @@ void RN_NET::RemoveItem( const ZONE_CONTAINER* aZone )
|
|||
// Remove all subpolygons that make the zone
|
||||
std::deque<RN_POLY>& polygons = zoneData.m_Polygons;
|
||||
BOOST_FOREACH( RN_POLY& polygon, polygons )
|
||||
{
|
||||
RN_NODE_PTR node = polygon.GetNode();
|
||||
node->RemoveParent( aZone );
|
||||
|
||||
if( m_links.RemoveNode( node ) )
|
||||
clearNode( node );
|
||||
}
|
||||
removeNode( polygon.GetNode(), aZone );
|
||||
polygons.clear();
|
||||
|
||||
// Remove all connections added by the zone
|
||||
std::deque<RN_EDGE_MST_PTR>& edges = zoneData.m_Edges;
|
||||
BOOST_FOREACH( RN_EDGE_PTR edge, edges )
|
||||
m_links.RemoveConnection( edge );
|
||||
BOOST_FOREACH( RN_EDGE_MST_PTR edge, edges )
|
||||
removeEdge( edge, aZone );
|
||||
edges.clear();
|
||||
|
||||
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:
|
||||
{
|
||||
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;
|
||||
|
||||
|
@ -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 )
|
||||
{
|
||||
if( it->second->GetTag() == tag )
|
||||
if( it->second.m_Node->GetTag() == tag )
|
||||
aOutput.push_back( const_cast<D_PAD*>( it->first ) );
|
||||
}
|
||||
}
|
||||
|
@ -972,6 +971,8 @@ void RN_NET::processZones()
|
|||
if( *point != node && ( (*point)->GetLayers() & layers ).any()
|
||||
&& poly->HitTest( *point ) )
|
||||
{
|
||||
//(*point)->AddParent( zone ); // do not assign parent for helper links
|
||||
|
||||
RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
|
||||
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 )
|
||||
{
|
||||
int net;
|
||||
|
|
|
@ -279,6 +279,11 @@ public:
|
|||
return m_node;
|
||||
}
|
||||
|
||||
inline RN_NODE_PTR& GetNode()
|
||||
{
|
||||
return m_node;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function HitTest()
|
||||
* 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.
|
||||
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.
|
||||
void clearNode( const RN_NODE_PTR& aNode );
|
||||
|
||||
///> Adds appropriate edges for nodes that are connected by zones.
|
||||
void processZones();
|
||||
|
||||
// TODO
|
||||
void processPads();
|
||||
|
||||
///> Recomputes ratsnset from scratch.
|
||||
void compute();
|
||||
|
||||
|
@ -569,6 +583,7 @@ protected:
|
|||
///> Flag indicating necessity of recalculation of ratsnest for a net.
|
||||
bool m_dirty;
|
||||
|
||||
// TODO
|
||||
typedef struct
|
||||
{
|
||||
///> Subpolygons belonging to a zone
|
||||
|
@ -578,8 +593,18 @@ protected:
|
|||
std::deque<RN_EDGE_MST_PTR> m_Edges;
|
||||
} 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
|
||||
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 TRACK*, RN_EDGE_MST_PTR> TRACK_EDGE_MAP;
|
||||
typedef boost::unordered_map<const ZONE_CONTAINER*, RN_ZONE_DATA> ZONE_DATA_MAP;
|
||||
|
|
Loading…
Reference in New Issue