router: abstract segment links into a LINK_HOLDER interface. DIFF_PAIRS are now also linkable
This commit is contained in:
parent
151b4e4e5e
commit
fd07e94760
|
@ -120,7 +120,7 @@ bool COMPONENT_DRAGGER::Drag( const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
auto l_new( cn.origLine );
|
auto l_new( cn.origLine );
|
||||||
l_new.Unmark();
|
l_new.Unmark();
|
||||||
l_new.ClearSegmentLinks();
|
l_new.ClearLinks();
|
||||||
l_new.DragCorner( cn.p_next, cn.origLine.CLine().Find( cn.p_orig ) );
|
l_new.DragCorner( cn.p_next, cn.origLine.CLine().Find( cn.p_orig ) );
|
||||||
|
|
||||||
Dbg()->AddLine( l_new.CLine(), 4, 100000 );
|
Dbg()->AddLine( l_new.CLine(), 4, 100000 );
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "pns_line.h"
|
#include "pns_line.h"
|
||||||
#include "pns_via.h"
|
#include "pns_via.h"
|
||||||
|
#include "pns_link_holder.h"
|
||||||
|
|
||||||
#include "ranged_num.h"
|
#include "ranged_num.h"
|
||||||
|
|
||||||
|
@ -262,7 +263,7 @@ class DP_GATEWAYS
|
||||||
* Basic class for a differential pair. Stores two PNS_LINEs (for positive and negative nets, respectively),
|
* Basic class for a differential pair. Stores two PNS_LINEs (for positive and negative nets, respectively),
|
||||||
* the gap and coupling constraints.
|
* the gap and coupling constraints.
|
||||||
**/
|
**/
|
||||||
class DIFF_PAIR : public ITEM {
|
class DIFF_PAIR : public LINK_HOLDER {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct COUPLED_SEGMENTS {
|
struct COUPLED_SEGMENTS {
|
||||||
|
@ -286,7 +287,7 @@ public:
|
||||||
|
|
||||||
typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
|
typedef std::vector<COUPLED_SEGMENTS> COUPLED_SEGMENTS_VEC;
|
||||||
|
|
||||||
DIFF_PAIR() : ITEM( DIFF_PAIR_T ), m_hasVias( false )
|
DIFF_PAIR() : LINK_HOLDER( ITEM::DIFF_PAIR_T ), m_hasVias( false )
|
||||||
{
|
{
|
||||||
// Initialize some members, to avoid uninitialized variables.
|
// Initialize some members, to avoid uninitialized variables.
|
||||||
m_net_p = 0;
|
m_net_p = 0;
|
||||||
|
@ -299,7 +300,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DIFF_PAIR( int aGap ) :
|
DIFF_PAIR( int aGap ) :
|
||||||
ITEM( DIFF_PAIR_T ),
|
LINK_HOLDER( ITEM::DIFF_PAIR_T ),
|
||||||
m_hasVias( false )
|
m_hasVias( false )
|
||||||
{
|
{
|
||||||
m_gapConstraint = aGap;
|
m_gapConstraint = aGap;
|
||||||
|
@ -315,7 +316,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DIFF_PAIR( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
|
DIFF_PAIR( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, int aGap = 0 ):
|
||||||
ITEM( DIFF_PAIR_T ),
|
LINK_HOLDER( ITEM::DIFF_PAIR_T ),
|
||||||
m_n( aN ),
|
m_n( aN ),
|
||||||
m_p( aP ),
|
m_p( aP ),
|
||||||
m_hasVias( false )
|
m_hasVias( false )
|
||||||
|
@ -333,7 +334,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
DIFF_PAIR( const LINE &aLineP, const LINE &aLineN, int aGap = 0 ):
|
DIFF_PAIR( const LINE &aLineP, const LINE &aLineN, int aGap = 0 ):
|
||||||
ITEM( DIFF_PAIR_T ),
|
LINK_HOLDER( ITEM::DIFF_PAIR_T ),
|
||||||
m_line_p( aLineP ),
|
m_line_p( aLineP ),
|
||||||
m_line_n( aLineN ),
|
m_line_n( aLineN ),
|
||||||
m_hasVias( false )
|
m_hasVias( false )
|
||||||
|
@ -354,11 +355,18 @@ public:
|
||||||
|
|
||||||
static inline bool ClassOf( const ITEM* aItem )
|
static inline bool ClassOf( const ITEM* aItem )
|
||||||
{
|
{
|
||||||
return aItem && DIFF_PAIR_T == aItem->Kind();
|
return aItem && ITEM::DIFF_PAIR_T == aItem->Kind();
|
||||||
}
|
}
|
||||||
|
|
||||||
DIFF_PAIR* Clone() const override { assert( false ); return NULL; }
|
DIFF_PAIR* Clone() const override { assert( false ); return NULL; }
|
||||||
|
|
||||||
|
virtual void ClearLinks() override
|
||||||
|
{
|
||||||
|
m_links.clear();
|
||||||
|
m_line_p.ClearLinks();
|
||||||
|
m_line_n.ClearLinks();
|
||||||
|
}
|
||||||
|
|
||||||
static DIFF_PAIR* AssembleDp( LINE *aLine );
|
static DIFF_PAIR* AssembleDp( LINE *aLine );
|
||||||
|
|
||||||
void SetShape( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false )
|
void SetShape( const SHAPE_LINE_CHAIN &aP, const SHAPE_LINE_CHAIN& aN, bool aSwapLanes = false )
|
||||||
|
|
|
@ -206,7 +206,7 @@ bool DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
||||||
LINE origLine( m_draggedLine );
|
LINE origLine( m_draggedLine );
|
||||||
LINE dragged( m_draggedLine );
|
LINE dragged( m_draggedLine );
|
||||||
dragged.SetSnapThreshhold( thresh );
|
dragged.SetSnapThreshhold( thresh );
|
||||||
dragged.ClearSegmentLinks();
|
dragged.ClearLinks();
|
||||||
|
|
||||||
if( m_mode == DM_SEGMENT )
|
if( m_mode == DM_SEGMENT )
|
||||||
dragged.DragSegment( aP, m_draggedSegmentIndex );
|
dragged.DragSegment( aP, m_draggedSegmentIndex );
|
||||||
|
@ -258,7 +258,7 @@ void DRAGGER::dragViaMarkObstacles( const VIA_HANDLE& aHandle, NODE* aNode, cons
|
||||||
LINE draggedLine( *l );
|
LINE draggedLine( *l );
|
||||||
|
|
||||||
draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
||||||
draggedLine.ClearSegmentLinks();
|
draggedLine.ClearLinks();
|
||||||
|
|
||||||
m_draggedItems.Add( draggedLine );
|
m_draggedItems.Add( draggedLine );
|
||||||
|
|
||||||
|
@ -298,7 +298,7 @@ void DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const V
|
||||||
LINE draggedLine( *l );
|
LINE draggedLine( *l );
|
||||||
|
|
||||||
draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
draggedLine.DragCorner( aP, origLine.CLine().Find( aHandle.pos ), m_freeAngleMode );
|
||||||
draggedLine.ClearSegmentLinks();
|
draggedLine.ClearLinks();
|
||||||
|
|
||||||
m_draggedItems.Add( draggedLine );
|
m_draggedItems.Add( draggedLine );
|
||||||
|
|
||||||
|
@ -322,7 +322,7 @@ void DRAGGER::dragViaWalkaround( const VIA_HANDLE& aHandle, NODE* aNode, const V
|
||||||
void DRAGGER::optimizeAndUpdateDraggedLine( LINE& dragged, const VECTOR2I& aP )
|
void DRAGGER::optimizeAndUpdateDraggedLine( LINE& dragged, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
VECTOR2D lockV;
|
VECTOR2D lockV;
|
||||||
dragged.ClearSegmentLinks();
|
dragged.ClearLinks();
|
||||||
dragged.Unmark();
|
dragged.Unmark();
|
||||||
|
|
||||||
lockV = dragged.CLine().NearestPoint( aP );
|
lockV = dragged.CLine().NearestPoint( aP );
|
||||||
|
@ -462,7 +462,7 @@ bool DRAGGER::dragShove( const VECTOR2I& aP )
|
||||||
if( ok )
|
if( ok )
|
||||||
{
|
{
|
||||||
VECTOR2D lockV;
|
VECTOR2D lockV;
|
||||||
dragged.ClearSegmentLinks();
|
dragged.ClearLinks();
|
||||||
dragged.Unmark();
|
dragged.Unmark();
|
||||||
|
|
||||||
lockV = dragged.CLine().NearestPoint( aP );
|
lockV = dragged.CLine().NearestPoint( aP );
|
||||||
|
|
|
@ -78,6 +78,7 @@ std::string ITEM::KindStr() const
|
||||||
case VIA_T: return "via";
|
case VIA_T: return "via";
|
||||||
case JOINT_T: return "joint";
|
case JOINT_T: return "joint";
|
||||||
case SOLID_T: return "solid";
|
case SOLID_T: return "solid";
|
||||||
|
case DIFF_PAIR_T: return "diff-pair";
|
||||||
default: return "unknown";
|
default: return "unknown";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
namespace PNS {
|
namespace PNS {
|
||||||
|
|
||||||
LINE::LINE( const LINE& aOther )
|
LINE::LINE( const LINE& aOther )
|
||||||
: ITEM( aOther ),
|
: LINK_HOLDER( aOther ),
|
||||||
m_line( aOther.m_line ),
|
m_line( aOther.m_line ),
|
||||||
m_width( aOther.m_width ),
|
m_width( aOther.m_width ),
|
||||||
m_snapThreshhold( aOther.m_snapThreshhold )
|
m_snapThreshhold( aOther.m_snapThreshhold )
|
||||||
|
@ -89,7 +89,7 @@ void LINE::Mark( int aMarker )
|
||||||
{
|
{
|
||||||
m_marker = aMarker;
|
m_marker = aMarker;
|
||||||
|
|
||||||
for( auto s : m_segmentRefs )
|
for( auto s : m_links )
|
||||||
s->Mark( aMarker );
|
s->Mark( aMarker );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,7 @@ void LINE::Mark( int aMarker )
|
||||||
|
|
||||||
void LINE::Unmark( int aMarker )
|
void LINE::Unmark( int aMarker )
|
||||||
{
|
{
|
||||||
for( auto s : m_segmentRefs )
|
for( auto s : m_links )
|
||||||
s->Unmark( aMarker );
|
s->Unmark( aMarker );
|
||||||
|
|
||||||
m_marker = 0;
|
m_marker = 0;
|
||||||
|
@ -108,7 +108,7 @@ int LINE::Marker() const
|
||||||
{
|
{
|
||||||
int marker = m_marker;
|
int marker = m_marker;
|
||||||
|
|
||||||
for( auto s : m_segmentRefs )
|
for( auto s : m_links )
|
||||||
{
|
{
|
||||||
marker |= s->Marker();
|
marker |= s->Marker();
|
||||||
}
|
}
|
||||||
|
@ -117,12 +117,6 @@ int LINE::Marker() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LINE::copyLinks( const LINE* aParent )
|
|
||||||
{
|
|
||||||
m_segmentRefs = aParent->m_segmentRefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SEGMENT* SEGMENT::Clone() const
|
SEGMENT* SEGMENT::Clone() const
|
||||||
{
|
{
|
||||||
SEGMENT* s = new SEGMENT;
|
SEGMENT* s = new SEGMENT;
|
||||||
|
@ -460,20 +454,6 @@ const LINE LINE::ClipToNearestObstacle( NODE* aNode ) const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LINE::ShowLinks() const
|
|
||||||
{
|
|
||||||
if( !IsLinked() )
|
|
||||||
{
|
|
||||||
wxLogTrace( "PNS", "line %p: no links", this );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxLogTrace( "PNS", "line %p: %d linked segs", this, (int) m_segmentRefs.size() );
|
|
||||||
|
|
||||||
for( int i = 0; i < (int) m_segmentRefs.size(); i++ )
|
|
||||||
wxLogTrace( "PNS", "seg %d: %p\n", i, m_segmentRefs[i] );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP )
|
SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
|
@ -852,7 +832,7 @@ void LINE::Reverse()
|
||||||
{
|
{
|
||||||
m_line = m_line.Reverse();
|
m_line = m_line.Reverse();
|
||||||
|
|
||||||
std::reverse( m_segmentRefs.begin(), m_segmentRefs.end() );
|
std::reverse( m_links.begin(), m_links.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -873,7 +853,7 @@ void LINE::SetRank( int aRank )
|
||||||
{
|
{
|
||||||
m_rank = aRank;
|
m_rank = aRank;
|
||||||
|
|
||||||
for( auto s : m_segmentRefs )
|
for( auto s : m_links )
|
||||||
s->SetRank( aRank );
|
s->SetRank( aRank );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -884,7 +864,7 @@ int LINE::Rank() const
|
||||||
int min_rank = INT_MAX;
|
int min_rank = INT_MAX;
|
||||||
|
|
||||||
if( IsLinked() ) {
|
if( IsLinked() ) {
|
||||||
for( auto s : m_segmentRefs )
|
for( auto s : m_links )
|
||||||
{
|
{
|
||||||
min_rank = std::min( min_rank, s->Rank() );
|
min_rank = std::min( min_rank, s->Rank() );
|
||||||
}
|
}
|
||||||
|
@ -903,17 +883,17 @@ void LINE::ClipVertexRange( int aStart, int aEnd )
|
||||||
m_line = m_line.Slice( aStart, aEnd );
|
m_line = m_line.Slice( aStart, aEnd );
|
||||||
|
|
||||||
if( IsLinked() ) {
|
if( IsLinked() ) {
|
||||||
assert( m_segmentRefs.size() < INT_MAX );
|
assert( m_links.size() < INT_MAX );
|
||||||
assert( (int) m_segmentRefs.size() >= (aEnd - aStart) );
|
assert( (int) m_links.size() >= (aEnd - aStart) );
|
||||||
|
|
||||||
// Note: The range includes aEnd, but we have n-1 segments.
|
// Note: The range includes aEnd, but we have n-1 segments.
|
||||||
std::rotate(
|
std::rotate(
|
||||||
m_segmentRefs.begin(),
|
m_links.begin(),
|
||||||
m_segmentRefs.begin() + aStart,
|
m_links.begin() + aStart,
|
||||||
m_segmentRefs.begin() + aEnd
|
m_links.begin() + aEnd
|
||||||
);
|
);
|
||||||
|
|
||||||
m_segmentRefs.resize( aEnd - aStart );
|
m_links.resize( aEnd - aStart );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -933,12 +913,6 @@ bool LINE::HasLoops() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LINE::ClearSegmentLinks()
|
|
||||||
{
|
|
||||||
m_segmentRefs.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void extendBox( BOX2I& aBox, bool& aDefined, const VECTOR2I& aP )
|
static void extendBox( BOX2I& aBox, bool& aDefined, const VECTOR2I& aP )
|
||||||
{
|
{
|
||||||
if( aDefined )
|
if( aDefined )
|
||||||
|
@ -1036,7 +1010,7 @@ OPT_BOX2I LINE::ChangedArea( const LINE* aOther ) const
|
||||||
|
|
||||||
bool LINE::HasLockedSegments() const
|
bool LINE::HasLockedSegments() const
|
||||||
{
|
{
|
||||||
for( const auto seg : m_segmentRefs )
|
for( const auto seg : m_links )
|
||||||
{
|
{
|
||||||
if( seg->Marker() & MK_LOCKED )
|
if( seg->Marker() & MK_LOCKED )
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include "pns_item.h"
|
#include "pns_item.h"
|
||||||
#include "pns_via.h"
|
#include "pns_via.h"
|
||||||
|
#include "pns_link_holder.h"
|
||||||
|
|
||||||
namespace PNS {
|
namespace PNS {
|
||||||
|
|
||||||
|
@ -58,16 +59,15 @@ class VIA;
|
||||||
|
|
||||||
#define PNS_HULL_MARGIN 10
|
#define PNS_HULL_MARGIN 10
|
||||||
|
|
||||||
class LINE : public ITEM
|
class LINE : public LINK_HOLDER
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::vector<LINKED_ITEM*> SEGMENT_REFS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
* Makes an empty line.
|
* Makes an empty line.
|
||||||
*/
|
*/
|
||||||
LINE() : ITEM( LINE_T )
|
LINE() : LINK_HOLDER( LINE_T )
|
||||||
{
|
{
|
||||||
m_hasVia = false;
|
m_hasVia = false;
|
||||||
m_width = 1; // Dummy value
|
m_width = 1; // Dummy value
|
||||||
|
@ -82,7 +82,7 @@ public:
|
||||||
* by another
|
* by another
|
||||||
**/
|
**/
|
||||||
LINE( const LINE& aBase, const SHAPE_LINE_CHAIN& aLine )
|
LINE( const LINE& aBase, const SHAPE_LINE_CHAIN& aLine )
|
||||||
: ITEM( aBase ),
|
: LINK_HOLDER( aBase ),
|
||||||
m_line( aLine ),
|
m_line( aLine ),
|
||||||
m_width( aBase.m_width ),
|
m_width( aBase.m_width ),
|
||||||
m_snapThreshhold( aBase.m_snapThreshhold )
|
m_snapThreshhold( aBase.m_snapThreshhold )
|
||||||
|
@ -98,7 +98,7 @@ public:
|
||||||
* @param aVia
|
* @param aVia
|
||||||
*/
|
*/
|
||||||
LINE( const VIA& aVia ) :
|
LINE( const VIA& aVia ) :
|
||||||
ITEM( LINE_T )
|
LINK_HOLDER( LINE_T )
|
||||||
{
|
{
|
||||||
m_hasVia = true;
|
m_hasVia = true;
|
||||||
m_via = aVia;
|
m_via = aVia;
|
||||||
|
@ -121,6 +121,11 @@ public:
|
||||||
|
|
||||||
LINE& operator=( const LINE& aOther );
|
LINE& operator=( const LINE& aOther );
|
||||||
|
|
||||||
|
bool IsLinkedChecked() const
|
||||||
|
{
|
||||||
|
return IsLinked() && LinkCount() == SegmentCount();
|
||||||
|
}
|
||||||
|
|
||||||
///> Assigns a shape to the line (a polyline/line chain)
|
///> Assigns a shape to the line (a polyline/line chain)
|
||||||
void SetShape( const SHAPE_LINE_CHAIN& aLine )
|
void SetShape( const SHAPE_LINE_CHAIN& aLine )
|
||||||
{
|
{
|
||||||
|
@ -195,53 +200,6 @@ public:
|
||||||
///> Reverses the point/vertex order
|
///> Reverses the point/vertex order
|
||||||
void Reverse();
|
void Reverse();
|
||||||
|
|
||||||
|
|
||||||
/* Linking functions */
|
|
||||||
|
|
||||||
///> Adds a reference to a segment registered in a NODE that is a part of this line.
|
|
||||||
void LinkSegment( LINKED_ITEM* aSeg )
|
|
||||||
{
|
|
||||||
m_segmentRefs.push_back( aSeg );
|
|
||||||
}
|
|
||||||
|
|
||||||
///> Returns the list of segments from the owning node that constitute this
|
|
||||||
///> line (or NULL if the line is not linked)
|
|
||||||
SEGMENT_REFS& LinkedSegments()
|
|
||||||
{
|
|
||||||
return m_segmentRefs;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsLinked() const
|
|
||||||
{
|
|
||||||
return m_segmentRefs.size() != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsLinkedChecked() const
|
|
||||||
{
|
|
||||||
return IsLinked() && LinkCount() == SegmentCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
///> Checks if the segment aSeg is a part of the line.
|
|
||||||
bool ContainsSegment( LINKED_ITEM* aSeg ) const
|
|
||||||
{
|
|
||||||
return std::find( m_segmentRefs.begin(), m_segmentRefs.end(),
|
|
||||||
aSeg ) != m_segmentRefs.end();
|
|
||||||
}
|
|
||||||
|
|
||||||
LINKED_ITEM* GetLink( int aIndex ) const
|
|
||||||
{
|
|
||||||
return m_segmentRefs[aIndex];
|
|
||||||
}
|
|
||||||
|
|
||||||
///> Erases the linking information. Used to detach the line from the owning node.
|
|
||||||
void ClearSegmentLinks();
|
|
||||||
|
|
||||||
///> Returns the number of segments that were assembled together to form this line.
|
|
||||||
int LinkCount() const
|
|
||||||
{
|
|
||||||
return m_segmentRefs.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
|
///> Clips the line to the nearest obstacle, traversing from the line's start vertex (0).
|
||||||
///> Returns the clipped line.
|
///> Returns the clipped line.
|
||||||
const LINE ClipToNearestObstacle( NODE* aNode ) const;
|
const LINE ClipToNearestObstacle( NODE* aNode ) const;
|
||||||
|
@ -320,13 +278,6 @@ private:
|
||||||
VECTOR2I snapDraggedCorner(
|
VECTOR2I snapDraggedCorner(
|
||||||
const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP, int aIndex ) const;
|
const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP, int aIndex ) const;
|
||||||
|
|
||||||
///> Copies m_segmentRefs from the line aParent.
|
|
||||||
void copyLinks( const LINE* aParent ) ;
|
|
||||||
|
|
||||||
///> List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL
|
|
||||||
///> if the line is not a part of any node.
|
|
||||||
SEGMENT_REFS m_segmentRefs;
|
|
||||||
|
|
||||||
///> The actual shape of the line
|
///> The actual shape of the line
|
||||||
SHAPE_LINE_CHAIN m_line;
|
SHAPE_LINE_CHAIN m_line;
|
||||||
|
|
||||||
|
|
|
@ -1294,9 +1294,9 @@ void LINE_PLACER::removeLoops( NODE* aNode, LINE& aLatest )
|
||||||
{
|
{
|
||||||
total++;
|
total++;
|
||||||
|
|
||||||
if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
|
if( !( line.ContainsLink( seg ) ) && line.SegmentCount() )
|
||||||
{
|
{
|
||||||
for( auto ss : line.LinkedSegments() )
|
for( auto ss : line.Links() )
|
||||||
toErase.insert( ss );
|
toErase.insert( ss );
|
||||||
|
|
||||||
removedCount++;
|
removedCount++;
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* KiRouter - a push-and-(sometimes-)shove PCB router
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019 CERN
|
||||||
|
* Author: Seth Hillbrand <hillbrand@ucdavis.edu>
|
||||||
|
* Author: Tomasz Wlostowski <tomasz.wlostowski@cern.h>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or (at your
|
||||||
|
* option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PCBNEW_ROUTER_PNS_LINK_HOLDER_H_
|
||||||
|
#define PCBNEW_ROUTER_PNS_LINK_HOLDER_H_
|
||||||
|
|
||||||
|
#include "pns_item.h"
|
||||||
|
#include "pns_linked_item.h"
|
||||||
|
|
||||||
|
namespace PNS
|
||||||
|
{
|
||||||
|
class LINK_HOLDER : public ITEM
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef std::vector<LINKED_ITEM*> LINKS;
|
||||||
|
|
||||||
|
LINK_HOLDER( PnsKind aKind ) : ITEM( aKind )
|
||||||
|
{}
|
||||||
|
|
||||||
|
///> Adds a reference to an item registered in a NODE that is a part of this line.
|
||||||
|
void Link( LINKED_ITEM* aLink )
|
||||||
|
{
|
||||||
|
m_links.push_back( aLink );
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Returns the list of links from the owning node that constitute this
|
||||||
|
///> line (or NULL if the line is not linked)
|
||||||
|
LINKS& Links()
|
||||||
|
{
|
||||||
|
return m_links;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLinked() const
|
||||||
|
{
|
||||||
|
return m_links.size() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Checks if the segment aLink is a part of the line.
|
||||||
|
bool ContainsLink( const LINKED_ITEM* aItem ) const
|
||||||
|
{
|
||||||
|
return std::find( m_links.begin(), m_links.end(),
|
||||||
|
aItem ) != m_links.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
LINKED_ITEM* GetLink( int aIndex ) const
|
||||||
|
{
|
||||||
|
return m_links[aIndex];
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Erases the linking information. Used to detach the line from the owning node.
|
||||||
|
virtual void ClearLinks()
|
||||||
|
{
|
||||||
|
m_links.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
///> Returns the number of segments that were assembled together to form this line.
|
||||||
|
int LinkCount() const
|
||||||
|
{
|
||||||
|
return m_links.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowLinks() const
|
||||||
|
{
|
||||||
|
#if 0 // fixme: move outside header
|
||||||
|
if( !IsLinked() )
|
||||||
|
{
|
||||||
|
wxLogTrace( "PNS", "item %p: no links", this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wxLogTrace( "PNS", "item %p: %d links", this, (int) m_links.size() );
|
||||||
|
|
||||||
|
for( int i = 0; i < (int) m_links.size(); i++ )
|
||||||
|
wxLogTrace( "PNS", "item %d: %p\n", i, m_links[i] );
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
///> Copies m_links from the line aParent.
|
||||||
|
void copyLinks( const LINK_HOLDER* aParent )
|
||||||
|
{
|
||||||
|
m_links = aParent->m_links;
|
||||||
|
}
|
||||||
|
|
||||||
|
///> List of segments in the owning NODE (ITEM::m_owner) that constitute this line, or NULL
|
||||||
|
///> if the line is not a part of any node.
|
||||||
|
LINKS m_links;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace PNS
|
||||||
|
#endif /* PCBNEW_ROUTER_PNS_LINK_HOLDER_H_ */
|
|
@ -574,11 +574,11 @@ void NODE::Add( LINE& aLine, bool aAllowRedundant )
|
||||||
ARC* rarc;
|
ARC* rarc;
|
||||||
|
|
||||||
if( !aAllowRedundant && ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(), aLine.Net() ) ) )
|
if( !aAllowRedundant && ( rarc = findRedundantArc( s.GetP0(), s.GetP1(), aLine.Layers(), aLine.Net() ) ) )
|
||||||
aLine.LinkSegment( rarc );
|
aLine.Link( rarc );
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto newarc = std::make_unique< ARC >( aLine, s );
|
auto newarc = std::make_unique< ARC >( aLine, s );
|
||||||
aLine.LinkSegment( newarc.get() );
|
aLine.Link( newarc.get() );
|
||||||
Add( std::move( newarc ), true );
|
Add( std::move( newarc ), true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -597,12 +597,12 @@ void NODE::Add( LINE& aLine, bool aAllowRedundant )
|
||||||
(rseg = findRedundantSegment( s.A, s.B, aLine.Layers(), aLine.Net() )) )
|
(rseg = findRedundantSegment( s.A, s.B, aLine.Layers(), aLine.Net() )) )
|
||||||
{
|
{
|
||||||
// another line could be referencing this segment too :(
|
// another line could be referencing this segment too :(
|
||||||
aLine.LinkSegment( rseg );
|
aLine.Link( rseg );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
std::unique_ptr< SEGMENT > newseg( new SEGMENT( aLine, s ) );
|
std::unique_ptr< SEGMENT > newseg( new SEGMENT( aLine, s ) );
|
||||||
aLine.LinkSegment( newseg.get() );
|
aLine.Link( newseg.get() );
|
||||||
Add( std::move( newseg ), true );
|
Add( std::move( newseg ), true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,7 +819,7 @@ void NODE::Remove( ITEM* aItem )
|
||||||
{
|
{
|
||||||
auto l = static_cast<LINE *> ( aItem );
|
auto l = static_cast<LINE *> ( aItem );
|
||||||
|
|
||||||
for ( auto s : l->LinkedSegments() )
|
for ( auto s : l->Links() )
|
||||||
Remove( s );
|
Remove( s );
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -838,7 +838,7 @@ void NODE::Remove( ITEM* aItem )
|
||||||
void NODE::Remove( LINE& aLine )
|
void NODE::Remove( LINE& aLine )
|
||||||
{
|
{
|
||||||
// LINE does not have a seperate remover, as LINEs are never truly a member of the tree
|
// LINE does not have a seperate remover, as LINEs are never truly a member of the tree
|
||||||
std::vector<LINKED_ITEM*>& segRefs = aLine.LinkedSegments();
|
std::vector<LINKED_ITEM*>& segRefs = aLine.Links();
|
||||||
|
|
||||||
for( auto li : segRefs )
|
for( auto li : segRefs )
|
||||||
{
|
{
|
||||||
|
@ -849,7 +849,7 @@ void NODE::Remove( LINE& aLine )
|
||||||
}
|
}
|
||||||
|
|
||||||
aLine.SetOwner( nullptr );
|
aLine.SetOwner( nullptr );
|
||||||
aLine.ClearSegmentLinks();
|
aLine.ClearLinks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -925,7 +925,7 @@ const LINE NODE::AssembleLine( LINKED_ITEM* aSeg, int* aOriginSegmentIndex, bool
|
||||||
|
|
||||||
if( segs[i] && prev_seg != segs[i] )
|
if( segs[i] && prev_seg != segs[i] )
|
||||||
{
|
{
|
||||||
pl.LinkSegment( segs[i] );
|
pl.Link( segs[i] );
|
||||||
|
|
||||||
// latter condition to avoid loops
|
// latter condition to avoid loops
|
||||||
if( segs[i] == aSeg && aOriginSegmentIndex && !originSet )
|
if( segs[i] == aSeg && aOriginSegmentIndex && !originSet )
|
||||||
|
|
|
@ -190,14 +190,14 @@ void OPTIMIZER::removeCachedSegments( LINE* aLine, int aStartVertex, int aEndVer
|
||||||
{
|
{
|
||||||
if( !aLine->IsLinked() ) return;
|
if( !aLine->IsLinked() ) return;
|
||||||
|
|
||||||
LINE::SEGMENT_REFS& segs = aLine->LinkedSegments();
|
auto links = aLine->Links();
|
||||||
|
|
||||||
if( aEndVertex < 0 )
|
if( aEndVertex < 0 )
|
||||||
aEndVertex += aLine->PointCount();
|
aEndVertex += aLine->PointCount();
|
||||||
|
|
||||||
for( int i = aStartVertex; i < aEndVertex - 1; i++ )
|
for( int i = aStartVertex; i < aEndVertex - 1; i++ )
|
||||||
{
|
{
|
||||||
LINKED_ITEM* s = segs[i];
|
LINKED_ITEM* s = links[i];
|
||||||
m_cacheTags.erase( s );
|
m_cacheTags.erase( s );
|
||||||
m_cache.Remove( s );
|
m_cache.Remove( s );
|
||||||
}
|
}
|
||||||
|
@ -594,7 +594,10 @@ bool OPTIMIZER::Optimize( LINE* aLine, LINE* aResult )
|
||||||
if( !aResult )
|
if( !aResult )
|
||||||
aResult = aLine;
|
aResult = aLine;
|
||||||
else
|
else
|
||||||
|
{
|
||||||
*aResult = *aLine;
|
*aResult = *aLine;
|
||||||
|
aResult->ClearLinks();
|
||||||
|
}
|
||||||
|
|
||||||
m_keepPostures = false;
|
m_keepPostures = false;
|
||||||
|
|
||||||
|
|
|
@ -266,11 +266,11 @@ SHOVE::SHOVE_STATUS SHOVE::processHullSet( LINE& aCurrent, LINE& aObstacle,
|
||||||
*/
|
*/
|
||||||
SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, LINE& aShoved )
|
SHOVE::SHOVE_STATUS SHOVE::ProcessSingleLine( LINE& aCurrent, LINE& aObstacle, LINE& aShoved )
|
||||||
{
|
{
|
||||||
aShoved.ClearSegmentLinks();
|
aShoved.ClearLinks();
|
||||||
|
|
||||||
bool obstacleIsHead = false;
|
bool obstacleIsHead = false;
|
||||||
|
|
||||||
for( auto s : aObstacle.LinkedSegments() )
|
for( auto s : aObstacle.Links() )
|
||||||
{
|
{
|
||||||
if( s->Marker() & MK_HEAD )
|
if( s->Marker() & MK_HEAD )
|
||||||
{
|
{
|
||||||
|
@ -555,7 +555,7 @@ SHOVE::SHOVE_STATUS SHOVE::onCollidingSolid( LINE& aCurrent, ITEM* aObstacle )
|
||||||
if( status != WALKAROUND::DONE )
|
if( status != WALKAROUND::DONE )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
walkaroundLine.ClearSegmentLinks();
|
walkaroundLine.ClearLinks();
|
||||||
walkaroundLine.Unmark();
|
walkaroundLine.Unmark();
|
||||||
walkaroundLine.Line().Simplify();
|
walkaroundLine.Line().Simplify();
|
||||||
|
|
||||||
|
@ -742,7 +742,7 @@ SHOVE::SHOVE_STATUS SHOVE::pushOrShoveVia( VIA* aVia, const VECTOR2I& aForce, in
|
||||||
lp.first.Reverse();
|
lp.first.Reverse();
|
||||||
|
|
||||||
lp.second = lp.first;
|
lp.second = lp.first;
|
||||||
lp.second.ClearSegmentLinks();
|
lp.second.ClearLinks();
|
||||||
lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
|
lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
|
||||||
lp.second.AppendVia( *pushedVia );
|
lp.second.AppendVia( *pushedVia );
|
||||||
draggedLines.push_back( lp );
|
draggedLines.push_back( lp );
|
||||||
|
@ -891,11 +891,11 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
||||||
{
|
{
|
||||||
int n = 0;
|
int n = 0;
|
||||||
LINE cur( aCurrent );
|
LINE cur( aCurrent );
|
||||||
cur.ClearSegmentLinks();
|
cur.ClearLinks();
|
||||||
|
|
||||||
JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
||||||
LINE shoved( aCurrent );
|
LINE shoved( aCurrent );
|
||||||
shoved.ClearSegmentLinks();
|
shoved.ClearLinks();
|
||||||
|
|
||||||
cur.RemoveVia();
|
cur.RemoveVia();
|
||||||
unwindLineStack( &aCurrent );
|
unwindLineStack( &aCurrent );
|
||||||
|
@ -939,7 +939,7 @@ SHOVE::SHOVE_STATUS SHOVE::onReverseCollidingVia( LINE& aCurrent, VIA* aObstacle
|
||||||
LINE head( aCurrent );
|
LINE head( aCurrent );
|
||||||
head.Line().Clear();
|
head.Line().Clear();
|
||||||
head.AppendVia( *aObstacleVia );
|
head.AppendVia( *aObstacleVia );
|
||||||
head.ClearSegmentLinks();
|
head.ClearLinks();
|
||||||
|
|
||||||
SHOVE_STATUS st = ProcessSingleLine( head, aCurrent, shoved );
|
SHOVE_STATUS st = ProcessSingleLine( head, aCurrent, shoved );
|
||||||
|
|
||||||
|
@ -974,7 +974,7 @@ void SHOVE::unwindLineStack( LINKED_ITEM* aSeg )
|
||||||
{
|
{
|
||||||
for( std::vector<LINE>::iterator i = m_lineStack.begin(); i != m_lineStack.end() ; )
|
for( std::vector<LINE>::iterator i = m_lineStack.begin(); i != m_lineStack.end() ; )
|
||||||
{
|
{
|
||||||
if( i->ContainsSegment( aSeg ) )
|
if( i->ContainsLink( aSeg ) )
|
||||||
i = m_lineStack.erase( i );
|
i = m_lineStack.erase( i );
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
|
@ -982,7 +982,7 @@ void SHOVE::unwindLineStack( LINKED_ITEM* aSeg )
|
||||||
|
|
||||||
for( std::vector<LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end() ; )
|
for( std::vector<LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end() ; )
|
||||||
{
|
{
|
||||||
if( i->ContainsSegment( aSeg ) )
|
if( i->ContainsLink( aSeg ) )
|
||||||
i = m_optimizerQueue.erase( i );
|
i = m_optimizerQueue.erase( i );
|
||||||
else
|
else
|
||||||
i++;
|
i++;
|
||||||
|
@ -998,7 +998,7 @@ void SHOVE::unwindLineStack( ITEM* aItem )
|
||||||
{
|
{
|
||||||
LINE* l = static_cast<LINE*>( aItem );
|
LINE* l = static_cast<LINE*>( aItem );
|
||||||
|
|
||||||
for( auto seg : l->LinkedSegments() )
|
for( auto seg : l->Links() )
|
||||||
unwindLineStack( seg );
|
unwindLineStack( seg );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1031,9 +1031,9 @@ void SHOVE::popLineStack( )
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for( auto s : l.LinkedSegments() )
|
for( auto s : l.Links() )
|
||||||
{
|
{
|
||||||
if( i->ContainsSegment( s ) )
|
if( i->ContainsLink( s ) )
|
||||||
{
|
{
|
||||||
i = m_optimizerQueue.erase( i );
|
i = m_optimizerQueue.erase( i );
|
||||||
found = true;
|
found = true;
|
||||||
|
@ -1254,7 +1254,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveLines( const LINE& aCurrentHead )
|
||||||
return SH_INCOMPLETE;
|
return SH_INCOMPLETE;
|
||||||
|
|
||||||
LINE head( aCurrentHead );
|
LINE head( aCurrentHead );
|
||||||
head.ClearSegmentLinks();
|
head.ClearLinks();
|
||||||
|
|
||||||
m_lineStack.clear();
|
m_lineStack.clear();
|
||||||
m_optimizerQueue.clear();
|
m_optimizerQueue.clear();
|
||||||
|
@ -1382,7 +1382,7 @@ SHOVE::SHOVE_STATUS SHOVE::ShoveMultiLines( const ITEM_SET& aHeadSet )
|
||||||
{
|
{
|
||||||
const LINE* headOrig = static_cast<const LINE*>( item );
|
const LINE* headOrig = static_cast<const LINE*>( item );
|
||||||
LINE head( *headOrig );
|
LINE head( *headOrig );
|
||||||
head.ClearSegmentLinks();
|
head.ClearLinks();
|
||||||
|
|
||||||
m_currentNode->Add( head );
|
m_currentNode->Add( head );
|
||||||
|
|
||||||
|
|
|
@ -182,7 +182,7 @@ bool TOPOLOGY::followTrivialPath( LINE* aLine, bool aLeft, ITEM_SET& aSet, std::
|
||||||
|
|
||||||
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
|
VECTOR2I anchor = aLeft ? aLine->CPoint( 0 ) : aLine->CPoint( -1 );
|
||||||
LINKED_ITEM* last =
|
LINKED_ITEM* last =
|
||||||
aLeft ? aLine->LinkedSegments().front() : aLine->LinkedSegments().back();
|
aLeft ? aLine->Links().front() : aLine->Links().back();
|
||||||
JOINT* jt = m_world->FindJoint( anchor, aLine );
|
JOINT* jt = m_world->FindJoint( anchor, aLine );
|
||||||
|
|
||||||
assert( jt != NULL );
|
assert( jt != NULL );
|
||||||
|
|
Loading…
Reference in New Issue