Reformatted PNS code to conform the coding policy.
This commit is contained in:
parent
58becbeb59
commit
c60698c24b
|
@ -237,7 +237,7 @@ public:
|
|||
pl.Append( aP1 );
|
||||
pl.Simplify();
|
||||
return pl;
|
||||
};
|
||||
}
|
||||
|
||||
bool operator==( const DIRECTION_45& aOther ) const
|
||||
{
|
||||
|
@ -286,8 +286,6 @@ public:
|
|||
return l;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function ToVector()
|
||||
*
|
||||
|
|
|
@ -33,17 +33,18 @@ class PNS_LOGGER;
|
|||
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging)
|
||||
**/
|
||||
|
||||
class PNS_ALGO_BASE {
|
||||
|
||||
class PNS_ALGO_BASE
|
||||
{
|
||||
public:
|
||||
PNS_ALGO_BASE( PNS_ROUTER *aRouter ) :
|
||||
m_router ( aRouter )
|
||||
{};
|
||||
{}
|
||||
|
||||
virtual ~PNS_ALGO_BASE() {}
|
||||
|
||||
///> Returns the instance of our router
|
||||
PNS_ROUTER *Router() const {
|
||||
PNS_ROUTER* Router() const
|
||||
{
|
||||
return m_router;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,8 @@ PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) :
|
|||
{
|
||||
m_world = NULL;
|
||||
m_shove = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PNS_DRAGGER::~PNS_DRAGGER()
|
||||
{
|
||||
|
@ -37,11 +38,13 @@ PNS_DRAGGER::~PNS_DRAGGER()
|
|||
delete m_shove;
|
||||
}
|
||||
|
||||
|
||||
void PNS_DRAGGER::SetWorld ( PNS_NODE* aWorld )
|
||||
{
|
||||
m_world = aWorld;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg )
|
||||
{
|
||||
int w2 = aSeg->Width() / 2;
|
||||
|
@ -59,9 +62,11 @@ bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT *aSeg )
|
|||
m_mode = CORNER;
|
||||
} else
|
||||
m_mode = SEGMENT;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA* aVia )
|
||||
{
|
||||
m_draggedVia = aVia;
|
||||
|
@ -83,14 +88,13 @@ bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA *aVia )
|
|||
l->Reverse();
|
||||
|
||||
m_origViaConnections.push_back( *l );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
m_shove = new PNS_SHOVE( m_world, Router() );
|
||||
|
@ -104,13 +108,16 @@ bool PNS_DRAGGER::Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
{
|
||||
case PNS_ITEM::SEGMENT:
|
||||
return startDragSegment ( aP, static_cast<PNS_SEGMENT *>( aStartItem ) );
|
||||
|
||||
case PNS_ITEM::VIA:
|
||||
return startDragVia ( aP, static_cast<PNS_VIA *> (aStartItem) );
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
|
||||
{
|
||||
if( m_lastNode )
|
||||
|
@ -143,12 +150,12 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case VIA: // fixme...
|
||||
{
|
||||
m_lastNode = m_shove->CurrentNode()->Branch();
|
||||
dumbDragVia ( m_initialVia, m_lastNode, aP );
|
||||
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -161,6 +168,7 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP )
|
||||
{
|
||||
// fixme: this is awful.
|
||||
|
@ -187,11 +195,11 @@ void PNS_DRAGGER::dumbDragVia ( PNS_VIA *aVia, PNS_NODE *aNode, const VECTOR2I&
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
|
||||
{
|
||||
bool ok = false;
|
||||
|
||||
|
||||
if( m_lastNode )
|
||||
{
|
||||
delete m_lastNode;
|
||||
|
@ -205,12 +213,13 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
|
|||
{
|
||||
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0;
|
||||
PNS_LINE tmp( *m_draggedLine );
|
||||
|
||||
if( m_mode == SEGMENT )
|
||||
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
|
||||
else
|
||||
tmp.DragCorner( aP, m_draggedSegmentIndex, thresh );
|
||||
|
||||
PNS_SHOVE::ShoveStatus st = m_shove->ShoveLines( tmp );
|
||||
PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveLines( tmp );
|
||||
|
||||
if( st == PNS_SHOVE::SH_OK )
|
||||
ok = true;
|
||||
|
@ -232,10 +241,11 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case VIA:
|
||||
{
|
||||
PNS_VIA *newVia;
|
||||
PNS_SHOVE::ShoveStatus st = m_shove -> ShoveDraggingVia ( m_draggedVia, aP, &newVia );
|
||||
PNS_SHOVE::SHOVE_STATUS st = m_shove->ShoveDraggingVia( m_draggedVia, aP, &newVia );
|
||||
|
||||
if( st == PNS_SHOVE::SH_OK || st == PNS_SHOVE::SH_HEAD_MODIFIED )
|
||||
ok = true;
|
||||
|
@ -250,13 +260,14 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_dragStatus = ok;
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::FixRoute()
|
||||
{
|
||||
if( m_dragStatus )
|
||||
|
@ -268,34 +279,41 @@ bool PNS_DRAGGER::FixRoute( )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_DRAGGER::Drag( const VECTOR2I& aP )
|
||||
{
|
||||
switch( m_currentMode )
|
||||
{
|
||||
case RM_MarkObstacles:
|
||||
return dragMarkObstacles( aP );
|
||||
|
||||
case RM_Shove:
|
||||
case RM_Walkaround:
|
||||
case RM_Smart:
|
||||
return dragShove( aP );
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE *PNS_DRAGGER::CurrentNode() const
|
||||
{
|
||||
return m_lastNode;
|
||||
}
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_DRAGGER::Traces()
|
||||
{
|
||||
return m_draggedItems;
|
||||
}
|
||||
|
||||
|
||||
PNS_LOGGER* PNS_DRAGGER::Logger()
|
||||
{
|
||||
if( m_shove )
|
||||
return m_shove->Logger();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -39,11 +39,9 @@ class PNS_ROUTER_BASE;
|
|||
*
|
||||
* Via, segment and corner dragging algorithm.
|
||||
*/
|
||||
|
||||
class PNS_DRAGGER : public PNS_ALGO_BASE
|
||||
{
|
||||
public:
|
||||
|
||||
PNS_DRAGGER( PNS_ROUTER* aRouter );
|
||||
~PNS_DRAGGER();
|
||||
|
||||
|
@ -54,7 +52,6 @@ public:
|
|||
*/
|
||||
void SetWorld( PNS_NODE* aWorld );
|
||||
|
||||
|
||||
/**
|
||||
* Function Start()
|
||||
*
|
||||
|
@ -86,7 +83,6 @@ public:
|
|||
* Returns the most recent world state, including all
|
||||
* items changed due to dragging operation.
|
||||
*/
|
||||
|
||||
PNS_NODE* CurrentNode() const;
|
||||
|
||||
/**
|
||||
|
@ -100,7 +96,6 @@ public:
|
|||
virtual PNS_LOGGER* Logger();
|
||||
|
||||
private:
|
||||
|
||||
typedef std::pair<PNS_LINE *, PNS_LINE *> LinePair;
|
||||
typedef std::vector<LinePair> LinePairVec;
|
||||
|
||||
|
|
|
@ -39,13 +39,12 @@
|
|||
* are assigned to separate R-Tree subindices depending on their type and spanned layers, reducing
|
||||
* overlap and improving search time.
|
||||
**/
|
||||
|
||||
class PNS_INDEX
|
||||
{
|
||||
public:
|
||||
typedef std::list<PNS_ITEM*> NetItemsList;
|
||||
typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex;
|
||||
typedef boost::unordered_set<PNS_ITEM*> ItemSet;
|
||||
typedef std::list<PNS_ITEM*> NET_ITEMS_LIST;
|
||||
typedef SHAPE_INDEX<PNS_ITEM*> ITEM_SHAPE_INDEX;
|
||||
typedef boost::unordered_set<PNS_ITEM*> ITEM_SET;
|
||||
|
||||
PNS_INDEX();
|
||||
~PNS_INDEX();
|
||||
|
@ -115,7 +114,7 @@ public:
|
|||
*
|
||||
* Returns list of all items in a given net.
|
||||
*/
|
||||
NetItemsList* GetItemsForNet( int aNet );
|
||||
NET_ITEMS_LIST* GetItemsForNet( int aNet );
|
||||
|
||||
/**
|
||||
* Function Contains()
|
||||
|
@ -134,8 +133,8 @@ public:
|
|||
*/
|
||||
int Size() const { return m_allItems.size(); }
|
||||
|
||||
ItemSet::iterator begin() { return m_allItems.begin(); }
|
||||
ItemSet::iterator end() { return m_allItems.end(); }
|
||||
ITEM_SET::iterator begin() { return m_allItems.begin(); }
|
||||
ITEM_SET::iterator end() { return m_allItems.end(); }
|
||||
|
||||
private:
|
||||
static const int MaxSubIndices = 64;
|
||||
|
@ -149,21 +148,20 @@ private:
|
|||
template <class Visitor>
|
||||
int querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor );
|
||||
|
||||
ItemShapeIndex* getSubindex( const PNS_ITEM* aItem );
|
||||
ITEM_SHAPE_INDEX* getSubindex( const PNS_ITEM* aItem );
|
||||
|
||||
ItemShapeIndex* m_subIndices[MaxSubIndices];
|
||||
std::map<int, NetItemsList> m_netMap;
|
||||
ItemSet m_allItems;
|
||||
ITEM_SHAPE_INDEX* m_subIndices[MaxSubIndices];
|
||||
std::map<int, NET_ITEMS_LIST> m_netMap;
|
||||
ITEM_SET m_allItems;
|
||||
};
|
||||
|
||||
|
||||
PNS_INDEX::PNS_INDEX()
|
||||
{
|
||||
memset( m_subIndices, 0, sizeof( m_subIndices ) );
|
||||
}
|
||||
|
||||
|
||||
PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
||||
PNS_INDEX::ITEM_SHAPE_INDEX* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
||||
{
|
||||
int idx_n = -1;
|
||||
|
||||
|
@ -199,7 +197,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
|||
assert( idx_n >= 0 && idx_n < MaxSubIndices );
|
||||
|
||||
if( !m_subIndices[idx_n] )
|
||||
m_subIndices[idx_n] = new ItemShapeIndex;
|
||||
m_subIndices[idx_n] = new ITEM_SHAPE_INDEX;
|
||||
|
||||
return m_subIndices[idx_n];
|
||||
}
|
||||
|
@ -207,9 +205,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
|
|||
|
||||
void PNS_INDEX::Add( PNS_ITEM* aItem )
|
||||
{
|
||||
ItemShapeIndex* idx = getSubindex( aItem );
|
||||
|
||||
|
||||
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
||||
|
||||
idx->Add( aItem );
|
||||
m_allItems.insert( aItem );
|
||||
|
@ -224,7 +220,7 @@ void PNS_INDEX::Add( PNS_ITEM* aItem )
|
|||
|
||||
void PNS_INDEX::Remove( PNS_ITEM* aItem )
|
||||
{
|
||||
ItemShapeIndex* idx = getSubindex( aItem );
|
||||
ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
|
||||
|
||||
idx->Remove( aItem );
|
||||
m_allItems.erase( aItem );
|
||||
|
@ -303,7 +299,7 @@ void PNS_INDEX::Clear()
|
|||
{
|
||||
for( int i = 0; i < MaxSubIndices; ++i )
|
||||
{
|
||||
ItemShapeIndex* idx = m_subIndices[i];
|
||||
ITEM_SHAPE_INDEX* idx = m_subIndices[i];
|
||||
|
||||
if( idx )
|
||||
delete idx;
|
||||
|
@ -319,7 +315,7 @@ PNS_INDEX::~PNS_INDEX()
|
|||
}
|
||||
|
||||
|
||||
PNS_INDEX::NetItemsList* PNS_INDEX::GetItemsForNet( int aNet )
|
||||
PNS_INDEX::NET_ITEMS_LIST* PNS_INDEX::GetItemsForNet( int aNet )
|
||||
{
|
||||
if( m_netMap.find( aNet ) == m_netMap.end() )
|
||||
return NULL;
|
||||
|
|
|
@ -50,8 +50,7 @@ bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
|
|||
const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther );
|
||||
|
||||
if( line->EndsWithVia() )
|
||||
return collideSimple( &line->Via(), aClearance - line->Width() / 2, aNeedMTV,
|
||||
aMTV );
|
||||
return collideSimple( &line->Via(), aClearance - line->Width() / 2, aNeedMTV, aMTV );
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -85,5 +84,4 @@ const std::string PNS_ITEM::KindStr() const
|
|||
|
||||
PNS_ITEM::~PNS_ITEM()
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const
|
||||
{
|
||||
return SHAPE_LINE_CHAIN();
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Function Kind()
|
||||
|
@ -252,7 +252,6 @@ public:
|
|||
*/
|
||||
PNS_NODE* Owner() const { return m_owner; }
|
||||
|
||||
|
||||
/**
|
||||
* Function Collide()
|
||||
*
|
||||
|
@ -321,7 +320,7 @@ public:
|
|||
virtual VECTOR2I Anchor( int n ) const
|
||||
{
|
||||
return VECTOR2I ();
|
||||
};
|
||||
}
|
||||
|
||||
virtual int AnchorCount() const
|
||||
{
|
||||
|
@ -329,7 +328,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
|
||||
VECTOR2I& aMTV ) const;
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include "pns_itemset.h"
|
||||
|
||||
|
||||
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem )
|
||||
{
|
||||
if(aInitialItem)
|
||||
|
@ -47,9 +46,10 @@ void PNS_ITEMSET::Clear()
|
|||
m_ownedItems.clear();
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
|
||||
{
|
||||
ItemVector newItems;
|
||||
ITEM_VECTOR newItems;
|
||||
PNS_LAYERSET l;
|
||||
|
||||
if( aEnd < 0 )
|
||||
|
@ -63,33 +63,38 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
|
|||
newItems.push_back( item );
|
||||
|
||||
m_items = newItems;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask )
|
||||
{
|
||||
ItemVector newItems;
|
||||
ITEM_VECTOR newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
|
||||
{
|
||||
if( item->OfKind ( aKindMask ) )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet )
|
||||
{
|
||||
ItemVector newItems;
|
||||
ITEM_VECTOR newItems;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, m_items )
|
||||
|
||||
{
|
||||
if( item->Net() == aNet )
|
||||
newItems.push_back( item );
|
||||
}
|
||||
|
||||
m_items = newItems;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
|
|
@ -35,27 +35,28 @@
|
|||
class PNS_ITEMSET
|
||||
{
|
||||
public:
|
||||
typedef std::vector<PNS_ITEM*> ItemVector;
|
||||
typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
|
||||
|
||||
PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
|
||||
|
||||
PNS_ITEMSET( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
m_ownedItems = ItemVector();
|
||||
m_ownedItems = ITEM_VECTOR();
|
||||
}
|
||||
|
||||
const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
|
||||
{
|
||||
m_items = aOther.m_items;
|
||||
m_ownedItems = ItemVector();
|
||||
m_ownedItems = ITEM_VECTOR();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~PNS_ITEMSET();
|
||||
|
||||
ItemVector& Items() { return m_items; }
|
||||
const ItemVector& CItems() const { return m_items; }
|
||||
ITEM_VECTOR& Items() { return m_items; }
|
||||
const ITEM_VECTOR& CItems() const { return m_items; }
|
||||
|
||||
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1 );
|
||||
PNS_ITEMSET& FilterKinds( int aKindMask );
|
||||
|
@ -63,9 +64,9 @@ public:
|
|||
|
||||
int Size() { return m_items.size(); }
|
||||
|
||||
void Add( PNS_ITEM* item )
|
||||
void Add( PNS_ITEM* aItem )
|
||||
{
|
||||
m_items.push_back( item );
|
||||
m_items.push_back( aItem );
|
||||
}
|
||||
|
||||
PNS_ITEM* Get( int index ) const { return m_items[index]; }
|
||||
|
@ -79,8 +80,8 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ItemVector m_items;
|
||||
ItemVector m_ownedItems;
|
||||
ITEM_VECTOR m_items;
|
||||
ITEM_VECTOR m_ownedItems;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -40,11 +40,11 @@
|
|||
class PNS_JOINT : public PNS_ITEM
|
||||
{
|
||||
public:
|
||||
typedef std::vector<PNS_ITEM*> LinkedItems;
|
||||
typedef std::vector<PNS_ITEM*> LINKED_ITEMS;
|
||||
|
||||
///> Joints are hashed by their position, layers and net.
|
||||
/// Linked items are, obviously, not hashed
|
||||
struct HashTag
|
||||
struct HASH_TAG
|
||||
{
|
||||
VECTOR2I pos;
|
||||
int net;
|
||||
|
@ -53,8 +53,7 @@ public:
|
|||
PNS_JOINT() :
|
||||
PNS_ITEM( JOINT ) {}
|
||||
|
||||
PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
|
||||
int aNet = -1 ) :
|
||||
PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1 ) :
|
||||
PNS_ITEM( JOINT )
|
||||
{
|
||||
m_tag.pos = aPos;
|
||||
|
@ -62,14 +61,14 @@ public:
|
|||
m_layers = aLayers;
|
||||
}
|
||||
|
||||
PNS_JOINT( const PNS_JOINT& b ) :
|
||||
PNS_JOINT( const PNS_JOINT& aB ) :
|
||||
PNS_ITEM( JOINT )
|
||||
{
|
||||
m_layers = b.m_layers;
|
||||
m_tag.pos = b.m_tag.pos;
|
||||
m_tag.net = b.m_tag.net;
|
||||
m_linkedItems = b.m_linkedItems;
|
||||
m_layers = b.m_layers;
|
||||
m_layers = aB.m_layers;
|
||||
m_tag.pos = aB.m_tag.pos;
|
||||
m_tag.net = aB.m_tag.net;
|
||||
m_linkedItems = aB.m_linkedItems;
|
||||
m_layers = aB.m_layers;
|
||||
}
|
||||
|
||||
PNS_ITEM* Clone ( ) const
|
||||
|
@ -85,8 +84,7 @@ public:
|
|||
if( m_linkedItems.size() != 2 )
|
||||
return false;
|
||||
|
||||
if( m_linkedItems[0]->Kind() != SEGMENT ||
|
||||
m_linkedItems[1]->Kind() != SEGMENT )
|
||||
if( m_linkedItems[0]->Kind() != SEGMENT || m_linkedItems[1]->Kind() != SEGMENT )
|
||||
return false;
|
||||
|
||||
PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
|
||||
|
@ -99,8 +97,7 @@ public:
|
|||
///> Links the joint to a given board item (when it's added to the PNS_NODE)
|
||||
void Link( PNS_ITEM* aItem )
|
||||
{
|
||||
LinkedItems::iterator f = std::find( m_linkedItems.begin(),
|
||||
m_linkedItems.end(), aItem );
|
||||
LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem );
|
||||
|
||||
if( f != m_linkedItems.end() )
|
||||
return;
|
||||
|
@ -112,8 +109,7 @@ public:
|
|||
///> Returns true if the joint became dangling after unlinking.
|
||||
bool Unlink( PNS_ITEM* aItem )
|
||||
{
|
||||
LinkedItems::iterator f = std::find( m_linkedItems.begin(),
|
||||
m_linkedItems.end(), aItem );
|
||||
LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem );
|
||||
|
||||
if( f != m_linkedItems.end() )
|
||||
m_linkedItems.erase( f );
|
||||
|
@ -133,15 +129,17 @@ public:
|
|||
|
||||
PNS_VIA* Via()
|
||||
{
|
||||
for( LinkedItems::iterator i = m_linkedItems.begin();
|
||||
i != m_linkedItems.end(); ++i )
|
||||
for( LINKED_ITEMS::iterator i = m_linkedItems.begin(); i != m_linkedItems.end(); ++i )
|
||||
{
|
||||
if( (*i)->Kind() == PNS_ITEM::VIA )
|
||||
return (PNS_VIA*)( *i );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// trivial accessors
|
||||
const HashTag& Tag() const
|
||||
const HASH_TAG& Tag() const
|
||||
{
|
||||
return m_tag;
|
||||
}
|
||||
|
@ -156,7 +154,7 @@ public:
|
|||
return m_tag.net;
|
||||
}
|
||||
|
||||
LinkedItems& LinkList()
|
||||
LINKED_ITEMS& LinkList()
|
||||
{
|
||||
return m_linkedItems;
|
||||
}
|
||||
|
@ -166,10 +164,12 @@ public:
|
|||
{
|
||||
int n = 0;
|
||||
|
||||
for( LinkedItems::const_iterator i = m_linkedItems.begin();
|
||||
for( LINKED_ITEMS::const_iterator i = m_linkedItems.begin();
|
||||
i != m_linkedItems.end(); ++i )
|
||||
{
|
||||
if( (*i)->Kind() & aMask )
|
||||
n++;
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
@ -189,10 +189,12 @@ public:
|
|||
m_layers.Merge( aJoint.m_layers );
|
||||
|
||||
// fixme: duplicate links (?)
|
||||
for( LinkedItems::const_iterator i = aJoint.m_linkedItems.begin();
|
||||
for( LINKED_ITEMS::const_iterator i = aJoint.m_linkedItems.begin();
|
||||
i != aJoint.m_linkedItems.end(); ++i )
|
||||
{
|
||||
m_linkedItems.push_back( *i );
|
||||
}
|
||||
}
|
||||
|
||||
bool Overlaps( const PNS_JOINT& rhs ) const
|
||||
{
|
||||
|
@ -202,27 +204,27 @@ public:
|
|||
|
||||
private:
|
||||
///> hash tag for unordered_multimap
|
||||
HashTag m_tag;
|
||||
HASH_TAG m_tag;
|
||||
|
||||
///> list of items linked to this joint
|
||||
LinkedItems m_linkedItems;
|
||||
LINKED_ITEMS m_linkedItems;
|
||||
};
|
||||
|
||||
|
||||
// hash function & comparison operator for boost::unordered_map<>
|
||||
inline bool operator==( PNS_JOINT::HashTag const& p1,
|
||||
PNS_JOINT::HashTag const& p2 )
|
||||
inline bool operator==( PNS_JOINT::HASH_TAG const& aP1,
|
||||
PNS_JOINT::HASH_TAG const& aP2 )
|
||||
{
|
||||
return p1.pos == p2.pos && p1.net == p2.net;
|
||||
return aP1.pos == aP2.pos && aP1.net == aP2.net;
|
||||
}
|
||||
|
||||
|
||||
inline std::size_t hash_value( PNS_JOINT::HashTag const& p )
|
||||
inline std::size_t hash_value( PNS_JOINT::HASH_TAG const& aP )
|
||||
{
|
||||
std::size_t seed = 0;
|
||||
boost::hash_combine( seed, p.pos.x );
|
||||
boost::hash_combine( seed, p.pos.y );
|
||||
boost::hash_combine( seed, p.net );
|
||||
boost::hash_combine( seed, aP.pos.x );
|
||||
boost::hash_combine( seed, aP.pos.y );
|
||||
boost::hash_combine( seed, aP.net );
|
||||
|
||||
return seed;
|
||||
}
|
||||
|
|
|
@ -50,17 +50,17 @@ public:
|
|||
m_start = m_end = aLayer;
|
||||
}
|
||||
|
||||
PNS_LAYERSET( const PNS_LAYERSET& b ) :
|
||||
m_start( b.m_start ),
|
||||
m_end( b.m_end )
|
||||
PNS_LAYERSET( const PNS_LAYERSET& aB ) :
|
||||
m_start( aB.m_start ),
|
||||
m_end( aB.m_end )
|
||||
{}
|
||||
|
||||
~PNS_LAYERSET() {};
|
||||
|
||||
const PNS_LAYERSET& operator=( const PNS_LAYERSET& b )
|
||||
const PNS_LAYERSET& operator=( const PNS_LAYERSET& aB )
|
||||
{
|
||||
m_start = b.m_start;
|
||||
m_end = b.m_end;
|
||||
m_start = aB.m_start;
|
||||
m_end = aB.m_end;
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -50,11 +50,12 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
|
|||
copyLinks ( &aOther );
|
||||
}
|
||||
|
||||
|
||||
PNS_LINE::~PNS_LINE()
|
||||
{
|
||||
if( m_segmentRefs )
|
||||
delete m_segmentRefs;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
const PNS_LINE& PNS_LINE::operator=( const PNS_LINE& aOther )
|
||||
|
@ -75,12 +76,15 @@ const PNS_LINE& PNS_LINE :: operator= (const PNS_LINE& aOther)
|
|||
return *this;
|
||||
}
|
||||
|
||||
|
||||
PNS_LINE* PNS_LINE::Clone() const
|
||||
{
|
||||
PNS_LINE* l = new PNS_LINE( *this );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::Mark( int aMarker )
|
||||
{
|
||||
m_marker = aMarker;
|
||||
|
@ -92,6 +96,7 @@ void PNS_LINE::Mark(int aMarker)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::Unmark ()
|
||||
{
|
||||
if( m_segmentRefs )
|
||||
|
@ -99,20 +104,25 @@ void PNS_LINE::Unmark ()
|
|||
BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
|
||||
s->Unmark();
|
||||
}
|
||||
|
||||
m_marker = 0;
|
||||
}
|
||||
|
||||
|
||||
int PNS_LINE::Marker()const
|
||||
{
|
||||
int marker = m_marker;
|
||||
|
||||
if( m_segmentRefs )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
|
||||
marker |= s->Marker();
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::copyLinks( const PNS_LINE *aParent )
|
||||
{
|
||||
if( aParent->m_segmentRefs == NULL )
|
||||
|
@ -121,7 +131,7 @@ void PNS_LINE::copyLinks( const PNS_LINE *aParent )
|
|||
return;
|
||||
}
|
||||
|
||||
m_segmentRefs = new SegmentRefs();
|
||||
m_segmentRefs = new SEGMENT_REFS();
|
||||
*m_segmentRefs = *aParent->m_segmentRefs;
|
||||
}
|
||||
|
||||
|
@ -140,6 +150,7 @@ PNS_SEGMENT* PNS_SEGMENT::Clone( ) const
|
|||
return s;
|
||||
}
|
||||
|
||||
|
||||
int PNS_LINE::CountCorners( int aAngles )
|
||||
{
|
||||
int count = 0;
|
||||
|
@ -161,6 +172,7 @@ int PNS_LINE::CountCorners( int aAngles )
|
|||
return count;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
|
||||
SHAPE_LINE_CHAIN& aWalk, SHAPE_LINE_CHAIN& aPost, bool aCw ) const
|
||||
{
|
||||
|
@ -171,8 +183,7 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
|
|||
if( line.SegmentCount() < 1 )
|
||||
return false;
|
||||
|
||||
if( aObstacle.PointInside( line.CPoint( 0 ) ) ||
|
||||
aObstacle.PointInside( line.CPoint( -1 ) ) )
|
||||
if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) )
|
||||
return false;
|
||||
|
||||
SHAPE_LINE_CHAIN::INTERSECTIONS ips, ips2;
|
||||
|
@ -249,9 +260,11 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
|
|||
aPost.Append( farthest.p );
|
||||
aPost.Append( line.Slice( farthest.our.Index() + 1, -1 ) );
|
||||
aPost.Simplify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
|
||||
SHAPE_LINE_CHAIN& aPath,
|
||||
bool aCw ) const
|
||||
|
@ -298,12 +311,12 @@ const PNS_LINE PNS_LINE::ClipToNearestObstacle( PNS_NODE* aNode ) const
|
|||
{
|
||||
PNS_LINE l( *this );
|
||||
|
||||
PNS_NODE::OptObstacle obs = aNode->NearestObstacle( &l );
|
||||
PNS_NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
|
||||
|
||||
if( obs )
|
||||
{
|
||||
l.RemoveVia();
|
||||
int p = l.Line().Split( obs->ip_first );
|
||||
int p = l.Line().Split( obs->m_ipFirst );
|
||||
l.Line().Remove( p + 1, -1 );
|
||||
}
|
||||
|
||||
|
@ -325,24 +338,23 @@ void PNS_LINE::ShowLinks()
|
|||
printf( "seg %d: %p\n", i, (*m_segmentRefs)[i] );
|
||||
}
|
||||
|
||||
SHAPE_LINE_CHAIN dragCornerInternal ( const SHAPE_LINE_CHAIN& origin, const VECTOR2I& aP )
|
||||
SHAPE_LINE_CHAIN dragCornerInternal( const SHAPE_LINE_CHAIN& aOrigin, const VECTOR2I& aP )
|
||||
{
|
||||
optional<SHAPE_LINE_CHAIN> picked;
|
||||
int i;
|
||||
|
||||
int d = 2;
|
||||
|
||||
if(origin.CSegment(-1).Length() > 100000 * 30) // fixme: constant/parameter?
|
||||
if( aOrigin.CSegment( -1 ).Length() > 100000 * 30 ) // fixme: constant/parameter?
|
||||
d = 1;
|
||||
|
||||
for(i = origin.SegmentCount() - d; i >= 0; i--)
|
||||
for( i = aOrigin.SegmentCount() - d; i >= 0; i-- )
|
||||
{
|
||||
|
||||
DIRECTION_45 d_start (origin.CSegment(i));
|
||||
VECTOR2I p_start = origin.CPoint(i);
|
||||
DIRECTION_45 d_start ( aOrigin.CSegment( i ) );
|
||||
VECTOR2I p_start = aOrigin.CPoint( i );
|
||||
SHAPE_LINE_CHAIN paths[2];
|
||||
DIRECTION_45 dirs[2];
|
||||
DIRECTION_45 d_prev = (i > 0 ? DIRECTION_45(origin.CSegment(i-1)) : DIRECTION_45());
|
||||
DIRECTION_45 d_prev = ( i > 0 ? DIRECTION_45( aOrigin.CSegment( i - 1 ) ) : DIRECTION_45() );
|
||||
|
||||
for( int j = 0; j < 2; j++ )
|
||||
{
|
||||
|
@ -350,40 +362,43 @@ SHAPE_LINE_CHAIN dragCornerInternal ( const SHAPE_LINE_CHAIN& origin, const VECT
|
|||
dirs[j] = DIRECTION_45( paths[j].CSegment( 0 ) );
|
||||
}
|
||||
|
||||
|
||||
for( int j = 0; j < 2; j++ )
|
||||
{
|
||||
if( dirs[j] == d_start )
|
||||
{
|
||||
picked = paths[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( picked )
|
||||
break;
|
||||
|
||||
for( int j = 0; j < 2; j++ )
|
||||
{
|
||||
if( dirs[j].IsObtuse( d_prev ) )
|
||||
{
|
||||
picked = paths[j];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( picked )
|
||||
break;
|
||||
}
|
||||
|
||||
if( picked )
|
||||
{
|
||||
SHAPE_LINE_CHAIN path = origin.Slice(0, i);
|
||||
SHAPE_LINE_CHAIN path = aOrigin.Slice( 0, i );
|
||||
path.Append( *picked );
|
||||
|
||||
return path;
|
||||
|
||||
}
|
||||
|
||||
return DIRECTION_45().BuildInitialTrace(origin.CPoint(0), aP, true);
|
||||
return DIRECTION_45().BuildInitialTrace( aOrigin.CPoint( 0 ), aP, true );
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PNS_LINE::DragCorner ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
|
||||
{
|
||||
SHAPE_LINE_CHAIN path;
|
||||
|
@ -394,17 +409,22 @@ void PNS_LINE::DragCorner ( const VECTOR2I& aP, int aIndex, int aSnappingThresho
|
|||
path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
|
||||
else if ( aIndex == m_line.SegmentCount() )
|
||||
path = dragCornerInternal( m_line, snapped );
|
||||
else {
|
||||
else
|
||||
{
|
||||
// fixme: awkward behaviour for "outwards" drags
|
||||
path = dragCornerInternal( m_line.Slice( 0, aIndex ), snapped );
|
||||
SHAPE_LINE_CHAIN path_rev = dragCornerInternal( m_line.Slice (aIndex, -1).Reverse(), snapped ).Reverse();
|
||||
SHAPE_LINE_CHAIN path_rev = dragCornerInternal( m_line.Slice( aIndex, -1 ).Reverse(),
|
||||
snapped ).Reverse();
|
||||
path.Append( path_rev );
|
||||
}
|
||||
|
||||
path.Simplify();
|
||||
m_line = path;
|
||||
}
|
||||
|
||||
VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, int aIndex, int aThreshold ) const
|
||||
|
||||
VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I& aP,
|
||||
int aIndex, int aThreshold ) const
|
||||
{
|
||||
int s_start = std::max( aIndex - 2, 0 );
|
||||
int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
|
||||
|
@ -432,6 +452,7 @@ VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTO
|
|||
if( ip )
|
||||
{
|
||||
int dist = ( *ip - aP ).EuclideanNorm();
|
||||
|
||||
if( dist < aThreshold && dist < best_dist )
|
||||
{
|
||||
best_dist = dist;
|
||||
|
@ -444,7 +465,8 @@ VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTO
|
|||
return best_snap;
|
||||
}
|
||||
|
||||
VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, int aIndex, int aThreshold ) const
|
||||
VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
||||
int aIndex, int aThreshold ) const
|
||||
{
|
||||
VECTOR2I snap_p[2];
|
||||
DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
|
||||
|
@ -456,16 +478,20 @@ VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const
|
|||
if( aIndex >= 2 )
|
||||
{
|
||||
SEG s = aPath.CSegment( aIndex - 2 );
|
||||
|
||||
if( DIRECTION_45( s ) == dragDir )
|
||||
snap_d[0] = s.LineDistance( aP );
|
||||
|
||||
snap_p[0] = s.A;
|
||||
}
|
||||
|
||||
if( aIndex < aPath.SegmentCount() - 2 )
|
||||
{
|
||||
SEG s = aPath.CSegment( aIndex + 2 );
|
||||
|
||||
if( DIRECTION_45( s ) == dragDir )
|
||||
snap_d[1] = s.LineDistance(aP);
|
||||
|
||||
snap_p[1] = s.A;
|
||||
}
|
||||
|
||||
|
@ -473,11 +499,13 @@ VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const
|
|||
int minDist = INT_MAX;
|
||||
|
||||
for( int i = 0; i < 2; i++ )
|
||||
{
|
||||
if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= aThreshold )
|
||||
{
|
||||
minDist = snap_d[i];
|
||||
best = snap_p[i];
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
@ -526,7 +554,6 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
path.Insert( index + 1, path.CPoint( index + 1 ) );
|
||||
}
|
||||
|
||||
|
||||
s_prev = path.CSegment( index - 1 );
|
||||
s_next = path.CSegment( index + 1 );
|
||||
dragged = path.CSegment( index );
|
||||
|
@ -538,16 +565,20 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
{
|
||||
if( !lockEndpointA )
|
||||
guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Right().Right().ToVector() );
|
||||
else {
|
||||
else
|
||||
{
|
||||
guideA[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
|
||||
guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dir_prev.IsObtuse(drag_dir ) )
|
||||
{
|
||||
guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() );
|
||||
guideA[1] = SEG( s_prev.A, s_prev.A + drag_dir.Right().ToVector() );
|
||||
} else
|
||||
}
|
||||
else
|
||||
guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
|
||||
}
|
||||
|
||||
|
@ -555,16 +586,20 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
{
|
||||
if( !lockEndpointB )
|
||||
guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Right().Right().ToVector() );
|
||||
else {
|
||||
else
|
||||
{
|
||||
guideB[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
|
||||
guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
if( dir_next.IsObtuse( drag_dir ) )
|
||||
{
|
||||
guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() );
|
||||
guideB[1] = SEG( s_next.B, s_next.B + drag_dir.Right().ToVector() );
|
||||
} else
|
||||
}
|
||||
else
|
||||
guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
|
||||
}
|
||||
|
||||
|
@ -596,17 +631,21 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
np.Append ( s1.A );
|
||||
np.Append ( *ip );
|
||||
np.Append ( s_next.B );
|
||||
} else if(ip = s3.Intersect(s_prev))
|
||||
}
|
||||
else if( ip = s3.Intersect( s_prev ) )
|
||||
{
|
||||
np.Append ( s_prev.A );
|
||||
np.Append ( *ip );
|
||||
np.Append ( s3.B );
|
||||
} else if(ip = s1.Intersect(s3))
|
||||
}
|
||||
else if( ip = s1.Intersect( s3 ) )
|
||||
{
|
||||
np.Append( s_prev.A );
|
||||
np.Append( *ip );
|
||||
np.Append( s_next.B );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
np.Append( s_prev.A );
|
||||
np.Append( *ip1 );
|
||||
np.Append( *ip2 );
|
||||
|
@ -618,7 +657,6 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
best_len = np.Length();
|
||||
best = np;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,7 +665,6 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
|
|||
if( !lockEndpointB && aIndex == m_line.SegmentCount() - 1 )
|
||||
best.Remove( -1, -1 );
|
||||
|
||||
|
||||
if( m_line.PointCount() == 1 )
|
||||
m_line = best;
|
||||
else if( aIndex == 0 )
|
||||
|
@ -646,18 +683,20 @@ bool PNS_LINE::CompareGeometry( const PNS_LINE& aOther )
|
|||
return m_line.CompareGeometry( aOther.m_line );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::Reverse()
|
||||
{
|
||||
m_line = m_line.Reverse();
|
||||
|
||||
if( m_segmentRefs )
|
||||
std::reverse( m_segmentRefs->begin(), m_segmentRefs->end() );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::AppendVia( const PNS_VIA& aVia )
|
||||
{
|
||||
if( aVia.Pos() == m_line.CPoint( 0 ) )
|
||||
{
|
||||
|
||||
Reverse();
|
||||
}
|
||||
|
||||
|
@ -666,9 +705,11 @@ void PNS_LINE::AppendVia(const PNS_VIA& aVia)
|
|||
m_via.SetNet( m_net );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::SetRank( int aRank )
|
||||
{
|
||||
m_rank = aRank;
|
||||
|
||||
if( m_segmentRefs )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
|
||||
|
@ -676,52 +717,61 @@ void PNS_LINE::SetRank(int aRank)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int PNS_LINE::Rank() const
|
||||
{
|
||||
int min_rank = INT_MAX;
|
||||
int rank;
|
||||
|
||||
if( m_segmentRefs )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs )
|
||||
min_rank = std::min( min_rank, s->Rank() );
|
||||
rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
rank = m_rank;
|
||||
}
|
||||
|
||||
return rank;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::ClipVertexRange( int aStart, int aEnd )
|
||||
{
|
||||
m_line = m_line.Slice( aStart, aEnd );
|
||||
|
||||
if( m_segmentRefs )
|
||||
{
|
||||
SegmentRefs *snew = new SegmentRefs( m_segmentRefs->begin() + aStart, m_segmentRefs->begin() + aEnd );
|
||||
SEGMENT_REFS* snew = new SEGMENT_REFS( m_segmentRefs->begin() + aStart,
|
||||
m_segmentRefs->begin() + aEnd );
|
||||
|
||||
delete m_segmentRefs;
|
||||
m_segmentRefs = snew;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE::HasLoops() const
|
||||
{
|
||||
|
||||
for( int i = 0; i < PointCount(); i++ )
|
||||
{
|
||||
for( int j = 0; j < PointCount(); j++ )
|
||||
{
|
||||
if( ( std::abs( i - j ) > 1 ) && CPoint( i ) == CPoint( j ) )
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE::ClearSegmentLinks()
|
||||
{
|
||||
if( m_segmentRefs )
|
||||
delete m_segmentRefs;
|
||||
|
||||
m_segmentRefs = NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class PNS_VIA;
|
|||
class PNS_LINE : public PNS_ITEM
|
||||
{
|
||||
public:
|
||||
typedef std::vector<PNS_SEGMENT*> SegmentRefs;
|
||||
typedef std::vector<PNS_SEGMENT*> SEGMENT_REFS;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
|
@ -69,7 +69,6 @@ public:
|
|||
m_hasVia = false;
|
||||
}
|
||||
|
||||
|
||||
PNS_LINE( const PNS_LINE& aOther ) ;
|
||||
|
||||
/**
|
||||
|
@ -77,7 +76,6 @@ public:
|
|||
* Copies properties (net, layers, etc.) from a base line and replaces the shape
|
||||
* by another
|
||||
**/
|
||||
|
||||
PNS_LINE( const PNS_LINE& aBase, const SHAPE_LINE_CHAIN& aLine ) :
|
||||
PNS_ITEM( aBase ),
|
||||
m_line( aLine ),
|
||||
|
@ -169,14 +167,14 @@ public:
|
|||
void LinkSegment( PNS_SEGMENT* aSeg )
|
||||
{
|
||||
if( !m_segmentRefs )
|
||||
m_segmentRefs = new SegmentRefs();
|
||||
m_segmentRefs = new SEGMENT_REFS();
|
||||
|
||||
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)
|
||||
SegmentRefs* LinkedSegments()
|
||||
SEGMENT_REFS* LinkedSegments()
|
||||
{
|
||||
return m_segmentRefs;
|
||||
}
|
||||
|
@ -195,9 +193,11 @@ public:
|
|||
void ClearSegmentLinks();
|
||||
|
||||
///> Returns the number of segments that were assembled together to form this line.
|
||||
int LinkCount() const {
|
||||
int LinkCount() const
|
||||
{
|
||||
if( !m_segmentRefs )
|
||||
return -1;
|
||||
|
||||
return m_segmentRefs->size();
|
||||
}
|
||||
|
||||
|
@ -208,7 +208,6 @@ public:
|
|||
///> Clips the line to a given range of vertices.
|
||||
void ClipVertexRange ( int aStart, int aEnd );
|
||||
|
||||
|
||||
///> Returns the number of corners of angles specified by mask aAngles.
|
||||
int CountCorners( int aAngles );
|
||||
|
||||
|
@ -218,12 +217,11 @@ public:
|
|||
///> aWalkaroundPath = path around the obstacle
|
||||
///> aPostPath = past from obstacle till the end
|
||||
///> aCW = whether to walk around in clockwise or counter-clockwise direction.
|
||||
|
||||
bool Walkaround( SHAPE_LINE_CHAIN obstacle,
|
||||
SHAPE_LINE_CHAIN& pre,
|
||||
SHAPE_LINE_CHAIN& walk,
|
||||
SHAPE_LINE_CHAIN& post,
|
||||
bool cw ) const;
|
||||
bool Walkaround( SHAPE_LINE_CHAIN aObstacle,
|
||||
SHAPE_LINE_CHAIN& aPre,
|
||||
SHAPE_LINE_CHAIN& aWalk,
|
||||
SHAPE_LINE_CHAIN& aPost,
|
||||
bool aCw ) const;
|
||||
|
||||
void Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
|
||||
SHAPE_LINE_CHAIN& aPath,
|
||||
|
@ -254,16 +252,18 @@ public:
|
|||
bool HasLoops() const;
|
||||
|
||||
private:
|
||||
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
||||
int aIndex, int aThreshold) const;
|
||||
|
||||
VECTOR2I snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, int aIndex, int aThreshold) const;
|
||||
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, int aIndex, int aThreshold ) const;
|
||||
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP,
|
||||
int aIndex, int aThreshold ) const;
|
||||
|
||||
///> Copies m_segmentRefs from the line aParent.
|
||||
void copyLinks( const PNS_LINE* aParent ) ;
|
||||
|
||||
///> List of segments in the owning PNS_NODE (PNS_ITEM::m_owner) that constitute this line, or NULL
|
||||
///> if the line is not a part of any node.
|
||||
SegmentRefs* m_segmentRefs;
|
||||
SEGMENT_REFS* m_segmentRefs;
|
||||
|
||||
///> The actual shape of the line
|
||||
SHAPE_LINE_CHAIN m_line;
|
||||
|
|
|
@ -44,7 +44,8 @@ PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
|
|||
m_world = NULL;
|
||||
m_shove = NULL;
|
||||
m_currentNode = NULL;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PNS_LINE_PLACER::~PNS_LINE_PLACER()
|
||||
{
|
||||
|
@ -52,11 +53,13 @@ PNS_LINE_PLACER::~PNS_LINE_PLACER()
|
|||
delete m_shove;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::setWorld ( PNS_NODE* aWorld )
|
||||
{
|
||||
m_world = aWorld;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill )
|
||||
{
|
||||
m_viaDiameter = aDiameter;
|
||||
|
@ -64,10 +67,9 @@ void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill )
|
|||
m_placingVia = aEnabled;
|
||||
}
|
||||
|
||||
void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet,
|
||||
int aWidth, int aLayer )
|
||||
{
|
||||
|
||||
void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet, int aWidth, int aLayer )
|
||||
{
|
||||
assert( m_world != NULL );
|
||||
|
||||
m_direction = m_initial_direction;
|
||||
|
@ -154,6 +156,7 @@ bool PNS_LINE_PLACER::handleSelfIntersections()
|
|||
m_direction = m_initial_direction;
|
||||
tail.Clear();
|
||||
head.Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -294,10 +297,10 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
|
|||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::checkObtusity( const SEG& a, const SEG& b ) const
|
||||
bool PNS_LINE_PLACER::checkObtusity( const SEG& aA, const SEG& aB ) const
|
||||
{
|
||||
const DIRECTION_45 dir_a( a );
|
||||
const DIRECTION_45 dir_b( b );
|
||||
const DIRECTION_45 dir_a( aA );
|
||||
const DIRECTION_45 dir_b( aB );
|
||||
|
||||
return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
|
||||
}
|
||||
|
@ -399,6 +402,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||
{
|
||||
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP );
|
||||
|
@ -412,18 +416,20 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
walkaround.SetSolidsOnly( false );
|
||||
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() );
|
||||
|
||||
PNS_WALKAROUND::WalkaroundStatus wf = walkaround.Route( initTrack, walkFull, false );
|
||||
PNS_WALKAROUND::WALKAROUND_STATUS wf = walkaround.Route( initTrack, walkFull, false );
|
||||
|
||||
switch( Settings().OptimizerEffort() )
|
||||
{
|
||||
case OE_Low:
|
||||
case OE_LOW:
|
||||
effort = 0;
|
||||
break;
|
||||
case OE_Medium:
|
||||
case OE_Full:
|
||||
|
||||
case OE_MEDIUM:
|
||||
case OE_FULL:
|
||||
effort = PNS_OPTIMIZER::MERGE_SEGMENTS;
|
||||
break;
|
||||
}
|
||||
|
||||
if( Settings().SmartPads() )
|
||||
effort |= PNS_OPTIMIZER::SMART_PADS;
|
||||
|
||||
|
@ -431,8 +437,9 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
{
|
||||
walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
|
||||
rv = true;
|
||||
|
||||
} else if( m_placingVia && viaOk ) {
|
||||
}
|
||||
else if( m_placingVia && viaOk )
|
||||
{
|
||||
PNS_LAYERSET allLayers( 0, 15 );
|
||||
PNS_VIA v1( walkFull.CPoint( -1 ), allLayers, m_viaDiameter );
|
||||
walkFull.AppendVia( v1 );
|
||||
|
@ -451,6 +458,7 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||
{
|
||||
m_head.SetShape( m_direction.BuildInitialTrace( m_p_start, aP ) );
|
||||
|
@ -467,6 +475,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
return m_currentNode->CheckColliding( &m_head );
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||
{
|
||||
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP );
|
||||
|
@ -482,7 +491,7 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
|
||||
walkaround.SetSolidsOnly( true );
|
||||
walkaround.SetIterationLimit( 10 );
|
||||
PNS_WALKAROUND::WalkaroundStatus stat_solids = walkaround.Route( initTrack, walkSolids );
|
||||
PNS_WALKAROUND::WALKAROUND_STATUS stat_solids = walkaround.Route( initTrack, walkSolids );
|
||||
|
||||
optimizer.SetEffortLevel( PNS_OPTIMIZER::MERGE_SEGMENTS );
|
||||
optimizer.SetCollisionMask ( PNS_ITEM::SOLID );
|
||||
|
@ -519,7 +528,7 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
return false;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus status = m_shove->ShoveLines( l );
|
||||
PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
|
||||
|
||||
m_currentNode = m_shove->CurrentNode();
|
||||
|
||||
|
@ -546,10 +555,10 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
||||
{
|
||||
switch( m_currentMode )
|
||||
|
@ -570,7 +579,6 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
|
|||
|
||||
bool PNS_LINE_PLACER::optimizeTailHeadTransition()
|
||||
{
|
||||
|
||||
PNS_LINE tmp = Trace();
|
||||
|
||||
if( PNS_OPTIMIZER::Optimize( &tmp, PNS_OPTIMIZER::FANOUT_CLEANUP, m_currentNode ) )
|
||||
|
@ -582,6 +590,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition()
|
|||
m_p_start = tmp.CLine().CPoint( 0 );
|
||||
m_direction = DIRECTION_45( tmp.CSegment( 0 ) );
|
||||
m_tail.Line().Clear();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -702,22 +711,26 @@ const PNS_LINE PNS_LINE_PLACER::Trace() const
|
|||
return tmp;
|
||||
}
|
||||
|
||||
|
||||
const PNS_ITEMSET PNS_LINE_PLACER::Traces()
|
||||
{
|
||||
m_currentTrace = Trace();
|
||||
return PNS_ITEMSET( &m_currentTrace );
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::FlipPosture()
|
||||
{
|
||||
m_initial_direction = m_initial_direction.Right();
|
||||
m_direction = m_direction.Right();
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE* PNS_LINE_PLACER::CurrentNode( bool aLoopsRemoved ) const
|
||||
{
|
||||
if( aLoopsRemoved && m_lastNode )
|
||||
return m_lastNode;
|
||||
|
||||
return m_currentNode;
|
||||
}
|
||||
|
||||
|
@ -747,16 +760,19 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::SetLayer(int aLayer)
|
||||
{
|
||||
m_currentLayer = aLayer;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::SetWidth(int aWidth)
|
||||
{
|
||||
m_currentWidth = aWidth;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
VECTOR2I p( aP );
|
||||
|
@ -783,7 +799,6 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
m_currentEnd = p;
|
||||
m_currentNet = net;
|
||||
|
||||
|
||||
PNS_NODE *rootNode = Router()->GetWorld()->Branch();
|
||||
|
||||
if( splitSeg )
|
||||
|
@ -819,14 +834,14 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
else
|
||||
m_currentEnd = current.CLine().CPoint(-1);
|
||||
|
||||
|
||||
PNS_NODE *latestNode = m_currentNode;
|
||||
m_lastNode = latestNode->Branch();
|
||||
|
||||
|
||||
if(eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() && current.CPoint(-1) == aP)
|
||||
if( eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth &&
|
||||
current.SegmentCount() && current.CPoint( -1 ) == aP )
|
||||
{
|
||||
splitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
|
||||
|
||||
if( Settings().RemoveLoops() )
|
||||
removeLoops( m_lastNode, ¤t );
|
||||
}
|
||||
|
@ -834,6 +849,7 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
updateLeadingRatLine();
|
||||
}
|
||||
|
||||
|
||||
bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
bool realEnd = false;
|
||||
|
@ -861,13 +877,11 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
|
||||
realEnd = true;
|
||||
|
||||
|
||||
if( realEnd || m_placingVia )
|
||||
lastV = l.SegmentCount();
|
||||
else
|
||||
lastV = std::max( 1, l.SegmentCount() - 1 );
|
||||
|
||||
|
||||
PNS_SEGMENT* lastSeg = NULL;
|
||||
|
||||
for( int i = 0; i < lastV; i++ )
|
||||
|
@ -908,6 +922,7 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
return realEnd;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
|
||||
{
|
||||
if( !aLatest->SegmentCount() )
|
||||
|
@ -918,10 +933,8 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
|
|||
for( int s = 0; s < aLatest->SegmentCount(); s++ )
|
||||
{
|
||||
PNS_SEGMENT *seg = ( *aLatest->LinkedSegments() )[s];
|
||||
|
||||
PNS_LINE* ourLine = aNode->AssembleLine( seg );
|
||||
PNS_JOINT a, b;
|
||||
|
||||
std::vector<PNS_LINE*> lines;
|
||||
|
||||
aNode->FindLineEnds( ourLine, a, b );
|
||||
|
@ -960,10 +973,12 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* 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() );
|
||||
|
||||
simplified.Simplify();
|
||||
|
||||
if( simplified.PointCount() != l->PointCount() )
|
||||
|
@ -975,6 +990,7 @@ void PNS_LINE_PLACER::simplifyNewLine ( PNS_NODE *aNode, PNS_SEGMENT *aLatest )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings )
|
||||
{
|
||||
int trackWidth = aSettings.GetTrackWidth();
|
||||
|
@ -986,6 +1002,7 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings )
|
|||
m_viaDrill = aSettings.GetViaDrill();
|
||||
}
|
||||
|
||||
|
||||
void PNS_LINE_PLACER::updateLeadingRatLine()
|
||||
{
|
||||
PNS_LINE current = Trace();
|
||||
|
@ -996,7 +1013,8 @@ void PNS_LINE_PLACER::updateLeadingRatLine()
|
|||
std::auto_ptr<PNS_NODE> tmpNode ( m_lastNode->Branch() );
|
||||
tmpNode->Add( ¤t );
|
||||
|
||||
PNS_JOINT *jt = tmpNode->FindJoint( current.CPoint(-1), current.Layers().Start(), current.Net() );
|
||||
PNS_JOINT *jt = tmpNode->FindJoint( current.CPoint( -1 ),
|
||||
current.Layers().Start(), current.Net() );
|
||||
|
||||
if( !jt )
|
||||
return;
|
||||
|
|
|
@ -185,7 +185,6 @@ public:
|
|||
*/
|
||||
void UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings );
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
* Function route()
|
||||
|
@ -197,7 +196,6 @@ private:
|
|||
* @param aP ending point of current route.
|
||||
* @return true, if the routing is complete.
|
||||
*/
|
||||
|
||||
bool route( const VECTOR2I& aP );
|
||||
|
||||
/**
|
||||
|
@ -268,9 +266,9 @@ private:
|
|||
*
|
||||
* Helper function, checking if segments a and b form an obtuse angle
|
||||
* (in 45-degree regime).
|
||||
* @return true, if angle (a, b) is obtuse
|
||||
* @return true, if angle (aA, aB) is obtuse
|
||||
*/
|
||||
bool checkObtusity( const SEG& a, const SEG& b ) const;
|
||||
bool checkObtusity( const SEG& aA, const SEG& aB ) const;
|
||||
|
||||
/**
|
||||
* Function handleSelfIntersections()
|
||||
|
@ -339,16 +337,15 @@ private:
|
|||
*/
|
||||
void routeStep( const VECTOR2I& aP );
|
||||
|
||||
///< route step, walkaround mode
|
||||
///> route step, walkaround mode
|
||||
bool rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead);
|
||||
|
||||
///< route step, shove mode
|
||||
///> route step, shove mode
|
||||
bool rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead);
|
||||
|
||||
///< route step, mark obstacles mode
|
||||
///> route step, mark obstacles mode
|
||||
bool rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead );
|
||||
|
||||
|
||||
///> current routing direction
|
||||
DIRECTION_45 m_direction;
|
||||
|
||||
|
@ -399,7 +396,6 @@ private:
|
|||
PNS_LINE m_currentTrace;
|
||||
|
||||
PNS_MODE m_currentMode;
|
||||
|
||||
};
|
||||
|
||||
#endif // __PNS_LINE_PLACER_H
|
||||
|
|
|
@ -38,23 +38,26 @@ PNS_LOGGER::PNS_LOGGER( )
|
|||
|
||||
PNS_LOGGER::~PNS_LOGGER()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::Clear()
|
||||
{
|
||||
m_theLog.str( std::string() );
|
||||
m_groupOpened = false;
|
||||
}
|
||||
|
||||
void PNS_LOGGER::NewGroup ( const std::string& name, int iter)
|
||||
|
||||
void PNS_LOGGER::NewGroup( const std::string& aName, int aIter )
|
||||
{
|
||||
if( m_groupOpened )
|
||||
m_theLog << "endgroup" << std::endl;
|
||||
m_theLog << "group " << name << " " << iter << std::endl;
|
||||
|
||||
m_theLog << "group " << aName << " " << aIter << std::endl;
|
||||
m_groupOpened = true;
|
||||
}
|
||||
|
||||
|
||||
void PNS_LOGGER::EndGroup()
|
||||
{
|
||||
if( !m_groupOpened )
|
||||
|
@ -64,41 +67,45 @@ void PNS_LOGGER::EndGroup()
|
|||
m_theLog << "endgroup" << std::endl;
|
||||
}
|
||||
|
||||
void PNS_LOGGER::Log ( const PNS_ITEM *item, int kind, const std::string name )
|
||||
{
|
||||
m_theLog << "item " << kind << " " << name << " ";
|
||||
m_theLog << item->Net() << " " << item->Layers().Start() << " " << item->Layers().End() << " " << item->Marker() << " " << item->Rank();
|
||||
|
||||
switch(item->Kind())
|
||||
void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
|
||||
{
|
||||
m_theLog << "aItem " << aKind << " " << aName << " ";
|
||||
m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
|
||||
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
|
||||
|
||||
switch( aItem->Kind() )
|
||||
{
|
||||
case PNS_ITEM::LINE:
|
||||
{
|
||||
PNS_LINE *l = (PNS_LINE *) item;
|
||||
PNS_LINE* l = (PNS_LINE*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
|
||||
dumpShape ( l->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::VIA:
|
||||
{
|
||||
m_theLog << " via 0 0 ";
|
||||
dumpShape ( item->Shape() );
|
||||
dumpShape ( aItem->Shape() );
|
||||
m_theLog << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::SEGMENT:
|
||||
{
|
||||
PNS_SEGMENT *s =(PNS_SEGMENT *) item;
|
||||
PNS_SEGMENT* s =(PNS_SEGMENT*) aItem;
|
||||
m_theLog << " line ";
|
||||
m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
|
||||
m_theLog << s->Width() << " 0 linechain 2 0 " << s->Seg().A.x << " " <<
|
||||
s->Seg().A.y << " " << s->Seg().B.x << " " <<s->Seg().B.y << std::endl;
|
||||
break;
|
||||
}
|
||||
|
||||
case PNS_ITEM::SOLID:
|
||||
{
|
||||
PNS_SOLID *s = (PNS_SOLID*) item;
|
||||
PNS_SOLID* s = (PNS_SOLID*) aItem;
|
||||
m_theLog << " solid 0 0 ";
|
||||
dumpShape( s->Shape() );
|
||||
m_theLog << std::endl;
|
||||
|
@ -110,63 +117,73 @@ void PNS_LOGGER::Log ( const PNS_ITEM *item, int kind, const std::string name )
|
|||
}
|
||||
}
|
||||
|
||||
void PNS_LOGGER::Log ( const SHAPE_LINE_CHAIN *l, int kind, const std::string name )
|
||||
|
||||
void PNS_LOGGER::Log( const SHAPE_LINE_CHAIN *aL, int aKind, const std::string aName )
|
||||
{
|
||||
m_theLog << "item " << kind << " " << name << " ";
|
||||
m_theLog << "item " << aKind << " " << aName << " ";
|
||||
m_theLog << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
|
||||
m_theLog << " line ";
|
||||
m_theLog << 0 << " " << 0 << " ";
|
||||
dumpShape ( l );
|
||||
dumpShape( aL );
|
||||
m_theLog << std::endl;
|
||||
}
|
||||
|
||||
void PNS_LOGGER::Log ( const VECTOR2I& start, const VECTOR2I& end, int kind , const std::string name)
|
||||
{
|
||||
|
||||
void PNS_LOGGER::Log( const VECTOR2I& aStart, const VECTOR2I& aEnd,
|
||||
int aKind, const std::string aName)
|
||||
{
|
||||
}
|
||||
|
||||
void PNS_LOGGER::dumpShape ( const SHAPE * sh )
|
||||
|
||||
void PNS_LOGGER::dumpShape( const SHAPE* aSh )
|
||||
{
|
||||
switch(sh->Type())
|
||||
switch( aSh->Type() )
|
||||
{
|
||||
case SH_LINE_CHAIN:
|
||||
{
|
||||
const SHAPE_LINE_CHAIN *lc = (const SHAPE_LINE_CHAIN *) sh;
|
||||
const SHAPE_LINE_CHAIN* lc = (const SHAPE_LINE_CHAIN*) aSh;
|
||||
m_theLog << "linechain " << lc->PointCount() << " " << ( lc->IsClosed() ? 1 : 0 ) << " ";
|
||||
|
||||
for( int i = 0; i < lc->PointCount(); i++ )
|
||||
m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_CIRCLE:
|
||||
{
|
||||
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE *) sh;
|
||||
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE*) aSh;
|
||||
m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_RECT:
|
||||
{
|
||||
const SHAPE_RECT *r = (const SHAPE_RECT *) sh;
|
||||
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " << r->GetSize().x << " " <<r->GetSize().y;
|
||||
const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
|
||||
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
|
||||
r->GetSize().x << " " <<r->GetSize().y;
|
||||
break;
|
||||
}
|
||||
|
||||
case SH_SEGMENT:
|
||||
{
|
||||
const SHAPE_SEGMENT *s = (const SHAPE_SEGMENT *) sh;
|
||||
m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " << s->GetSeg().B.x << " " << s->GetSeg().B.y;
|
||||
const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) aSh;
|
||||
m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
|
||||
s->GetSeg().B.x << " " << s->GetSeg().B.y;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PNS_LOGGER::Save ( const std::string& filename )
|
||||
void PNS_LOGGER::Save( const std::string& aFilename )
|
||||
{
|
||||
|
||||
EndGroup();
|
||||
|
||||
FILE *f=fopen(filename.c_str(),"wb");
|
||||
printf("Saving to '%s' [%p]\n", filename.c_str(), f);
|
||||
FILE* f = fopen( aFilename.c_str(), "wb" );
|
||||
printf( "Saving to '%s' [%p]\n", aFilename.c_str(), f );
|
||||
const std::string s = m_theLog.str();
|
||||
fwrite( s.c_str(), 1, s.length(), f );
|
||||
fclose( f );
|
||||
|
|
|
@ -32,24 +32,25 @@ class PNS_ITEM;
|
|||
class SHAPE_LINE_CHAIN;
|
||||
class SHAPE;
|
||||
|
||||
class PNS_LOGGER {
|
||||
|
||||
class PNS_LOGGER
|
||||
{
|
||||
public:
|
||||
PNS_LOGGER();
|
||||
~PNS_LOGGER();
|
||||
|
||||
void Save ( const std::string& filename );
|
||||
|
||||
void Save( const std::string& aFilename );
|
||||
void Clear();
|
||||
void NewGroup ( const std::string& name, int iter = 0);
|
||||
|
||||
void NewGroup( const std::string& aName, int aIter = 0 );
|
||||
void EndGroup();
|
||||
void Log ( const PNS_ITEM *item, int kind = 0, const std::string name = std::string () );
|
||||
void Log ( const SHAPE_LINE_CHAIN *l, int kind = 0, const std::string name = std::string () );
|
||||
void Log ( const VECTOR2I& start, const VECTOR2I& end, int kind = 0, const std::string name = std::string () );
|
||||
|
||||
void Log( const PNS_ITEM* aItem, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const SHAPE_LINE_CHAIN *aL, int aKind = 0, const std::string aName = std::string() );
|
||||
void Log( const VECTOR2I& aStart, const VECTOR2I& aEnd, int aKind = 0,
|
||||
const std::string aName = std::string() );
|
||||
|
||||
private:
|
||||
|
||||
void dumpShape ( const SHAPE* sh );
|
||||
void dumpShape ( const SHAPE* aSh );
|
||||
|
||||
bool m_groupOpened;
|
||||
std::stringstream m_theLog;
|
||||
|
|
|
@ -53,11 +53,13 @@ PNS_NODE::PNS_NODE()
|
|||
m_parent = NULL;
|
||||
m_maxClearance = 800000; // fixme: depends on how thick traces are.
|
||||
m_index = new PNS_INDEX;
|
||||
|
||||
#ifdef DEBUG
|
||||
allocNodes.insert( this );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE::~PNS_NODE()
|
||||
{
|
||||
TRACE( 0, "PNS_NODE::delete %p", this );
|
||||
|
@ -69,7 +71,6 @@ PNS_NODE::~PNS_NODE()
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
if( allocNodes.find( this ) == allocNodes.end() )
|
||||
{
|
||||
TRACEn( 0, "attempting to free an already-free'd node.\n" );
|
||||
|
@ -77,31 +78,31 @@ PNS_NODE::~PNS_NODE()
|
|||
}
|
||||
|
||||
allocNodes.erase( this );
|
||||
|
||||
#endif
|
||||
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin();
|
||||
i != m_index->end(); ++i )
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
{
|
||||
if( (*i)->BelongsTo( this ) )
|
||||
delete *i;
|
||||
}
|
||||
|
||||
unlinkParent();
|
||||
delete m_index;
|
||||
}
|
||||
|
||||
|
||||
int PNS_NODE::GetClearance( const PNS_ITEM* a, const PNS_ITEM* b ) const
|
||||
int PNS_NODE::GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const
|
||||
{
|
||||
return (*m_clearanceFunctor)( a, b );
|
||||
return (*m_clearanceFunctor)( aA, aB );
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE* PNS_NODE::Branch()
|
||||
{
|
||||
PNS_NODE* child = new PNS_NODE;
|
||||
|
||||
TRACE( 0, "PNS_NODE::branch %p (parent %p)", child % this );
|
||||
|
||||
|
||||
m_children.push_back( child );
|
||||
|
||||
child->m_depth = m_depth + 1;
|
||||
|
@ -114,10 +115,9 @@ PNS_NODE* PNS_NODE::Branch()
|
|||
// to stored items.
|
||||
if( !isRoot() )
|
||||
{
|
||||
JointMap::iterator j;
|
||||
JOINT_MAP::iterator j;
|
||||
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin();
|
||||
i != m_index->end(); ++i )
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
child->m_index->Add( *i );
|
||||
|
||||
child->m_joints = m_joints;
|
||||
|
@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent()
|
|||
|
||||
// function object that visits potential obstacles and performs
|
||||
// the actual collision refining
|
||||
struct PNS_NODE::obstacleVisitor
|
||||
struct PNS_NODE::OBSTACLE_VISITOR
|
||||
{
|
||||
///> node we are searching in (either root or a branch)
|
||||
PNS_NODE* m_node;
|
||||
|
@ -159,7 +159,7 @@ struct PNS_NODE::obstacleVisitor
|
|||
PNS_NODE* m_override;
|
||||
|
||||
///> list of encountered obstacles
|
||||
Obstacles& m_tab;
|
||||
OBSTACLES& m_tab;
|
||||
|
||||
///> the item we are looking for collisions with
|
||||
const PNS_ITEM* m_item;
|
||||
|
@ -176,8 +176,7 @@ struct PNS_NODE::obstacleVisitor
|
|||
///> additional clearance
|
||||
int m_extraClearance;
|
||||
|
||||
obstacleVisitor( PNS_NODE::Obstacles& aTab, const PNS_ITEM* aItem,
|
||||
int aKindMask ) :
|
||||
OBSTACLE_VISITOR( PNS_NODE::OBSTACLES& aTab, const PNS_ITEM* aItem, int aKindMask ) :
|
||||
m_tab( aTab ),
|
||||
m_item( aItem ),
|
||||
m_kindMask( aKindMask ),
|
||||
|
@ -187,7 +186,7 @@ struct PNS_NODE::obstacleVisitor
|
|||
{
|
||||
if( aItem->Kind() == PNS_ITEM::LINE )
|
||||
m_extraClearance += static_cast<const PNS_LINE*>( aItem )->Width() / 2;
|
||||
};
|
||||
}
|
||||
|
||||
void SetCountLimit( int aLimit )
|
||||
{
|
||||
|
@ -220,7 +219,7 @@ struct PNS_NODE::obstacleVisitor
|
|||
|
||||
PNS_OBSTACLE obs;
|
||||
|
||||
obs.item = aItem;
|
||||
obs.m_item = aItem;
|
||||
m_tab.push_back( obs );
|
||||
|
||||
m_matchCount++;
|
||||
|
@ -234,9 +233,9 @@ struct PNS_NODE::obstacleVisitor
|
|||
|
||||
|
||||
int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
|
||||
PNS_NODE::Obstacles& aObstacles, int aKindMask, int aLimitCount )
|
||||
PNS_NODE::OBSTACLES& aObstacles, int aKindMask, int aLimitCount )
|
||||
{
|
||||
obstacleVisitor visitor( aObstacles, aItem, aKindMask );
|
||||
OBSTACLE_VISITOR visitor( aObstacles, aItem, aKindMask );
|
||||
|
||||
#ifdef DEBUG
|
||||
assert( allocNodes.find( this ) != allocNodes.end() );
|
||||
|
@ -259,9 +258,9 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
|
|||
}
|
||||
|
||||
|
||||
PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKindMask )
|
||||
PNS_NODE::OPT_OBSTACLE PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKindMask )
|
||||
{
|
||||
Obstacles obs_list;
|
||||
OBSTACLES obs_list;
|
||||
bool found_isects = false;
|
||||
|
||||
const SHAPE_LINE_CHAIN& line = aItem->CLine();
|
||||
|
@ -281,13 +280,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
|
|||
|
||||
// if(! QueryColliding ( aItem, obs_list, aKindMask ))
|
||||
if( !n )
|
||||
return OptObstacle();
|
||||
return OPT_OBSTACLE();
|
||||
|
||||
PNS_LINE& aLine = (PNS_LINE&) *aItem;
|
||||
|
||||
PNS_OBSTACLE nearest;
|
||||
nearest.item = NULL;
|
||||
nearest.dist_first = INT_MAX;
|
||||
nearest.m_item = NULL;
|
||||
nearest.m_distFirst = INT_MAX;
|
||||
|
||||
BOOST_FOREACH( PNS_OBSTACLE obs, obs_list )
|
||||
{
|
||||
|
@ -296,13 +295,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
|
|||
|
||||
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> isect_list;
|
||||
|
||||
int clearance = GetClearance( obs.item, &aLine );
|
||||
int clearance = GetClearance( obs.m_item, &aLine );
|
||||
|
||||
SHAPE_LINE_CHAIN hull = obs.item->Hull( clearance, aItem->Width() );
|
||||
SHAPE_LINE_CHAIN hull = obs.m_item->Hull( clearance, aItem->Width() );
|
||||
|
||||
if( aLine.EndsWithVia() )
|
||||
{
|
||||
int clearance = GetClearance( obs.item, &aLine.Via() );
|
||||
int clearance = GetClearance( obs.m_item, &aLine.Via() );
|
||||
|
||||
SHAPE_LINE_CHAIN viaHull = aLine.Via().Hull( clearance, aItem->Width() );
|
||||
|
||||
|
@ -313,13 +312,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
|
|||
int dist = aLine.CLine().Length() +
|
||||
( isect.p - aLine.Via().Pos() ).EuclideanNorm();
|
||||
|
||||
if( dist < nearest.dist_first )
|
||||
if( dist < nearest.m_distFirst )
|
||||
{
|
||||
found_isects = true;
|
||||
nearest.dist_first = dist;
|
||||
nearest.ip_first = isect.p;
|
||||
nearest.item = obs.item;
|
||||
nearest.hull = hull;
|
||||
nearest.m_distFirst = dist;
|
||||
nearest.m_ipFirst = isect.p;
|
||||
nearest.m_item = obs.m_item;
|
||||
nearest.m_hull = hull;
|
||||
}
|
||||
|
||||
if( dist > dist_max )
|
||||
|
@ -338,13 +337,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
|
|||
{
|
||||
int dist = aLine.CLine().PathLength( isect.p );
|
||||
|
||||
if( dist < nearest.dist_first )
|
||||
if( dist < nearest.m_distFirst )
|
||||
{
|
||||
found_isects = true;
|
||||
nearest.dist_first = dist;
|
||||
nearest.ip_first = isect.p;
|
||||
nearest.item = obs.item;
|
||||
nearest.hull = hull;
|
||||
nearest.m_distFirst = dist;
|
||||
nearest.m_ipFirst = isect.p;
|
||||
nearest.m_item = obs.m_item;
|
||||
nearest.m_hull = hull;
|
||||
}
|
||||
|
||||
if( dist > dist_max )
|
||||
|
@ -354,30 +353,34 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
|
|||
}
|
||||
}
|
||||
|
||||
nearest.ip_last = ip_last;
|
||||
nearest.dist_last = dist_max;
|
||||
nearest.m_ipLast = ip_last;
|
||||
nearest.m_distLast = dist_max;
|
||||
}
|
||||
|
||||
if( !found_isects )
|
||||
nearest.item = obs_list[0].item;
|
||||
nearest.m_item = obs_list[0].m_item;
|
||||
|
||||
return nearest;
|
||||
}
|
||||
|
||||
PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEMSET& aSet, int aKindMask )
|
||||
|
||||
PNS_NODE::OPT_OBSTACLE PNS_NODE::CheckColliding( const PNS_ITEMSET& aSet, int aKindMask )
|
||||
{
|
||||
BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
|
||||
{
|
||||
OptObstacle obs = CheckColliding(item, aKindMask);
|
||||
OPT_OBSTACLE obs = CheckColliding( item, aKindMask );
|
||||
|
||||
if( obs )
|
||||
return obs;
|
||||
}
|
||||
return OptObstacle();
|
||||
|
||||
return OPT_OBSTACLE();
|
||||
}
|
||||
|
||||
PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKindMask )
|
||||
|
||||
PNS_NODE::OPT_OBSTACLE PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKindMask )
|
||||
{
|
||||
Obstacles obs;
|
||||
OBSTACLES obs;
|
||||
|
||||
obs.reserve( 100 );
|
||||
|
||||
|
@ -393,7 +396,7 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
|
|||
n += QueryColliding( &s, obs, aKindMask, 1 );
|
||||
|
||||
if( n )
|
||||
return OptObstacle( obs[0] );
|
||||
return OPT_OBSTACLE( obs[0] );
|
||||
}
|
||||
|
||||
if( line->EndsWithVia() )
|
||||
|
@ -401,13 +404,13 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
|
|||
n += QueryColliding( &line->Via(), obs, aKindMask, 1 );
|
||||
|
||||
if( n )
|
||||
return OptObstacle( obs[0] );
|
||||
return OPT_OBSTACLE( obs[0] );
|
||||
}
|
||||
}
|
||||
else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
|
||||
return OptObstacle( obs[0] );
|
||||
return OPT_OBSTACLE( obs[0] );
|
||||
|
||||
return OptObstacle();
|
||||
return OPT_OBSTACLE();
|
||||
}
|
||||
|
||||
|
||||
|
@ -426,14 +429,15 @@ bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, i
|
|||
}
|
||||
|
||||
|
||||
struct hitVisitor
|
||||
struct HIT_VISITOR
|
||||
{
|
||||
PNS_ITEMSET& m_items;
|
||||
const VECTOR2I& m_point;
|
||||
const PNS_NODE* m_world;
|
||||
|
||||
hitVisitor( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) :
|
||||
m_items( aTab ), m_point( aPoint ), m_world( aWorld ) {};
|
||||
HIT_VISITOR( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) :
|
||||
m_items( aTab ), m_point( aPoint ), m_world( aWorld )
|
||||
{}
|
||||
|
||||
bool operator()( PNS_ITEM* aItem )
|
||||
{
|
||||
|
@ -455,14 +459,14 @@ const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const
|
|||
|
||||
// fixme: we treat a point as an infinitely small circle - this is inefficient.
|
||||
SHAPE_CIRCLE s( aPoint, 0 );
|
||||
hitVisitor visitor( items, aPoint, this );
|
||||
HIT_VISITOR visitor( items, aPoint, this );
|
||||
|
||||
m_index->Query( &s, m_maxClearance, visitor );
|
||||
|
||||
if( !isRoot() ) // fixme: could be made cleaner
|
||||
{
|
||||
PNS_ITEMSET items_root;
|
||||
hitVisitor visitor_root( items_root, aPoint, m_root );
|
||||
HIT_VISITOR visitor_root( items_root, aPoint, m_root );
|
||||
m_root->m_index->Query( &s, m_maxClearance, visitor_root );
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, items_root.Items() )
|
||||
|
@ -508,8 +512,8 @@ void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant )
|
|||
|
||||
if( psegR )
|
||||
aLine->LinkSegment( psegR );
|
||||
else {
|
||||
|
||||
else
|
||||
{
|
||||
pseg->SetOwner( this );
|
||||
|
||||
linkJoint( s.A, pseg->Layers(), aLine->Net(), pseg );
|
||||
|
@ -574,7 +578,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:
|
||||
|
@ -627,20 +630,19 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
|
|||
}
|
||||
|
||||
|
||||
|
||||
void PNS_NODE::removeVia( PNS_VIA* aVia )
|
||||
{
|
||||
// We have to split a single joint (associated with a via, binding together multiple layers)
|
||||
// into multiple independent joints. As I'm a lazy bastard, I simply delete the via and all its links and re-insert them.
|
||||
|
||||
PNS_JOINT::HashTag tag;
|
||||
PNS_JOINT::HASH_TAG tag;
|
||||
|
||||
VECTOR2I p( aVia->Pos() );
|
||||
PNS_LAYERSET vLayers( aVia->Layers() );
|
||||
int net = aVia->Net();
|
||||
|
||||
PNS_JOINT* jt = FindJoint( p, vLayers.Start(), net );
|
||||
PNS_JOINT::LinkedItems links ( jt->LinkList() );
|
||||
PNS_JOINT::LINKED_ITEMS links( jt->LinkList() );
|
||||
|
||||
tag.net = net;
|
||||
tag.pos = p;
|
||||
|
@ -649,14 +651,14 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
|
|||
do
|
||||
{
|
||||
split = false;
|
||||
std::pair<JointMap::iterator, JointMap::iterator> range = m_joints.equal_range( tag );
|
||||
std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range = m_joints.equal_range( tag );
|
||||
|
||||
if( range.first == m_joints.end() )
|
||||
break;
|
||||
|
||||
// find and remove all joints containing the via to be removed
|
||||
|
||||
for( JointMap::iterator f = range.first; f != range.second; ++f )
|
||||
for( JOINT_MAP::iterator f = range.first; f != range.second; ++f )
|
||||
{
|
||||
if( aVia->LayersOverlap ( &f->second ) )
|
||||
{
|
||||
|
@ -677,6 +679,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
|
|||
doRemove( aVia );
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
|
||||
{
|
||||
Remove( aOldItem );
|
||||
|
@ -711,32 +714,32 @@ void PNS_NODE::Remove( PNS_ITEM* aItem )
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::followLine( PNS_SEGMENT* current, bool scanDirection, int& pos,
|
||||
int limit, VECTOR2I* corners, PNS_SEGMENT** segments )
|
||||
void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos,
|
||||
int aLimit, VECTOR2I* aCorners, PNS_SEGMENT** aSegments )
|
||||
{
|
||||
bool prevReversed = false;
|
||||
|
||||
for( ; ; )
|
||||
{
|
||||
const VECTOR2I p =
|
||||
(scanDirection ^ prevReversed) ? current->Seg().B : current->Seg().A;
|
||||
const PNS_JOINT *jt = FindJoint( p, current );
|
||||
( aScanDirection ^ prevReversed ) ? aCurrent->Seg().B : aCurrent->Seg().A;
|
||||
const PNS_JOINT* jt = FindJoint( p, aCurrent );
|
||||
|
||||
assert( jt );
|
||||
assert( pos > 0 && pos < limit );
|
||||
assert( aPos > 0 && aPos < aLimit );
|
||||
|
||||
corners[pos] = jt->Pos();
|
||||
segments[pos] = current;
|
||||
aCorners[aPos] = jt->Pos();
|
||||
aSegments[aPos] = aCurrent;
|
||||
|
||||
pos += (scanDirection ? 1 : -1);
|
||||
aPos += ( aScanDirection ? 1 : -1 );
|
||||
|
||||
if( !jt->IsLineCorner() )
|
||||
break;
|
||||
|
||||
current = jt->NextSegment( current );
|
||||
aCurrent = jt->NextSegment( aCurrent );
|
||||
|
||||
prevReversed =
|
||||
( jt->Pos() == (scanDirection ? current->Seg().B : current->Seg().A ) );
|
||||
( jt->Pos() == (aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -775,6 +778,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
|
|||
|
||||
if( segs[i] == aSeg && aOriginSegmentIndex )
|
||||
*aOriginSegmentIndex = n;
|
||||
|
||||
n++;
|
||||
}
|
||||
|
||||
|
@ -789,12 +793,13 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::FindLineEnds( PNS_LINE* aLine, PNS_JOINT& a, PNS_JOINT& b )
|
||||
void PNS_NODE::FindLineEnds( PNS_LINE* aLine, PNS_JOINT& aA, PNS_JOINT& aB )
|
||||
{
|
||||
a = *FindJoint( aLine->CPoint( 0 ), aLine );
|
||||
b = *FindJoint( aLine->CPoint( -1 ), aLine );
|
||||
aA = *FindJoint( aLine->CPoint( 0 ), aLine );
|
||||
aB = *FindJoint( aLine->CPoint( -1 ), aLine );
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFoundJoints )
|
||||
{
|
||||
std::deque<PNS_JOINT*> searchQueue;
|
||||
|
@ -809,6 +814,7 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aF
|
|||
searchQueue.pop_front();
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, current->LinkList() )
|
||||
{
|
||||
if ( item->OfKind( PNS_ITEM::SEGMENT ) )
|
||||
{
|
||||
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT *>( item );
|
||||
|
@ -823,11 +829,13 @@ void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aF
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_FOREACH(PNS_JOINT* jt, processed)
|
||||
aFoundJoints.push_back( jt );
|
||||
}
|
||||
|
||||
|
||||
PNS_ITEM* PNS_NODE::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor, int aKindMask )
|
||||
{
|
||||
std::set<PNS_ITEM*> disconnected;
|
||||
|
@ -861,6 +869,7 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
|
|||
{
|
||||
best_dist = d;
|
||||
best = item;
|
||||
|
||||
if( aAnchor )
|
||||
*aAnchor = i;
|
||||
}
|
||||
|
@ -871,9 +880,10 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
|
|||
return best;
|
||||
}
|
||||
|
||||
int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, 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, a.LinkList() )
|
||||
BOOST_FOREACH( PNS_ITEM* item, aA.LinkList() )
|
||||
{
|
||||
if( item->Kind() == PNS_ITEM::SEGMENT )
|
||||
{
|
||||
|
@ -884,9 +894,8 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, std::vector<PN
|
|||
|
||||
FindLineEnds( line, j_start, j_end );
|
||||
|
||||
|
||||
int id_start = line->CLine().Find (a.Pos());
|
||||
int id_end = line->CLine().Find (b.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 );
|
||||
|
@ -895,7 +904,8 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, std::vector<PN
|
|||
{
|
||||
line->ClipVertexRange ( id_start, id_end );
|
||||
aLines.push_back( line );
|
||||
} else
|
||||
}
|
||||
else
|
||||
delete line;
|
||||
}
|
||||
}
|
||||
|
@ -906,12 +916,12 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, std::vector<PN
|
|||
|
||||
PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
|
||||
{
|
||||
PNS_JOINT::HashTag tag;
|
||||
PNS_JOINT::HASH_TAG tag;
|
||||
|
||||
tag.net = aNet;
|
||||
tag.pos = aPos;
|
||||
|
||||
JointMap::iterator f = m_joints.find( tag ), end = m_joints.end();
|
||||
JOINT_MAP::iterator f = m_joints.find( tag ), end = m_joints.end();
|
||||
|
||||
if( f == end && !isRoot() )
|
||||
{
|
||||
|
@ -936,15 +946,15 @@ PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
|
|||
|
||||
PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet )
|
||||
{
|
||||
PNS_JOINT::HashTag tag;
|
||||
PNS_JOINT::HASH_TAG tag;
|
||||
|
||||
tag.pos = aPos;
|
||||
tag.net = aNet;
|
||||
|
||||
// try to find the joint in this node.
|
||||
JointMap::iterator f = m_joints.find( tag );
|
||||
JOINT_MAP::iterator f = m_joints.find( tag );
|
||||
|
||||
std::pair<JointMap::iterator, JointMap::iterator> range;
|
||||
std::pair<JOINT_MAP::iterator, JOINT_MAP::iterator> range;
|
||||
|
||||
// not found and we are not root? find in the root and copy results here.
|
||||
if( f == m_joints.end() && !isRoot() )
|
||||
|
@ -978,7 +988,8 @@ PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLaye
|
|||
break;
|
||||
}
|
||||
}
|
||||
} while( merged );
|
||||
}
|
||||
while( merged );
|
||||
|
||||
return m_joints.insert( TagJointPair( tag, jt ) )->second;
|
||||
}
|
||||
|
@ -991,10 +1002,8 @@ void PNS_JOINT::Dump() const
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::linkJoint( const VECTOR2I& aPos,
|
||||
const PNS_LAYERSET& aLayers,
|
||||
int aNet,
|
||||
PNS_ITEM* aWhere )
|
||||
void PNS_NODE::linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
|
||||
int aNet, PNS_ITEM* aWhere )
|
||||
{
|
||||
PNS_JOINT& jt = touchJoint( aPos, aLayers, aNet );
|
||||
|
||||
|
@ -1033,24 +1042,24 @@ void PNS_NODE::Dump( bool aLong )
|
|||
}
|
||||
}
|
||||
|
||||
JointMap::iterator j;
|
||||
JOINT_MAP::iterator j;
|
||||
|
||||
if( aLong )
|
||||
for( j = m_joints.begin(); j != m_joints.end(); ++j )
|
||||
{
|
||||
printf( "joint : %s, links : %d\n",
|
||||
j->second.GetPos().Format().c_str(), j->second.LinkCount() );
|
||||
PNS_JOINT::LinkedItems::const_iterator k;
|
||||
PNS_JOINT::LINKED_ITEMS::const_iterator k;
|
||||
|
||||
for( k = j->second.GetLinkList().begin(); k != j->second.GetLinkList().end(); ++k )
|
||||
{
|
||||
const PNS_ITEM* item = *k;
|
||||
const PNS_ITEM* m_item = *k;
|
||||
|
||||
switch( item->GetKind() )
|
||||
switch( m_item->GetKind() )
|
||||
{
|
||||
case PNS_ITEM::SEGMENT:
|
||||
{
|
||||
const PNS_SEGMENT* seg = static_cast<const PNS_SEGMENT*>(item);
|
||||
const PNS_SEGMENT* seg = static_cast<const PNS_SEGMENT*>( m_item );
|
||||
printf( " -> seg %s %s\n", seg->GetSeg().A.Format().c_str(),
|
||||
seg->GetSeg().B.Format().c_str() );
|
||||
break;
|
||||
|
@ -1075,7 +1084,6 @@ void PNS_NODE::Dump( bool aLong )
|
|||
if( aLong )
|
||||
printf( "Line: %s, net %d ", l->GetLine().Format().c_str(), l->GetNet() );
|
||||
|
||||
|
||||
for( std::vector<PNS_SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
|
||||
{
|
||||
printf( "%s ", (*j)->GetSeg().A.Format().c_str() );
|
||||
|
@ -1094,7 +1102,7 @@ void PNS_NODE::Dump( bool aLong )
|
|||
}
|
||||
|
||||
|
||||
void PNS_NODE::GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded )
|
||||
void PNS_NODE::GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded )
|
||||
{
|
||||
aRemoved.reserve( m_override.size() );
|
||||
aAdded.reserve( m_index->Size() );
|
||||
|
@ -1105,7 +1113,7 @@ void PNS_NODE::GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded )
|
|||
BOOST_FOREACH( PNS_ITEM* item, m_override )
|
||||
aRemoved.push_back( item );
|
||||
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); i!=m_index->end(); ++i )
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
aAdded.push_back( *i );
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1123,8 @@ void PNS_NODE::releaseChildren()
|
|||
// copy the kids as the PNS_NODE destructor erases the item from the parent node.
|
||||
std::vector<PNS_NODE*> kids = m_children;
|
||||
|
||||
BOOST_FOREACH( PNS_NODE * node, kids ) {
|
||||
BOOST_FOREACH( PNS_NODE * node, kids )
|
||||
{
|
||||
node->releaseChildren();
|
||||
delete node;
|
||||
}
|
||||
|
@ -1130,7 +1139,7 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
|
|||
BOOST_FOREACH( PNS_ITEM * item, aNode->m_override )
|
||||
Remove( item );
|
||||
|
||||
for( PNS_INDEX::ItemSet::iterator i = aNode->m_index->begin();
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = aNode->m_index->begin();
|
||||
i != aNode->m_index->end(); ++i )
|
||||
{
|
||||
(*i)->SetRank( -1 );
|
||||
|
@ -1151,8 +1160,7 @@ void PNS_NODE::KillChildren()
|
|||
|
||||
void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems )
|
||||
{
|
||||
PNS_INDEX::NetItemsList* l_cur = m_index->GetItemsForNet( aNet );
|
||||
|
||||
PNS_INDEX::NET_ITEMS_LIST* l_cur = m_index->GetItemsForNet( aNet );
|
||||
|
||||
if( l_cur )
|
||||
{
|
||||
|
@ -1162,41 +1170,52 @@ void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems )
|
|||
|
||||
if( !isRoot() )
|
||||
{
|
||||
PNS_INDEX::NetItemsList* l_root = m_root->m_index->GetItemsForNet( aNet );
|
||||
PNS_INDEX::NET_ITEMS_LIST* l_root = m_root->m_index->GetItemsForNet( aNet );
|
||||
|
||||
if( l_root )
|
||||
for( PNS_INDEX::NetItemsList::iterator i = l_root->begin(); i!= l_root->end(); ++i )
|
||||
for( PNS_INDEX::NET_ITEMS_LIST::iterator i = l_root->begin(); i!= l_root->end(); ++i )
|
||||
if( !overrides( *i ) )
|
||||
aItems.insert( *i );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_NODE::ClearRanks()
|
||||
{
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
{
|
||||
(*i)->SetRank( -1 );
|
||||
(*i)->Mark( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PNS_NODE::FindByMarker( int aMarker, PNS_ITEMSET& aItems )
|
||||
{
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
if ( (*i)->Marker() & aMarker ) aItems.Add(*i);
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
{
|
||||
if( (*i)->Marker() & aMarker )
|
||||
aItems.Add( *i );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int PNS_NODE::RemoveByMarker( int aMarker )
|
||||
{
|
||||
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
|
||||
{
|
||||
if ( (*i)->Marker() & aMarker )
|
||||
{
|
||||
Remove( *i );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
||||
{
|
||||
PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
|
||||
|
@ -1205,6 +1224,7 @@ PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
|||
return NULL;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
|
||||
{
|
||||
if( item->OfKind( PNS_ITEM::SEGMENT ) )
|
||||
{
|
||||
PNS_SEGMENT* seg2 = (PNS_SEGMENT*) item;
|
||||
|
@ -1219,6 +1239,7 @@ PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
|
|||
( ( a1 == a2 && b1 == b2 ) || ( a1 == b2 && a2 == b1 ) ) )
|
||||
return seg2;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ class PNS_INDEX;
|
|||
class PNS_CLEARANCE_FUNC
|
||||
{
|
||||
public:
|
||||
virtual int operator()( const PNS_ITEM* a, const PNS_ITEM* b ) = 0;
|
||||
virtual int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB ) = 0;
|
||||
virtual ~PNS_CLEARANCE_FUNC() {}
|
||||
};
|
||||
|
||||
|
@ -65,20 +65,20 @@ public:
|
|||
struct PNS_OBSTACLE
|
||||
{
|
||||
///> Item we search collisions with
|
||||
PNS_ITEM* head;
|
||||
PNS_ITEM* m_head;
|
||||
|
||||
///> Item found to be colliding with head
|
||||
PNS_ITEM* item;
|
||||
///> Item found to be colliding with m_head
|
||||
PNS_ITEM* m_item;
|
||||
|
||||
///> Hull of the colliding item
|
||||
SHAPE_LINE_CHAIN hull;
|
||||
///> Hull of the colliding m_item
|
||||
SHAPE_LINE_CHAIN m_hull;
|
||||
|
||||
///> First and last intersection point between the head item and the hull
|
||||
///> of the colliding item
|
||||
VECTOR2I ip_first, ip_last;
|
||||
///> of the colliding m_item
|
||||
VECTOR2I m_ipFirst, m_ipLast;
|
||||
|
||||
///> ... and the distance thereof
|
||||
int dist_first, dist_last;
|
||||
int m_distFirst, m_distLast;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -93,19 +93,18 @@ struct PNS_OBSTACLE
|
|||
* - lightweight cloning/branching (for recursive optimization and shove
|
||||
* springback)
|
||||
**/
|
||||
|
||||
class PNS_NODE
|
||||
{
|
||||
public:
|
||||
typedef boost::optional<PNS_OBSTACLE> OptObstacle;
|
||||
typedef std::vector<PNS_ITEM*> ItemVector;
|
||||
typedef std::vector<PNS_OBSTACLE> Obstacles;
|
||||
typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;
|
||||
typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
|
||||
typedef std::vector<PNS_OBSTACLE> OBSTACLES;
|
||||
|
||||
PNS_NODE ();
|
||||
~PNS_NODE ();
|
||||
|
||||
///> Returns the expected clearance between items a and b.
|
||||
int GetClearance ( const PNS_ITEM* a, const PNS_ITEM* b ) const;
|
||||
int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
|
||||
|
||||
///> Returns the pre-set worst case clearance between any pair of items
|
||||
int GetMaxClearance() const
|
||||
|
@ -148,11 +147,10 @@ public:
|
|||
* @return number of obstacles found
|
||||
*/
|
||||
int QueryColliding( const PNS_ITEM* aItem,
|
||||
Obstacles& aObstacles,
|
||||
OBSTACLES& aObstacles,
|
||||
int aKindMask = PNS_ITEM::ANY,
|
||||
int aLimitCount = -1 );
|
||||
|
||||
|
||||
/**
|
||||
* Function NearestObstacle()
|
||||
*
|
||||
|
@ -162,7 +160,7 @@ public:
|
|||
* @param aKindMask mask of obstacle types to take into account
|
||||
* @return the obstacle, if found, otherwise empty.
|
||||
*/
|
||||
OptObstacle NearestObstacle ( const PNS_LINE* aItem,
|
||||
OPT_OBSTACLE NearestObstacle( const PNS_LINE* aItem,
|
||||
int aKindMask = PNS_ITEM::ANY );
|
||||
|
||||
/**
|
||||
|
@ -174,7 +172,7 @@ public:
|
|||
* @param aKindMask mask of obstacle types to take into account
|
||||
* @return the obstacle, if found, otherwise empty.
|
||||
*/
|
||||
OptObstacle CheckColliding ( const PNS_ITEM* aItem,
|
||||
OPT_OBSTACLE CheckColliding( const PNS_ITEM* aItem,
|
||||
int aKindMask = PNS_ITEM::ANY );
|
||||
|
||||
|
||||
|
@ -187,7 +185,7 @@ public:
|
|||
* @param aKindMask mask of obstacle types to take into account
|
||||
* @return the obstacle, if found, otherwise empty.
|
||||
*/
|
||||
OptObstacle CheckColliding ( const PNS_ITEMSET& aSet,
|
||||
OPT_OBSTACLE CheckColliding( const PNS_ITEMSET& aSet,
|
||||
int aKindMask = PNS_ITEM::ANY );
|
||||
|
||||
|
||||
|
@ -259,15 +257,11 @@ public:
|
|||
* @param aOriginSegmentIndex index of aSeg in the resulting line
|
||||
* @return the line
|
||||
*/
|
||||
|
||||
PNS_LINE* AssembleLine ( PNS_SEGMENT* aSeg,
|
||||
int *aOriginSegmentIndex = NULL );
|
||||
PNS_LINE* AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex = NULL );
|
||||
|
||||
///> Prints the contents and joints structure
|
||||
void Dump( bool aLong = false );
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Function GetUpdatedItems()
|
||||
*
|
||||
|
@ -276,8 +270,7 @@ public:
|
|||
* @param aRemoved removed items
|
||||
* @param aAdded added items
|
||||
*/
|
||||
void GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded );
|
||||
|
||||
void GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded );
|
||||
|
||||
/**
|
||||
* Function Commit()
|
||||
|
@ -309,16 +302,17 @@ public:
|
|||
|
||||
void MapConnectivity( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aFoundJoints );
|
||||
|
||||
PNS_ITEM *NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor = NULL, int aKindMask = PNS_ITEM::ANY);
|
||||
PNS_ITEM* NearestUnconnectedItem( PNS_JOINT* aStart, int *aAnchor = NULL,
|
||||
int aKindMask = PNS_ITEM::ANY);
|
||||
|
||||
|
||||
///> finds all lines between a pair of joints. Used by the loop removal procedure.
|
||||
int FindLinesBetweenJoints( PNS_JOINT& a,
|
||||
PNS_JOINT& b,
|
||||
int FindLinesBetweenJoints( PNS_JOINT& aA,
|
||||
PNS_JOINT& aB,
|
||||
std::vector<PNS_LINE*>& aLines );
|
||||
|
||||
///> finds the joints corresponding to the ends of line aLine
|
||||
void FindLineEnds( PNS_LINE* aLine, PNS_JOINT& a, PNS_JOINT& b );
|
||||
void FindLineEnds( PNS_LINE* aLine, PNS_JOINT& aA, PNS_JOINT& aB );
|
||||
|
||||
///> Destroys all child nodes. Applicable only to the root node.
|
||||
void KillChildren();
|
||||
|
@ -327,25 +321,24 @@ public:
|
|||
|
||||
void ClearRanks();
|
||||
|
||||
|
||||
int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
|
||||
int RemoveByMarker( int aMarker );
|
||||
|
||||
private:
|
||||
struct obstacleVisitor;
|
||||
typedef boost::unordered_multimap<PNS_JOINT::HashTag, PNS_JOINT> JointMap;
|
||||
typedef JointMap::value_type TagJointPair;
|
||||
struct OBSTACLE_VISITOR;
|
||||
typedef boost::unordered_multimap<PNS_JOINT::HASH_TAG, PNS_JOINT> JOINT_MAP;
|
||||
typedef JOINT_MAP::value_type TagJointPair;
|
||||
|
||||
/// nodes are not copyable
|
||||
PNS_NODE ( const PNS_NODE& b );
|
||||
PNS_NODE& operator= ( const PNS_NODE& b );
|
||||
PNS_NODE( const PNS_NODE& aB );
|
||||
PNS_NODE& operator=( const PNS_NODE& aB );
|
||||
|
||||
///> tries to find matching joint and creates a new one if not found
|
||||
PNS_JOINT& touchJoint( const VECTOR2I& aPos,
|
||||
const PNS_LAYERSET& aLayers,
|
||||
int aNet );
|
||||
|
||||
///> touches a joint and links it to an item
|
||||
///> touches a joint and links it to an m_item
|
||||
void linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
|
||||
int aNet, PNS_ITEM* aWhere );
|
||||
|
||||
|
@ -372,7 +365,7 @@ private:
|
|||
return m_parent == NULL;
|
||||
}
|
||||
|
||||
///> checks if this branch contains an updated version of the item
|
||||
///> checks if this branch contains an updated version of the m_item
|
||||
///> from the root branch.
|
||||
bool overrides( PNS_ITEM* aItem ) const
|
||||
{
|
||||
|
@ -382,16 +375,16 @@ private:
|
|||
PNS_SEGMENT *findRedundantSegment ( PNS_SEGMENT* aSeg );
|
||||
|
||||
///> scans the joint map, forming a line starting from segment (current).
|
||||
void followLine ( PNS_SEGMENT* current,
|
||||
bool scanDirection,
|
||||
int& pos,
|
||||
int limit,
|
||||
VECTOR2I* corners,
|
||||
PNS_SEGMENT** segments );
|
||||
void followLine( PNS_SEGMENT* aCurrent,
|
||||
bool aScanDirection,
|
||||
int& aPos,
|
||||
int aLimit,
|
||||
VECTOR2I* aCorners,
|
||||
PNS_SEGMENT** aSegments );
|
||||
|
||||
///> hash table with the joints, linking the items. Joints are hashed by
|
||||
///> their position, layer set and net.
|
||||
JointMap m_joints;
|
||||
JOINT_MAP m_joints;
|
||||
|
||||
///> node this node was branched from
|
||||
PNS_NODE* m_parent;
|
||||
|
|
|
@ -30,14 +30,11 @@
|
|||
#include "pns_router.h"
|
||||
|
||||
/**
|
||||
*
|
||||
* Cost Estimator Methods
|
||||
*
|
||||
*/
|
||||
|
||||
int PNS_COST_ESTIMATOR::CornerCost( const SEG& a, const SEG& b )
|
||||
int PNS_COST_ESTIMATOR::CornerCost( const SEG& aA, const SEG& aB )
|
||||
{
|
||||
DIRECTION_45 dir_a( a ), dir_b( b );
|
||||
DIRECTION_45 dir_a( aA ), dir_b( aB );
|
||||
|
||||
switch( dir_a.Angle( dir_b ) )
|
||||
{
|
||||
|
@ -109,8 +106,8 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
|
|||
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
|
||||
return true;
|
||||
|
||||
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance && aOther.m_lengthCost <
|
||||
m_lengthCost * aLengthTollerance )
|
||||
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance &&
|
||||
aOther.m_lengthCost < m_lengthCost * aLengthTollerance )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@ -118,9 +115,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* Optimizer
|
||||
*
|
||||
**/
|
||||
PNS_OPTIMIZER::PNS_OPTIMIZER( PNS_NODE* aWorld ) :
|
||||
m_world( aWorld ), m_collisionKindMask( PNS_ITEM::ANY ), m_effortLevel( MERGE_SEGMENTS )
|
||||
|
@ -135,14 +130,14 @@ PNS_OPTIMIZER::~PNS_OPTIMIZER()
|
|||
}
|
||||
|
||||
|
||||
struct PNS_OPTIMIZER::CacheVisitor
|
||||
struct PNS_OPTIMIZER::CACHE_VISITOR
|
||||
{
|
||||
CacheVisitor( const PNS_ITEM* aOurItem, PNS_NODE* aNode, int aMask ) :
|
||||
CACHE_VISITOR( const PNS_ITEM* aOurItem, PNS_NODE* aNode, int aMask ) :
|
||||
m_ourItem( aOurItem ),
|
||||
m_collidingItem( NULL ),
|
||||
m_node( aNode ),
|
||||
m_mask( aMask )
|
||||
{};
|
||||
{}
|
||||
|
||||
bool operator()( PNS_ITEM* aOtherItem )
|
||||
{
|
||||
|
@ -171,14 +166,14 @@ void PNS_OPTIMIZER::cacheAdd( PNS_ITEM* aItem, bool aIsStatic = false )
|
|||
return;
|
||||
|
||||
m_cache.Add( aItem );
|
||||
m_cacheTags[aItem].hits = 1;
|
||||
m_cacheTags[aItem].isStatic = aIsStatic;
|
||||
m_cacheTags[aItem].m_hits = 1;
|
||||
m_cacheTags[aItem].m_isStatic = aIsStatic;
|
||||
}
|
||||
|
||||
|
||||
void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int aEndVertex )
|
||||
{
|
||||
PNS_LINE::SegmentRefs* segs = aLine->LinkedSegments();
|
||||
PNS_LINE::SEGMENT_REFS* segs = aLine->LinkedSegments();
|
||||
|
||||
if( !segs )
|
||||
return;
|
||||
|
@ -219,7 +214,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
|
|||
|
||||
for( CachedItemTags::iterator i = m_cacheTags.begin(); i!= m_cacheTags.end(); ++i )
|
||||
{
|
||||
if( i->second.isStatic )
|
||||
if( i->second.m_isStatic )
|
||||
{
|
||||
m_cache.Remove( i->first );
|
||||
m_cacheTags.erase( i->first );
|
||||
|
@ -230,7 +225,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
|
|||
|
||||
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
|
||||
{
|
||||
CacheVisitor v( aItem, m_world, m_collisionKindMask );
|
||||
CACHE_VISITOR v( aItem, m_world, m_collisionKindMask );
|
||||
|
||||
return m_world->CheckColliding( aItem );
|
||||
|
||||
|
@ -239,19 +234,19 @@ bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
|
|||
|
||||
if( !v.m_collidingItem )
|
||||
{
|
||||
PNS_NODE::OptObstacle obs = m_world->CheckColliding( aItem );
|
||||
PNS_NODE::OPT_OBSTACLE obs = m_world->CheckColliding( aItem );
|
||||
|
||||
if( obs )
|
||||
{
|
||||
if( aUpdateCache )
|
||||
cacheAdd( obs->item );
|
||||
cacheAdd( obs->m_item );
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cacheTags[v.m_collidingItem].hits++;
|
||||
m_cacheTags[v.m_collidingItem].m_hits++;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -430,7 +425,6 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
|
|||
|
||||
int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath );
|
||||
|
||||
|
||||
if( aLine->SegmentCount() < 4 )
|
||||
return false;
|
||||
|
||||
|
@ -442,7 +436,8 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
|
|||
const SEG s1 = aCurrentPath.CSegment( n );
|
||||
const SEG s2 = aCurrentPath.CSegment( n + step );
|
||||
|
||||
SHAPE_LINE_CHAIN path[2], * picked = NULL;
|
||||
SHAPE_LINE_CHAIN path[2];
|
||||
SHAPE_LINE_CHAIN* picked = NULL;
|
||||
int cost[2];
|
||||
|
||||
for( int i = 0; i < 2; i++ )
|
||||
|
@ -485,10 +480,10 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
|
|||
}
|
||||
|
||||
|
||||
PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::circleBreakouts( int aWidth,
|
||||
PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::circleBreakouts( int aWidth,
|
||||
const SHAPE* aShape, bool aPermitDiagonal ) const
|
||||
{
|
||||
BreakoutList breakouts;
|
||||
BREAKOUT_LIST breakouts;
|
||||
|
||||
for( int angle = 0; angle < 360; angle += 45 )
|
||||
{
|
||||
|
@ -505,12 +500,12 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::circleBreakouts( int aWidth,
|
|||
}
|
||||
|
||||
|
||||
PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
|
||||
PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::rectBreakouts( int aWidth,
|
||||
const SHAPE* aShape, bool aPermitDiagonal ) const
|
||||
{
|
||||
const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>(aShape);
|
||||
VECTOR2I s = rect->GetSize(), c = rect->GetPosition() + VECTOR2I( s.x / 2, s.y / 2 );
|
||||
BreakoutList breakouts;
|
||||
BREAKOUT_LIST breakouts;
|
||||
|
||||
VECTOR2I d_offset;
|
||||
|
||||
|
@ -520,7 +515,6 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
|
|||
VECTOR2I d_vert = VECTOR2I( 0, s.y / 2 + aWidth );
|
||||
VECTOR2I d_horiz = VECTOR2I( s.x / 2 + aWidth, 0 );
|
||||
|
||||
|
||||
breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_horiz ) );
|
||||
breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_horiz ) );
|
||||
breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_vert ) );
|
||||
|
@ -560,7 +554,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
|
|||
}
|
||||
|
||||
|
||||
PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
|
||||
PNS_OPTIMIZER::BREAKOUT_LIST PNS_OPTIMIZER::computeBreakouts( int aWidth,
|
||||
const PNS_ITEM* aItem, bool aPermitDiagonal ) const
|
||||
{
|
||||
switch( aItem->Kind() )
|
||||
|
@ -599,7 +593,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
|
|||
break;
|
||||
}
|
||||
|
||||
return BreakoutList();
|
||||
return BREAKOUT_LIST();
|
||||
}
|
||||
|
||||
|
||||
|
@ -632,7 +626,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
|
|||
typedef std::pair<int, SHAPE_LINE_CHAIN> RtVariant;
|
||||
std::vector<RtVariant> variants;
|
||||
|
||||
BreakoutList breakouts = computeBreakouts( aLine->Width(), aPad, true );
|
||||
BREAKOUT_LIST breakouts = computeBreakouts( aLine->Width(), aPad, true );
|
||||
|
||||
SHAPE_LINE_CHAIN line = ( aEnd ? aLine->CLine().Reverse() : aLine->CLine() );
|
||||
|
||||
|
@ -742,6 +736,7 @@ bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine )
|
|||
vtx < 0 ? line.PointCount() - 1 : line.PointCount() - 1 - vtx );
|
||||
|
||||
aLine->Line().Simplify();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -769,11 +764,9 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
|
|||
int thr = aLine->Width() * 10;
|
||||
int len = aLine->CLine().Length();
|
||||
|
||||
|
||||
if( !startPad )
|
||||
return false;
|
||||
|
||||
|
||||
bool startMatch = startPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
|
||||
bool endMatch = false;
|
||||
|
||||
|
@ -784,10 +777,8 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
|
|||
endMatch = aLine->EndsWithVia();
|
||||
}
|
||||
|
||||
|
||||
if( startMatch && endMatch && len < thr )
|
||||
{
|
||||
|
||||
for(int i = 0; i < 2; i++ )
|
||||
{
|
||||
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
|
||||
|
@ -795,8 +786,6 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
|
|||
PNS_LINE repl;
|
||||
repl = PNS_LINE( *aLine, l2 );
|
||||
|
||||
|
||||
|
||||
if( !m_world->CheckColliding( &repl ) )
|
||||
{
|
||||
aLine->SetShape( repl.CLine() );
|
||||
|
@ -804,5 +793,6 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -38,23 +38,22 @@ class PNS_ROUTER;
|
|||
*
|
||||
* Calculates the cost of a given line, taking corner angles and total length into account.
|
||||
**/
|
||||
|
||||
class PNS_COST_ESTIMATOR
|
||||
{
|
||||
public:
|
||||
PNS_COST_ESTIMATOR() :
|
||||
m_lengthCost( 0 ),
|
||||
m_cornerCost( 0 )
|
||||
{};
|
||||
{}
|
||||
|
||||
PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& b ) :
|
||||
m_lengthCost( b.m_lengthCost ),
|
||||
m_cornerCost( b.m_cornerCost )
|
||||
{};
|
||||
PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& aB ) :
|
||||
m_lengthCost( aB.m_lengthCost ),
|
||||
m_cornerCost( aB.m_cornerCost )
|
||||
{}
|
||||
|
||||
~PNS_COST_ESTIMATOR() {};
|
||||
|
||||
static int CornerCost( const SEG& a, const SEG& b );
|
||||
static int CornerCost( const SEG& aA, const SEG& aB );
|
||||
static int CornerCost( const SHAPE_LINE_CHAIN& aLine );
|
||||
static int CornerCost( const PNS_LINE& aLine );
|
||||
|
||||
|
@ -84,7 +83,6 @@ private:
|
|||
* the procedure as long as the total cost of the line keeps decreasing
|
||||
* - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS).
|
||||
**/
|
||||
|
||||
class PNS_OPTIMIZER
|
||||
{
|
||||
public:
|
||||
|
@ -122,14 +120,14 @@ public:
|
|||
private:
|
||||
static const int MaxCachedItems = 256;
|
||||
|
||||
typedef std::vector<SHAPE_LINE_CHAIN> BreakoutList;
|
||||
typedef std::vector<SHAPE_LINE_CHAIN> BREAKOUT_LIST;
|
||||
|
||||
struct CacheVisitor;
|
||||
struct CACHE_VISITOR;
|
||||
|
||||
struct CachedItem
|
||||
struct CACHED_ITEM
|
||||
{
|
||||
int hits;
|
||||
bool isStatic;
|
||||
int m_hits;
|
||||
bool m_isStatic;
|
||||
};
|
||||
|
||||
bool mergeObtuse( PNS_LINE* aLine );
|
||||
|
@ -142,15 +140,13 @@ private:
|
|||
bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
|
||||
bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
|
||||
|
||||
|
||||
void cacheAdd( PNS_ITEM* aItem, bool aIsStatic );
|
||||
void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 );
|
||||
|
||||
BreakoutList circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BreakoutList rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BreakoutList ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BreakoutList computeBreakouts( int aWidth, const PNS_ITEM* aItem,
|
||||
bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
|
||||
BREAKOUT_LIST computeBreakouts( int aWidth, const PNS_ITEM* aItem, bool aPermitDiagonal ) const;
|
||||
|
||||
int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex );
|
||||
|
||||
|
@ -158,7 +154,7 @@ private:
|
|||
|
||||
SHAPE_INDEX_LIST<PNS_ITEM*> m_cache;
|
||||
|
||||
typedef boost::unordered_map<PNS_ITEM*, CachedItem> CachedItemTags;
|
||||
typedef boost::unordered_map<PNS_ITEM*, CACHED_ITEM> CachedItemTags;
|
||||
CachedItemTags m_cacheTags;
|
||||
PNS_NODE* m_world;
|
||||
int m_collisionKindMask;
|
||||
|
|
|
@ -82,25 +82,25 @@ public:
|
|||
m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance();
|
||||
}
|
||||
|
||||
int localPadClearance( const PNS_ITEM * item ) const
|
||||
int localPadClearance( const PNS_ITEM* aItem ) const
|
||||
{
|
||||
if(!item->Parent() || item->Parent()->Type() != PCB_PAD_T )
|
||||
if( !aItem->Parent() || aItem->Parent()->Type() != PCB_PAD_T )
|
||||
return 0;
|
||||
|
||||
const D_PAD *pad = static_cast<D_PAD *>( item->Parent() );
|
||||
const D_PAD* pad = static_cast<D_PAD*>( aItem->Parent() );
|
||||
|
||||
return pad->GetLocalClearance();
|
||||
}
|
||||
|
||||
int operator()( const PNS_ITEM* a, const PNS_ITEM* b )
|
||||
int operator()( const PNS_ITEM* aA, const PNS_ITEM* aB )
|
||||
{
|
||||
int net_a = a->Net();
|
||||
int net_a = aA->Net();
|
||||
int cl_a = ( net_a >= 0 ? m_clearanceCache[net_a] : m_defaultClearance );
|
||||
int net_b = b->Net();
|
||||
int net_b = aB->Net();
|
||||
int cl_b = ( net_b >= 0 ? m_clearanceCache[net_b] : m_defaultClearance );
|
||||
|
||||
int pad_a = localPadClearance( a );
|
||||
int pad_b = localPadClearance( b );
|
||||
int pad_a = localPadClearance( aA );
|
||||
int pad_b = localPadClearance( aB );
|
||||
|
||||
cl_a = std::max( cl_a, pad_a );
|
||||
cl_b = std::max( cl_b, pad_b );
|
||||
|
@ -113,6 +113,7 @@ private:
|
|||
int m_defaultClearance;
|
||||
};
|
||||
|
||||
|
||||
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
||||
{
|
||||
PNS_LAYERSET layers( 0, 15 );
|
||||
|
@ -162,7 +163,6 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
|||
double orient = aPad->GetOrientation() / 10.0;
|
||||
bool nonOrtho = false;
|
||||
|
||||
|
||||
if( orient == 90.0 || orient == 270.0 )
|
||||
sz = VECTOR2I( sz.y, sz.x );
|
||||
else if( orient != 0.0 && orient != 180.0 )
|
||||
|
@ -183,7 +183,8 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
|||
case PAD_OVAL:
|
||||
if( sz.x == sz.y )
|
||||
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
|
||||
else {
|
||||
else
|
||||
{
|
||||
VECTOR2I delta;
|
||||
|
||||
if( sz.x > sz.y )
|
||||
|
@ -191,7 +192,8 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
|||
else
|
||||
delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );
|
||||
|
||||
SHAPE_SEGMENT *shape = new SHAPE_SEGMENT( c - delta, c + delta, std::min(sz.x, sz.y) );
|
||||
SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
|
||||
std::min( sz.x, sz.y ) );
|
||||
solid->SetShape( shape );
|
||||
}
|
||||
break;
|
||||
|
@ -203,6 +205,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
|
|||
default:
|
||||
TRACEn( 0, "unsupported pad shape" );
|
||||
delete solid;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
@ -250,7 +253,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
|
|||
LAYER_MSK mask = m_board->GetEnabledLayers() & m_board->GetVisibleLayers();
|
||||
LAYER_NUM l = m_currentLayer;
|
||||
|
||||
do {
|
||||
do
|
||||
{
|
||||
l += ( aUp ? 1 : -1 );
|
||||
|
||||
if( l > LAST_COPPER_LAYER )
|
||||
|
@ -261,7 +265,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
|
|||
|
||||
if( mask & GetLayerMask( l ) )
|
||||
return l;
|
||||
} while( l != m_currentLayer );
|
||||
}
|
||||
while( l != m_currentLayer );
|
||||
|
||||
return l;
|
||||
}
|
||||
|
@ -269,7 +274,6 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
|
|||
|
||||
void PNS_ROUTER::SyncWorld()
|
||||
{
|
||||
|
||||
if( !m_board )
|
||||
{
|
||||
TRACEn( 0, "No board attached, aborting sync." );
|
||||
|
@ -379,13 +383,6 @@ void PNS_ROUTER::ClearWorld()
|
|||
}
|
||||
|
||||
|
||||
/*void PNS_ROUTER::SetCurrentWidth( int w )
|
||||
{
|
||||
// fixme: change width while routing
|
||||
m_currentWidth = w;
|
||||
}*/
|
||||
|
||||
|
||||
bool PNS_ROUTER::RoutingInProgress() const
|
||||
{
|
||||
return m_state != IDLE;
|
||||
|
@ -405,31 +402,31 @@ const PNS_ITEMSET PNS_ROUTER::QueryHoverItems( const VECTOR2I& aP )
|
|||
}
|
||||
|
||||
|
||||
const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplitsSegment )
|
||||
const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSplitsSegment )
|
||||
{
|
||||
VECTOR2I anchor;
|
||||
|
||||
if( !item )
|
||||
if( !aItem )
|
||||
{
|
||||
aSplitsSegment = false;
|
||||
return aP;
|
||||
}
|
||||
|
||||
switch( item->Kind() )
|
||||
switch( aItem->Kind() )
|
||||
{
|
||||
case PNS_ITEM::SOLID:
|
||||
anchor = static_cast<PNS_SOLID*>(item)->Pos();
|
||||
anchor = static_cast<PNS_SOLID*>( aItem )->Pos();
|
||||
aSplitsSegment = false;
|
||||
break;
|
||||
|
||||
case PNS_ITEM::VIA:
|
||||
anchor = static_cast<PNS_VIA*>(item)->Pos();
|
||||
anchor = static_cast<PNS_VIA*>( aItem )->Pos();
|
||||
aSplitsSegment = false;
|
||||
break;
|
||||
|
||||
case PNS_ITEM::SEGMENT:
|
||||
{
|
||||
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
|
||||
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( aItem );
|
||||
const SEG& s = seg->Seg();
|
||||
int w = seg->Width();
|
||||
|
||||
|
@ -455,6 +452,7 @@ const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplit
|
|||
return anchor;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
if( !aStartItem || aStartItem->OfKind( PNS_ITEM::SOLID ) )
|
||||
|
@ -462,9 +460,11 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
|
||||
m_dragger = new PNS_DRAGGER ( this );
|
||||
m_dragger->SetWorld( m_world );
|
||||
|
||||
if( m_dragger->Start ( aP, aStartItem ) )
|
||||
m_state = DRAG_SEGMENT;
|
||||
else {
|
||||
else
|
||||
{
|
||||
delete m_dragger;
|
||||
m_state = IDLE;
|
||||
return false;
|
||||
|
@ -476,8 +476,6 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
|||
|
||||
bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem )
|
||||
{
|
||||
|
||||
|
||||
m_state = ROUTE_TRACK;
|
||||
|
||||
m_placer = new PNS_LINE_PLACER( this );
|
||||
|
@ -530,12 +528,14 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance
|
|||
m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::DisplayItems( const PNS_ITEMSET& aItems )
|
||||
{
|
||||
BOOST_FOREACH( const PNS_ITEM *item, aItems.CItems() )
|
||||
DisplayItem( item );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth )
|
||||
{
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems );
|
||||
|
@ -547,18 +547,17 @@ void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int
|
|||
}
|
||||
|
||||
|
||||
|
||||
void PNS_ROUTER::DisplayDebugPoint( const VECTOR2I pos, int aType )
|
||||
void PNS_ROUTER::DisplayDebugPoint( const VECTOR2I aPos, int aType )
|
||||
{
|
||||
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems );
|
||||
|
||||
pitem->Point( pos, aType );
|
||||
pitem->Point( aPos, aType );
|
||||
m_previewItems->Add( pitem );
|
||||
pitem->ViewSetVisible( true );
|
||||
m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
|
||||
{
|
||||
m_currentEnd = aP;
|
||||
|
@ -573,12 +572,14 @@ void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
|
|||
case DRAG_SEGMENT:
|
||||
moveDragging (aP, endItem );
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* endItem )
|
||||
|
||||
void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
eraseView();
|
||||
|
||||
|
@ -588,18 +589,20 @@ void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* endItem )
|
|||
updateView ( m_dragger->CurrentNode(), dragged );
|
||||
}
|
||||
|
||||
void PNS_ROUTER::markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ItemVector& aRemoved )
|
||||
{
|
||||
|
||||
void PNS_ROUTER::markViolations( PNS_NODE* aNode, PNS_ITEMSET& aCurrent,
|
||||
PNS_NODE::ITEM_VECTOR& aRemoved )
|
||||
{
|
||||
BOOST_FOREACH( PNS_ITEM *item, aCurrent.Items() )
|
||||
{
|
||||
PNS_NODE::Obstacles obstacles;
|
||||
PNS_NODE::OBSTACLES obstacles;
|
||||
|
||||
aNode->QueryColliding( item, obstacles, PNS_ITEM::ANY );
|
||||
|
||||
if( item->OfKind( PNS_ITEM::LINE ) )
|
||||
{
|
||||
PNS_LINE *l = static_cast<PNS_LINE*>( item );
|
||||
|
||||
if( l->EndsWithVia() )
|
||||
{
|
||||
PNS_VIA v ( l->Via() );
|
||||
|
@ -609,19 +612,20 @@ void PNS_ROUTER::markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NOD
|
|||
|
||||
BOOST_FOREACH( PNS_OBSTACLE& obs, obstacles )
|
||||
{
|
||||
int clearance = aNode->GetClearance( item, obs.item );
|
||||
std::auto_ptr<PNS_ITEM> tmp ( obs.item->Clone() );
|
||||
int clearance = aNode->GetClearance( item, obs.m_item );
|
||||
std::auto_ptr<PNS_ITEM> tmp( obs.m_item->Clone() );
|
||||
tmp->Mark( MK_VIOLATION );
|
||||
DisplayItem( tmp.get(), -1, clearance );
|
||||
aRemoved.push_back(obs.item);
|
||||
aRemoved.push_back( obs.m_item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent )
|
||||
{
|
||||
PNS_NODE::ItemVector removed, added;
|
||||
PNS_NODE::Obstacles obstacles;
|
||||
PNS_NODE::ITEM_VECTOR removed, added;
|
||||
PNS_NODE::OBSTACLES obstacles;
|
||||
|
||||
if( !aNode )
|
||||
return;
|
||||
|
@ -661,15 +665,14 @@ void PNS_ROUTER::ApplySettings()
|
|||
m_placer->Move( m_currentEnd, m_currentEndItem );
|
||||
movePlacing( m_currentEnd, m_currentEndItem );
|
||||
}
|
||||
|
||||
// TODO handle mode/optimization/other options change
|
||||
}
|
||||
|
||||
void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* endItem )
|
||||
|
||||
void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
eraseView();
|
||||
|
||||
m_placer->Move( aP, endItem );
|
||||
m_placer->Move( aP, aEndItem );
|
||||
PNS_LINE current = m_placer->Trace();
|
||||
|
||||
DisplayItem( ¤t );
|
||||
|
@ -681,9 +684,10 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* endItem )
|
|||
updateView ( m_placer->CurrentNode ( true ), tmp );
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::CommitRouting( PNS_NODE* aNode )
|
||||
{
|
||||
PNS_NODE::ItemVector removed, added;
|
||||
PNS_NODE::ITEM_VECTOR removed, added;
|
||||
|
||||
aNode->GetUpdatedItems( removed, added );
|
||||
|
||||
|
@ -770,6 +774,7 @@ PNS_VIA* PNS_ROUTER::checkLoneVia( PNS_JOINT* aJoint ) const
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
||||
{
|
||||
bool rv = false;
|
||||
|
@ -779,8 +784,8 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
case ROUTE_TRACK:
|
||||
rv = m_placer->FixRoute( aP, aEndItem );
|
||||
m_placingVia = false;
|
||||
|
||||
break;
|
||||
|
||||
case DRAG_SEGMENT:
|
||||
rv = m_dragger->FixRoute();
|
||||
break;
|
||||
|
@ -789,7 +794,6 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
break;
|
||||
}
|
||||
|
||||
|
||||
if( rv )
|
||||
StopRouting();
|
||||
|
||||
|
@ -797,7 +801,6 @@ bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
|
|||
}
|
||||
|
||||
|
||||
|
||||
void PNS_ROUTER::StopRouting()
|
||||
{
|
||||
// Update the ratsnest with new changes
|
||||
|
@ -833,22 +836,23 @@ void PNS_ROUTER::FlipPosture()
|
|||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::SwitchLayer( int layer )
|
||||
void PNS_ROUTER::SwitchLayer( int aLayer )
|
||||
{
|
||||
switch( m_state )
|
||||
{
|
||||
case IDLE:
|
||||
m_currentLayer = layer;
|
||||
m_currentLayer = aLayer;
|
||||
break;
|
||||
|
||||
case ROUTE_TRACK:
|
||||
if( m_startsOnVia )
|
||||
{
|
||||
m_currentLayer = layer;
|
||||
m_currentLayer = aLayer;
|
||||
//m_placer->StartPlacement( m_currentStart, m_currentNet, m_currentWidth,
|
||||
// m_currentLayer );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -864,31 +868,37 @@ void PNS_ROUTER::ToggleViaPlacement()
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
int PNS_ROUTER::GetCurrentNet() const
|
||||
{
|
||||
switch( m_state )
|
||||
{
|
||||
case ROUTE_TRACK:
|
||||
return m_placer->CurrentNet();
|
||||
|
||||
default:
|
||||
return m_currentNet;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int PNS_ROUTER::GetCurrentLayer() const
|
||||
{
|
||||
switch( m_state )
|
||||
{
|
||||
case ROUTE_TRACK:
|
||||
return m_placer->CurrentLayer();
|
||||
|
||||
default:
|
||||
return m_currentLayer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PNS_ROUTER::DumpLog()
|
||||
{
|
||||
PNS_LOGGER* logger = NULL;
|
||||
|
||||
switch( m_state )
|
||||
{
|
||||
case DRAG_SEGMENT:
|
||||
|
|
|
@ -51,7 +51,8 @@ class PNS_CLEARANCE_FUNC;
|
|||
class PNS_SHOVE;
|
||||
class PNS_DRAGGER;
|
||||
|
||||
namespace KIGFX {
|
||||
namespace KIGFX
|
||||
{
|
||||
class VIEW;
|
||||
class VIEW_GROUP;
|
||||
};
|
||||
|
@ -62,7 +63,6 @@ class VIEW_GROUP;
|
|||
*
|
||||
* Main router class.
|
||||
*/
|
||||
|
||||
class PNS_ROUTER
|
||||
{
|
||||
private:
|
||||
|
@ -94,7 +94,7 @@ public:
|
|||
|
||||
const VECTOR2I CurrentEnd() const;
|
||||
|
||||
int GetClearance( const PNS_ITEM* a, const PNS_ITEM* b ) const;
|
||||
int GetClearance( const PNS_ITEM* aA, const PNS_ITEM* aB ) const;
|
||||
|
||||
PNS_NODE* GetWorld() const
|
||||
{
|
||||
|
@ -114,8 +114,8 @@ public:
|
|||
|
||||
void ToggleViaPlacement();
|
||||
|
||||
int GetCurrentLayer() const;// { return m_currentLayer; }
|
||||
int GetCurrentNet() const;// { return m_currentNet; }
|
||||
int GetCurrentLayer() const;
|
||||
int GetCurrentNet() const;
|
||||
|
||||
void DumpLog();
|
||||
|
||||
|
@ -134,14 +134,19 @@ public:
|
|||
// typedef boost::optional<hoverItem> optHoverItem;
|
||||
|
||||
const PNS_ITEMSET QueryHoverItems( const VECTOR2I& aP );
|
||||
const VECTOR2I SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplitsSegment );
|
||||
const VECTOR2I SnapToItem( PNS_ITEM* aItem, VECTOR2I aP, bool& aSplitsSegment );
|
||||
|
||||
bool StartDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
|
||||
|
||||
void SetIterLimit( int aX ) { m_iterLimit = aX; }
|
||||
int GetIterLimit() const { return m_iterLimit; };
|
||||
|
||||
void SetShowIntermediateSteps(bool aX, int aSnapshotIter = -1 ) { m_showInterSteps = aX; m_snapshotIter = aSnapshotIter; }
|
||||
void SetShowIntermediateSteps( bool aX, int aSnapshotIter = -1 )
|
||||
{
|
||||
m_showInterSteps = aX;
|
||||
m_snapshotIter = aSnapshotIter;
|
||||
}
|
||||
|
||||
bool GetShowIntermediateSteps() const { return m_showInterSteps; }
|
||||
int GetShapshotIter() const { return m_snapshotIter; }
|
||||
|
||||
|
@ -168,7 +173,7 @@ public:
|
|||
|
||||
/**
|
||||
* Applies stored settings.
|
||||
* \see Settings()
|
||||
* @see Settings()
|
||||
*/
|
||||
void ApplySettings();
|
||||
|
||||
|
@ -193,20 +198,19 @@ public:
|
|||
return m_snappingEnabled;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem );
|
||||
void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
|
||||
|
||||
void eraseView();
|
||||
void updateView( PNS_NODE *aNode, PNS_ITEMSET &aCurrent ); //PNS_LINE *aCurrent = NULL );
|
||||
void updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent );
|
||||
|
||||
void clearViewFlags();
|
||||
|
||||
// optHoverItem queryHoverItemEx(const VECTOR2I& aP);
|
||||
|
||||
PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const; // std::vector<PNS_ITEM*> aItems) const;
|
||||
void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP ); // optHoverItem& aItem);
|
||||
PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const;
|
||||
void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP );
|
||||
PNS_VIA* checkLoneVia( PNS_JOINT* aJoint ) const;
|
||||
|
||||
PNS_ITEM* syncPad( D_PAD* aPad );
|
||||
|
@ -219,7 +223,7 @@ private:
|
|||
|
||||
void highlightCurrent( bool enabled );
|
||||
|
||||
void markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ItemVector& aRemoved );
|
||||
void markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ITEM_VECTOR& aRemoved );
|
||||
|
||||
int m_currentLayer;
|
||||
int m_currentNet;
|
||||
|
@ -241,7 +245,6 @@ private:
|
|||
KIGFX::VIEW* m_view;
|
||||
KIGFX::VIEW_GROUP* m_previewItems;
|
||||
|
||||
|
||||
PNS_ITEM* m_currentEndItem;
|
||||
|
||||
VECTOR2I m_currentEnd;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
|
||||
{
|
||||
m_routingMode = RM_Walkaround;
|
||||
m_optimizerEffort = OE_Full;
|
||||
m_optimizerEffort = OE_FULL;
|
||||
m_removeLoops = true;
|
||||
m_smartPads = true;
|
||||
m_shoveVias = true;
|
||||
|
@ -38,11 +38,13 @@ PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
|
|||
m_canViolateDRC = false;
|
||||
}
|
||||
|
||||
|
||||
TIME_LIMIT PNS_ROUTING_SETTINGS::ShoveTimeLimit() const
|
||||
{
|
||||
return TIME_LIMIT ( m_shoveTimeLimit );
|
||||
}
|
||||
|
||||
|
||||
int PNS_ROUTING_SETTINGS::ShoveIterationLimit() const
|
||||
{
|
||||
return m_shoveIterationLimit;
|
||||
|
|
|
@ -36,9 +36,9 @@ enum PNS_MODE
|
|||
///> Optimization effort
|
||||
enum PNS_OPTIMIZATION_EFFORT
|
||||
{
|
||||
OE_Low = 0,
|
||||
OE_Medium = 1,
|
||||
OE_Full = 2
|
||||
OE_LOW = 0,
|
||||
OE_MEDIUM = 1,
|
||||
OE_FULL = 2
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -133,7 +133,6 @@ public:
|
|||
TIME_LIMIT WalkaroundTimeLimit() const;
|
||||
|
||||
private:
|
||||
|
||||
bool m_shoveVias;
|
||||
bool m_startDiagonal;
|
||||
bool m_removeLoops;
|
||||
|
|
|
@ -37,13 +37,13 @@ class PNS_SEGMENT : public PNS_ITEM
|
|||
public:
|
||||
PNS_SEGMENT() :
|
||||
PNS_ITEM( SEGMENT )
|
||||
{};
|
||||
{}
|
||||
|
||||
PNS_SEGMENT( const SEG& aSeg, int aNet ) :
|
||||
PNS_ITEM( SEGMENT ), m_seg( aSeg, 0 )
|
||||
{
|
||||
m_net = aNet;
|
||||
};
|
||||
}
|
||||
|
||||
PNS_SEGMENT( const PNS_LINE& aParentLine, const SEG& aSeg ) :
|
||||
PNS_ITEM( SEGMENT ),
|
||||
|
@ -55,7 +55,6 @@ public:
|
|||
m_rank = aParentLine.Rank();
|
||||
};
|
||||
|
||||
|
||||
PNS_SEGMENT* Clone( ) const;
|
||||
|
||||
const SHAPE* Shape() const
|
||||
|
|
|
@ -41,17 +41,18 @@
|
|||
|
||||
#include <profile.h>
|
||||
|
||||
static void sanityCheck (PNS_LINE *l_old, PNS_LINE *l_new)
|
||||
static void sanityCheck( PNS_LINE *aOld, PNS_LINE *aNew )
|
||||
{
|
||||
assert (l_old->CPoint(0) == l_new->CPoint(0) );
|
||||
assert (l_old->CPoint(-1) == l_new->CPoint(-1 ));
|
||||
assert( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
|
||||
assert( aOld->CPoint( -1 ) == aNew->CPoint( -1 ) );
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
||||
PNS_ALGO_BASE ( aRouter )
|
||||
{
|
||||
m_root = aWorld;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::~PNS_SHOVE()
|
||||
|
@ -61,15 +62,18 @@ PNS_SHOVE::~PNS_SHOVE()
|
|||
delete item;
|
||||
}
|
||||
|
||||
|
||||
// garbage-collected line assembling
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
// garbage-collected line cloning
|
||||
PNS_LINE *PNS_SHOVE::cloneLine ( const PNS_LINE *aLine )
|
||||
{
|
||||
|
@ -79,6 +83,7 @@ PNS_LINE *PNS_SHOVE::cloneLine ( const PNS_LINE *aLine )
|
|||
return l;
|
||||
}
|
||||
|
||||
|
||||
// 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:
|
||||
|
@ -97,7 +102,9 @@ bool PNS_SHOVE::checkBumpDirection ( PNS_LINE *aCurrent, PNS_LINE *aShoved ) con
|
|||
return !aShoved->CLine().PointOnEdge( ps );
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus 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 = m_currentNode->GetClearance( aCurrent, aObstacle );
|
||||
const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() );
|
||||
|
@ -110,8 +117,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
|
|||
|
||||
if( shortest.PointCount() < 2 )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
if( aObstacle->CPoint( -1 ) != shortest.CPoint( -1 ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
if( aObstacle->CPoint( 0 ) != shortest.CPoint( 0 ) )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
|
@ -123,7 +132,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
|
|||
return SH_OK;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE *aObstacle, PNS_LINE *aShoved, const HullSet& hulls )
|
||||
|
||||
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();
|
||||
bool failingDirCheck = false;
|
||||
|
@ -138,9 +149,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
|
|||
SHAPE_LINE_CHAIN path;
|
||||
PNS_LINE l( *aObstacle );
|
||||
|
||||
for(int i = 0; i < (int)hulls.size(); i++ )
|
||||
for( int i = 0; i < (int) aHulls.size(); i++ )
|
||||
{
|
||||
const SHAPE_LINE_CHAIN& hull = hulls[invertTraversal ? hulls.size() - 1 - i : i];
|
||||
const SHAPE_LINE_CHAIN& hull = aHulls[invertTraversal ? aHulls.size() - 1 - i : i];
|
||||
|
||||
l.Walkaround( hull, path, clockwise );
|
||||
path.Simplify();
|
||||
|
@ -183,6 +194,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
|
|||
TRACE( 100, "attempt %d fail direction-check", attempt );
|
||||
failingDirCheck = true;
|
||||
aShoved->SetShape( l.CLine() );
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -219,7 +231,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
|
|||
return failingDirCheck ? SH_OK : SH_INCOMPLETE;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus 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();
|
||||
|
||||
|
@ -228,6 +242,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI
|
|||
if( aObstacle->LinkedSegments() )
|
||||
{
|
||||
BOOST_FOREACH( PNS_SEGMENT* s, *aObstacle->LinkedSegments() )
|
||||
|
||||
if( s->Marker() & MK_HEAD )
|
||||
{
|
||||
obstacleIsHead = true;
|
||||
|
@ -235,19 +250,21 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI
|
|||
}
|
||||
}
|
||||
|
||||
ShoveStatus rv;
|
||||
SHOVE_STATUS rv;
|
||||
|
||||
bool viaOnEnd = aCurrent->EndsWithVia();
|
||||
|
||||
if( viaOnEnd && ( !aCurrent->LayersOverlap( aObstacle ) || aCurrent->SegmentCount() == 0 ) )
|
||||
{
|
||||
rv = walkaroundLoneVia( aCurrent, aObstacle, aShoved );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
int w = aObstacle->Width();
|
||||
int n_segs = aCurrent->SegmentCount();
|
||||
int clearance = m_currentNode->GetClearance( aCurrent, aObstacle );
|
||||
|
||||
HullSet hulls;
|
||||
HULL_SET hulls;
|
||||
|
||||
hulls.reserve( n_segs + 1 );
|
||||
|
||||
|
@ -270,17 +287,16 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI
|
|||
}
|
||||
|
||||
|
||||
PNS_SHOVE::ShoveStatus 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 = cloneLine( obstacleLine );
|
||||
|
||||
ShoveStatus rv = processSingleLine ( aCurrent, obstacleLine, shovedLine );
|
||||
SHOVE_STATUS rv = processSingleLine( aCurrent, obstacleLine, shovedLine );
|
||||
|
||||
assert ( obstacleLine->LayersOverlap( shovedLine ) );
|
||||
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
if ( shovedLine->Marker() & MK_HEAD )
|
||||
|
@ -307,11 +323,12 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSegment( PNS_LINE *aCurrent, PNS_SE
|
|||
return rv;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingLine( PNS_LINE *aCurrent, PNS_LINE *aObstacle )
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingLine( PNS_LINE *aCurrent, PNS_LINE *aObstacle )
|
||||
{
|
||||
PNS_LINE* shovedLine = cloneLine( aObstacle );
|
||||
|
||||
ShoveStatus rv = processSingleLine ( aCurrent, aObstacle, shovedLine );
|
||||
SHOVE_STATUS rv = processSingleLine( aCurrent, aObstacle, shovedLine );
|
||||
|
||||
if( rv == SH_OK )
|
||||
{
|
||||
|
@ -333,20 +350,17 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingLine( PNS_LINE *aCurrent, PNS_LINE
|
|||
m_logger.Log( aCurrent, 1, "current-line" );
|
||||
m_logger.Log( shovedLine, 3, "shoved-line" );
|
||||
#endif
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLID *aObstacleSolid )
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid )
|
||||
{
|
||||
PNS_WALKAROUND walkaround( m_currentNode, Router() );
|
||||
PNS_LINE* walkaroundLine = cloneLine( aCurrent );
|
||||
|
||||
|
||||
if( aCurrent->EndsWithVia() )
|
||||
{
|
||||
PNS_VIA vh = aCurrent->Via();
|
||||
|
@ -357,11 +371,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI
|
|||
return SH_INCOMPLETE;
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
|
||||
{
|
||||
if( item->OfKind( PNS_ITEM::VIA ) )
|
||||
{
|
||||
via = (PNS_VIA*) item;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( via && m_currentNode->CheckColliding( via, aObstacleSolid ) )
|
||||
return onCollidingVia( aObstacleSolid, via );
|
||||
|
@ -377,12 +393,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI
|
|||
{
|
||||
nextRank = currentRank + 10000;
|
||||
walkaround.SetSingleDirection( false );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
nextRank = currentRank - 1;
|
||||
walkaround.SetSingleDirection( true );
|
||||
}
|
||||
|
||||
|
||||
if( walkaround.Route( *aCurrent, *walkaroundLine, false ) != PNS_WALKAROUND::DONE )
|
||||
return SH_INCOMPLETE;
|
||||
|
||||
|
@ -399,7 +416,6 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI
|
|||
m_newHead = *walkaroundLine;
|
||||
}
|
||||
|
||||
|
||||
m_currentNode->Replace( aCurrent, walkaroundLine );
|
||||
walkaroundLine->SetRank ( nextRank );
|
||||
|
||||
|
@ -423,13 +439,13 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
|
|||
|
||||
while( !m_nodeStack.empty() )
|
||||
{
|
||||
SpringbackTag spTag = m_nodeStack.back();
|
||||
SPRINGBACK_TAG spTag = m_nodeStack.back();
|
||||
|
||||
if( !spTag.node->CheckColliding( aHeadSet ) )
|
||||
if( !spTag.m_node->CheckColliding( aHeadSet ) )
|
||||
{
|
||||
rv = true;
|
||||
|
||||
delete spTag.node;
|
||||
delete spTag.m_node;
|
||||
m_nodeStack.pop_back();
|
||||
}
|
||||
else
|
||||
|
@ -440,23 +456,23 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
|
|||
}
|
||||
|
||||
|
||||
|
||||
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems, const PNS_COST_ESTIMATOR& aCost )
|
||||
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
|
||||
const PNS_COST_ESTIMATOR& aCost )
|
||||
{
|
||||
SpringbackTag st;
|
||||
SPRINGBACK_TAG st;
|
||||
|
||||
st.node = aNode;
|
||||
st.cost = aCost;
|
||||
st.headItems = aHeadItems;
|
||||
st.m_node = aNode;
|
||||
st.m_cost = aCost;
|
||||
st.m_headItems = aHeadItems;
|
||||
m_nodeStack.push_back( st );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForce, int aCurrentRank )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank )
|
||||
{
|
||||
|
||||
LinePairVec draggedLines;
|
||||
LINE_PAIR_VEC draggedLines;
|
||||
VECTOR2I p0 ( aVia->Pos() );
|
||||
PNS_JOINT* jt = m_currentNode->FindJoint( p0, 1, aVia->Net() );
|
||||
PNS_VIA* pushedVia = aVia -> Clone();
|
||||
|
@ -480,7 +496,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc
|
|||
if( item->OfKind( PNS_ITEM::SEGMENT ) )
|
||||
{
|
||||
PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
|
||||
LinePair lp;
|
||||
LINE_PAIR lp;
|
||||
int segIndex;
|
||||
|
||||
lp.first = assembleLine( seg, &segIndex );
|
||||
|
@ -511,7 +527,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc
|
|||
m_logger.Log ( pushedVia, 1, "pushed-via");
|
||||
#endif
|
||||
|
||||
BOOST_FOREACH( LinePair lp, draggedLines )
|
||||
BOOST_FOREACH( LINE_PAIR lp, draggedLines )
|
||||
{
|
||||
if( lp.first->Marker() & MK_HEAD )
|
||||
{
|
||||
|
@ -526,7 +542,8 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc
|
|||
m_currentNode->Replace( lp.first, lp.second );
|
||||
lp.second->SetRank( aCurrentRank - 1 );
|
||||
pushLine( lp.second );
|
||||
} else
|
||||
}
|
||||
else
|
||||
m_currentNode->Remove( lp.first );
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -539,10 +556,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc
|
|||
}
|
||||
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingVia (PNS_ITEM *aCurrent, PNS_VIA *aObstacleVia )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::onCollidingVia (PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia )
|
||||
{
|
||||
int clearance = m_currentNode->GetClearance( aCurrent, aObstacleVia ) ;
|
||||
LinePairVec draggedLines;
|
||||
LINE_PAIR_VEC draggedLines;
|
||||
VECTOR2I p0( aObstacleVia->Pos() );
|
||||
bool colLine = false, colVia = false;
|
||||
PNS_LINE *currentLine = NULL;
|
||||
|
@ -551,17 +568,19 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingVia (PNS_ITEM *aCurrent, PNS_VIA *a
|
|||
|
||||
if( aCurrent->OfKind( PNS_ITEM::LINE ) )
|
||||
{
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( "push-via-by-line", m_iter );
|
||||
m_logger.Log( aCurrent, 4, "current" );
|
||||
#endif
|
||||
|
||||
currentLine = (PNS_LINE*) aCurrent;
|
||||
colLine = CollideShapes( aObstacleVia->Shape(), currentLine->Shape(), clearance + currentLine->Width() / 2 + PNS_HULL_MARGIN, true, mtvLine );
|
||||
colLine = CollideShapes( aObstacleVia->Shape(), currentLine->Shape(),
|
||||
clearance + currentLine->Width() / 2 + PNS_HULL_MARGIN,
|
||||
true, mtvLine );
|
||||
|
||||
if( currentLine->EndsWithVia() )
|
||||
colVia = CollideShapes (currentLine->Via().Shape(), aObstacleVia->Shape(), clearance + PNS_HULL_MARGIN, true, mtvVia);
|
||||
colVia = CollideShapes( currentLine->Via().Shape(), aObstacleVia->Shape(),
|
||||
clearance + PNS_HULL_MARGIN, true, mtvVia );
|
||||
|
||||
if( !colLine && !colVia )
|
||||
return SH_OK;
|
||||
|
@ -572,11 +591,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingVia (PNS_ITEM *aCurrent, PNS_VIA *a
|
|||
mtv = mtvLine;
|
||||
else
|
||||
mtv = mtvVia;
|
||||
|
||||
rank = currentLine->Rank();
|
||||
}
|
||||
else if (aCurrent->OfKind(PNS_ITEM::SOLID))
|
||||
{
|
||||
CollideShapes( aObstacleVia->Shape(), aCurrent->Shape(), clearance + PNS_HULL_MARGIN, true, mtvSolid );
|
||||
CollideShapes( aObstacleVia->Shape(), aCurrent->Shape(),
|
||||
clearance + PNS_HULL_MARGIN, true, mtvSolid );
|
||||
mtv = mtvSolid;
|
||||
rank = aCurrent->Rank() + 10000;
|
||||
}
|
||||
|
@ -584,7 +605,8 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingVia (PNS_ITEM *aCurrent, PNS_VIA *a
|
|||
return pushVia( aObstacleVia, mtv, rank );
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus 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;
|
||||
|
@ -595,13 +617,11 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
|
|||
PNS_LINE* shoved = cloneLine( aCurrent );
|
||||
shoved->ClearSegmentLinks();
|
||||
|
||||
|
||||
cur->RemoveVia();
|
||||
unwindStack(aCurrent);
|
||||
|
||||
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
|
||||
{
|
||||
|
||||
if( item->OfKind( PNS_ITEM::SEGMENT ) && item->LayersOverlap( aCurrent ) )
|
||||
{
|
||||
PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
|
||||
|
@ -609,7 +629,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
|
|||
|
||||
head->AppendVia( *aObstacleVia );
|
||||
|
||||
ShoveStatus st = processSingleLine ( head, cur, shoved );
|
||||
SHOVE_STATUS st = processSingleLine ( head, cur, shoved );
|
||||
|
||||
if( st != SH_OK )
|
||||
{
|
||||
|
@ -622,6 +642,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
|
|||
|
||||
return st;
|
||||
}
|
||||
|
||||
cur->SetShape( shoved->CLine() );
|
||||
n++;
|
||||
}
|
||||
|
@ -640,7 +661,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
|
|||
head.AppendVia( *aObstacleVia );
|
||||
head.ClearSegmentLinks();
|
||||
|
||||
ShoveStatus st = processSingleLine ( &head, aCurrent, shoved );
|
||||
SHOVE_STATUS st = processSingleLine( &head, aCurrent, shoved );
|
||||
|
||||
if( st != SH_OK )
|
||||
return st;
|
||||
|
@ -667,11 +688,11 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
|
|||
}
|
||||
|
||||
|
||||
void PNS_SHOVE::unwindStack ( PNS_SEGMENT *seg )
|
||||
void PNS_SHOVE::unwindStack( PNS_SEGMENT *aSeg )
|
||||
{
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_lineStack.begin(); i != m_lineStack.end(); )
|
||||
{
|
||||
if( (*i)->ContainsSegment ( seg ) )
|
||||
if( (*i)->ContainsSegment ( aSeg ) )
|
||||
i = m_lineStack.erase( i );
|
||||
else
|
||||
i++;
|
||||
|
@ -679,19 +700,21 @@ void PNS_SHOVE::unwindStack ( PNS_SEGMENT *seg )
|
|||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
|
||||
{
|
||||
if( (*i)->ContainsSegment ( seg ) )
|
||||
if( (*i)->ContainsSegment( aSeg ) )
|
||||
i = m_optimizerQueue.erase( i );
|
||||
else
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
void PNS_SHOVE::unwindStack ( PNS_ITEM *item )
|
||||
|
||||
void PNS_SHOVE::unwindStack( PNS_ITEM* aItem )
|
||||
{
|
||||
if (item->OfKind(PNS_ITEM::SEGMENT))
|
||||
unwindStack(static_cast<PNS_SEGMENT *>(item));
|
||||
else if (item->OfKind(PNS_ITEM::LINE)) {
|
||||
PNS_LINE *l = static_cast<PNS_LINE *>( item );
|
||||
if( aItem->OfKind( PNS_ITEM::SEGMENT ) )
|
||||
unwindStack( static_cast<PNS_SEGMENT*>( aItem ) );
|
||||
else if( aItem->OfKind( PNS_ITEM::LINE ) )
|
||||
{
|
||||
PNS_LINE* l = static_cast<PNS_LINE*>( aItem );
|
||||
|
||||
if ( !l->LinkedSegments() )
|
||||
return;
|
||||
|
@ -701,15 +724,17 @@ void PNS_SHOVE::unwindStack ( PNS_ITEM *item )
|
|||
}
|
||||
}
|
||||
|
||||
void PNS_SHOVE::pushLine (PNS_LINE *l)
|
||||
|
||||
void PNS_SHOVE::pushLine( PNS_LINE* aL )
|
||||
{
|
||||
if(l->LinkCount() >= 0 && (l->LinkCount() != l->SegmentCount()))
|
||||
if( aL->LinkCount() >= 0 && ( aL->LinkCount() != aL->SegmentCount() ) )
|
||||
assert( false );
|
||||
|
||||
m_lineStack.push_back(l);
|
||||
m_optimizerQueue.push_back(l);
|
||||
m_lineStack.push_back( aL );
|
||||
m_optimizerQueue.push_back( aL );
|
||||
}
|
||||
|
||||
|
||||
void PNS_SHOVE::popLine( )
|
||||
{
|
||||
PNS_LINE* l = m_lineStack.back();
|
||||
|
@ -719,24 +744,27 @@ void PNS_SHOVE::popLine( )
|
|||
if( ( *i ) == l )
|
||||
{
|
||||
i = m_optimizerQueue.erase( i );
|
||||
} else
|
||||
}
|
||||
else
|
||||
i++;
|
||||
}
|
||||
|
||||
m_lineStack.pop_back();
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveIteration( int aIter )
|
||||
{
|
||||
PNS_LINE* currentLine = m_lineStack.back();
|
||||
PNS_NODE::OptObstacle nearest;
|
||||
ShoveStatus st;
|
||||
PNS_NODE::OPT_OBSTACLE nearest;
|
||||
SHOVE_STATUS st;
|
||||
|
||||
PNS_ITEM::PnsKind search_order[] = { PNS_ITEM::SOLID, PNS_ITEM::VIA, PNS_ITEM::SEGMENT };
|
||||
|
||||
for( int i = 0; i < 3; i++ )
|
||||
{
|
||||
nearest = m_currentNode->NearestObstacle( currentLine, search_order[i] );
|
||||
|
||||
if( nearest )
|
||||
break;
|
||||
}
|
||||
|
@ -747,7 +775,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
|
|||
return SH_OK;
|
||||
}
|
||||
|
||||
PNS_ITEM *ni = nearest->item;
|
||||
PNS_ITEM* ni = nearest->m_item;
|
||||
|
||||
unwindStack( ni );
|
||||
|
||||
|
@ -763,7 +791,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
|
|||
if( currentLine->EndsWithVia() && m_currentNode->CheckColliding( ¤tLine->Via(), revVia ) )
|
||||
{
|
||||
st = SH_INCOMPLETE;
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
st = onReverseCollidingVia ( currentLine, revVia );
|
||||
}
|
||||
|
||||
|
@ -785,7 +815,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
|
|||
default:
|
||||
assert( false );
|
||||
}
|
||||
} else { // "forward" collisoins
|
||||
}
|
||||
else
|
||||
{ // "forward" collisoins
|
||||
switch( ni->Kind() )
|
||||
{
|
||||
case PNS_ITEM::SEGMENT:
|
||||
|
@ -811,9 +843,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
|
|||
return st;
|
||||
}
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop()
|
||||
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::shoveMainLoop()
|
||||
{
|
||||
ShoveStatus st = SH_OK;
|
||||
SHOVE_STATUS st = SH_OK;
|
||||
|
||||
TRACE( 1, "ShoveStart [root: %d jts, current: %d jts]", m_root->JointCount() %
|
||||
m_currentNode->JointCount() );
|
||||
|
@ -842,9 +875,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop()
|
|||
}
|
||||
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
||||
{
|
||||
ShoveStatus st = SH_OK;
|
||||
SHOVE_STATUS st = SH_OK;
|
||||
|
||||
// empty head? nothing to shove...
|
||||
if( !aCurrentHead.SegmentCount() )
|
||||
|
@ -855,14 +888,14 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
|
||||
m_lineStack.clear();
|
||||
m_optimizerQueue.clear();
|
||||
m_newHead = OptLine();
|
||||
m_newHead = OPT_LINE();
|
||||
m_logger.Clear();
|
||||
|
||||
PNS_ITEMSET headSet( cloneLine( &aCurrentHead ) );
|
||||
|
||||
reduceSpringback( headSet );
|
||||
|
||||
PNS_NODE *parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().node;
|
||||
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
|
||||
m_currentNode = parent->Branch();
|
||||
m_currentNode->ClearRanks();
|
||||
|
@ -883,7 +916,6 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
headVia->Mark( MK_HEAD );
|
||||
headVia->SetRank( 100000 );
|
||||
m_logger.Log( headVia, 0, "head-via" );
|
||||
|
||||
}
|
||||
|
||||
pushLine( head );
|
||||
|
@ -898,7 +930,8 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
|
||||
m_currentNode->RemoveByMarker( MK_HEAD );
|
||||
|
||||
TRACE( 1, "Shove status : %s after %d iterations", ((st == SH_OK || st == SH_HEAD_MODIFIED) ? "OK" : "FAILURE") % m_iter );
|
||||
TRACE( 1, "Shove status : %s after %d iterations",
|
||||
( ( st == SH_OK || st == SH_HEAD_MODIFIED ) ? "OK" : "FAILURE") % m_iter );
|
||||
|
||||
if( st == SH_OK || st == SH_HEAD_MODIFIED )
|
||||
{
|
||||
|
@ -909,31 +942,31 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
|
|||
delete m_currentNode;
|
||||
|
||||
m_currentNode = parent;
|
||||
m_newHead = OptLine();
|
||||
m_newHead = OPT_LINE();
|
||||
}
|
||||
|
||||
return st;
|
||||
}
|
||||
|
||||
|
||||
PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR2I& aWhere, PNS_VIA **aNewVia )
|
||||
PNS_SHOVE::SHOVE_STATUS PNS_SHOVE::ShoveDraggingVia( PNS_VIA* aVia, const VECTOR2I& aWhere,
|
||||
PNS_VIA** aNewVia )
|
||||
{
|
||||
ShoveStatus st = SH_OK;
|
||||
SHOVE_STATUS st = SH_OK;
|
||||
|
||||
m_lineStack.clear();
|
||||
m_optimizerQueue.clear();
|
||||
m_newHead = OptLine();
|
||||
m_newHead = OPT_LINE();
|
||||
m_draggedVia = NULL;
|
||||
|
||||
//reduceSpringback( aCurrentHead );
|
||||
|
||||
PNS_NODE *parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().node;
|
||||
PNS_NODE* parent = m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
m_currentNode = parent->Branch();
|
||||
m_currentNode->ClearRanks();
|
||||
|
||||
aVia->Mark( MK_HEAD );
|
||||
|
||||
|
||||
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
|
||||
st = shoveMainLoop();
|
||||
runOptimizer( m_currentNode, NULL );
|
||||
|
@ -954,30 +987,33 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR
|
|||
return st;
|
||||
}
|
||||
|
||||
void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
|
||||
|
||||
void PNS_SHOVE::runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead )
|
||||
{
|
||||
PNS_OPTIMIZER optimizer( node );
|
||||
PNS_OPTIMIZER optimizer( aNode );
|
||||
int optFlags = 0, n_passes = 0, extend = 0;
|
||||
|
||||
PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort();
|
||||
|
||||
|
||||
switch( effort )
|
||||
{
|
||||
case OE_Low:
|
||||
case OE_LOW:
|
||||
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
|
||||
n_passes = 1;
|
||||
extend = 0;
|
||||
break;
|
||||
case OE_Medium:
|
||||
|
||||
case OE_MEDIUM:
|
||||
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
|
||||
n_passes = 2;
|
||||
extend = 1;
|
||||
break;
|
||||
case OE_Full:
|
||||
|
||||
case OE_FULL:
|
||||
optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
|
||||
n_passes = 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -991,13 +1027,15 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
|
|||
for( int pass = 0; pass < n_passes; pass++ )
|
||||
{
|
||||
std::reverse( m_optimizerQueue.begin(), m_optimizerQueue.end() );
|
||||
for(std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); ++i)
|
||||
|
||||
for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin();
|
||||
i != m_optimizerQueue.end(); ++i)
|
||||
{
|
||||
PNS_LINE* line = *i;
|
||||
|
||||
if( !( line -> Marker() & MK_HEAD ) )
|
||||
{
|
||||
if(effort == OE_Medium || effort == OE_Low )
|
||||
if( effort == OE_MEDIUM || effort == OE_LOW )
|
||||
{
|
||||
RANGE<int> r = findShovedVertexRange( line );
|
||||
|
||||
|
@ -1013,9 +1051,9 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
|
|||
|
||||
if( optimizer.Optimize( line, &optimized ) )
|
||||
{
|
||||
node->Remove( line );
|
||||
aNode->Remove( line );
|
||||
line->SetShape( optimized.CLine() );
|
||||
node->Add( line );
|
||||
aNode->Add( line );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1024,13 +1062,14 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
|
|||
|
||||
}
|
||||
|
||||
const RANGE<int> PNS_SHOVE::findShovedVertexRange ( PNS_LINE *l )
|
||||
|
||||
const RANGE<int> PNS_SHOVE::findShovedVertexRange( PNS_LINE *aL )
|
||||
{
|
||||
RANGE<int> r;
|
||||
|
||||
for(int i = 0; i < l->SegmentCount(); i++)
|
||||
for( int i = 0; i < aL->SegmentCount(); i++ )
|
||||
{
|
||||
PNS_SEGMENT *s = (*l->LinkedSegments())[i];
|
||||
PNS_SEGMENT* s = (*aL->LinkedSegments())[i];
|
||||
PNS_JOINT* jt = m_root->FindJoint( s->Seg().A, s->Layer(), s->Net() );
|
||||
bool found = false;
|
||||
|
||||
|
@ -1060,17 +1099,21 @@ const RANGE<int> PNS_SHOVE::findShovedVertexRange ( PNS_LINE *l )
|
|||
r.Grow( i + 1 );
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE* PNS_SHOVE::CurrentNode()
|
||||
{
|
||||
return m_nodeStack.empty() ? m_root : m_nodeStack.back().node;
|
||||
return m_nodeStack.empty() ? m_root : m_nodeStack.back().m_node;
|
||||
}
|
||||
|
||||
|
||||
const PNS_LINE PNS_SHOVE::NewHead() const
|
||||
{
|
||||
assert( m_newHead );
|
||||
|
||||
return *m_newHead;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ class PNS_SHOVE : public PNS_ALGO_BASE
|
|||
{
|
||||
public:
|
||||
|
||||
enum ShoveStatus
|
||||
enum SHOVE_STATUS
|
||||
{
|
||||
SH_OK = 0,
|
||||
SH_NULL,
|
||||
|
@ -60,8 +60,8 @@ public:
|
|||
return &m_logger;
|
||||
}
|
||||
|
||||
ShoveStatus ShoveLines( const PNS_LINE& aCurrentHead );
|
||||
ShoveStatus ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR2I& aWhere, PNS_VIA **aNewVia );
|
||||
SHOVE_STATUS ShoveLines( const PNS_LINE& aCurrentHead );
|
||||
SHOVE_STATUS ShoveDraggingVia( PNS_VIA*aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
|
||||
|
||||
PNS_NODE* CurrentNode();
|
||||
|
||||
|
@ -70,54 +70,56 @@ public:
|
|||
void SetInitialLine ( PNS_LINE* aInitial );
|
||||
|
||||
private:
|
||||
typedef std::vector<SHAPE_LINE_CHAIN> HullSet;
|
||||
typedef boost::optional<PNS_LINE> OptLine;
|
||||
typedef std::pair <PNS_LINE *, PNS_LINE *> LinePair;
|
||||
typedef std::vector<LinePair> LinePairVec;
|
||||
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::vector<LINE_PAIR> LINE_PAIR_VEC;
|
||||
|
||||
struct SpringbackTag
|
||||
struct SPRINGBACK_TAG
|
||||
{
|
||||
int64_t length;
|
||||
int segments;
|
||||
VECTOR2I p;
|
||||
PNS_NODE *node;
|
||||
PNS_ITEMSET headItems;
|
||||
PNS_COST_ESTIMATOR cost;
|
||||
int64_t m_length;
|
||||
int m_segments;
|
||||
VECTOR2I m_p;
|
||||
PNS_NODE* m_node;
|
||||
PNS_ITEMSET m_headItems;
|
||||
PNS_COST_ESTIMATOR m_cost;
|
||||
};
|
||||
|
||||
ShoveStatus processSingleLine(PNS_LINE *aCurrent, PNS_LINE* aObstacle, PNS_LINE *aShoved );
|
||||
ShoveStatus processHullSet ( PNS_LINE *aCurrent, PNS_LINE *aObstacle, PNS_LINE *aShoved, const HullSet& hulls );
|
||||
SHOVE_STATUS processSingleLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
||||
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 );
|
||||
bool pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET &aHeadItems,
|
||||
const PNS_COST_ESTIMATOR& aCost );
|
||||
|
||||
ShoveStatus walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LINE *aObstacle, PNS_LINE *aShoved );
|
||||
SHOVE_STATUS walkaroundLoneVia( PNS_LINE* aCurrent, PNS_LINE* aObstacle, PNS_LINE* aShoved );
|
||||
bool checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const;
|
||||
|
||||
ShoveStatus onCollidingLine( PNS_LINE *aCurrent, PNS_LINE *aObstacle );
|
||||
ShoveStatus onCollidingSegment( PNS_LINE *aCurrent, PNS_SEGMENT *aObstacleSeg );
|
||||
ShoveStatus onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLID *aObstacleSolid );
|
||||
ShoveStatus onCollidingVia( PNS_ITEM *aCurrent, PNS_VIA *aObstacleVia );
|
||||
ShoveStatus onReverseCollidingVia( PNS_LINE *aCurrent, PNS_VIA *aObstacleVia );
|
||||
ShoveStatus pushVia ( PNS_VIA *aVia, const VECTOR2I& aForce, int aCurrentRank );
|
||||
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 pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank );
|
||||
|
||||
void unwindStack ( PNS_SEGMENT *seg );
|
||||
void unwindStack ( PNS_ITEM *item );
|
||||
void unwindStack( PNS_SEGMENT* aSeg );
|
||||
void unwindStack( PNS_ITEM *aItem );
|
||||
|
||||
void runOptimizer ( PNS_NODE *node, PNS_LINE *head );
|
||||
void runOptimizer( PNS_NODE* aNode, PNS_LINE* aHead );
|
||||
|
||||
void pushLine ( PNS_LINE *l );
|
||||
void pushLine( PNS_LINE *aL );
|
||||
void popLine();
|
||||
|
||||
const RANGE<int> findShovedVertexRange ( PNS_LINE *l );
|
||||
const RANGE<int> findShovedVertexRange( PNS_LINE *aL );
|
||||
|
||||
PNS_LINE* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
|
||||
PNS_LINE* cloneLine( const PNS_LINE* aLine );
|
||||
|
||||
ShoveStatus shoveIteration(int aIter);
|
||||
ShoveStatus shoveMainLoop();
|
||||
SHOVE_STATUS shoveIteration( int aIter );
|
||||
SHOVE_STATUS shoveMainLoop();
|
||||
|
||||
std::vector<SpringbackTag> m_nodeStack;
|
||||
std::vector<SPRINGBACK_TAG> m_nodeStack;
|
||||
std::vector<PNS_LINE*> m_lineStack;
|
||||
std::vector<PNS_LINE*> m_optimizerQueue;
|
||||
std::vector<PNS_ITEM*> m_gcItems;
|
||||
|
@ -127,7 +129,7 @@ private:
|
|||
PNS_LINE* m_currentHead;
|
||||
PNS_LINE* m_collidingLine;
|
||||
|
||||
OptLine m_newHead;
|
||||
OPT_LINE m_newHead;
|
||||
|
||||
PNS_LOGGER m_logger;
|
||||
PNS_VIA* m_draggedVia;
|
||||
|
|
|
@ -37,8 +37,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
|
|||
case SH_RECT:
|
||||
{
|
||||
SHAPE_RECT* rect = static_cast<SHAPE_RECT*>( m_shape );
|
||||
return OctagonalHull( rect->GetPosition(), rect->GetSize(),
|
||||
cl + 1, 0.2 * cl );
|
||||
return OctagonalHull( rect->GetPosition(), rect->GetSize(), cl + 1, 0.2 * cl );
|
||||
}
|
||||
|
||||
case SH_CIRCLE:
|
||||
|
@ -48,6 +47,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
|
|||
return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ),
|
||||
cl + 1, 0.52 * ( r + cl ) );
|
||||
}
|
||||
|
||||
case SH_SEGMENT:
|
||||
{
|
||||
SHAPE_SEGMENT* seg = static_cast<SHAPE_SEGMENT*> ( m_shape );
|
||||
|
|
|
@ -73,7 +73,7 @@ public:
|
|||
m_pos = aCenter;
|
||||
}
|
||||
|
||||
virtual VECTOR2I Anchor(int n) const
|
||||
virtual VECTOR2I Anchor( int aN ) const
|
||||
{
|
||||
return m_pos;
|
||||
}
|
||||
|
@ -83,7 +83,6 @@ public:
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
VECTOR2I m_pos;
|
||||
SHAPE* m_shape;
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
|
||||
#include <geometry/shape_segment.h>
|
||||
|
||||
const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0,
|
||||
const VECTOR2I& aSize,
|
||||
int aClearance,
|
||||
int aChamfer )
|
||||
const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
|
||||
int aClearance, int aChamfer )
|
||||
{
|
||||
SHAPE_LINE_CHAIN s;
|
||||
|
||||
|
@ -45,8 +43,8 @@ const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0,
|
|||
return s;
|
||||
}
|
||||
|
||||
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg,
|
||||
int aClearance,
|
||||
|
||||
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||
int aWalkaroundThickness )
|
||||
{
|
||||
int d = aSeg.GetWidth() / 2 + aClearance + aWalkaroundThickness / 2 + HULL_MARGIN;
|
||||
|
@ -81,6 +79,7 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg,
|
|||
return s;
|
||||
}
|
||||
|
||||
|
||||
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
|
||||
{
|
||||
SHAPE_RECT r;
|
||||
|
|
|
@ -33,8 +33,7 @@
|
|||
const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
|
||||
int aClearance, int aChamfer );
|
||||
|
||||
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg,
|
||||
int aClearance,
|
||||
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
|
||||
int aWalkaroundThickness );
|
||||
|
||||
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
|
||||
|
|
|
@ -25,26 +25,22 @@
|
|||
|
||||
#include <geometry/shape_rect.h>
|
||||
|
||||
bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
|
||||
const VECTOR2I& aDirection,
|
||||
VECTOR2I& aForce,
|
||||
bool aSolidsOnly,
|
||||
int aMaxIterations )
|
||||
bool PNS_VIA::PushoutForce( PNS_NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForce,
|
||||
bool aSolidsOnly, int aMaxIterations )
|
||||
{
|
||||
int iter = 0;
|
||||
PNS_VIA mv( *this );
|
||||
VECTOR2I force, totalForce, force2;
|
||||
|
||||
|
||||
while( iter < aMaxIterations )
|
||||
{
|
||||
|
||||
PNS_NODE::OptObstacle obs = aNode->CheckColliding( &mv, aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY );
|
||||
PNS_NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv,
|
||||
aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY );
|
||||
|
||||
if( !obs )
|
||||
break;
|
||||
|
||||
int clearance = aNode->GetClearance( obs->item, &mv );
|
||||
int clearance = aNode->GetClearance( obs->m_item, &mv );
|
||||
|
||||
if( iter > aMaxIterations / 2 )
|
||||
{
|
||||
|
@ -53,14 +49,13 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
|
|||
mv.SetPos( mv.Pos() + l );
|
||||
}
|
||||
|
||||
bool col = CollideShapes( obs->item->Shape(), mv.Shape(), clearance, true, force2 );
|
||||
bool col = CollideShapes( obs->m_item->Shape(), mv.Shape(), clearance, true, force2 );
|
||||
|
||||
if( col ) {
|
||||
totalForce += force2;
|
||||
mv.SetPos( mv.Pos() + force2 );
|
||||
}
|
||||
|
||||
|
||||
iter++;
|
||||
}
|
||||
|
||||
|
@ -68,6 +63,7 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
|
|||
return false;
|
||||
|
||||
aForce = totalForce;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -77,10 +73,11 @@ const SHAPE_LINE_CHAIN PNS_VIA::Hull( int aClearance, int aWalkaroundThickness )
|
|||
int cl = ( aClearance + aWalkaroundThickness / 2 );
|
||||
|
||||
return OctagonalHull( m_pos -
|
||||
VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter,
|
||||
m_diameter ), cl + 1, (2 * cl + m_diameter) * 0.26 );
|
||||
VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter, m_diameter ),
|
||||
cl + 1, ( 2 * cl + m_diameter ) * 0.26 );
|
||||
}
|
||||
|
||||
|
||||
PNS_VIA* PNS_VIA::Clone ( ) const
|
||||
{
|
||||
PNS_VIA* v = new PNS_VIA();
|
||||
|
|
|
@ -32,7 +32,8 @@ class PNS_VIA : public PNS_ITEM
|
|||
{
|
||||
public:
|
||||
PNS_VIA() :
|
||||
PNS_ITEM( VIA ) {};
|
||||
PNS_ITEM( VIA )
|
||||
{}
|
||||
|
||||
PNS_VIA( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aDiameter, int aNet = -1 ) :
|
||||
PNS_ITEM( VIA )
|
||||
|
@ -42,21 +43,21 @@ public:
|
|||
m_pos = aPos;
|
||||
m_diameter = aDiameter;
|
||||
m_shape = SHAPE_CIRCLE( aPos, aDiameter / 2 );
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
PNS_VIA( const PNS_VIA& b ) :
|
||||
PNS_VIA( const PNS_VIA& aB ) :
|
||||
PNS_ITEM( VIA )
|
||||
{
|
||||
SetNet( b.Net() );
|
||||
SetLayers( b.Layers() );
|
||||
m_pos = b.m_pos;
|
||||
m_diameter = b.m_diameter;
|
||||
SetNet( aB.Net() );
|
||||
SetLayers( aB.Layers() );
|
||||
m_pos = aB.m_pos;
|
||||
m_diameter = aB.m_diameter;
|
||||
m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
|
||||
m_marker = b.m_marker;
|
||||
m_rank = b.m_rank;
|
||||
m_owner = b.m_owner;
|
||||
m_drill = b.m_drill;
|
||||
m_marker = aB.m_marker;
|
||||
m_rank = aB.m_rank;
|
||||
m_owner = aB.m_owner;
|
||||
m_drill = aB.m_drill;
|
||||
}
|
||||
|
||||
const VECTOR2I& Pos() const
|
||||
|
@ -117,7 +118,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
int m_diameter;
|
||||
int m_drill;
|
||||
VECTOR2I m_pos;
|
||||
|
|
|
@ -32,22 +32,22 @@ using boost::optional;
|
|||
void PNS_WALKAROUND::start( const PNS_LINE& aInitialPath )
|
||||
{
|
||||
m_iteration = 0;
|
||||
m_iteration_limit = 50;
|
||||
m_iterationLimit = 50;
|
||||
}
|
||||
|
||||
|
||||
PNS_NODE::OptObstacle PNS_WALKAROUND::nearestObstacle( const PNS_LINE& aPath )
|
||||
PNS_NODE::OPT_OBSTACLE PNS_WALKAROUND::nearestObstacle( const PNS_LINE& aPath )
|
||||
{
|
||||
return m_world->NearestObstacle( &aPath, m_item_mask);
|
||||
|
||||
return m_world->NearestObstacle( &aPath, m_itemMask );
|
||||
}
|
||||
|
||||
|
||||
PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
||||
PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
||||
bool aWindingDirection )
|
||||
{
|
||||
optional<PNS_OBSTACLE>& current_obs =
|
||||
aWindingDirection ? m_currentObstacle[0] : m_currentObstacle[1];
|
||||
|
||||
bool& prev_recursive = aWindingDirection ? m_recursiveCollision[0] : m_recursiveCollision[1];
|
||||
|
||||
if( !current_obs )
|
||||
|
@ -55,15 +55,14 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
|||
|
||||
SHAPE_LINE_CHAIN path_pre[2], path_walk[2], path_post[2];
|
||||
|
||||
VECTOR2I last = aPath.CPoint( -1 );;
|
||||
VECTOR2I last = aPath.CPoint( -1 );
|
||||
|
||||
|
||||
if( ( current_obs->hull ).PointInside( last ) )
|
||||
if( ( current_obs->m_hull ).PointInside( last ) )
|
||||
{
|
||||
m_recursiveBlockageCount++;
|
||||
|
||||
if( m_recursiveBlockageCount < 3 )
|
||||
aPath.Line().Append( current_obs->hull.NearestPoint( last ) );
|
||||
aPath.Line().Append( current_obs->m_hull.NearestPoint( last ) );
|
||||
else
|
||||
{
|
||||
aPath = aPath.ClipToNearestObstacle( m_world );
|
||||
|
@ -71,17 +70,18 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
|||
}
|
||||
}
|
||||
|
||||
aPath.Walkaround( current_obs->hull, path_pre[0], path_walk[0],
|
||||
aPath.Walkaround( current_obs->m_hull, path_pre[0], path_walk[0],
|
||||
path_post[0], aWindingDirection );
|
||||
aPath.Walkaround( current_obs->hull, path_pre[1], path_walk[1],
|
||||
aPath.Walkaround( current_obs->m_hull, path_pre[1], path_walk[1],
|
||||
path_post[1], !aWindingDirection );
|
||||
|
||||
#ifdef DEBUG
|
||||
m_logger.NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );
|
||||
m_logger.Log( &path_walk[0], 0, "path-walk" );
|
||||
m_logger.Log( &path_pre[0], 1, "path-pre" );
|
||||
m_logger.Log( &path_post[0], 4, "path-post" );
|
||||
m_logger.Log ( ¤t_obs->hull, 2, "hull");
|
||||
m_logger.Log ( current_obs->item, 3, "item");
|
||||
m_logger.Log( ¤t_obs->m_hull, 2, "hull" );
|
||||
m_logger.Log( current_obs->m_item, 3, "item" );
|
||||
#endif
|
||||
|
||||
int len_pre = path_walk[0].Length();
|
||||
|
@ -89,8 +89,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
|||
|
||||
PNS_LINE walk_path( aPath, path_walk[1] );
|
||||
|
||||
bool alt_collides = m_world->CheckColliding( &walk_path, m_item_mask );
|
||||
|
||||
bool alt_collides = m_world->CheckColliding( &walk_path, m_itemMask );
|
||||
|
||||
SHAPE_LINE_CHAIN pnew;
|
||||
|
||||
|
@ -127,15 +126,13 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
|
|||
}
|
||||
|
||||
|
||||
PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitialPath,
|
||||
PNS_LINE& aWalkPath,
|
||||
bool aOptimize )
|
||||
PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitialPath,
|
||||
PNS_LINE& aWalkPath, bool aOptimize )
|
||||
{
|
||||
PNS_LINE path_cw( aInitialPath ), path_ccw( aInitialPath );
|
||||
WalkaroundStatus s_cw = IN_PROGRESS, s_ccw = IN_PROGRESS;
|
||||
WALKAROUND_STATUS s_cw = IN_PROGRESS, s_ccw = IN_PROGRESS;
|
||||
SHAPE_LINE_CHAIN best_path;
|
||||
|
||||
|
||||
start( aInitialPath );
|
||||
|
||||
m_currentObstacle[0] = m_currentObstacle[1] = nearestObstacle( aInitialPath );
|
||||
|
@ -143,7 +140,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
|
|||
|
||||
aWalkPath = aInitialPath;
|
||||
|
||||
while( m_iteration < m_iteration_limit )
|
||||
while( m_iteration < m_iterationLimit )
|
||||
{
|
||||
if( s_cw != STUCK )
|
||||
s_cw = singleStep( path_cw, true );
|
||||
|
@ -156,7 +153,6 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
|
|||
int len_cw = path_cw.CLine().Length();
|
||||
int len_ccw = path_ccw.CLine().Length();
|
||||
|
||||
|
||||
if( m_forceLongerPath )
|
||||
aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw);
|
||||
else
|
||||
|
@ -178,12 +174,11 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
|
|||
m_iteration++;
|
||||
}
|
||||
|
||||
if( m_iteration == m_iteration_limit )
|
||||
if( m_iteration == m_iterationLimit )
|
||||
{
|
||||
int len_cw = path_cw.CLine().Length();
|
||||
int len_ccw = path_ccw.CLine().Length();
|
||||
|
||||
|
||||
if( m_forceLongerPath )
|
||||
aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
|
||||
else
|
||||
|
@ -235,7 +230,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
|
|||
if( aWalkPath.CPoint( 0 ) != aInitialPath.CPoint( 0 ) )
|
||||
return STUCK;
|
||||
|
||||
WalkaroundStatus st = s_ccw == DONE || s_cw == DONE ? DONE : STUCK;
|
||||
WALKAROUND_STATUS st = s_ccw == DONE || s_cw == DONE ? DONE : STUCK;
|
||||
|
||||
if( aOptimize && st == DONE )
|
||||
PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world );
|
||||
|
|
|
@ -35,17 +35,17 @@ public:
|
|||
PNS_WALKAROUND( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
|
||||
PNS_ALGO_BASE ( aRouter ),
|
||||
m_world( aWorld ),
|
||||
m_iteration_limit( DefaultIterationLimit )
|
||||
m_iterationLimit( DefaultIterationLimit )
|
||||
{
|
||||
m_forceSingleDirection = false;
|
||||
m_forceLongerPath = false;
|
||||
m_cursorApproachMode = false;
|
||||
m_item_mask = PNS_ITEM::ANY;
|
||||
};
|
||||
m_itemMask = PNS_ITEM::ANY;
|
||||
}
|
||||
|
||||
~PNS_WALKAROUND() {};
|
||||
|
||||
enum WalkaroundStatus
|
||||
enum WALKAROUND_STATUS
|
||||
{
|
||||
IN_PROGRESS = 0,
|
||||
DONE,
|
||||
|
@ -59,20 +59,20 @@ public:
|
|||
|
||||
void SetIterationLimit( const int aIterLimit )
|
||||
{
|
||||
m_iteration_limit = aIterLimit;
|
||||
m_iterationLimit = aIterLimit;
|
||||
}
|
||||
|
||||
void SetSolidsOnly( bool aSolidsOnly )
|
||||
{
|
||||
if( aSolidsOnly )
|
||||
m_item_mask = PNS_ITEM::SOLID;
|
||||
m_itemMask = PNS_ITEM::SOLID;
|
||||
else
|
||||
m_item_mask = PNS_ITEM::ANY;
|
||||
m_itemMask = PNS_ITEM::ANY;
|
||||
}
|
||||
|
||||
void SetItemMask( int aMask )
|
||||
{
|
||||
m_item_mask = aMask;
|
||||
m_itemMask = aMask;
|
||||
}
|
||||
|
||||
void SetSingleDirection( bool aForceSingleDirection )
|
||||
|
@ -88,29 +88,30 @@ public:
|
|||
m_cursorApproachMode = aEnabled;
|
||||
}
|
||||
|
||||
WalkaroundStatus Route( const PNS_LINE& aInitialPath, PNS_LINE& aWalkPath,
|
||||
WALKAROUND_STATUS Route( const PNS_LINE& aInitialPath, PNS_LINE& aWalkPath,
|
||||
bool aOptimize = true );
|
||||
|
||||
virtual PNS_LOGGER *Logger() {
|
||||
virtual PNS_LOGGER* Logger()
|
||||
{
|
||||
return &m_logger;
|
||||
}
|
||||
|
||||
private:
|
||||
void start( const PNS_LINE& aInitialPath );
|
||||
|
||||
WalkaroundStatus singleStep( PNS_LINE& aPath, bool aWindingDirection );
|
||||
PNS_NODE::OptObstacle nearestObstacle( const PNS_LINE& aPath );
|
||||
WALKAROUND_STATUS singleStep( PNS_LINE& aPath, bool aWindingDirection );
|
||||
PNS_NODE::OPT_OBSTACLE nearestObstacle( const PNS_LINE& aPath );
|
||||
|
||||
PNS_NODE* m_world;
|
||||
|
||||
int m_recursiveBlockageCount;
|
||||
int m_iteration;
|
||||
int m_iteration_limit;
|
||||
int m_item_mask;
|
||||
int m_iterationLimit;
|
||||
int m_itemMask;
|
||||
bool m_forceSingleDirection, m_forceLongerPath;
|
||||
bool m_cursorApproachMode;
|
||||
VECTOR2I m_cursorPos;
|
||||
PNS_NODE::OptObstacle m_currentObstacle[2];
|
||||
PNS_NODE::OPT_OBSTACLE m_currentObstacle[2];
|
||||
bool m_recursiveCollision[2];
|
||||
PNS_LOGGER m_logger;
|
||||
};
|
||||
|
|
|
@ -21,8 +21,9 @@
|
|||
#ifndef __RANGE_H
|
||||
#define __RANGE_H
|
||||
|
||||
template<class T> class RANGE {
|
||||
|
||||
template<class T>
|
||||
class RANGE
|
||||
{
|
||||
public:
|
||||
RANGE( T aMin, T aMax ) :
|
||||
m_min( aMin ),
|
||||
|
@ -30,7 +31,7 @@ template<class T> class RANGE {
|
|||
m_defined( true ) {}
|
||||
|
||||
RANGE():
|
||||
m_defined (false) {};
|
||||
m_defined( false ) {}
|
||||
|
||||
T MinV() const
|
||||
{
|
||||
|
@ -48,25 +49,27 @@ template<class T> class RANGE {
|
|||
m_min = aMin;
|
||||
}
|
||||
|
||||
void Grow ( T value )
|
||||
void Grow( T aValue )
|
||||
{
|
||||
if( !m_defined )
|
||||
{
|
||||
m_min = value;
|
||||
m_max = value;
|
||||
m_min = aValue;
|
||||
m_max = aValue;
|
||||
m_defined = true;
|
||||
} else {
|
||||
m_min = std::min(m_min, value);
|
||||
m_max = std::max(m_max, value);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_min = std::min( m_min, aValue );
|
||||
m_max = std::max( m_max, aValue );
|
||||
}
|
||||
}
|
||||
|
||||
bool Inside ( const T& value ) const
|
||||
bool Inside( const T& aValue ) const
|
||||
{
|
||||
if( !m_defined )
|
||||
return true;
|
||||
|
||||
return value >= m_min && value <= m_max;
|
||||
return aValue >= m_min && aValue <= m_max;
|
||||
}
|
||||
|
||||
bool Overlaps ( const RANGE<T>& aOther ) const
|
||||
|
@ -85,7 +88,6 @@ template<class T> class RANGE {
|
|||
private:
|
||||
T m_min, m_max;
|
||||
bool m_defined;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
|
@ -43,7 +43,6 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aPa
|
|||
m_clearance = -1;
|
||||
m_originLayer = m_layer = ITEM_GAL_LAYER ( GP_OVERLAY );
|
||||
|
||||
|
||||
if( aItem )
|
||||
Update( aItem );
|
||||
}
|
||||
|
@ -56,7 +55,6 @@ ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
|
|||
|
||||
void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
|
||||
{
|
||||
|
||||
m_originLayer = aItem->Layers().Start();
|
||||
|
||||
assert( m_originLayer >= 0 );
|
||||
|
@ -65,7 +63,6 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
|
|||
m_color = getLayerColor( m_originLayer );
|
||||
m_color.a = 0.8;
|
||||
m_depth = BaseOverlayDepth - aItem->Layers().Start();
|
||||
|
||||
m_shape = aItem->Shape()->Clone();
|
||||
|
||||
switch( aItem->Kind() )
|
||||
|
@ -110,6 +107,7 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
|
|||
ViewUpdate( GEOMETRY | APPEARANCE );
|
||||
}
|
||||
|
||||
|
||||
const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
|
||||
{
|
||||
BOX2I bbox;
|
||||
|
@ -132,14 +130,17 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
|
|||
return bbox;
|
||||
}
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN &l, KIGFX::GAL* aGal ) const
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::drawLineChain( const SHAPE_LINE_CHAIN &aL, KIGFX::GAL* aGal ) const
|
||||
{
|
||||
for( int s = 0; s < l.SegmentCount(); s++ )
|
||||
aGal->DrawLine( l.CSegment( s ).A, l.CSegment( s ).B );
|
||||
if( l.IsClosed() )
|
||||
aGal->DrawLine( l.CSegment( -1 ).B, l.CSegment( 0 ).A );
|
||||
for( int s = 0; s < aL.SegmentCount(); s++ )
|
||||
aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
|
||||
|
||||
if( aL.IsClosed() )
|
||||
aGal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
|
||||
{
|
||||
//col.Brighten(0.7);
|
||||
|
@ -153,7 +154,6 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
|
|||
aGal->SetIsStroke( m_width ? true : false );
|
||||
aGal->SetIsFill( true );
|
||||
|
||||
|
||||
if( !m_shape )
|
||||
return;
|
||||
|
||||
|
@ -177,7 +177,6 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
|
|||
aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ));
|
||||
aGal->SetLineWidth( m_width + 2 * m_clearance );
|
||||
aGal->DrawLine( s->GetSeg().A, s->GetSeg().B );
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
@ -226,7 +225,6 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
|
|||
|
||||
void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
|
||||
{
|
||||
|
||||
m_originLayer = m_layer = 0;
|
||||
m_width = aWidth;
|
||||
m_color = assignColor( aStyle );
|
||||
|
@ -236,13 +234,14 @@ void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int a
|
|||
|
||||
ViewSetVisible( true );
|
||||
ViewUpdate( GEOMETRY | APPEARANCE );
|
||||
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
|
||||
{
|
||||
}
|
||||
|
|
|
@ -44,14 +44,13 @@ class PNS_ROUTER;
|
|||
class ROUTER_PREVIEW_ITEM : public EDA_ITEM
|
||||
{
|
||||
public:
|
||||
enum ItemType
|
||||
enum ITEM_TYPE
|
||||
{
|
||||
PR_STUCK_MARKER = 0,
|
||||
PR_POINT,
|
||||
PR_SHAPE
|
||||
};
|
||||
|
||||
|
||||
ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem = NULL, KIGFX::VIEW_GROUP* aParent = NULL );
|
||||
~ROUTER_PREVIEW_ITEM();
|
||||
|
||||
|
@ -73,7 +72,7 @@ public:
|
|||
m_clearance = aClearance;
|
||||
}
|
||||
|
||||
void Show( int a, std::ostream& b ) const {};
|
||||
void Show( int aA, std::ostream& aB ) const {};
|
||||
|
||||
const BOX2I ViewBBox() const;
|
||||
|
||||
|
@ -85,7 +84,7 @@ public:
|
|||
aCount = 1;
|
||||
}
|
||||
|
||||
void drawLineChain( const SHAPE_LINE_CHAIN &l, KIGFX::GAL *aGal ) const;
|
||||
void drawLineChain( const SHAPE_LINE_CHAIN& aL, KIGFX::GAL *aGal ) const;
|
||||
|
||||
private:
|
||||
const KIGFX::COLOR4D assignColor( int aStyle ) const;
|
||||
|
@ -96,7 +95,7 @@ private:
|
|||
PNS_ROUTER* m_router;
|
||||
SHAPE* m_shape;
|
||||
|
||||
ItemType m_type;
|
||||
ITEM_TYPE m_type;
|
||||
|
||||
int m_style;
|
||||
int m_width;
|
||||
|
|
|
@ -82,12 +82,14 @@ ROUTER_TOOL::ROUTER_TOOL() :
|
|||
m_router = NULL;
|
||||
}
|
||||
|
||||
|
||||
class CONTEXT_TRACK_WIDTH_MENU: public CONTEXT_MENU
|
||||
{
|
||||
public:
|
||||
CONTEXT_TRACK_WIDTH_MENU()
|
||||
{
|
||||
setCustomEventHandler( boost::bind( &CONTEXT_TRACK_WIDTH_MENU::handleCustomEvent, this, _1 ) );
|
||||
setCustomEventHandler( boost::bind( &CONTEXT_TRACK_WIDTH_MENU::handleCustomEvent,
|
||||
this, _1 ) );
|
||||
}
|
||||
|
||||
void SetBoard( BOARD* aBoard )
|
||||
|
@ -97,16 +99,14 @@ public:
|
|||
wxString msg;
|
||||
m_board = aBoard;
|
||||
|
||||
Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Custom size" ), wxEmptyString, wxITEM_CHECK );
|
||||
Append( ID_POPUP_PCB_SELECT_CUSTOM_WIDTH, _( "Custom size" ),
|
||||
wxEmptyString, wxITEM_CHECK );
|
||||
|
||||
Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use the starting track width" ),
|
||||
_( "Route using the width of the starting track." ),
|
||||
wxITEM_CHECK );
|
||||
_( "Route using the width of the starting track." ), wxITEM_CHECK );
|
||||
|
||||
Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES,
|
||||
_( "Use netclass values" ),
|
||||
_( "Use track and via sizes from the net class" ),
|
||||
wxITEM_CHECK );
|
||||
Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use netclass values" ),
|
||||
_( "Use track and via sizes from the net class" ), wxITEM_CHECK );
|
||||
|
||||
for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
|
||||
{
|
||||
|
@ -124,8 +124,7 @@ public:
|
|||
for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
|
||||
{
|
||||
msg = _("Via ");
|
||||
msg << StringFromValue( g_UserUnit, bds.m_ViasDimensionsList[i].m_Diameter,
|
||||
true );
|
||||
msg << StringFromValue( g_UserUnit, bds.m_ViasDimensionsList[i].m_Diameter, true );
|
||||
wxString drill = StringFromValue( g_UserUnit,
|
||||
bds.m_ViasDimensionsList[i].m_Drill,
|
||||
true );
|
||||
|
@ -133,7 +132,9 @@ public:
|
|||
if( bds.m_ViasDimensionsList[i].m_Drill <= 0 )
|
||||
{
|
||||
msg << _ (", drill: default");
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
msg << _ (", drill: ") << drill;
|
||||
}
|
||||
|
||||
|
@ -148,7 +149,7 @@ protected:
|
|||
OPT_TOOL_EVENT handleCustomEvent( const wxEvent& aEvent )
|
||||
{
|
||||
#if ID_POPUP_PCB_SELECT_VIASIZE1 < ID_POPUP_PCB_SELECT_WIDTH1
|
||||
#error You have changed event ids, it breaks a piece of code. Lookup this line for more details.
|
||||
#error You have changed event ids order, it breaks code. Check the source code for more details.
|
||||
// Recognising type of event (track width/via size) is based on comparison if the event id is
|
||||
// within a specific range. If ranges of event ids changes, then the following is not valid anymore.
|
||||
#endif
|
||||
|
@ -156,7 +157,7 @@ protected:
|
|||
|
||||
int id = aEvent.GetId();
|
||||
|
||||
// General settings, to be modified below
|
||||
// Initial settings, to be modified below
|
||||
bds.m_UseConnectedTrackWidth = false;
|
||||
bds.UseCustomTrackViaSize( false );
|
||||
|
||||
|
@ -198,11 +199,8 @@ protected:
|
|||
};
|
||||
|
||||
|
||||
class CONTEXT_GRID_MENU: public CONTEXT_MENU { };
|
||||
|
||||
|
||||
class ROUTER_TOOL_MENU: public CONTEXT_MENU {
|
||||
|
||||
class ROUTER_TOOL_MENU: public CONTEXT_MENU
|
||||
{
|
||||
public:
|
||||
ROUTER_TOOL_MENU( BOARD* aBoard )
|
||||
{
|
||||
|
@ -227,6 +225,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
ROUTER_TOOL::~ROUTER_TOOL()
|
||||
{
|
||||
delete m_router;
|
||||
|
@ -259,6 +258,7 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode )
|
|||
int w, d1, d2;
|
||||
|
||||
getNetclassDimensions( aNetCode, w, d1, d2 );
|
||||
|
||||
return w;
|
||||
}
|
||||
|
||||
|
@ -349,12 +349,12 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa
|
|||
rv = NULL;
|
||||
|
||||
if( rv )
|
||||
TRACE( 0, "%s, layer : %d, tl: %d", rv->KindStr().c_str() % rv->Layers().Start() %
|
||||
tl );
|
||||
TRACE( 0, "%s, layer : %d, tl: %d", rv->KindStr().c_str() % rv->Layers().Start() % tl );
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
|
||||
{
|
||||
RENDER_SETTINGS* rs = getView()->GetPainter()->GetSettings();
|
||||
|
@ -367,12 +367,13 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
|
|||
getView()->UpdateAllLayersColor();
|
||||
}
|
||||
|
||||
void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
|
||||
|
||||
void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if( evt.IsKeyPressed() )
|
||||
if( aEvent.IsKeyPressed() )
|
||||
{
|
||||
switch( evt.KeyCode() )
|
||||
switch( aEvent.KeyCode() )
|
||||
{
|
||||
case 'S':
|
||||
TRACEn( 2, "saving drag/route log...\n" );
|
||||
|
@ -382,7 +383,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
|
|||
}
|
||||
else
|
||||
#endif
|
||||
if( evt.IsAction( &ACT_RouterOptions ) )
|
||||
if( aEvent.IsAction( &ACT_RouterOptions ) )
|
||||
{
|
||||
DIALOG_PNS_SETTINGS settingsDlg( m_toolMgr->GetEditFrame(), m_router->Settings() );
|
||||
|
||||
|
@ -390,7 +391,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
|
|||
m_router->ApplySettings();
|
||||
}
|
||||
|
||||
else if( evt.IsAction( &ACT_CustomTrackWidth ) )
|
||||
else if( aEvent.IsAction( &ACT_CustomTrackWidth ) )
|
||||
{
|
||||
DIALOG_TRACK_VIA_SIZE sizeDlg( m_toolMgr->GetEditFrame(), m_router->Settings() );
|
||||
BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>( PCB_T )->GetDesignSettings();
|
||||
|
@ -410,7 +411,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
|
|||
handleCommonEvents( event );
|
||||
}
|
||||
|
||||
else if( evt.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )
|
||||
else if( aEvent.IsAction( &COMMON_ACTIONS::trackViaSizeChanged ) )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>( PCB_T )->GetDesignSettings();
|
||||
|
||||
|
@ -421,6 +422,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
|
||||
{
|
||||
VIEW_CONTROLS* ctls = getViewControls();
|
||||
|
@ -431,11 +433,8 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
|
|||
if( aEvent.IsMotion() || aEvent.IsClick() )
|
||||
{
|
||||
VECTOR2I p = aEvent.Position();
|
||||
|
||||
startItem = pickSingleItem( p );
|
||||
|
||||
bool snapEnabled = !aEvent.Modifier(MD_SHIFT);
|
||||
|
||||
m_router->EnableSnapping ( snapEnabled );
|
||||
|
||||
if( !snapEnabled && startItem && !startItem->Layers().Overlaps( tl ) )
|
||||
|
@ -446,10 +445,13 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
|
|||
bool dummy;
|
||||
VECTOR2I psnap = m_router->SnapToItem( startItem, p, dummy );
|
||||
|
||||
if (snapEnabled) {
|
||||
if( snapEnabled )
|
||||
{
|
||||
m_startSnapPoint = psnap;
|
||||
ctls->ForceCursorPosition( true, psnap );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
m_startSnapPoint = cp;
|
||||
ctls->ForceCursorPosition( false );
|
||||
}
|
||||
|
@ -514,8 +516,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent )
|
|||
}
|
||||
|
||||
if( m_endItem )
|
||||
TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() %
|
||||
m_endItem->Layers().Start() );
|
||||
TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() );
|
||||
}
|
||||
|
||||
|
||||
|
@ -573,7 +574,8 @@ void ROUTER_TOOL::performRouting()
|
|||
break;
|
||||
|
||||
m_router->Move( m_endSnapPoint, m_endItem );
|
||||
} else if( evt->IsAction( &ACT_PlaceThroughVia ) )
|
||||
}
|
||||
else if( evt->IsAction( &ACT_PlaceThroughVia ) )
|
||||
{
|
||||
m_router->ToggleViaPlacement();
|
||||
frame->SetTopLayer( m_router->GetCurrentLayer() );
|
||||
|
@ -636,7 +638,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent )
|
|||
// Deselect all items
|
||||
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear );
|
||||
|
||||
getEditFrame<PCB_EDIT_FRAME>()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL, _( "Interactive Router" ) );
|
||||
getEditFrame<PCB_EDIT_FRAME>()->SetToolID( ID_TRACK_BUTT, wxCURSOR_PENCIL,
|
||||
_( "Interactive Router" ) );
|
||||
|
||||
ctls->SetSnapping( true );
|
||||
ctls->ShowCursor( true );
|
||||
|
@ -725,11 +728,10 @@ void ROUTER_TOOL::performDragging()
|
|||
}
|
||||
else if( evt->IsClick( BUT_LEFT ) )
|
||||
{
|
||||
|
||||
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
handleCommonEvents( *evt );
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ public:
|
|||
int Main( TOOL_EVENT& aEvent );
|
||||
|
||||
private:
|
||||
|
||||
PNS_ITEM* pickSingleItem( const VECTOR2I& aWhere, int aNet = -1, int aLayer = -1 );
|
||||
|
||||
int getDefaultWidth( int aNetCode );
|
||||
|
@ -57,7 +56,7 @@ private:
|
|||
void performRouting();
|
||||
void performDragging();
|
||||
|
||||
void highlightNet( bool enabled, int netcode = -1 );
|
||||
void highlightNet( bool aEnabled, int aNetcode = -1 );
|
||||
|
||||
void updateStartItem( TOOL_EVENT& aEvent );
|
||||
void updateEndItem( TOOL_EVENT& aEvent );
|
||||
|
@ -78,7 +77,6 @@ private:
|
|||
PNS_ITEM* m_endItem;
|
||||
VECTOR2I m_endSnapPoint;
|
||||
|
||||
|
||||
CONTEXT_MENU* m_menu;
|
||||
|
||||
///> Flag marking that the router's world needs syncing.
|
||||
|
|
|
@ -26,20 +26,25 @@ TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) :
|
|||
m_limitMs( aMilliseconds )
|
||||
{
|
||||
Restart();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
TIME_LIMIT::~TIME_LIMIT()
|
||||
{}
|
||||
|
||||
TIME_LIMIT::~TIME_LIMIT () {}
|
||||
|
||||
bool TIME_LIMIT::Expired() const
|
||||
{
|
||||
return ( wxGetLocalTimeMillis().GetValue() - m_startTics ) >= m_limitMs;
|
||||
}
|
||||
|
||||
|
||||
void TIME_LIMIT::Restart()
|
||||
{
|
||||
m_startTics = wxGetLocalTimeMillis().GetValue();
|
||||
}
|
||||
|
||||
|
||||
void TIME_LIMIT::Set( int aMilliseconds )
|
||||
{
|
||||
m_limitMs = aMilliseconds;
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
class TIME_LIMIT {
|
||||
|
||||
class TIME_LIMIT
|
||||
{
|
||||
public:
|
||||
TIME_LIMIT( int aMilliseconds = 0 );
|
||||
~TIME_LIMIT();
|
||||
|
@ -35,10 +35,8 @@ public:
|
|||
void Set( int aMilliseconds );
|
||||
|
||||
private:
|
||||
|
||||
int m_limitMs;
|
||||
int64_t m_startTics;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -25,10 +25,10 @@
|
|||
#include <iostream>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
static inline void _trace_print( const char* aFuncName, int level, const std::string& aMsg )
|
||||
static inline void _trace_print( const char* aFuncName, int aLevel, const std::string& aMsg )
|
||||
{
|
||||
#ifdef DEBUG
|
||||
std::cerr << "trace[" << level << "]: " << aFuncName << ": " << aMsg << std::endl;
|
||||
std::cerr << "trace[" << aLevel << "]: " << aFuncName << ": " << aMsg << std::endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue