Ratsnest fix (GAL).
This commit is contained in:
parent
d89d1d49a3
commit
a2b8ab6b41
|
@ -42,7 +42,7 @@
|
||||||
#ifndef _HE_TRIANG_H_
|
#ifndef _HE_TRIANG_H_
|
||||||
#define _HE_TRIANG_H_
|
#define _HE_TRIANG_H_
|
||||||
|
|
||||||
#define TTL_USE_NODE_ID // Each node gets it's own unique id
|
//#define TTL_USE_NODE_ID // Each node gets it's own unique id
|
||||||
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
|
#define TTL_USE_NODE_FLAG // Each node gets a flag (can be set to true or false)
|
||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
|
@ -136,15 +136,15 @@ static std::vector<RN_EDGE_MST_PTR>* kruskalMST( RN_LINKS::RN_EDGE_LIST& aEdges,
|
||||||
int srcTag = tags[dt->GetSourceNode()];
|
int srcTag = tags[dt->GetSourceNode()];
|
||||||
int trgTag = tags[dt->GetTargetNode()];
|
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
|
// Check if by adding this edge we are going to join two different forests
|
||||||
if( srcTag != trgTag )
|
if( srcTag != trgTag )
|
||||||
{
|
{
|
||||||
|
// 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;
|
||||||
|
|
||||||
// Update tags
|
// Update tags
|
||||||
std::list<int>::iterator it, itEnd;
|
std::list<int>::iterator it, itEnd;
|
||||||
|
|
||||||
|
@ -267,6 +267,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 );
|
||||||
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 );
|
||||||
m_edges.push_back( edge );
|
m_edges.push_back( edge );
|
||||||
|
|
||||||
|
@ -279,7 +280,7 @@ void RN_NET::compute()
|
||||||
const RN_LINKS::RN_NODE_SET& boardNodes = m_links.GetNodes();
|
const RN_LINKS::RN_NODE_SET& boardNodes = m_links.GetNodes();
|
||||||
const RN_LINKS::RN_EDGE_LIST& boardEdges = m_links.GetConnections();
|
const RN_LINKS::RN_EDGE_LIST& boardEdges = m_links.GetConnections();
|
||||||
|
|
||||||
// Special cases that does need so complicated algorithm
|
// Special cases do not need complicated algorithms
|
||||||
if( boardNodes.size() <= 2 )
|
if( boardNodes.size() <= 2 )
|
||||||
{
|
{
|
||||||
m_rnEdges.reset( new std::vector<RN_EDGE_MST_PTR>( 0 ) );
|
m_rnEdges.reset( new std::vector<RN_EDGE_MST_PTR>( 0 ) );
|
||||||
|
@ -326,7 +327,7 @@ void RN_NET::clearNode( const RN_NODE_PTR& aNode )
|
||||||
|
|
||||||
// Remove all ratsnest edges for associated with the node
|
// Remove all ratsnest edges for associated with the node
|
||||||
newEnd = std::remove_if( m_rnEdges->begin(), m_rnEdges->end(),
|
newEnd = std::remove_if( m_rnEdges->begin(), m_rnEdges->end(),
|
||||||
boost::bind( isEdgeConnectingNode, _1, boost::ref( aNode ) ) );
|
boost::bind( isEdgeConnectingNode, _1, boost::cref( aNode ) ) );
|
||||||
|
|
||||||
m_rnEdges->resize( std::distance( m_rnEdges->begin(), newEnd ) );
|
m_rnEdges->resize( std::distance( m_rnEdges->begin(), newEnd ) );
|
||||||
}
|
}
|
||||||
|
@ -334,11 +335,11 @@ void RN_NET::clearNode( const RN_NODE_PTR& aNode )
|
||||||
|
|
||||||
RN_POLY::RN_POLY( const CPolyPt* aBegin, const CPolyPt* aEnd, const ZONE_CONTAINER* aParent,
|
RN_POLY::RN_POLY( const CPolyPt* aBegin, const CPolyPt* aEnd, const ZONE_CONTAINER* aParent,
|
||||||
RN_LINKS& aConnections, const BOX2I& aBBox ) :
|
RN_LINKS& aConnections, const BOX2I& aBBox ) :
|
||||||
m_parent( aParent), m_begin( aBegin ), m_end( aEnd ), m_bbox( aBBox )
|
m_parent( aParent ), m_begin( aBegin ), m_end( aEnd ), m_bbox( aBBox )
|
||||||
{
|
{
|
||||||
m_node = aConnections.AddNode( m_begin->x, m_begin->y );
|
m_node = aConnections.AddNode( m_begin->x, m_begin->y );
|
||||||
|
|
||||||
// Mark it as not feasible as a destination of ratsnest edges
|
// Mark it as not appropriate as a destination of ratsnest edges
|
||||||
// (edges coming out from a polygon vertex look weird)
|
// (edges coming out from a polygon vertex look weird)
|
||||||
m_node->SetFlag( true );
|
m_node->SetFlag( true );
|
||||||
}
|
}
|
||||||
|
@ -426,9 +427,11 @@ void RN_NET::AddItem( const TRACK* aTrack )
|
||||||
RN_NODE_PTR start = m_links.AddNode( aTrack->GetStart().x, aTrack->GetStart().y );
|
RN_NODE_PTR start = m_links.AddNode( aTrack->GetStart().x, aTrack->GetStart().y );
|
||||||
RN_NODE_PTR end = m_links.AddNode( aTrack->GetEnd().x, aTrack->GetEnd().y );
|
RN_NODE_PTR end = m_links.AddNode( aTrack->GetEnd().x, aTrack->GetEnd().y );
|
||||||
|
|
||||||
m_tracks[aTrack] = m_links.AddConnection( start, end );
|
if( start != end )
|
||||||
|
{
|
||||||
m_dirty = true;
|
m_tracks[aTrack] = m_links.AddConnection( start, end );
|
||||||
|
m_dirty = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -436,6 +439,7 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
|
||||||
{
|
{
|
||||||
// Prepare a list of polygons (every zone can contain one or more polygons)
|
// Prepare a list of polygons (every zone can contain one or more polygons)
|
||||||
const std::vector<CPolyPt>& polyPoints = aZone->GetFilledPolysList().GetList();
|
const std::vector<CPolyPt>& polyPoints = aZone->GetFilledPolysList().GetList();
|
||||||
|
|
||||||
if( polyPoints.size() == 0 )
|
if( polyPoints.size() == 0 )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -449,21 +453,8 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
|
||||||
{
|
{
|
||||||
const CPolyPt& point = polyPoints[i];
|
const CPolyPt& point = polyPoints[i];
|
||||||
|
|
||||||
// Determine bounding box
|
|
||||||
if( point.x < origin.x )
|
|
||||||
origin.x = point.x;
|
|
||||||
else if( point.x > end.x )
|
|
||||||
end.x = point.x;
|
|
||||||
|
|
||||||
if( point.y < origin.y )
|
|
||||||
origin.y = point.y;
|
|
||||||
else if( point.y > end.y )
|
|
||||||
end.y = point.y;
|
|
||||||
|
|
||||||
if( point.end_contour )
|
if( point.end_contour )
|
||||||
{
|
{
|
||||||
// The last vertex is enclosing the polygon (it repeats at the beginning and
|
|
||||||
// at the end), so we skip it
|
|
||||||
m_zonePolygons[aZone].push_back( RN_POLY( &polyPoints[idxStart], &point, aZone,
|
m_zonePolygons[aZone].push_back( RN_POLY( &polyPoints[idxStart], &point, aZone,
|
||||||
m_links, BOX2I( origin, end - origin ) ) );
|
m_links, BOX2I( origin, end - origin ) ) );
|
||||||
|
|
||||||
|
@ -477,6 +468,19 @@ void RN_NET::AddItem( const ZONE_CONTAINER* aZone )
|
||||||
end.y = polyPoints[idxStart].y;
|
end.y = polyPoints[idxStart].y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Determine bounding box
|
||||||
|
if( point.x < origin.x )
|
||||||
|
origin.x = point.x;
|
||||||
|
else if( point.x > end.x )
|
||||||
|
end.x = point.x;
|
||||||
|
|
||||||
|
if( point.y < origin.y )
|
||||||
|
origin.y = point.y;
|
||||||
|
else if( point.y > end.y )
|
||||||
|
end.y = point.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dirty = true;
|
m_dirty = true;
|
||||||
|
@ -721,11 +725,21 @@ std::list<RN_NODE_PTR> RN_NET::GetNodes( const BOARD_CONNECTED_ITEM* aItem ) con
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case PCB_ZONE_AREA_T:
|
||||||
|
{
|
||||||
|
const ZONE_CONTAINER* zone = static_cast<const ZONE_CONTAINER*>( aItem );
|
||||||
|
const std::deque<RN_POLY>& polys = m_zonePolygons.at( zone );
|
||||||
|
|
||||||
|
for( std::deque<RN_POLY>::const_iterator it = polys.begin(); it != polys.end(); ++it )
|
||||||
|
nodes.push_back( it->GetNode() );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch ( ... )
|
catch( ... )
|
||||||
{
|
{
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
@ -959,30 +973,32 @@ void RN_NET::processZones()
|
||||||
edges.clear();
|
edges.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
|
|
||||||
|
|
||||||
BOOST_FOREACH( std::deque<RN_POLY>& polygons, m_zonePolygons | boost::adaptors::map_values )
|
BOOST_FOREACH( std::deque<RN_POLY>& polygons, m_zonePolygons | boost::adaptors::map_values )
|
||||||
{
|
{
|
||||||
if( polygons.empty() )
|
RN_LINKS::RN_NODE_SET candidates = m_links.GetNodes();
|
||||||
continue;
|
|
||||||
|
|
||||||
RN_LINKS::RN_NODE_SET::iterator point, pointEnd;
|
RN_LINKS::RN_NODE_SET::iterator point, pointEnd;
|
||||||
|
|
||||||
// Sorting by area should speed up the processing, as smaller polygons are computed
|
// Sorting by area should speed up the processing, as smaller polygons are computed
|
||||||
// faster and may reduce the number of points for further checks
|
// faster and may reduce the number of points for further checks
|
||||||
std::sort( polygons.begin(), polygons.end(), sortArea );
|
std::sort( polygons.begin(), polygons.end(), sortArea );
|
||||||
|
|
||||||
std::deque<RN_POLY>::iterator poly = polygons.begin(), polyEnd = polygons.end();
|
for( std::deque<RN_POLY>::iterator poly = polygons.begin(), polyEnd = polygons.end();
|
||||||
const RN_NODE_PTR& node = poly->GetNode();
|
poly != polyEnd; ++poly )
|
||||||
std::deque<RN_EDGE_MST_PTR>& connections = m_zoneConnections[poly->GetParent()];
|
|
||||||
|
|
||||||
for( ; poly != polyEnd; ++poly )
|
|
||||||
{
|
{
|
||||||
|
const RN_NODE_PTR& node = poly->GetNode();
|
||||||
|
std::deque<RN_EDGE_MST_PTR>& connections = m_zoneConnections[poly->GetParent()];
|
||||||
|
|
||||||
point = candidates.begin();
|
point = candidates.begin();
|
||||||
pointEnd = candidates.end();
|
pointEnd = candidates.end();
|
||||||
|
|
||||||
while( point != pointEnd )
|
while( point != pointEnd )
|
||||||
{
|
{
|
||||||
|
if( *point == node )
|
||||||
|
{
|
||||||
|
++point;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if( poly->HitTest( *point ) )
|
if( poly->HitTest( *point ) )
|
||||||
{
|
{
|
||||||
RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
|
RN_EDGE_MST_PTR connection = m_links.AddConnection( node, *point );
|
||||||
|
@ -1142,8 +1158,9 @@ void RN_DATA::Update( const BOARD_ITEM* aItem )
|
||||||
|
|
||||||
void RN_DATA::ProcessBoard()
|
void RN_DATA::ProcessBoard()
|
||||||
{
|
{
|
||||||
|
int netCount = m_board->GetNetCount();
|
||||||
m_nets.clear();
|
m_nets.clear();
|
||||||
m_nets.resize( m_board->GetNetCount() );
|
m_nets.resize( netCount );
|
||||||
int netCode;
|
int netCode;
|
||||||
|
|
||||||
// Iterate over all items that may need to be connected
|
// Iterate over all items that may need to be connected
|
||||||
|
@ -1153,7 +1170,9 @@ void RN_DATA::ProcessBoard()
|
||||||
{
|
{
|
||||||
netCode = pad->GetNetCode();
|
netCode = pad->GetNetCode();
|
||||||
|
|
||||||
if( netCode > 0 )
|
assert( netCode >= 0 && netCode < netCount );
|
||||||
|
|
||||||
|
if( netCode > 0 && netCode < netCount )
|
||||||
m_nets[netCode].AddItem( pad );
|
m_nets[netCode].AddItem( pad );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1162,7 +1181,9 @@ void RN_DATA::ProcessBoard()
|
||||||
{
|
{
|
||||||
netCode = track->GetNetCode();
|
netCode = track->GetNetCode();
|
||||||
|
|
||||||
if( netCode > 0 )
|
assert( netCode >= 0 && netCode < netCount );
|
||||||
|
|
||||||
|
if( netCode > 0 && netCode < netCount )
|
||||||
{
|
{
|
||||||
if( track->Type() == PCB_VIA_T )
|
if( track->Type() == PCB_VIA_T )
|
||||||
m_nets[netCode].AddItem( static_cast<VIA*>( track ) );
|
m_nets[netCode].AddItem( static_cast<VIA*>( track ) );
|
||||||
|
@ -1177,7 +1198,9 @@ void RN_DATA::ProcessBoard()
|
||||||
|
|
||||||
netCode = zone->GetNetCode();
|
netCode = zone->GetNetCode();
|
||||||
|
|
||||||
if( netCode > 0 )
|
assert( netCode >= 0 && netCode < netCount );
|
||||||
|
|
||||||
|
if( netCode > 0 && netCode < netCount )
|
||||||
m_nets[netCode].AddItem( zone );
|
m_nets[netCode].AddItem( zone );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -215,7 +215,7 @@ public:
|
||||||
* Returns node representing a polygon (it has the same coordinates as the first point of its
|
* Returns node representing a polygon (it has the same coordinates as the first point of its
|
||||||
* bounding polyline.
|
* bounding polyline.
|
||||||
*/
|
*/
|
||||||
const RN_NODE_PTR& GetNode() const
|
inline const RN_NODE_PTR& GetNode() const
|
||||||
{
|
{
|
||||||
return m_node;
|
return m_node;
|
||||||
}
|
}
|
||||||
|
@ -556,7 +556,7 @@ protected:
|
||||||
/**
|
/**
|
||||||
* Class RN_DATA
|
* Class RN_DATA
|
||||||
*
|
*
|
||||||
* Stores information about unconnected items for the whole PCB.
|
* Stores information about unconnected items for a board.
|
||||||
*/
|
*/
|
||||||
class RN_DATA
|
class RN_DATA
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue