P&S: memory mgr & disappearing trace fixes. Still a bit buggy, though...
This commit is contained in:
parent
07f5516e59
commit
0fbf31ef38
|
@ -212,7 +212,7 @@ bool PNS_DIFF_PAIR_PLACER::attemptWalk ( PNS_NODE* aNode, PNS_DIFF_PAIR* aCurren
|
|||
|
||||
PNS_SHOVE::SHOVE_STATUS sh1;
|
||||
|
||||
sh1 = shove.ProcessSingleLine( &postWalk, &preShove, &postShove );
|
||||
sh1 = shove.ProcessSingleLine( postWalk, preShove, postShove );
|
||||
|
||||
if( sh1 != PNS_SHOVE::SH_OK )
|
||||
return false;
|
||||
|
|
|
@ -30,7 +30,6 @@ PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) :
|
|||
m_world = NULL;
|
||||
m_lastNode = NULL;
|
||||
m_mode = SEGMENT;
|
||||
m_draggedLine = NULL;
|
||||
m_draggedVia = NULL;
|
||||
m_shove = NULL;
|
||||
m_draggedSegmentIndex = 0;
|
||||
|
@ -59,7 +58,7 @@ bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg )
|
|||
|
||||
m_draggedLine = m_world->AssembleLine( aSeg, &m_draggedSegmentIndex );
|
||||
m_shove->SetInitialLine( m_draggedLine );
|
||||
m_lastValidDraggedLine = *m_draggedLine;
|
||||
m_lastValidDraggedLine = m_draggedLine;
|
||||
m_lastValidDraggedLine.ClearSegmentLinks();
|
||||
|
||||
if( ( aP - aSeg->Seg().A ).EuclideanNorm() <= w2 )
|
||||
|
@ -90,12 +89,12 @@ bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA* aVia )
|
|||
{
|
||||
int segIndex;
|
||||
PNS_SEGMENT* seg = ( PNS_SEGMENT*) item;
|
||||
std::auto_ptr<PNS_LINE> l( m_world->AssembleLine( seg, &segIndex ) );
|
||||
PNS_LINE l = m_world->AssembleLine( seg, &segIndex );
|
||||
|
||||
if( segIndex != 0 )
|
||||
l->Reverse();
|
||||
l.Reverse();
|
||||
|
||||
m_origViaConnections.push_back( *l );
|
||||
m_origViaConnections.Add( l );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -139,8 +138,8 @@ bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
|||
case SEGMENT:
|
||||
case CORNER:
|
||||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0;
|
||||
PNS_LINE tmp( *m_draggedLine );
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||
PNS_LINE tmp( m_draggedLine );
|
||||
|
||||
if( m_mode == SEGMENT )
|
||||
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
|
@ -188,18 +187,21 @@ void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& a
|
|||
m_lastNode->Remove( aVia );
|
||||
m_lastNode->Add( m_draggedVia );
|
||||
|
||||
BOOST_FOREACH( PNS_LINE &l, m_origViaConnections )
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_origViaConnections.Items() )
|
||||
{
|
||||
PNS_LINE origLine( l );
|
||||
PNS_LINE* draggedLine = l.Clone();
|
||||
if ( const PNS_LINE* l = dyn_cast<const PNS_LINE*>( item ) )
|
||||
{
|
||||
PNS_LINE origLine( *l );
|
||||
PNS_LINE draggedLine( *l );
|
||||
|
||||
draggedLine->DragCorner( aP, 0 );
|
||||
draggedLine->ClearSegmentLinks();
|
||||
draggedLine.DragCorner( aP, 0 );
|
||||
draggedLine.ClearSegmentLinks();
|
||||
|
||||
m_draggedItems.Add( draggedLine ); // FIXME: mem leak
|
||||
m_draggedItems.Add( draggedLine );
|
||||
|
||||
m_lastNode->Remove( &origLine );
|
||||
m_lastNode->Add( draggedLine );
|
||||
m_lastNode->Add( &draggedLine );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -219,8 +221,8 @@ bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
|
|||
case SEGMENT:
|
||||
case CORNER:
|
||||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0;
|
||||
PNS_LINE tmp( *m_draggedLine );
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine.Width() / 4 : 0;
|
||||
PNS_LINE tmp( m_draggedLine );
|
||||
|
||||
if( m_mode == SEGMENT )
|
||||
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
|
|
|
@ -114,15 +114,15 @@ private:
|
|||
PNS_NODE* m_world;
|
||||
PNS_NODE* m_lastNode;
|
||||
DragMode m_mode;
|
||||
PNS_LINE* m_draggedLine;
|
||||
PNS_LINE m_draggedLine;
|
||||
PNS_VIA* m_draggedVia;
|
||||
PNS_LINE m_lastValidDraggedLine;
|
||||
PNS_SHOVE* m_shove;
|
||||
int m_draggedSegmentIndex;
|
||||
bool m_dragStatus;
|
||||
PNS_MODE m_currentMode;
|
||||
std::vector<PNS_LINE> m_origViaConnections;
|
||||
std::vector<PNS_LINE> m_draggedViaConnections;
|
||||
PNS_ITEMSET m_origViaConnections;
|
||||
PNS_ITEMSET m_draggedViaConnections;
|
||||
PNS_VIA* m_initialVia;
|
||||
PNS_ITEMSET m_draggedItems;
|
||||
};
|
||||
|
|
|
@ -40,13 +40,60 @@ enum LineMarker {
|
|||
MK_DP_COUPLED = ( 1 << 5 )
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PNS_OBJECT
|
||||
*
|
||||
* Abstract base class to hold ownership information about items/nodes
|
||||
* used by the router.
|
||||
*/
|
||||
class PNS_OBJECT
|
||||
{
|
||||
public:
|
||||
PNS_OBJECT ():
|
||||
m_owner(NULL) {};
|
||||
~PNS_OBJECT() {};
|
||||
|
||||
/**
|
||||
* Functon SetOwner()
|
||||
*
|
||||
* Sets the node that owns this item. An item can belong to a single
|
||||
* PNS_OBJECT or stay unowned.
|
||||
*/
|
||||
void SetOwner( PNS_OBJECT* aOwner )
|
||||
{
|
||||
m_owner = aOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BelongsTo()
|
||||
*
|
||||
* @return true if the item is owned by aObj
|
||||
*/
|
||||
bool BelongsTo( const PNS_OBJECT* aObj ) const
|
||||
{
|
||||
return m_owner == aObj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Owner()
|
||||
*
|
||||
* Returns the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
PNS_OBJECT* Owner() const { return m_owner; }
|
||||
|
||||
protected:
|
||||
PNS_OBJECT *m_owner;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class PNS_ITEM
|
||||
*
|
||||
* Base class for PNS router board items. Implements the shared properties of all PCB items -
|
||||
* net, spanned layers, geometric shape & refererence to owning model.
|
||||
*/
|
||||
class PNS_ITEM
|
||||
class PNS_ITEM : public PNS_OBJECT
|
||||
{
|
||||
public:
|
||||
static const int UnusedNet = INT_MAX;
|
||||
|
@ -226,34 +273,6 @@ public:
|
|||
return Layers().Overlaps( aOther->Layers() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Functon SetOwner()
|
||||
*
|
||||
* Sets the node that owns this item. An item can belong to a single
|
||||
* PNS_NODE or stay unowned.
|
||||
*/
|
||||
void SetOwner( PNS_NODE* aOwner )
|
||||
{
|
||||
m_owner = aOwner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function BelongsTo()
|
||||
*
|
||||
* @return true if the item is owned by the node aNode.
|
||||
*/
|
||||
bool BelongsTo( PNS_NODE* aNode ) const
|
||||
{
|
||||
return m_owner == aNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Owner()
|
||||
*
|
||||
* Returns the owner of this item, or NULL if there's none.
|
||||
*/
|
||||
PNS_NODE* Owner() const { return m_owner; }
|
||||
|
||||
/**
|
||||
* Function Collide()
|
||||
*
|
||||
|
@ -337,7 +356,6 @@ protected:
|
|||
PnsKind m_kind;
|
||||
|
||||
BOARD_CONNECTED_ITEM* m_parent;
|
||||
PNS_NODE* m_owner;
|
||||
PNS_LAYERSET m_layers;
|
||||
|
||||
bool m_movable;
|
||||
|
|
|
@ -21,22 +21,40 @@
|
|||
#include <boost/foreach.hpp>
|
||||
|
||||
#include "pns_itemset.h"
|
||||
#include "pns_line.h"
|
||||
|
||||
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem ) :
|
||||
m_owner( false )
|
||||
|
||||
void PNS_ITEMSET::release()
|
||||
{
|
||||
if( aInitialItem )
|
||||
m_items.push_back( aInitialItem );
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET::~PNS_ITEMSET()
|
||||
{
|
||||
if( m_owner )
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
delete item;
|
||||
release();
|
||||
}
|
||||
|
||||
|
||||
void PNS_ITEMSET::Add( const PNS_LINE& aLine )
|
||||
{
|
||||
PNS_LINE* copy = aLine.Clone();
|
||||
copy->SetOwner( this );
|
||||
m_items.push_back( copy );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ITEMSET::Prepend( const PNS_LINE& aLine )
|
||||
{
|
||||
PNS_LINE* copy = aLine.Clone();
|
||||
copy->SetOwner( this );
|
||||
m_items.push_front( copy );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -32,44 +32,55 @@
|
|||
* Holds a list of board items, that can be filtered against net, kinds,
|
||||
* layers, etc.
|
||||
**/
|
||||
class PNS_LINE;
|
||||
|
||||
class PNS_ITEMSET
|
||||
class PNS_ITEMSET : public PNS_OBJECT
|
||||
{
|
||||
public:
|
||||
typedef std::deque<PNS_ITEM*> ITEMS;
|
||||
|
||||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
|
||||
|
||||
PNS_ITEMSET( const PNS_ITEMSET& aOther ):
|
||||
m_owner( false )
|
||||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL, bool aBecomeOwner = false )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
if( aInitialItem )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aInitialItem->SetOwner( this );
|
||||
|
||||
m_items.push_back( aInitialItem );
|
||||
}
|
||||
}
|
||||
|
||||
PNS_ITEMSET( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
copyFrom( aOther );
|
||||
}
|
||||
|
||||
~PNS_ITEMSET();
|
||||
|
||||
void MakeOwner()
|
||||
{
|
||||
m_owner = true;
|
||||
}
|
||||
|
||||
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
copyFrom( aOther );
|
||||
return *this;
|
||||
}
|
||||
|
||||
int Count( int aKindMask = -1 ) const
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->Kind() & aKindMask )
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
bool Empty() const
|
||||
{
|
||||
return m_items.empty();
|
||||
}
|
||||
|
||||
ITEMS& Items() { return m_items; }
|
||||
const ITEMS& CItems() const { return m_items; }
|
||||
|
||||
|
@ -100,13 +111,22 @@ public:
|
|||
return m_items.size();
|
||||
}
|
||||
|
||||
void Add( PNS_ITEM* aItem )
|
||||
void Add( const PNS_LINE& aLine );
|
||||
void Prepend( const PNS_LINE& aLine );
|
||||
|
||||
void Add( PNS_ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
|
||||
m_items.push_back( aItem );
|
||||
}
|
||||
|
||||
void Prepend( PNS_ITEM* aItem )
|
||||
void Prepend( PNS_ITEM* aItem, bool aBecomeOwner = false )
|
||||
{
|
||||
if( aBecomeOwner )
|
||||
aItem->SetOwner( this );
|
||||
|
||||
m_items.push_front( aItem );
|
||||
}
|
||||
|
||||
|
@ -122,6 +142,12 @@ public:
|
|||
|
||||
void Clear()
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM *item, m_items )
|
||||
{
|
||||
if( item->BelongsTo( this ) )
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_items.clear();
|
||||
}
|
||||
|
||||
|
@ -130,17 +156,53 @@ public:
|
|||
return std::find( m_items.begin(), m_items.end(), aItem ) != m_items.end();
|
||||
}
|
||||
|
||||
void Erase( const PNS_ITEM* aItem )
|
||||
void Erase( PNS_ITEM* aItem )
|
||||
{
|
||||
ITEMS::iterator f = std::find( m_items.begin(), m_items.end(), aItem );
|
||||
|
||||
if( f != m_items.end() )
|
||||
m_items.erase( f );
|
||||
|
||||
if( aItem->BelongsTo( this ) )
|
||||
delete aItem;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
T* FindByKind( PNS_ITEM::PnsKind kind, int index = 0 )
|
||||
{
|
||||
int n = 0;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
{
|
||||
if( item->OfKind (kind) )
|
||||
{
|
||||
if( index == n )
|
||||
return static_cast<T*>( item );
|
||||
else
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
void release();
|
||||
|
||||
void copyFrom( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
release();
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM *item, aOther.m_items )
|
||||
{
|
||||
if( item->BelongsTo( &aOther ) )
|
||||
m_items.push_back( item->Clone() );
|
||||
else
|
||||
m_items.push_back( item );
|
||||
}
|
||||
}
|
||||
|
||||
ITEMS m_items;
|
||||
bool m_owner;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
};
|
||||
|
||||
PNS_JOINT() :
|
||||
PNS_ITEM( JOINT ) {}
|
||||
PNS_ITEM( JOINT ), m_locked( false ) {}
|
||||
|
||||
PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1 ) :
|
||||
PNS_ITEM( JOINT )
|
||||
|
@ -60,6 +60,7 @@ public:
|
|||
m_tag.pos = aPos;
|
||||
m_tag.net = aNet;
|
||||
m_layers = aLayers;
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
PNS_JOINT( const PNS_JOINT& aB ) :
|
||||
|
@ -70,6 +71,7 @@ public:
|
|||
m_tag.net = aB.m_tag.net;
|
||||
m_linkedItems = aB.m_linkedItems;
|
||||
m_layers = aB.m_layers;
|
||||
m_locked = false;
|
||||
}
|
||||
|
||||
PNS_ITEM* Clone( ) const
|
||||
|
@ -82,6 +84,9 @@ public:
|
|||
/// segments of the same net, on the same layer.
|
||||
bool IsLineCorner() const
|
||||
{
|
||||
if( m_locked )
|
||||
return false;
|
||||
|
||||
if( m_linkedItems.Size() != 2 )
|
||||
return false;
|
||||
|
||||
|
@ -138,6 +143,17 @@ public:
|
|||
return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
|
||||
}
|
||||
|
||||
PNS_VIA* Via()
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_linkedItems.Items() )
|
||||
{
|
||||
if( item->OfKind( VIA ) )
|
||||
return static_cast<PNS_VIA*>( item );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/// trivial accessors
|
||||
const HASH_TAG& Tag() const
|
||||
|
@ -201,12 +217,25 @@ public:
|
|||
m_tag.net == rhs.m_tag.net && m_layers.Overlaps( rhs.m_layers );
|
||||
}
|
||||
|
||||
void Lock( bool aLock = true )
|
||||
{
|
||||
m_locked = aLock;
|
||||
}
|
||||
|
||||
bool IsLocked() const
|
||||
{
|
||||
return m_locked;
|
||||
}
|
||||
|
||||
private:
|
||||
///> hash tag for unordered_multimap
|
||||
HASH_TAG m_tag;
|
||||
|
||||
///> list of items linked to this joint
|
||||
PNS_ITEMSET m_linkedItems;
|
||||
|
||||
///> locked (non-movable) flag
|
||||
bool m_locked;
|
||||
};
|
||||
|
||||
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1, PNS_JOINT::HASH_TAG const& aP2 )
|
||||
|
|
|
@ -115,8 +115,10 @@ int PNS_LINE::Marker() const
|
|||
if( m_segmentRefs )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
|
||||
{
|
||||
marker |= s->Marker();
|
||||
}
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
@ -293,6 +295,9 @@ bool PNS_LINE::Is45Degree()
|
|||
{
|
||||
const SEG& s = m_line.CSegment( i );
|
||||
|
||||
if( s.Length() < 10 )
|
||||
continue;
|
||||
|
||||
double angle = 180.0 / M_PI *
|
||||
atan2( (double) s.B.y - (double) s.A.y,
|
||||
(double) s.B.x - (double) s.A.x );
|
||||
|
|
|
@ -690,7 +690,6 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co
|
|||
return;
|
||||
|
||||
PNS_SEGMENT* s_old = static_cast<PNS_SEGMENT*>( aSeg );
|
||||
|
||||
PNS_SEGMENT* s_new[2];
|
||||
|
||||
s_new[0] = s_old->Clone();
|
||||
|
@ -814,7 +813,7 @@ bool PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
int eiDepth = -1;
|
||||
|
||||
if( aEndItem && aEndItem->Owner() )
|
||||
eiDepth = aEndItem->Owner()->Depth();
|
||||
eiDepth = static_cast<PNS_NODE*>( aEndItem->Owner() )->Depth();
|
||||
|
||||
if( m_lastNode )
|
||||
{
|
||||
|
@ -839,7 +838,7 @@ bool PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
splitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
|
||||
|
||||
if( Settings().RemoveLoops() )
|
||||
removeLoops( m_lastNode, ¤t );
|
||||
removeLoops( m_lastNode, current );
|
||||
}
|
||||
|
||||
updateLeadingRatLine();
|
||||
|
@ -929,22 +928,22 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
|
||||
void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest )
|
||||
{
|
||||
if( !aLatest->SegmentCount() )
|
||||
if( !aLatest.SegmentCount() )
|
||||
return;
|
||||
|
||||
if ( aLatest->CLine().CPoint( 0 ) == aLatest->CLine().CPoint( -1 ) )
|
||||
if ( aLatest.CLine().CPoint( 0 ) == aLatest.CLine().CPoint( -1 ) )
|
||||
return;
|
||||
|
||||
aNode->Add( aLatest, true );
|
||||
aNode->Add( &aLatest, true );
|
||||
|
||||
for( int s = 0; s < aLatest->SegmentCount(); s++ )
|
||||
for( int s = 0; s < aLatest.SegmentCount(); s++ )
|
||||
{
|
||||
PNS_SEGMENT* seg = ( *aLatest->LinkedSegments() )[s];
|
||||
PNS_LINE* ourLine = aNode->AssembleLine( seg );
|
||||
PNS_SEGMENT* seg = ( *aLatest.LinkedSegments() )[s];
|
||||
PNS_LINE ourLine = aNode->AssembleLine( seg );
|
||||
PNS_JOINT a, b;
|
||||
std::vector<PNS_LINE*> lines;
|
||||
std::vector<PNS_LINE> lines;
|
||||
|
||||
aNode->FindLineEnds( ourLine, a, b );
|
||||
|
||||
|
@ -958,42 +957,38 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
|
|||
int removedCount = 0;
|
||||
int total = 0;
|
||||
|
||||
BOOST_FOREACH( PNS_LINE* line, lines )
|
||||
BOOST_FOREACH( PNS_LINE& line, lines )
|
||||
{
|
||||
total++;
|
||||
|
||||
if( !( line->ContainsSegment( seg ) ) && line->SegmentCount() )
|
||||
if( !( line.ContainsSegment( seg ) ) && line.SegmentCount() )
|
||||
{
|
||||
aNode->Remove( line );
|
||||
aNode->Remove( &line );
|
||||
removedCount++;
|
||||
}
|
||||
}
|
||||
|
||||
TRACE( 0, "total segs removed: %d/%d\n", removedCount % total );
|
||||
|
||||
delete ourLine;
|
||||
}
|
||||
|
||||
aNode->Remove( aLatest );
|
||||
aNode->Remove( &aLatest );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest )
|
||||
{
|
||||
PNS_LINE* l = aNode->AssembleLine( aLatest );
|
||||
SHAPE_LINE_CHAIN simplified ( l->CLine() );
|
||||
PNS_LINE l = aNode->AssembleLine( aLatest );
|
||||
SHAPE_LINE_CHAIN simplified( l.CLine() );
|
||||
|
||||
simplified.Simplify();
|
||||
|
||||
if( simplified.PointCount() != l->PointCount() )
|
||||
if( simplified.PointCount() != l.PointCount() )
|
||||
{
|
||||
std::auto_ptr<PNS_LINE> lnew( l->Clone() );
|
||||
aNode->Remove( l );
|
||||
lnew->SetShape( simplified );
|
||||
aNode->Add( lnew.get() );
|
||||
PNS_LINE lnew( l );
|
||||
aNode->Remove( &l );
|
||||
lnew.SetShape( simplified );
|
||||
aNode->Add( &lnew );
|
||||
}
|
||||
|
||||
delete l;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -242,7 +242,7 @@ private:
|
|||
* Searches aNode for traces concurrent to aLatest and removes them. Updated
|
||||
* topology is stored in aNode.
|
||||
*/
|
||||
void removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest );
|
||||
void removeLoops( PNS_NODE* aNode, PNS_LINE& aLatest );
|
||||
|
||||
/**
|
||||
* Function simplifyNewLine()
|
||||
|
|
|
@ -37,7 +37,6 @@ PNS_MEANDER_PLACER::PNS_MEANDER_PLACER( PNS_ROUTER* aRouter ) :
|
|||
{
|
||||
m_world = NULL;
|
||||
m_currentNode = NULL;
|
||||
m_originLine = NULL;
|
||||
|
||||
// Init temporary variables (do not leave uninitialized members)
|
||||
m_initialSegment = NULL;
|
||||
|
@ -74,7 +73,6 @@ bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
|
||||
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||
|
||||
m_originLine = NULL;
|
||||
m_currentNode = NULL;
|
||||
m_currentStart = p;
|
||||
|
||||
|
@ -84,9 +82,9 @@ bool PNS_MEANDER_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
PNS_TOPOLOGY topo( m_world );
|
||||
m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );
|
||||
|
||||
m_world->Remove( m_originLine );
|
||||
m_world->Remove( &m_originLine );
|
||||
|
||||
m_currentWidth = m_originLine->Width();
|
||||
m_currentWidth = m_originLine.Width();
|
||||
m_currentEnd = VECTOR2I( 0, 0 );
|
||||
|
||||
return true;
|
||||
|
@ -123,10 +121,10 @@ bool PNS_MEANDER_PLACER::doMove( const VECTOR2I& aP, PNS_ITEM* aEndItem, int aTa
|
|||
|
||||
m_currentNode = m_world->Branch();
|
||||
|
||||
cutTunedLine( m_originLine->CLine(), m_currentStart, aP, pre, tuned, post );
|
||||
cutTunedLine( m_originLine.CLine(), m_currentStart, aP, pre, tuned, post );
|
||||
|
||||
m_result = PNS_MEANDERED_LINE( this, false );
|
||||
m_result.SetWidth( m_originLine->Width() );
|
||||
m_result.SetWidth( m_originLine.Width() );
|
||||
m_result.SetBaselineOffset( 0 );
|
||||
|
||||
for( int i = 0; i < tuned.SegmentCount(); i++ )
|
||||
|
@ -197,7 +195,7 @@ bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
if( !m_currentNode )
|
||||
return false;
|
||||
|
||||
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||
m_currentTrace = PNS_LINE( m_originLine, m_finalShape );
|
||||
m_currentNode->Add( &m_currentTrace );
|
||||
|
||||
Router()->CommitRouting( m_currentNode );
|
||||
|
@ -207,7 +205,7 @@ bool PNS_MEANDER_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
|
||||
bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
|
||||
{
|
||||
PNS_LINE l( *m_originLine, aShape->CLine( 0 ) );
|
||||
PNS_LINE l( m_originLine, aShape->CLine( 0 ) );
|
||||
|
||||
if( m_currentNode->CheckColliding( &l ) )
|
||||
return false;
|
||||
|
@ -221,7 +219,7 @@ bool PNS_MEANDER_PLACER::CheckFit( PNS_MEANDER_SHAPE* aShape )
|
|||
|
||||
const PNS_ITEMSET PNS_MEANDER_PLACER::Traces()
|
||||
{
|
||||
m_currentTrace = PNS_LINE( *m_originLine, m_finalShape );
|
||||
m_currentTrace = PNS_LINE( m_originLine, m_finalShape );
|
||||
return PNS_ITEMSET( &m_currentTrace );
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ protected:
|
|||
///> Current world state
|
||||
PNS_NODE* m_currentNode;
|
||||
|
||||
PNS_LINE* m_originLine;
|
||||
PNS_LINE m_originLine;
|
||||
PNS_LINE m_currentTrace;
|
||||
PNS_ITEMSET m_tunedPath;
|
||||
|
||||
|
|
|
@ -60,7 +60,6 @@ bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
|
||||
p = m_initialSegment->Seg().NearestPoint( aP );
|
||||
|
||||
m_originLine = NULL;
|
||||
m_currentNode = NULL;
|
||||
m_currentStart = p;
|
||||
|
||||
|
@ -88,12 +87,12 @@ bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
|
||||
m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );
|
||||
|
||||
m_world->Remove( m_originLine );
|
||||
m_world->Remove( &m_originLine );
|
||||
|
||||
m_currentWidth = m_originLine->Width( );
|
||||
m_currentWidth = m_originLine.Width();
|
||||
m_currentEnd = VECTOR2I( 0, 0 );
|
||||
|
||||
if ( m_originPair.PLine().Net () == m_originLine->Net() )
|
||||
if ( m_originPair.PLine().Net() == m_originLine.Net() )
|
||||
m_coupledLength = itemsetLength( m_tunedPathN );
|
||||
else
|
||||
m_coupledLength = itemsetLength( m_tunedPathP );
|
||||
|
|
|
@ -88,13 +88,18 @@ PNS_NODE::~PNS_NODE()
|
|||
delete *i;
|
||||
}
|
||||
|
||||
|
||||
releaseGarbage();
|
||||
unlinkParent();
|
||||
|
||||
delete m_index;
|
||||
}
|
||||
|
||||
|
||||
int PNS_NODE::GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const
|
||||
{
|
||||
if( !m_clearanceFunctor )
|
||||
return 100000;
|
||||
|
||||
return (*m_clearanceFunctor)( aA, aB );
|
||||
}
|
||||
|
||||
|
@ -595,8 +600,6 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
|
|||
|
||||
void PNS_NODE::doRemove( PNS_ITEM* aItem )
|
||||
{
|
||||
// assert(m_root->m_index->Contains(aItem) || m_index->Contains(aItem));
|
||||
|
||||
// case 1: removing an item that is stored in the root node from any branch:
|
||||
// mark it as overridden, but do not remove
|
||||
if( aItem->BelongsTo( m_root ) && !isRoot() )
|
||||
|
@ -609,7 +612,10 @@ void PNS_NODE::doRemove( PNS_ITEM* aItem )
|
|||
|
||||
// the item belongs to this particular branch: un-reference it
|
||||
if( aItem->BelongsTo( this ) )
|
||||
{
|
||||
aItem->SetOwner( NULL );
|
||||
m_root->m_garbageItems.insert( aItem );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -626,9 +632,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
{
|
||||
std::vector<PNS_SEGMENT*>* segRefs = aLine->LinkedSegments();
|
||||
|
||||
if( !aLine->SegmentCount() )
|
||||
return;
|
||||
|
||||
assert( segRefs != NULL );
|
||||
assert( aLine->Owner() );
|
||||
|
||||
|
@ -636,9 +639,6 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
{
|
||||
removeSegment( seg );
|
||||
}
|
||||
|
||||
aLine->SetOwner( NULL );
|
||||
aLine->ClearSegmentLinks();
|
||||
}
|
||||
|
||||
|
||||
|
@ -769,22 +769,22 @@ void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos
|
|||
}
|
||||
|
||||
|
||||
PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
||||
const PNS_LINE PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex )
|
||||
{
|
||||
const int MaxVerts = 1024 * 16;
|
||||
|
||||
VECTOR2I corners[MaxVerts + 1];
|
||||
PNS_SEGMENT* segs[MaxVerts + 1];
|
||||
|
||||
PNS_LINE* pl = new PNS_LINE;
|
||||
PNS_LINE pl;
|
||||
bool guardHit = false;
|
||||
|
||||
int i_start = MaxVerts / 2, i_end = i_start + 1;
|
||||
|
||||
pl->SetWidth( aSeg->Width() );
|
||||
pl->SetLayers( aSeg->Layers() );
|
||||
pl->SetNet( aSeg->Net() );
|
||||
pl->SetOwner( this );
|
||||
pl.SetWidth( aSeg->Width() );
|
||||
pl.SetLayers( aSeg->Layers() );
|
||||
pl.SetNet( aSeg->Net() );
|
||||
pl.SetOwner( this );
|
||||
|
||||
followLine( aSeg, false, i_start, MaxVerts, corners, segs, guardHit );
|
||||
|
||||
|
@ -800,11 +800,11 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
|||
{
|
||||
const VECTOR2I& p = corners[i];
|
||||
|
||||
pl->Line().Append( p );
|
||||
pl.Line().Append( p );
|
||||
|
||||
if( segs[i] && prev_seg != segs[i] )
|
||||
{
|
||||
pl->LinkSegment( segs[i] );
|
||||
pl.LinkSegment( segs[i] );
|
||||
|
||||
// latter condition to avoid loops
|
||||
if( segs[i] == aSeg && aOriginSegmentIndex && !originSet )
|
||||
|
@ -818,16 +818,16 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
|
|||
prev_seg = segs[i];
|
||||
}
|
||||
|
||||
assert( pl->SegmentCount() != 0 );
|
||||
assert( pl.SegmentCount() != 0 );
|
||||
|
||||
return pl;
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::FindLineEnds( PNS_LINE* aLine, PNS_JOINT& aA, PNS_JOINT& aB )
|
||||
void PNS_NODE::FindLineEnds( const PNS_LINE& aLine, PNS_JOINT& aA, PNS_JOINT& aB )
|
||||
{
|
||||
aA = *FindJoint( aLine->CPoint( 0 ), aLine );
|
||||
aB = *FindJoint( aLine->CPoint( -1 ), aLine );
|
||||
aA = *FindJoint( aLine.CPoint( 0 ), &aLine );
|
||||
aB = *FindJoint( aLine.CPoint( -1 ), &aLine );
|
||||
}
|
||||
|
||||
|
||||
|
@ -869,32 +869,30 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFo
|
|||
#endif
|
||||
|
||||
|
||||
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE*>& aLines )
|
||||
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& aA, PNS_JOINT& aB, std::vector<PNS_LINE>& aLines )
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() )
|
||||
{
|
||||
if( item->Kind() == PNS_ITEM::SEGMENT )
|
||||
{
|
||||
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
|
||||
PNS_LINE* line = AssembleLine( seg );
|
||||
PNS_LINE line = AssembleLine( seg );
|
||||
|
||||
PNS_JOINT j_start, j_end;
|
||||
|
||||
FindLineEnds( line, j_start, j_end );
|
||||
|
||||
int id_start = line->CLine().Find( aA.Pos() );
|
||||
int id_end = line->CLine().Find( aB.Pos() );
|
||||
int id_start = line.CLine().Find( aA.Pos() );
|
||||
int id_end = line.CLine().Find( aB.Pos() );
|
||||
|
||||
if( id_end < id_start )
|
||||
std::swap( id_end, id_start );
|
||||
|
||||
if( id_start >= 0 && id_end >= 0 )
|
||||
{
|
||||
line->ClipVertexRange ( id_start, id_end );
|
||||
line.ClipVertexRange( id_start, id_end );
|
||||
aLines.push_back( line );
|
||||
}
|
||||
else
|
||||
delete line;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -932,6 +930,13 @@ PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::LockJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem, bool aLock )
|
||||
{
|
||||
PNS_JOINT& jt = touchJoint( aPos, aItem->Layers(), aItem->Net() );
|
||||
jt.Lock( aLock );
|
||||
}
|
||||
|
||||
|
||||
PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet )
|
||||
{
|
||||
PNS_JOINT::HASH_TAG tag;
|
||||
|
@ -1119,6 +1124,21 @@ void PNS_NODE::releaseChildren()
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::releaseGarbage()
|
||||
{
|
||||
if( !isRoot( ) )
|
||||
return;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_garbageItems )
|
||||
{
|
||||
if( !item->BelongsTo( this ) )
|
||||
delete item;
|
||||
}
|
||||
|
||||
m_garbageItems.clear();
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::Commit( PNS_NODE* aNode )
|
||||
{
|
||||
if( aNode->isRoot() )
|
||||
|
@ -1136,6 +1156,7 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
|
|||
}
|
||||
|
||||
releaseChildren();
|
||||
releaseGarbage();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -128,7 +128,7 @@ struct PNS_COLLISION_FILTER {
|
|||
* - lightweight cloning/branching (for recursive optimization and shove
|
||||
* springback)
|
||||
**/
|
||||
class PNS_NODE
|
||||
class PNS_NODE : public PNS_OBJECT
|
||||
{
|
||||
public:
|
||||
typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;
|
||||
|
@ -303,7 +303,7 @@ public:
|
|||
* @param aOriginSegmentIndex index of aSeg in the resulting line
|
||||
* @return the line
|
||||
*/
|
||||
PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex = NULL );
|
||||
const PNS_LINE AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex = NULL );
|
||||
|
||||
///> Prints the contents and joints structure
|
||||
void Dump( bool aLong = false );
|
||||
|
@ -335,6 +335,8 @@ public:
|
|||
*/
|
||||
PNS_JOINT* FindJoint( const VECTOR2I& aPos, int aLayer, int aNet );
|
||||
|
||||
void LockJoint( const VECTOR2I& aPos, const PNS_ITEM* aItem, bool aLock );
|
||||
|
||||
/**
|
||||
* Function FindJoint()
|
||||
*
|
||||
|
@ -357,10 +359,10 @@ public:
|
|||
///> finds all lines between a pair of joints. Used by the loop removal procedure.
|
||||
int FindLinesBetweenJoints( PNS_JOINT& aA,
|
||||
PNS_JOINT& aB,
|
||||
std::vector<PNS_LINE*>& aLines );
|
||||
std::vector<PNS_LINE>& aLines );
|
||||
|
||||
///> finds the joints corresponding to the ends of line aLine
|
||||
void FindLineEnds( PNS_LINE* aLine, PNS_JOINT& aA, PNS_JOINT& aB );
|
||||
void FindLineEnds( const PNS_LINE& aLine, PNS_JOINT& aA, PNS_JOINT& aB );
|
||||
|
||||
///> Destroys all child nodes. Applicable only to the root node.
|
||||
void KillChildren();
|
||||
|
@ -410,6 +412,7 @@ private:
|
|||
void doRemove( PNS_ITEM* aItem );
|
||||
void unlinkParent();
|
||||
void releaseChildren();
|
||||
void releaseGarbage();
|
||||
|
||||
bool isRoot() const
|
||||
{
|
||||
|
@ -464,6 +467,8 @@ private:
|
|||
|
||||
///> optional collision filtering object
|
||||
PNS_COLLISION_FILTER *m_collisionFilter;
|
||||
|
||||
boost::unordered_set<PNS_ITEM*> m_garbageItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -57,7 +57,7 @@ void PNS_SHOVE::replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew )
|
|||
}
|
||||
|
||||
|
||||
int PNS_SHOVE::getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const
|
||||
int PNS_SHOVE::getClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const
|
||||
{
|
||||
if( m_forceClearance >= 0 )
|
||||
return m_forceClearance;
|
||||
|
@ -66,7 +66,7 @@ int PNS_SHOVE::getClearance( PNS_ITEM *aA, PNS_ITEM *aB ) const
|
|||
}
|
||||
|
||||
|
||||
static void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
||||
void PNS_SHOVE::sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew )
|
||||
{
|
||||
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
|
||||
assert( aOld->CPoint( -1 ) == aNew->CPoint( -1 ) );
|
||||
|
@ -78,9 +78,9 @@ PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
|||
{
|
||||
m_forceClearance = -1;
|
||||
m_root = aWorld;
|
||||
m_currentNode = aWorld;
|
||||
|
||||
// Initialize other temporary variables:
|
||||
m_currentNode = NULL;
|
||||
m_draggedVia = NULL;
|
||||
m_iter = 0;
|
||||
m_multiLineMode = false;
|
||||
|
@ -89,76 +89,68 @@ PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
|||
|
||||
PNS_SHOVE::~PNS_SHOVE()
|
||||
{
|
||||
// free all the stuff we've created during routing/dragging operation.
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_gcItems )
|
||||
delete item;
|
||||
}
|
||||
|
||||
|
||||
// garbage-collected line assembling
|
||||
PNS_LINE* PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
|
||||
PNS_LINE PNS_SHOVE::assembleLine( const PNS_SEGMENT* aSeg, int* aIndex )
|
||||
{
|
||||
PNS_LINE* l = m_currentNode->AssembleLine( const_cast<PNS_SEGMENT*>( aSeg ), aIndex );
|
||||
|
||||
m_gcItems.push_back( l );
|
||||
|
||||
return l;
|
||||
return m_currentNode->AssembleLine( const_cast<PNS_SEGMENT*>( aSeg ), aIndex );
|
||||
}
|
||||
|
||||
|
||||
// A dumb function that checks if the shoved line is shoved the right way, e.g.
|
||||
// visually "outwards" of the line/via applying pressure on it. Unfortunately there's no
|
||||
// mathematical concept of orientation of an open curve, so we use some primitive heuristics:
|
||||
// if the shoved line wraps around the start of the "pusher", it's likely shoved in wrong direction.
|
||||
bool PNS_SHOVE::checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const
|
||||
bool PNS_SHOVE::checkBumpDirection( const PNS_LINE& aCurrent, const PNS_LINE& aShoved ) const
|
||||
{
|
||||
const SEG ss = aCurrent->CSegment( 0 );
|
||||
const SEG& ss = aCurrent.CSegment( 0 );
|
||||
|
||||
int dist = getClearance( aCurrent, aShoved ) + PNS_HULL_MARGIN;
|
||||
int dist = getClearance( &aCurrent, &aShoved ) + PNS_HULL_MARGIN;
|
||||
|
||||
dist += aCurrent->Width() / 2;
|
||||
dist += aShoved->Width() / 2;
|
||||
dist += aCurrent.Width() / 2;
|
||||
dist += aShoved.Width() / 2;
|
||||
|
||||
const VECTOR2I ps = ss.A - ( ss.B - ss.A ).Resize( dist );
|
||||
|
||||
return !aShoved->CLine().PointOnEdge( ps );
|
||||
return !aShoved.CLine().PointOnEdge( ps );
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::walkaroundLoneVia( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
|
||||
PNS_LINE& aShoved )
|
||||
{
|
||||
int clearance = getClearance( aCurrent, aObstacle );
|
||||
const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() );
|
||||
int clearance = getClearance( &aCurrent, &aObstacle );
|
||||
const SHAPE_LINE_CHAIN hull = aCurrent.Via().Hull( clearance, aObstacle.Width() );
|
||||
SHAPE_LINE_CHAIN path_cw, path_ccw;
|
||||
|
||||
aObstacle->Walkaround( hull, path_cw, true );
|
||||
aObstacle->Walkaround( hull, path_ccw, false );
|
||||
aObstacle.Walkaround( hull, path_cw, true );
|
||||
aObstacle.Walkaround( hull, path_ccw, false );
|
||||
|
||||
const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw;
|
||||
|
||||
if( shortest.PointCount() < 2 )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
if( aObstacle->CPoint( -1 ) != shortest.CPoint( -1 ) )
|
||||
if( aObstacle.CPoint( -1 ) != shortest.CPoint( -1 ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
if( aObstacle->CPoint( 0 ) != shortest.CPoint( 0 ) )
|
||||
if( aObstacle.CPoint( 0 ) != shortest.CPoint( 0 ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
aShoved->SetShape( shortest );
|
||||
aShoved.SetShape( shortest );
|
||||
|
||||
if( m_currentNode->CheckColliding( aShoved, aCurrent ) )
|
||||
if( m_currentNode->CheckColliding( &aShoved, &aCurrent ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
return SH_OK;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved, const HULL_SET& aHulls )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
|
||||
PNS_LINE& aShoved, const HULL_SET& aHulls )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& obs = aObstacle->CLine();
|
||||
const SHAPE_LINE_CHAIN& obs = aObstacle.CLine();
|
||||
|
||||
bool failingDirCheck = false;
|
||||
int attempt;
|
||||
|
||||
|
@ -169,7 +161,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
int vFirst = -1, vLast = -1;
|
||||
|
||||
SHAPE_LINE_CHAIN path;
|
||||
PNS_LINE l( *aObstacle );
|
||||
PNS_LINE l( aObstacle );
|
||||
|
||||
for( int i = 0; i < (int) aHulls.size(); i++ )
|
||||
{
|
||||
|
@ -199,7 +191,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
}
|
||||
}
|
||||
|
||||
if( ( vFirst < 0 || vLast < 0 ) && !path.CompareGeometry( aObstacle->CLine() ) )
|
||||
if( ( vFirst < 0 || vLast < 0 ) && !path.CompareGeometry( aObstacle.CLine() ) )
|
||||
{
|
||||
TRACE( 100, "attempt %d fail vfirst-last", attempt );
|
||||
continue;
|
||||
|
@ -211,11 +203,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
continue;
|
||||
}
|
||||
|
||||
if( !checkBumpDirection( aCurrent, &l ) )
|
||||
if( !checkBumpDirection( aCurrent, l ) )
|
||||
{
|
||||
TRACE( 100, "attempt %d fail direction-check", attempt );
|
||||
failingDirCheck = true;
|
||||
aShoved->SetShape( l.CLine() );
|
||||
aShoved.SetShape( l.CLine() );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
@ -226,11 +218,11 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
continue;
|
||||
}
|
||||
|
||||
bool colliding = m_currentNode->CheckColliding( &l, aCurrent, PNS_ITEM::ANY, m_forceClearance );
|
||||
bool colliding = m_currentNode->CheckColliding( &l, &aCurrent, PNS_ITEM::ANY, m_forceClearance );
|
||||
|
||||
if( ( aCurrent->Marker() & MK_HEAD ) && !colliding )
|
||||
if( ( aCurrent.Marker() & MK_HEAD ) && !colliding )
|
||||
{
|
||||
PNS_JOINT* jtStart = m_currentNode->FindJoint( aCurrent->CPoint( 0 ), aCurrent );
|
||||
PNS_JOINT* jtStart = m_currentNode->FindJoint( aCurrent.CPoint( 0 ), &aCurrent );
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
|
||||
{
|
||||
|
@ -245,7 +237,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
continue;
|
||||
}
|
||||
|
||||
aShoved->SetShape( l.CLine() );
|
||||
aShoved.SetShape( l.CLine() );
|
||||
|
||||
return SH_OK;
|
||||
}
|
||||
|
@ -254,16 +246,16 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::processHullSet( PNS_LINE* aCurrent, PNS_LINE*
|
|||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
|
||||
PNS_LINE& aShoved )
|
||||
{
|
||||
aShoved->ClearSegmentLinks();
|
||||
aShoved.ClearSegmentLinks();
|
||||
|
||||
bool obstacleIsHead = false;
|
||||
|
||||
if( aObstacle->LinkedSegments() )
|
||||
if( aObstacle.LinkedSegments() )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *aObstacle->LinkedSegments() )
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *aObstacle.LinkedSegments() )
|
||||
|
||||
if( s->Marker() & MK_HEAD )
|
||||
{
|
||||
|
@ -274,18 +266,18 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE* aCurrent, PNS_LI
|
|||
|
||||
SHOVE_STATUS rv;
|
||||
|
||||
bool viaOnEnd = aCurrent->EndsWithVia();
|
||||
bool viaOnEnd = aCurrent.EndsWithVia();
|
||||
|
||||
if( viaOnEnd && ( !aCurrent->LayersOverlap( aObstacle ) || aCurrent->SegmentCount() == 0 ) )
|
||||
if( viaOnEnd && ( !aCurrent.LayersOverlap( &aObstacle ) || aCurrent.SegmentCount() == 0 ) )
|
||||
{
|
||||
rv = walkaroundLoneVia( aCurrent, aObstacle, aShoved );
|
||||
}
|
||||
else
|
||||
{
|
||||
int w = aObstacle->Width();
|
||||
int n_segs = aCurrent->SegmentCount();
|
||||
int w = aObstacle.Width();
|
||||
int n_segs = aCurrent.SegmentCount();
|
||||
|
||||
int clearance = getClearance( aCurrent, aObstacle );
|
||||
int clearance = getClearance( &aCurrent, &aObstacle );
|
||||
|
||||
HULL_SET hulls;
|
||||
|
||||
|
@ -293,114 +285,119 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ProcessSingleLine( PNS_LINE* aCurrent, PNS_LI
|
|||
|
||||
for( int i = 0; i < n_segs; i++ )
|
||||
{
|
||||
PNS_SEGMENT seg( *aCurrent, aCurrent->CSegment( i ) );
|
||||
hulls.push_back( seg.Hull( clearance, w ) );
|
||||
PNS_SEGMENT seg( aCurrent, aCurrent.CSegment( i ) );
|
||||
SHAPE_LINE_CHAIN hull = seg.Hull( clearance, w );
|
||||
|
||||
hulls.push_back( hull );
|
||||
}
|
||||
|
||||
if( viaOnEnd )
|
||||
hulls.push_back ( aCurrent->Via().Hull( clearance, w ) );
|
||||
hulls.push_back ( aCurrent.Via().Hull( clearance, w ) );
|
||||
|
||||
rv = processHullSet ( aCurrent, aObstacle, aShoved, hulls );
|
||||
}
|
||||
|
||||
if( obstacleIsHead )
|
||||
aShoved->Mark( aShoved->Marker() | MK_HEAD );
|
||||
aShoved.Mark( aShoved.Marker() | MK_HEAD );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE* aCurrent, PNS_SEGMENT* aObstacleSeg )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSegment( PNS_LINE& aCurrent, PNS_SEGMENT* aObstacleSeg )
|
||||
{
|
||||
int segIndex;
|
||||
PNS_LINE* obstacleLine = assembleLine( aObstacleSeg, &segIndex );
|
||||
PNS_LINE* shovedLine = clone( obstacleLine );
|
||||
PNS_LINE obstacleLine = assembleLine( aObstacleSeg, &segIndex );
|
||||
PNS_LINE shovedLine( obstacleLine );
|
||||
PNS_SEGMENT tmp( *aObstacleSeg );
|
||||
|
||||
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, obstacleLine, shovedLine );
|
||||
|
||||
assert( obstacleLine->LayersOverlap( shovedLine ) );
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
if( shovedLine->Marker() & MK_HEAD )
|
||||
{
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *shovedLine;
|
||||
}
|
||||
|
||||
sanityCheck( obstacleLine, shovedLine );
|
||||
replaceItems ( obstacleLine, shovedLine );
|
||||
sanityCheck( obstacleLine, shovedLine );
|
||||
|
||||
int rank = aCurrent->Rank();
|
||||
shovedLine->SetRank( rank - 1 );
|
||||
|
||||
if( !pushLine( shovedLine ) )
|
||||
rv = SH_INCOMPLETE;
|
||||
}
|
||||
assert( obstacleLine.LayersOverlap( &shovedLine ) );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-colliding-segment", m_iter );
|
||||
m_logger.Log( aObstacleSeg, 0, "obstacle-segment" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( obstacleLine, 2, "obstacle-line" );
|
||||
m_logger.Log( shovedLine, 3, "shoved-line" );
|
||||
m_logger.Log( &tmp, 0, "obstacle-segment" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &obstacleLine, 2, "obstacle-line" );
|
||||
m_logger.Log( &shovedLine, 3, "shoved-line" );
|
||||
#endif
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle )
|
||||
{
|
||||
PNS_LINE* shovedLine = clone( aObstacle );
|
||||
|
||||
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
if( shovedLine->Marker() & MK_HEAD )
|
||||
if( shovedLine.Marker() & MK_HEAD )
|
||||
{
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *shovedLine;
|
||||
m_newHead = shovedLine;
|
||||
}
|
||||
|
||||
sanityCheck( aObstacle, shovedLine );
|
||||
replaceItems( aObstacle, shovedLine );
|
||||
sanityCheck( aObstacle, shovedLine );
|
||||
sanityCheck( &obstacleLine, &shovedLine );
|
||||
replaceItems( &obstacleLine, &shovedLine );
|
||||
|
||||
int rank = aObstacle->Rank();
|
||||
shovedLine->SetRank ( rank );
|
||||
int rank = aCurrent.Rank();
|
||||
shovedLine.SetRank( rank - 1 );
|
||||
|
||||
if( !pushLine( shovedLine ) )
|
||||
rv = SH_INCOMPLETE;
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-colliding-line", m_iter );
|
||||
m_logger.Log( aObstacle, 0, "obstacle-line" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( shovedLine, 3, "shoved-line" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle )
|
||||
{
|
||||
PNS_LINE shovedLine( aObstacle );
|
||||
|
||||
SHOVE_STATUS rv = ProcessSingleLine( aCurrent, aObstacle, shovedLine );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-colliding-line", m_iter );
|
||||
m_logger.Log( &aObstacle, 0, "obstacle-line" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &shovedLine, 3, "shoved-line" );
|
||||
#endif
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
if( shovedLine.Marker() & MK_HEAD )
|
||||
{
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = shovedLine;
|
||||
}
|
||||
|
||||
sanityCheck( &aObstacle, &shovedLine );
|
||||
replaceItems( &aObstacle, &shovedLine );
|
||||
|
||||
int rank = aObstacle.Rank();
|
||||
shovedLine.SetRank( rank - 1 );
|
||||
|
||||
|
||||
if( !pushLine( shovedLine ) )
|
||||
{
|
||||
rv = SH_INCOMPLETE;
|
||||
//printf( "pushLine failed\n" );
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE& aCurrent, PNS_SOLID* aObstacleSolid )
|
||||
{
|
||||
PNS_WALKAROUND walkaround( m_currentNode, Router() );
|
||||
PNS_LINE* walkaroundLine = clone( aCurrent );
|
||||
PNS_LINE walkaroundLine( aCurrent );
|
||||
|
||||
if( aCurrent->EndsWithVia() )
|
||||
if( aCurrent.EndsWithVia() )
|
||||
{
|
||||
PNS_VIA vh = aCurrent->Via();
|
||||
PNS_VIA vh = aCurrent.Via();
|
||||
PNS_VIA* via = NULL;
|
||||
PNS_JOINT* jtStart = m_currentNode->FindJoint( vh.Pos(), aCurrent );
|
||||
PNS_JOINT* jtStart = m_currentNode->FindJoint( vh.Pos(), &aCurrent );
|
||||
|
||||
if( !jtStart )
|
||||
return SH_INCOMPLETE;
|
||||
|
@ -421,7 +418,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOL
|
|||
walkaround.SetSolidsOnly( true );
|
||||
walkaround.SetIterationLimit ( 8 ); // fixme: make configurable
|
||||
|
||||
int currentRank = aCurrent->Rank();
|
||||
int currentRank = aCurrent.Rank();
|
||||
int nextRank;
|
||||
|
||||
if( !Settings().JumpOverObstacles() )
|
||||
|
@ -435,34 +432,35 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOL
|
|||
walkaround.SetSingleDirection( true );
|
||||
}
|
||||
|
||||
if( walkaround.Route( *aCurrent, *walkaroundLine, false ) != PNS_WALKAROUND::DONE )
|
||||
if( walkaround.Route( aCurrent, walkaroundLine, false ) != PNS_WALKAROUND::DONE )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
walkaroundLine->ClearSegmentLinks();
|
||||
walkaroundLine->Unmark();
|
||||
walkaroundLine->Line().Simplify();
|
||||
walkaroundLine.ClearSegmentLinks();
|
||||
walkaroundLine.Unmark();
|
||||
walkaroundLine.Line().Simplify();
|
||||
|
||||
if( walkaroundLine->HasLoops() )
|
||||
if( walkaroundLine.HasLoops() )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
if( aCurrent->Marker() & MK_HEAD )
|
||||
if( aCurrent.Marker() & MK_HEAD )
|
||||
{
|
||||
walkaroundLine->Mark( MK_HEAD );
|
||||
walkaroundLine.Mark( MK_HEAD );
|
||||
|
||||
if( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *walkaroundLine;
|
||||
m_newHead = walkaroundLine;
|
||||
}
|
||||
|
||||
replaceItems ( aCurrent, walkaroundLine );
|
||||
walkaroundLine->SetRank( nextRank );
|
||||
sanityCheck( &aCurrent, &walkaroundLine );
|
||||
replaceItems( &aCurrent, &walkaroundLine );
|
||||
walkaroundLine.SetRank( nextRank );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-colliding-solid", m_iter );
|
||||
m_logger.Log( aObstacleSolid, 0, "obstacle-solid" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( walkaroundLine, 3, "walk-line" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &walkaroundLine, 3, "walk-line" );
|
||||
#endif
|
||||
|
||||
popLine();
|
||||
|
@ -532,6 +530,9 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
PNS_JOINT* jt = m_currentNode->FindJoint( p0, aVia );
|
||||
VECTOR2I p0_pushed( p0 + aForce );
|
||||
|
||||
if( jt->IsLocked() )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
while( aForce.x != 0 || aForce.y != 0 )
|
||||
{
|
||||
PNS_JOINT* jt_next = m_currentNode->FindJoint( p0_pushed, aVia );
|
||||
|
@ -542,6 +543,12 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
p0_pushed += aForce.Resize( 2 ); // make sure pushed via does not overlap with any existing joint
|
||||
}
|
||||
|
||||
if( !jt )
|
||||
{
|
||||
TRACEn( 1, "weird, can't find the center-of-via joint\n" );
|
||||
return SH_INCOMPLETE;
|
||||
}
|
||||
|
||||
PNS_VIA* pushedVia = aVia->Clone();
|
||||
pushedVia->SetPos( p0_pushed );
|
||||
pushedVia->Mark( aVia->Marker() );
|
||||
|
@ -552,12 +559,6 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
m_draggedViaHeadSet.Clear();
|
||||
}
|
||||
|
||||
if( !jt )
|
||||
{
|
||||
TRACEn( 1, "weird, can't find the center-of-via joint\n" );
|
||||
return SH_INCOMPLETE;
|
||||
}
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
||||
{
|
||||
if( PNS_SEGMENT* seg = dyn_cast<PNS_SEGMENT*>( item ) )
|
||||
|
@ -567,19 +568,19 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
|
||||
lp.first = assembleLine( seg, &segIndex );
|
||||
|
||||
assert( segIndex == 0 || ( segIndex == ( lp.first->SegmentCount() - 1 ) ) );
|
||||
assert( segIndex == 0 || ( segIndex == ( lp.first.SegmentCount() - 1 ) ) );
|
||||
|
||||
if( segIndex == 0 )
|
||||
lp.first->Reverse();
|
||||
lp.first.Reverse();
|
||||
|
||||
lp.second = clone( lp.first );
|
||||
lp.second->ClearSegmentLinks();
|
||||
lp.second->DragCorner( p0_pushed, lp.second->CLine().Find( p0 ) );
|
||||
lp.second->AppendVia( *pushedVia );
|
||||
lp.second = lp.first;
|
||||
lp.second.ClearSegmentLinks();
|
||||
lp.second.DragCorner( p0_pushed, lp.second.CLine().Find( p0 ) );
|
||||
lp.second.AppendVia( *pushedVia );
|
||||
draggedLines.push_back( lp );
|
||||
|
||||
if( aVia->Marker() & MK_HEAD )
|
||||
m_draggedViaHeadSet.Add( clone ( lp.second ) );
|
||||
m_draggedViaHeadSet.Add( lp.second );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -594,9 +595,6 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
m_logger.Log( aVia, 0, "obstacle-via" );
|
||||
#endif
|
||||
|
||||
if( aVia->BelongsTo( m_currentNode ) )
|
||||
delete aVia;
|
||||
|
||||
pushedVia->SetRank( aCurrentRank - 1 );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -605,32 +603,34 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForc
|
|||
|
||||
BOOST_FOREACH( LINE_PAIR lp, draggedLines )
|
||||
{
|
||||
if( lp.first->Marker() & MK_HEAD )
|
||||
if( lp.first.Marker() & MK_HEAD )
|
||||
{
|
||||
lp.second->Mark( MK_HEAD );
|
||||
lp.second.Mark( MK_HEAD );
|
||||
|
||||
if ( m_multiLineMode )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
m_newHead = *lp.second;
|
||||
m_newHead = lp.second;
|
||||
}
|
||||
|
||||
unwindStack( lp.first );
|
||||
unwindStack( &lp.first );
|
||||
|
||||
if( lp.second->SegmentCount() )
|
||||
if( lp.second.SegmentCount() )
|
||||
{
|
||||
replaceItems( lp.first, lp.second );
|
||||
lp.second->SetRank( aCurrentRank - 1 );
|
||||
replaceItems( &lp.first, &lp.second );
|
||||
lp.second.SetRank( aCurrentRank - 1 );
|
||||
|
||||
if( !pushLine( lp.second ) )
|
||||
return SH_INCOMPLETE;
|
||||
}
|
||||
else
|
||||
m_currentNode->Remove( lp.first );
|
||||
{
|
||||
m_currentNode->Remove( &lp.first );
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.Log( lp.first, 2, "fan-pre" );
|
||||
m_logger.Log( lp.second, 3, "fan-post" );
|
||||
m_logger.Log( &lp.first, 2, "fan-pre" );
|
||||
m_logger.Log( &lp.second, 3, "fan-post" );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -687,28 +687,27 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA*
|
|||
}
|
||||
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE& aCurrent, PNS_VIA* aObstacleVia )
|
||||
{
|
||||
std::vector<PNS_LINE*> steps;
|
||||
int n = 0;
|
||||
PNS_LINE* cur = clone( aCurrent );
|
||||
cur->ClearSegmentLinks();
|
||||
PNS_LINE cur( aCurrent );
|
||||
cur.ClearSegmentLinks();
|
||||
|
||||
PNS_JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
|
||||
PNS_LINE* shoved = clone( aCurrent );
|
||||
shoved->ClearSegmentLinks();
|
||||
PNS_LINE shoved( aCurrent );
|
||||
shoved.ClearSegmentLinks();
|
||||
|
||||
cur->RemoveVia();
|
||||
unwindStack( aCurrent );
|
||||
cur.RemoveVia();
|
||||
unwindStack( &aCurrent );
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
||||
{
|
||||
if( item->OfKind( PNS_ITEM::SEGMENT ) && item->LayersOverlap( aCurrent ) )
|
||||
if( item->OfKind( PNS_ITEM::SEGMENT ) && item->LayersOverlap( &aCurrent ) )
|
||||
{
|
||||
PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
|
||||
PNS_LINE* head = assembleLine( seg );
|
||||
PNS_LINE head = assembleLine( seg );
|
||||
|
||||
head->AppendVia( *aObstacleVia );
|
||||
head.AppendVia( *aObstacleVia );
|
||||
|
||||
SHOVE_STATUS st = ProcessSingleLine( head, cur, shoved );
|
||||
|
||||
|
@ -717,14 +716,14 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
|||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-reverse-via-fail-shove", m_iter );
|
||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( shoved, 3, "shoved-line" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &shoved, 3, "shoved-line" );
|
||||
#endif
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
cur->SetShape( shoved->CLine() );
|
||||
cur.SetShape( shoved.CLine() );
|
||||
n++;
|
||||
}
|
||||
}
|
||||
|
@ -734,38 +733,38 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
|||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-reverse-via-fail-lonevia", m_iter );
|
||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
#endif
|
||||
|
||||
PNS_LINE head( *aCurrent );
|
||||
PNS_LINE head( aCurrent );
|
||||
head.Line().Clear();
|
||||
head.AppendVia( *aObstacleVia );
|
||||
head.ClearSegmentLinks();
|
||||
|
||||
SHOVE_STATUS st = ProcessSingleLine( &head, aCurrent, shoved );
|
||||
SHOVE_STATUS st = ProcessSingleLine( head, aCurrent, shoved );
|
||||
|
||||
if( st != SH_OK )
|
||||
return st;
|
||||
|
||||
cur->SetShape( shoved->CLine() );
|
||||
cur.SetShape( shoved.CLine() );
|
||||
}
|
||||
|
||||
if( aCurrent->EndsWithVia() )
|
||||
shoved->AppendVia( aCurrent->Via() );
|
||||
if( aCurrent.EndsWithVia() )
|
||||
shoved.AppendVia( aCurrent.Via() );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "on-reverse-via", m_iter );
|
||||
m_logger.Log( aObstacleVia, 0, "the-via" );
|
||||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( shoved, 3, "shoved-line" );
|
||||
m_logger.Log( &aCurrent, 1, "current-line" );
|
||||
m_logger.Log( &shoved, 3, "shoved-line" );
|
||||
#endif
|
||||
int currentRank = aCurrent->Rank();
|
||||
replaceItems( aCurrent, shoved );
|
||||
int currentRank = aCurrent.Rank();
|
||||
replaceItems( &aCurrent, &shoved );
|
||||
|
||||
if ( !pushLine( shoved ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
shoved->SetRank( currentRank );
|
||||
shoved.SetRank( currentRank );
|
||||
|
||||
return SH_OK;
|
||||
}
|
||||
|
@ -773,17 +772,17 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onReverseCollidingVia( PNS_LINE* aCurrent, PN
|
|||
|
||||
void PNS_SHOVE::unwindStack( PNS_SEGMENT *aSeg )
|
||||
{
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_lineStack.begin(); i != m_lineStack.end(); )
|
||||
for( std::vector<PNS_LINE>::iterator i = m_lineStack.begin(); i != m_lineStack.end() ; )
|
||||
{
|
||||
if( (*i)->ContainsSegment( aSeg ) )
|
||||
if( i->ContainsSegment( aSeg ) )
|
||||
i = m_lineStack.erase( i );
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
|
||||
for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end() ; )
|
||||
{
|
||||
if( (*i)->ContainsSegment( aSeg ) )
|
||||
if( i->ContainsSegment( aSeg ) )
|
||||
i = m_optimizerQueue.erase( i );
|
||||
else
|
||||
i++;
|
||||
|
@ -808,9 +807,9 @@ void PNS_SHOVE::unwindStack( PNS_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
bool PNS_SHOVE::pushLine( PNS_LINE* aL )
|
||||
bool PNS_SHOVE::pushLine( const PNS_LINE& aL )
|
||||
{
|
||||
if( aL->LinkCount() >= 0 && ( aL->LinkCount() != aL->SegmentCount() ) )
|
||||
if( aL.LinkCount() >= 0 && ( aL.LinkCount() != aL.SegmentCount() ) )
|
||||
return false;
|
||||
|
||||
m_lineStack.push_back( aL );
|
||||
|
@ -819,18 +818,28 @@ bool PNS_SHOVE::pushLine( PNS_LINE* aL )
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_SHOVE::popLine( )
|
||||
{
|
||||
PNS_LINE* l = m_lineStack.back();
|
||||
PNS_LINE& l = m_lineStack.back();
|
||||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
|
||||
for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
|
||||
{
|
||||
if( ( *i ) == l )
|
||||
bool found = false;
|
||||
|
||||
if( !l.LinkedSegments() )
|
||||
continue;
|
||||
|
||||
BOOST_FOREACH( PNS_SEGMENT *s, *l.LinkedSegments() )
|
||||
{
|
||||
if( i->ContainsSegment( s ) )
|
||||
{
|
||||
i = m_optimizerQueue.erase( i );
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
else
|
||||
}
|
||||
|
||||
if( !found )
|
||||
i++;
|
||||
}
|
||||
|
||||
|
@ -840,7 +849,7 @@ void PNS_SHOVE::popLine( )
|
|||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
||||
{
|
||||
PNS_LINE* currentLine = m_lineStack.back();
|
||||
PNS_LINE currentLine = m_lineStack.back();
|
||||
PNS_NODE::OPT_OBSTACLE nearest;
|
||||
SHOVE_STATUS st = SH_NULL;
|
||||
|
||||
|
@ -848,7 +857,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
|||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
nearest = m_currentNode->NearestObstacle( currentLine, search_order[i] );
|
||||
nearest = m_currentNode->NearestObstacle( ¤tLine, search_order[i] );
|
||||
|
||||
if( nearest )
|
||||
break;
|
||||
|
@ -864,7 +873,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
|||
|
||||
unwindStack( ni );
|
||||
|
||||
if( !ni->OfKind( PNS_ITEM::SOLID ) && ni->Rank() >= 0 && ni->Rank() > currentLine->Rank() )
|
||||
if( !ni->OfKind( PNS_ITEM::SOLID ) && ni->Rank() >= 0 && ni->Rank() > currentLine.Rank() )
|
||||
{
|
||||
switch( ni->Kind() )
|
||||
{
|
||||
|
@ -873,7 +882,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
|||
PNS_VIA* revVia = (PNS_VIA*) ni;
|
||||
TRACE( 2, "iter %d: reverse-collide-via", aIter );
|
||||
|
||||
if( currentLine->EndsWithVia() && m_currentNode->CheckColliding( ¤tLine->Via(), revVia ) )
|
||||
if( currentLine.EndsWithVia() && m_currentNode->CheckColliding( ¤tLine.Via(), revVia ) )
|
||||
{
|
||||
st = SH_INCOMPLETE;
|
||||
}
|
||||
|
@ -889,7 +898,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
|||
{
|
||||
PNS_SEGMENT* seg = (PNS_SEGMENT*) ni;
|
||||
TRACE( 2, "iter %d: reverse-collide-segment ", aIter );
|
||||
PNS_LINE* revLine = assembleLine( seg );
|
||||
PNS_LINE revLine = assembleLine( seg );
|
||||
|
||||
popLine();
|
||||
st = onCollidingLine( revLine, currentLine );
|
||||
|
@ -914,7 +923,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
|||
|
||||
case PNS_ITEM::VIA:
|
||||
TRACE( 2, "iter %d: shove-via ", aIter );
|
||||
st = onCollidingVia( currentLine, (PNS_VIA*) ni );
|
||||
st = onCollidingVia( ¤tLine, (PNS_VIA*) ni );
|
||||
break;
|
||||
|
||||
case PNS_ITEM::SOLID:
|
||||
|
@ -988,22 +997,20 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
m_multiLineMode = false;
|
||||
|
||||
// empty head? nothing to shove...
|
||||
|
||||
if( !aCurrentHead.SegmentCount() && !aCurrentHead.EndsWithVia() )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
PNS_LINE* head = clone( &aCurrentHead );
|
||||
|
||||
if( !head )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
head->ClearSegmentLinks();
|
||||
PNS_LINE head( aCurrentHead );
|
||||
head.ClearSegmentLinks();
|
||||
|
||||
m_lineStack.clear();
|
||||
m_optimizerQueue.clear();
|
||||
m_newHead = OPT_LINE();
|
||||
m_logger.Clear();
|
||||
|
||||
PNS_ITEMSET headSet( clone( &aCurrentHead ) );
|
||||
PNS_ITEMSET headSet;
|
||||
headSet.Add( aCurrentHead );
|
||||
|
||||
reduceSpringback( headSet );
|
||||
|
||||
|
@ -1011,19 +1018,24 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
|
||||
m_currentNode = parent->Branch();
|
||||
m_currentNode->ClearRanks();
|
||||
m_currentNode->Add( head );
|
||||
m_currentNode->Add( &head );
|
||||
|
||||
head->Mark( MK_HEAD );
|
||||
head->SetRank( 100000 );
|
||||
m_currentNode->LockJoint( head.CPoint(0), &head, true );
|
||||
|
||||
if( !head.EndsWithVia() )
|
||||
m_currentNode->LockJoint( head.CPoint( -1 ), &head, true );
|
||||
|
||||
head.Mark( MK_HEAD );
|
||||
head.SetRank( 100000 );
|
||||
|
||||
m_logger.NewGroup( "initial", 0 );
|
||||
m_logger.Log( head, 0, "head" );
|
||||
m_logger.Log( &head, 0, "head" );
|
||||
|
||||
PNS_VIA* headVia = NULL;
|
||||
|
||||
if( head->EndsWithVia() )
|
||||
if( head.EndsWithVia() )
|
||||
{
|
||||
headVia = head->Via().Clone();
|
||||
headVia = head.Via().Clone();
|
||||
m_currentNode->Add( headVia );
|
||||
headVia->Mark( MK_HEAD );
|
||||
headVia->SetRank( 100000 );
|
||||
|
@ -1037,7 +1049,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
|
||||
|
||||
if( ( st == SH_OK || st == SH_HEAD_MODIFIED ) )
|
||||
runOptimizer( m_currentNode, head );
|
||||
runOptimizer( m_currentNode );
|
||||
|
||||
if( m_newHead && st == SH_OK )
|
||||
{
|
||||
|
@ -1081,7 +1093,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
if( !headOrig->SegmentCount() )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
headSet.Add( clone( headOrig ) );
|
||||
headSet.Add( *headOrig );
|
||||
}
|
||||
|
||||
m_lineStack.clear();
|
||||
|
@ -1095,25 +1107,26 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
m_currentNode = parent->Branch();
|
||||
m_currentNode->ClearRanks();
|
||||
int n = 0;
|
||||
|
||||
BOOST_FOREACH ( const PNS_ITEM* item, aHeadSet.CItems() )
|
||||
{
|
||||
const PNS_LINE* headOrig = static_cast<const PNS_LINE*>( item );
|
||||
PNS_LINE* head = clone( headOrig );
|
||||
head->ClearSegmentLinks();
|
||||
PNS_LINE head( *headOrig );
|
||||
head.ClearSegmentLinks();
|
||||
|
||||
m_currentNode->Add( head );
|
||||
m_currentNode->Add( &head );
|
||||
|
||||
head->Mark( MK_HEAD );
|
||||
head->SetRank( 100000 );
|
||||
head.Mark( MK_HEAD );
|
||||
head.SetRank( 100000 );
|
||||
n++;
|
||||
if ( !pushLine( head ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
PNS_VIA* headVia = NULL;
|
||||
|
||||
if( head->EndsWithVia() )
|
||||
if( head.EndsWithVia() )
|
||||
{
|
||||
headVia = head->Via().Clone(); // fixme: leak
|
||||
headVia = head.Via().Clone(); // fixme: leak
|
||||
m_currentNode->Add( headVia );
|
||||
headVia->Mark( MK_HEAD );
|
||||
headVia->SetRank( 100000 );
|
||||
|
@ -1127,7 +1140,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveMultiLines( const PNS_ITEMSET& aHeadSet
|
|||
st = shoveMainLoop();
|
||||
|
||||
if( st == SH_OK )
|
||||
runOptimizer( m_currentNode, NULL );
|
||||
runOptimizer( m_currentNode );
|
||||
|
||||
m_currentNode->RemoveByMarker( MK_HEAD );
|
||||
|
||||
|
@ -1162,8 +1175,6 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
|||
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
|
||||
m_currentNode = parent;
|
||||
//st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0, true );
|
||||
//reduceSpringback( m_draggedViaHeadSet );
|
||||
|
||||
parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
|
||||
|
@ -1176,7 +1187,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
|||
st = shoveMainLoop();
|
||||
|
||||
if( st == SH_OK )
|
||||
runOptimizer( m_currentNode, NULL );
|
||||
runOptimizer( m_currentNode );
|
||||
|
||||
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
||||
{
|
||||
|
@ -1196,7 +1207,7 @@ PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR
|
|||
}
|
||||
|
||||
|
||||
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
||||
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode )
|
||||
{
|
||||
PNS_OPTIMIZER optimizer( aNode );
|
||||
int optFlags = 0, n_passes = 0;
|
||||
|
@ -1207,10 +1218,10 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
|
||||
int maxWidth = 0;
|
||||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin();
|
||||
for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin();
|
||||
i != m_optimizerQueue.end(); ++i )
|
||||
{
|
||||
maxWidth = std::max( (*i)->Width(), maxWidth );
|
||||
maxWidth = std::max( i->Width(), maxWidth );
|
||||
}
|
||||
|
||||
if( area )
|
||||
|
@ -1253,20 +1264,20 @@ void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
|||
{
|
||||
std::reverse( m_optimizerQueue.begin(), m_optimizerQueue.end() );
|
||||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin();
|
||||
for( std::vector<PNS_LINE>::iterator i = m_optimizerQueue.begin();
|
||||
i != m_optimizerQueue.end(); ++i )
|
||||
{
|
||||
PNS_LINE* line = *i;
|
||||
PNS_LINE& line = *i;
|
||||
|
||||
if( !( line -> Marker() & MK_HEAD ) )
|
||||
if( !( line.Marker() & MK_HEAD ) )
|
||||
{
|
||||
PNS_LINE optimized;
|
||||
|
||||
if( optimizer.Optimize( line, &optimized ) )
|
||||
if( optimizer.Optimize( &line, &optimized ) )
|
||||
{
|
||||
aNode->Remove( line );
|
||||
line->SetShape( optimized.CLine() );
|
||||
aNode->Add( line );
|
||||
aNode->Remove( &line );
|
||||
line.SetShape( optimized.CLine() );
|
||||
aNode->Add( &line );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1288,8 +1299,8 @@ const PNS_LINE PNS_SHOVE::NewHead() const
|
|||
}
|
||||
|
||||
|
||||
void PNS_SHOVE::SetInitialLine( PNS_LINE* aInitial )
|
||||
void PNS_SHOVE::SetInitialLine( PNS_LINE& aInitial )
|
||||
{
|
||||
m_root = m_root->Branch();
|
||||
m_root->Remove( aInitial );
|
||||
m_root->Remove( &aInitial );
|
||||
}
|
||||
|
|
|
@ -64,8 +64,8 @@ public:
|
|||
SHOVE_STATUS ShoveMultiLines( const PNS_ITEMSET& aHeadSet );
|
||||
|
||||
SHOVE_STATUS ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
|
||||
SHOVE_STATUS ProcessSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved );
|
||||
SHOVE_STATUS ProcessSingleLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
|
||||
PNS_LINE& aShoved );
|
||||
|
||||
void ForceClearance ( bool aEnabled, int aClearance )
|
||||
{
|
||||
|
@ -79,12 +79,12 @@ public:
|
|||
|
||||
const PNS_LINE NewHead() const;
|
||||
|
||||
void SetInitialLine( PNS_LINE* aInitial );
|
||||
void SetInitialLine( PNS_LINE& aInitial );
|
||||
|
||||
private:
|
||||
typedef std::vector<SHAPE_LINE_CHAIN> HULL_SET;
|
||||
typedef boost::optional<PNS_LINE> OPT_LINE;
|
||||
typedef std::pair <PNS_LINE*, PNS_LINE*> LINE_PAIR;
|
||||
typedef std::pair<PNS_LINE, PNS_LINE> LINE_PAIR;
|
||||
typedef std::vector<LINE_PAIR> LINE_PAIR_VEC;
|
||||
|
||||
struct SPRINGBACK_TAG
|
||||
|
@ -98,21 +98,21 @@ private:
|
|||
OPT_BOX2I m_affectedArea;
|
||||
};
|
||||
|
||||
SHOVE_STATUS processHullSet( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
|
||||
PNS_LINE* aShoved, const HULL_SET& hulls );
|
||||
SHOVE_STATUS processHullSet( PNS_LINE& aCurrent, PNS_LINE& aObstacle,
|
||||
PNS_LINE& aShoved, const HULL_SET& hulls );
|
||||
|
||||
bool reduceSpringback( const PNS_ITEMSET& aHeadItems );
|
||||
bool pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
||||
const PNS_COST_ESTIMATOR& aCost, const OPT_BOX2I& aAffectedArea );
|
||||
|
||||
SHOVE_STATUS walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
||||
bool checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const;
|
||||
SHOVE_STATUS walkaroundLoneVia( PNS_LINE& aCurrent, PNS_LINE& aObstacle, PNS_LINE& aShoved );
|
||||
bool checkBumpDirection( const PNS_LINE& aCurrent, const PNS_LINE& aShoved ) const;
|
||||
|
||||
SHOVE_STATUS onCollidingLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle );
|
||||
SHOVE_STATUS onCollidingSegment( PNS_LINE* aCurrent, PNS_SEGMENT* aObstacleSeg );
|
||||
SHOVE_STATUS onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid );
|
||||
SHOVE_STATUS onCollidingLine( PNS_LINE& aCurrent, PNS_LINE& aObstacle );
|
||||
SHOVE_STATUS onCollidingSegment( PNS_LINE& aCurrent, PNS_SEGMENT* aObstacleSeg );
|
||||
SHOVE_STATUS onCollidingSolid( PNS_LINE& aCurrent, PNS_SOLID* aObstacleSolid );
|
||||
SHOVE_STATUS onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia );
|
||||
SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
|
||||
SHOVE_STATUS onReverseCollidingVia( PNS_LINE& aCurrent, PNS_VIA* aObstacleVia );
|
||||
SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank, bool aDryRun = false );
|
||||
|
||||
OPT_BOX2I totalAffectedArea() const;
|
||||
|
@ -120,34 +120,25 @@ private:
|
|||
void unwindStack( PNS_SEGMENT* aSeg );
|
||||
void unwindStack( PNS_ITEM* aItem );
|
||||
|
||||
void runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead );
|
||||
void runOptimizer( PNS_NODE* aNode );
|
||||
|
||||
bool pushLine( PNS_LINE* aL );
|
||||
bool pushLine( const PNS_LINE& aL );
|
||||
void popLine();
|
||||
|
||||
PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
|
||||
PNS_LINE assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
|
||||
|
||||
void replaceItems( PNS_ITEM* aOld, PNS_ITEM* aNew );
|
||||
|
||||
template<class T> T* clone( const T* aItem )
|
||||
{
|
||||
T *cloned = aItem->Clone();
|
||||
|
||||
m_gcItems.push_back( cloned );
|
||||
return cloned;
|
||||
}
|
||||
|
||||
OPT_BOX2I m_affectedAreaSum;
|
||||
|
||||
SHOVE_STATUS shoveIteration( int aIter );
|
||||
SHOVE_STATUS shoveMainLoop();
|
||||
|
||||
int getClearance( PNS_ITEM* aA, PNS_ITEM* aB ) const;
|
||||
int getClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
|
||||
|
||||
std::vector<SPRINGBACK_TAG> m_nodeStack;
|
||||
std::vector<PNS_LINE*> m_lineStack;
|
||||
std::vector<PNS_LINE*> m_optimizerQueue;
|
||||
std::vector<PNS_ITEM*> m_gcItems;
|
||||
std::vector<PNS_LINE> m_lineStack;
|
||||
std::vector<PNS_LINE> m_optimizerQueue;
|
||||
|
||||
PNS_NODE* m_root;
|
||||
PNS_NODE* m_currentNode;
|
||||
|
@ -161,6 +152,7 @@ private:
|
|||
int m_iter;
|
||||
int m_forceClearance;
|
||||
bool m_multiLineMode;
|
||||
void sanityCheck( PNS_LINE* aOld, PNS_LINE* aNew );
|
||||
};
|
||||
|
||||
#endif // __PNS_SHOVE_H
|
||||
|
|
|
@ -49,7 +49,7 @@ int PNS_SIZES_SETTINGS::inheritTrackWidth( PNS_ITEM* aItem )
|
|||
return 0;
|
||||
}
|
||||
|
||||
PNS_JOINT* jt = aItem->Owner()->FindJoint( p, aItem );
|
||||
PNS_JOINT* jt = static_cast<PNS_NODE*>( aItem->Owner() )->FindJoint( p, aItem );
|
||||
|
||||
assert( jt != NULL );
|
||||
|
||||
|
|
|
@ -37,17 +37,17 @@ bool PNS_TOPOLOGY::SimplifyLine( PNS_LINE* aLine )
|
|||
return false;
|
||||
|
||||
PNS_SEGMENT* root = ( *aLine->LinkedSegments() )[0];
|
||||
std::auto_ptr<PNS_LINE> l( m_world->AssembleLine( root ) );
|
||||
SHAPE_LINE_CHAIN simplified( l->CLine() );
|
||||
PNS_LINE l = m_world->AssembleLine( root );
|
||||
SHAPE_LINE_CHAIN simplified( l.CLine() );
|
||||
|
||||
simplified.Simplify();
|
||||
|
||||
if( simplified.PointCount() != l->PointCount() )
|
||||
if( simplified.PointCount() != l.PointCount() )
|
||||
{
|
||||
std::auto_ptr<PNS_LINE> lnew( l->Clone() );
|
||||
m_world->Remove( l.get() );
|
||||
lnew->SetShape( simplified );
|
||||
m_world->Add( lnew.get() );
|
||||
PNS_LINE lnew( l );
|
||||
m_world->Remove( &l );
|
||||
lnew.SetShape( simplified );
|
||||
m_world->Add( &lnew );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -199,13 +199,13 @@ bool PNS_TOPOLOGY::followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET&
|
|||
if( !next_seg )
|
||||
return false;
|
||||
|
||||
PNS_LINE* l = m_world->AssembleLine( next_seg );
|
||||
PNS_LINE l = m_world->AssembleLine( next_seg );
|
||||
|
||||
VECTOR2I nextAnchor = ( aLeft ? l->CLine().CPoint( -1 ) : l->CLine().CPoint( 0 ) );
|
||||
VECTOR2I nextAnchor = ( aLeft ? l.CLine().CPoint( -1 ) : l.CLine().CPoint( 0 ) );
|
||||
|
||||
if( nextAnchor != anchor )
|
||||
{
|
||||
l->Reverse();
|
||||
l.Reverse();
|
||||
}
|
||||
|
||||
if( aLeft )
|
||||
|
@ -219,7 +219,7 @@ bool PNS_TOPOLOGY::followTrivialPath( PNS_LINE* aLine, bool aLeft, PNS_ITEMSET&
|
|||
aSet.Add( l );
|
||||
}
|
||||
|
||||
return followTrivialPath( l, aLeft, aSet, aVisited );
|
||||
return followTrivialPath( &l, aLeft, aSet, aVisited );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -231,12 +231,12 @@ const PNS_ITEMSET PNS_TOPOLOGY::AssembleTrivialPath( PNS_SEGMENT* aStart )
|
|||
PNS_ITEMSET path;
|
||||
std::set<PNS_ITEM*> visited;
|
||||
|
||||
PNS_LINE* l = m_world->AssembleLine( aStart );
|
||||
PNS_LINE l = m_world->AssembleLine( aStart );
|
||||
|
||||
path.Add( l );
|
||||
|
||||
followTrivialPath( l, false, path, visited );
|
||||
followTrivialPath( l, true, path, visited );
|
||||
followTrivialPath( &l, false, path, visited );
|
||||
followTrivialPath( &l, true, path, visited );
|
||||
|
||||
return path;
|
||||
}
|
||||
|
@ -362,14 +362,17 @@ bool PNS_TOPOLOGY::AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair )
|
|||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if( !coupledSeg )
|
||||
return false;
|
||||
|
||||
std::auto_ptr<PNS_LINE> lp( m_world->AssembleLine( refSeg ) );
|
||||
std::auto_ptr<PNS_LINE> ln( m_world->AssembleLine( coupledSeg ) );
|
||||
PNS_LINE lp = m_world->AssembleLine( refSeg );
|
||||
PNS_LINE ln = m_world->AssembleLine( coupledSeg );
|
||||
|
||||
if( DpNetPolarity( refNet ) < 0 )
|
||||
{
|
||||
|
@ -377,17 +380,18 @@ bool PNS_TOPOLOGY::AssembleDiffPair( PNS_ITEM* aStart, PNS_DIFF_PAIR& aPair )
|
|||
}
|
||||
|
||||
int gap = -1;
|
||||
|
||||
if( refSeg->Seg().ApproxParallel( coupledSeg->Seg() ) )
|
||||
{
|
||||
// Segments are parallel -> compute pair gap
|
||||
const VECTOR2I refDir = refSeg->Anchor( 1 ) - refSeg->Anchor( 0 );
|
||||
const VECTOR2I displacement = refSeg->Anchor( 1 ) - coupledSeg->Anchor( 1 );
|
||||
gap = (int) std::abs( refDir.Cross( displacement ) / refDir.EuclideanNorm() ) - lp->Width();
|
||||
gap = (int) std::abs( refDir.Cross( displacement ) / refDir.EuclideanNorm() ) - lp.Width();
|
||||
}
|
||||
|
||||
aPair = PNS_DIFF_PAIR( *lp, *ln );
|
||||
aPair.SetWidth( lp->Width() );
|
||||
aPair.SetLayers( lp->Layers() );
|
||||
aPair = PNS_DIFF_PAIR( lp, ln );
|
||||
aPair.SetWidth( lp.Width() );
|
||||
aPair.SetLayers( lp.Layers() );
|
||||
aPair.SetGap( gap );
|
||||
|
||||
return true;
|
||||
|
|
|
@ -292,7 +292,7 @@ void ROUTER_TOOL::handleCommonEvents( const TOOL_EVENT& aEvent )
|
|||
{
|
||||
switch( aEvent.KeyCode() )
|
||||
{
|
||||
case 'S':
|
||||
case '0':
|
||||
TRACEn( 2, "saving drag/route log...\n" );
|
||||
m_router->DumpLog();
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue