Commit ad1b138f authored by Maciej Suminski's avatar Maciej Suminski

Reformatted PNS code to conform the coding policy.

parent ebf35fd4
...@@ -209,12 +209,12 @@ public: ...@@ -209,12 +209,12 @@ public:
// we are more horizontal than vertical? // we are more horizontal than vertical?
if( w > h ) if( w > h )
{ {
mp0 = VECTOR2I( (w - h) * sw, 0 ); // direction: E mp0 = VECTOR2I( ( w - h ) * sw, 0 ); // direction: E
mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE mp1 = VECTOR2I( h * sw, h * sh ); // direction: NE
} }
else else
{ {
mp0 = VECTOR2I( 0, sh * (h - w) ); // direction: N mp0 = VECTOR2I( 0, sh * ( h - w ) ); // direction: N
mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE mp1 = VECTOR2I( sw * w, sh * w ); // direction: NE
} }
...@@ -237,7 +237,7 @@ public: ...@@ -237,7 +237,7 @@ public:
pl.Append( aP1 ); pl.Append( aP1 );
pl.Simplify(); pl.Simplify();
return pl; return pl;
}; }
bool operator==( const DIRECTION_45& aOther ) const bool operator==( const DIRECTION_45& aOther ) const
{ {
...@@ -275,19 +275,17 @@ public: ...@@ -275,19 +275,17 @@ public:
{ {
DIRECTION_45 l; DIRECTION_45 l;
if (m_dir == UNDEFINED) if ( m_dir == UNDEFINED )
return l; return l;
if(m_dir == N) if( m_dir == N )
l.m_dir = NW; l.m_dir = NW;
else else
l.m_dir = static_cast<Directions> (m_dir - 1); l.m_dir = static_cast<Directions>( m_dir - 1 );
return l; return l;
} }
/** /**
* Function ToVector() * Function ToVector()
* *
...@@ -295,19 +293,19 @@ public: ...@@ -295,19 +293,19 @@ public:
*/ */
const VECTOR2I ToVector() const const VECTOR2I ToVector() const
{ {
switch(m_dir) switch( m_dir )
{ {
case N: return VECTOR2I(0, 1); case N: return VECTOR2I( 0, 1 );
case S: return VECTOR2I(0, -1); case S: return VECTOR2I( 0, -1 );
case E: return VECTOR2I(1, 0); case E: return VECTOR2I( 1, 0 );
case W: return VECTOR2I(-1, 0); case W: return VECTOR2I( -1, 0 );
case NE: return VECTOR2I(1, 1); case NE: return VECTOR2I( 1, 1 );
case NW: return VECTOR2I(-1, 1); case NW: return VECTOR2I( -1, 1 );
case SE: return VECTOR2I(1, -1); case SE: return VECTOR2I( 1, -1 );
case SW: return VECTOR2I(-1, -1); case SW: return VECTOR2I( -1, -1 );
default: default:
return VECTOR2I(0, 0); return VECTOR2I( 0, 0 );
} }
} }
......
...@@ -33,17 +33,18 @@ class PNS_LOGGER; ...@@ -33,17 +33,18 @@ class PNS_LOGGER;
* Holds a bunch of objects commonly used by all algorithms (P&S settings, parent router instance, logging) * 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: public:
PNS_ALGO_BASE ( PNS_ROUTER *aRouter ): PNS_ALGO_BASE( PNS_ROUTER *aRouter ) :
m_router ( aRouter ) m_router ( aRouter )
{}; {}
virtual ~PNS_ALGO_BASE() {} virtual ~PNS_ALGO_BASE() {}
///> Returns the instance of our router ///> Returns the instance of our router
PNS_ROUTER *Router() const { PNS_ROUTER* Router() const
{
return m_router; return m_router;
} }
...@@ -51,10 +52,10 @@ public: ...@@ -51,10 +52,10 @@ public:
PNS_ROUTING_SETTINGS& Settings() const; PNS_ROUTING_SETTINGS& Settings() const;
///> Returns the logger object, allowing to dump geometry to a file. ///> Returns the logger object, allowing to dump geometry to a file.
virtual PNS_LOGGER *Logger(); virtual PNS_LOGGER* Logger();
private: private:
PNS_ROUTER *m_router; PNS_ROUTER* m_router;
}; };
#endif #endif
...@@ -29,7 +29,8 @@ PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) : ...@@ -29,7 +29,8 @@ PNS_DRAGGER::PNS_DRAGGER( PNS_ROUTER* aRouter ) :
{ {
m_world = NULL; m_world = NULL;
m_shove = NULL; m_shove = NULL;
}; }
PNS_DRAGGER::~PNS_DRAGGER() PNS_DRAGGER::~PNS_DRAGGER()
{ {
...@@ -37,97 +38,103 @@ PNS_DRAGGER::~PNS_DRAGGER() ...@@ -37,97 +38,103 @@ PNS_DRAGGER::~PNS_DRAGGER()
delete m_shove; delete m_shove;
} }
void PNS_DRAGGER::SetWorld ( PNS_NODE *aWorld )
void PNS_DRAGGER::SetWorld ( PNS_NODE* aWorld )
{ {
m_world = aWorld; m_world = aWorld;
} }
bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT *aSeg )
bool PNS_DRAGGER::startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg )
{ {
int w2 = aSeg->Width() / 2; int w2 = aSeg->Width() / 2;
m_draggedLine = m_world->AssembleLine ( aSeg, &m_draggedSegmentIndex ); m_draggedLine = m_world->AssembleLine ( aSeg, &m_draggedSegmentIndex );
m_shove->SetInitialLine (m_draggedLine); m_shove->SetInitialLine( m_draggedLine );
m_lastValidDraggedLine = *m_draggedLine; m_lastValidDraggedLine = *m_draggedLine;
m_lastValidDraggedLine.ClearSegmentLinks(); m_lastValidDraggedLine.ClearSegmentLinks();
if( (aP - aSeg->Seg().A).EuclideanNorm() <= w2 ) if( ( aP - aSeg->Seg().A ).EuclideanNorm() <= w2 )
m_mode = CORNER; m_mode = CORNER;
else if( (aP - aSeg->Seg().B).EuclideanNorm() <= w2 ) else if( ( aP - aSeg->Seg().B ).EuclideanNorm() <= w2 )
{ {
m_draggedSegmentIndex ++; m_draggedSegmentIndex ++;
m_mode = CORNER; m_mode = CORNER;
} else } else
m_mode = SEGMENT; m_mode = SEGMENT;
return true; return true;
} }
bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA *aVia )
bool PNS_DRAGGER::startDragVia( const VECTOR2D& aP, PNS_VIA* aVia )
{ {
m_draggedVia = aVia; m_draggedVia = aVia;
m_initialVia = aVia; m_initialVia = aVia;
m_mode = VIA; m_mode = VIA;
VECTOR2I p0 ( aVia->Pos() ); VECTOR2I p0( aVia->Pos() );
PNS_JOINT *jt = m_world->FindJoint( p0, aVia->Layers().Start(), aVia->Net() ); PNS_JOINT *jt = m_world->FindJoint( p0, aVia->Layers().Start(), aVia->Net() );
BOOST_FOREACH(PNS_ITEM *item, jt->LinkList() ) BOOST_FOREACH(PNS_ITEM *item, jt->LinkList() )
{ {
if(item->OfKind( PNS_ITEM::SEGMENT )) if( item->OfKind( PNS_ITEM::SEGMENT ) )
{ {
int segIndex; int segIndex;
PNS_SEGMENT *seg = (PNS_SEGMENT *) item; PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
std::auto_ptr<PNS_LINE> l ( m_world->AssembleLine(seg, &segIndex) ); std::auto_ptr<PNS_LINE> l( m_world->AssembleLine( seg, &segIndex ) );
if(segIndex != 0) if( segIndex != 0 )
l->Reverse(); l->Reverse();
m_origViaConnections.push_back (*l); m_origViaConnections.push_back( *l );
} }
} }
return true; return true;
} }
bool PNS_DRAGGER::Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem )
bool PNS_DRAGGER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
m_shove = new PNS_SHOVE ( m_world, Router() ); m_shove = new PNS_SHOVE( m_world, Router() );
m_lastNode = NULL; m_lastNode = NULL;
m_draggedItems.Clear(); m_draggedItems.Clear();
m_currentMode = Settings().Mode(); m_currentMode = Settings().Mode();
TRACE(2, "StartDragging: item %p [kind %d]", aStartItem % aStartItem->Kind()); TRACE( 2, "StartDragging: item %p [kind %d]", aStartItem % aStartItem->Kind() );
switch( aStartItem->Kind() ) switch( aStartItem->Kind() )
{ {
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
return startDragSegment ( aP, static_cast<PNS_SEGMENT *> (aStartItem) ); return startDragSegment ( aP, static_cast<PNS_SEGMENT *>( aStartItem ) );
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
return startDragVia ( aP, static_cast<PNS_VIA *> (aStartItem) ); return startDragVia ( aP, static_cast<PNS_VIA *> (aStartItem) );
default: default:
return false; return false;
} }
} }
bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
bool PNS_DRAGGER::dragMarkObstacles( const VECTOR2I& aP )
{ {
if(m_lastNode) if( m_lastNode )
{ {
delete m_lastNode; delete m_lastNode;
m_lastNode = NULL; m_lastNode = NULL;
} }
switch(m_mode) switch( m_mode )
{ {
case SEGMENT: case SEGMENT:
case CORNER: case CORNER:
{ {
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0; int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0;
PNS_LINE tmp (*m_draggedLine); PNS_LINE tmp( *m_draggedLine );
if(m_mode == SEGMENT) if( m_mode == SEGMENT )
tmp.DragSegment ( aP, m_draggedSegmentIndex, thresh ); tmp.DragSegment ( aP, m_draggedSegmentIndex, thresh );
else else
tmp.DragCorner ( aP, m_draggedSegmentIndex, thresh ); tmp.DragCorner ( aP, m_draggedSegmentIndex, thresh );
...@@ -143,17 +150,17 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP) ...@@ -143,17 +150,17 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
break; break;
} }
case VIA: // fixme... case VIA: // fixme...
{ {
m_lastNode = m_shove->CurrentNode()->Branch(); m_lastNode = m_shove->CurrentNode()->Branch();
dumbDragVia ( m_initialVia, m_lastNode, aP ); dumbDragVia ( m_initialVia, m_lastNode, aP );
break; break;
} }
} }
if (Settings().CanViolateDRC()) if( Settings().CanViolateDRC() )
m_dragStatus = true; m_dragStatus = true;
else else
m_dragStatus = !m_world->CheckColliding( m_draggedItems ); m_dragStatus = !m_world->CheckColliding( m_draggedItems );
...@@ -161,60 +168,62 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP) ...@@ -161,60 +168,62 @@ bool PNS_DRAGGER::dragMarkObstacles(const VECTOR2I& aP)
return true; return true;
} }
void PNS_DRAGGER::dumbDragVia ( PNS_VIA *aVia, PNS_NODE *aNode, const VECTOR2I& aP )
void PNS_DRAGGER::dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP )
{ {
// fixme: this is awful. // fixme: this is awful.
m_draggedVia = aVia->Clone(); m_draggedVia = aVia->Clone();
m_draggedVia->SetPos( aP ); m_draggedVia->SetPos( aP );
m_draggedItems.Clear(); m_draggedItems.Clear();
m_draggedItems.Add(m_draggedVia); m_draggedItems.Add( m_draggedVia );
m_lastNode->Remove ( aVia ); m_lastNode->Remove( aVia );
m_lastNode->Add ( m_draggedVia ); m_lastNode->Add( m_draggedVia );
BOOST_FOREACH(PNS_LINE &l, m_origViaConnections) BOOST_FOREACH( PNS_LINE &l, m_origViaConnections )
{ {
PNS_LINE origLine (l); PNS_LINE origLine (l);
PNS_LINE *draggedLine = l.Clone(); PNS_LINE* draggedLine = l.Clone();
draggedLine->DragCorner( aP, 0 ); draggedLine->DragCorner( aP, 0 );
draggedLine->ClearSegmentLinks(); draggedLine->ClearSegmentLinks();
m_draggedItems.AddOwned( draggedLine ); m_draggedItems.AddOwned( draggedLine );
m_lastNode->Remove ( &origLine ); m_lastNode->Remove( &origLine );
m_lastNode->Add ( draggedLine ); m_lastNode->Add( draggedLine );
} }
} }
bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
bool PNS_DRAGGER::dragShove( const VECTOR2I& aP )
{ {
bool ok = false; bool ok = false;
if( m_lastNode )
if(m_lastNode)
{ {
delete m_lastNode; delete m_lastNode;
m_lastNode = NULL; m_lastNode = NULL;
} }
switch(m_mode) switch( m_mode )
{ {
case SEGMENT: case SEGMENT:
case CORNER: case CORNER:
{ {
int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0; int thresh = Settings().SmoothDraggedSegments() ? m_draggedLine->Width() / 4 : 0;
PNS_LINE tmp (*m_draggedLine); PNS_LINE tmp( *m_draggedLine );
if(m_mode == SEGMENT)
tmp.DragSegment ( aP, m_draggedSegmentIndex, thresh ); if( m_mode == SEGMENT )
tmp.DragSegment( aP, m_draggedSegmentIndex, thresh );
else else
tmp.DragCorner ( aP, m_draggedSegmentIndex, thresh ); 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) if( st == PNS_SHOVE::SH_OK )
ok = true; ok = true;
else if (st == PNS_SHOVE::SH_HEAD_MODIFIED) else if( st == PNS_SHOVE::SH_HEAD_MODIFIED )
{ {
tmp = m_shove->NewHead(); tmp = m_shove->NewHead();
ok = true; ok = true;
...@@ -222,22 +231,23 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP) ...@@ -222,22 +231,23 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
m_lastNode = m_shove->CurrentNode()->Branch(); m_lastNode = m_shove->CurrentNode()->Branch();
if(ok) if( ok )
m_lastValidDraggedLine = tmp; m_lastValidDraggedLine = tmp;
m_lastValidDraggedLine.ClearSegmentLinks(); m_lastValidDraggedLine.ClearSegmentLinks();
m_lastValidDraggedLine.Unmark(); m_lastValidDraggedLine.Unmark();
m_lastNode->Add ( &m_lastValidDraggedLine ); m_lastNode->Add( &m_lastValidDraggedLine );
m_draggedItems = PNS_ITEMSET ( &m_lastValidDraggedLine ); m_draggedItems = PNS_ITEMSET( &m_lastValidDraggedLine );
break; break;
} }
case VIA: case VIA:
{ {
PNS_VIA *newVia; 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) if( st == PNS_SHOVE::SH_OK || st == PNS_SHOVE::SH_HEAD_MODIFIED )
ok = true; ok = true;
m_lastNode = m_shove->CurrentNode()->Branch(); m_lastNode = m_shove->CurrentNode()->Branch();
...@@ -250,16 +260,17 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP) ...@@ -250,16 +260,17 @@ bool PNS_DRAGGER::dragShove(const VECTOR2I& aP)
break; break;
} }
} }
m_dragStatus = ok; m_dragStatus = ok;
return ok; return ok;
} }
bool PNS_DRAGGER::FixRoute( )
bool PNS_DRAGGER::FixRoute()
{ {
if(m_dragStatus) if( m_dragStatus )
{ {
Router()->CommitRouting( CurrentNode() ); Router()->CommitRouting( CurrentNode() );
return true; return true;
...@@ -268,34 +279,41 @@ bool PNS_DRAGGER::FixRoute( ) ...@@ -268,34 +279,41 @@ bool PNS_DRAGGER::FixRoute( )
return false; return false;
} }
bool PNS_DRAGGER::Drag ( const VECTOR2I& aP )
bool PNS_DRAGGER::Drag( const VECTOR2I& aP )
{ {
switch ( m_currentMode ) switch( m_currentMode )
{ {
case RM_MarkObstacles: case RM_MarkObstacles:
return dragMarkObstacles (aP); return dragMarkObstacles( aP );
case RM_Shove: case RM_Shove:
case RM_Walkaround: case RM_Walkaround:
case RM_Smart: case RM_Smart:
return dragShove ( aP ); return dragShove( aP );
default: default:
return false; return false;
} }
} }
PNS_NODE *PNS_DRAGGER::CurrentNode() const PNS_NODE *PNS_DRAGGER::CurrentNode() const
{ {
return m_lastNode; return m_lastNode;
} }
const PNS_ITEMSET PNS_DRAGGER::Traces() const PNS_ITEMSET PNS_DRAGGER::Traces()
{ {
return m_draggedItems; return m_draggedItems;
} }
PNS_LOGGER *PNS_DRAGGER::Logger()
PNS_LOGGER* PNS_DRAGGER::Logger()
{ {
if(m_shove) if( m_shove )
return m_shove->Logger(); return m_shove->Logger();
return NULL; return NULL;
} }
...@@ -39,12 +39,10 @@ class PNS_ROUTER_BASE; ...@@ -39,12 +39,10 @@ class PNS_ROUTER_BASE;
* *
* Via, segment and corner dragging algorithm. * Via, segment and corner dragging algorithm.
*/ */
class PNS_DRAGGER : public PNS_ALGO_BASE class PNS_DRAGGER : public PNS_ALGO_BASE
{ {
public: public:
PNS_DRAGGER( PNS_ROUTER* aRouter );
PNS_DRAGGER( PNS_ROUTER *aRouter );
~PNS_DRAGGER(); ~PNS_DRAGGER();
/** /**
...@@ -52,8 +50,7 @@ public: ...@@ -52,8 +50,7 @@ public:
* *
* Sets the board to work on. * Sets the board to work on.
*/ */
void SetWorld ( PNS_NODE *aWorld ); void SetWorld( PNS_NODE* aWorld );
/** /**
* Function Start() * Function Start()
...@@ -61,7 +58,7 @@ public: ...@@ -61,7 +58,7 @@ public:
* Starts routing a single track at point aP, taking item aStartItem as anchor * Starts routing a single track at point aP, taking item aStartItem as anchor
* (unless NULL). Returns true if a dragging operation has started. * (unless NULL). Returns true if a dragging operation has started.
*/ */
bool Start ( const VECTOR2I& aP, PNS_ITEM* aStartItem ); bool Start( const VECTOR2I& aP, PNS_ITEM* aStartItem );
/** /**
* Function Drag() * Function Drag()
...@@ -69,7 +66,7 @@ public: ...@@ -69,7 +66,7 @@ public:
* Drags the current segment/corner/via to the point aP. * Drags the current segment/corner/via to the point aP.
* @return true, if dragging finished with success. * @return true, if dragging finished with success.
*/ */
bool Drag ( const VECTOR2I& aP ); bool Drag( const VECTOR2I& aP );
/** /**
* Function FixRoute() * Function FixRoute()
...@@ -78,7 +75,7 @@ public: ...@@ -78,7 +75,7 @@ public:
* and eventually commits it to the world. * and eventually commits it to the world.
* @return true, if dragging finished with success. * @return true, if dragging finished with success.
*/ */
bool FixRoute ( ); bool FixRoute();
/** /**
* Function CurrentNode() * Function CurrentNode()
...@@ -86,7 +83,6 @@ public: ...@@ -86,7 +83,6 @@ public:
* Returns the most recent world state, including all * Returns the most recent world state, including all
* items changed due to dragging operation. * items changed due to dragging operation.
*/ */
PNS_NODE* CurrentNode() const; PNS_NODE* CurrentNode() const;
/** /**
...@@ -97,11 +93,10 @@ public: ...@@ -97,11 +93,10 @@ public:
const PNS_ITEMSET Traces(); const PNS_ITEMSET Traces();
/// @copydoc PNS_ALGO_BASE::Logger() /// @copydoc PNS_ALGO_BASE::Logger()
virtual PNS_LOGGER *Logger(); virtual PNS_LOGGER* Logger();
private: private:
typedef std::pair<PNS_LINE *, PNS_LINE *> LinePair;
typedef std::pair <PNS_LINE *, PNS_LINE *> LinePair;
typedef std::vector<LinePair> LinePairVec; typedef std::vector<LinePair> LinePairVec;
enum DragMode { enum DragMode {
...@@ -110,25 +105,25 @@ private: ...@@ -110,25 +105,25 @@ private:
VIA VIA
}; };
bool dragMarkObstacles(const VECTOR2I& aP); bool dragMarkObstacles( const VECTOR2I& aP );
bool dragShove(const VECTOR2I& aP); bool dragShove(const VECTOR2I& aP );
bool startDragSegment( const VECTOR2D& aP, PNS_SEGMENT *aSeg ); bool startDragSegment( const VECTOR2D& aP, PNS_SEGMENT* aSeg );
bool startDragVia( const VECTOR2D& aP, PNS_VIA *aVia ); bool startDragVia( const VECTOR2D& aP, PNS_VIA* aVia );
void dumbDragVia ( PNS_VIA *aVia, PNS_NODE *aNode, const VECTOR2I& aP ); void dumbDragVia( PNS_VIA* aVia, PNS_NODE* aNode, const VECTOR2I& aP );
PNS_NODE * m_world; PNS_NODE* m_world;
PNS_NODE * m_lastNode; PNS_NODE* m_lastNode;
DragMode m_mode; DragMode m_mode;
PNS_LINE * m_draggedLine; PNS_LINE* m_draggedLine;
PNS_VIA * m_draggedVia; PNS_VIA* m_draggedVia;
PNS_LINE m_lastValidDraggedLine; PNS_LINE m_lastValidDraggedLine;
PNS_SHOVE * m_shove; PNS_SHOVE* m_shove;
int m_draggedSegmentIndex; int m_draggedSegmentIndex;
bool m_dragStatus; bool m_dragStatus;
PNS_MODE m_currentMode; PNS_MODE m_currentMode;
std::vector<PNS_LINE> m_origViaConnections; std::vector<PNS_LINE> m_origViaConnections;
std::vector<PNS_LINE> m_draggedViaConnections; std::vector<PNS_LINE> m_draggedViaConnections;
PNS_VIA * m_initialVia; PNS_VIA* m_initialVia;
PNS_ITEMSET m_draggedItems; PNS_ITEMSET m_draggedItems;
}; };
......
...@@ -39,13 +39,12 @@ ...@@ -39,13 +39,12 @@
* are assigned to separate R-Tree subindices depending on their type and spanned layers, reducing * are assigned to separate R-Tree subindices depending on their type and spanned layers, reducing
* overlap and improving search time. * overlap and improving search time.
**/ **/
class PNS_INDEX class PNS_INDEX
{ {
public: public:
typedef std::list<PNS_ITEM*> NetItemsList; typedef std::list<PNS_ITEM*> NET_ITEMS_LIST;
typedef SHAPE_INDEX<PNS_ITEM*> ItemShapeIndex; typedef SHAPE_INDEX<PNS_ITEM*> ITEM_SHAPE_INDEX;
typedef boost::unordered_set<PNS_ITEM*> ItemSet; typedef boost::unordered_set<PNS_ITEM*> ITEM_SET;
PNS_INDEX(); PNS_INDEX();
~PNS_INDEX(); ~PNS_INDEX();
...@@ -115,7 +114,7 @@ public: ...@@ -115,7 +114,7 @@ public:
* *
* Returns list of all items in a given net. * Returns list of all items in a given net.
*/ */
NetItemsList* GetItemsForNet( int aNet ); NET_ITEMS_LIST* GetItemsForNet( int aNet );
/** /**
* Function Contains() * Function Contains()
...@@ -134,8 +133,8 @@ public: ...@@ -134,8 +133,8 @@ public:
*/ */
int Size() const { return m_allItems.size(); } int Size() const { return m_allItems.size(); }
ItemSet::iterator begin() { return m_allItems.begin(); } ITEM_SET::iterator begin() { return m_allItems.begin(); }
ItemSet::iterator end() { return m_allItems.end(); } ITEM_SET::iterator end() { return m_allItems.end(); }
private: private:
static const int MaxSubIndices = 64; static const int MaxSubIndices = 64;
...@@ -149,21 +148,20 @@ private: ...@@ -149,21 +148,20 @@ private:
template <class Visitor> template <class Visitor>
int querySingle( int index, const SHAPE* aShape, int aMinDistance, Visitor& aVisitor ); 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]; ITEM_SHAPE_INDEX* m_subIndices[MaxSubIndices];
std::map<int, NetItemsList> m_netMap; std::map<int, NET_ITEMS_LIST> m_netMap;
ItemSet m_allItems; ITEM_SET m_allItems;
}; };
PNS_INDEX::PNS_INDEX() PNS_INDEX::PNS_INDEX()
{ {
memset( m_subIndices, 0, sizeof( m_subIndices ) ); 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; int idx_n = -1;
...@@ -199,7 +197,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) ...@@ -199,7 +197,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
assert( idx_n >= 0 && idx_n < MaxSubIndices ); assert( idx_n >= 0 && idx_n < MaxSubIndices );
if( !m_subIndices[idx_n] ) if( !m_subIndices[idx_n] )
m_subIndices[idx_n] = new ItemShapeIndex; m_subIndices[idx_n] = new ITEM_SHAPE_INDEX;
return m_subIndices[idx_n]; return m_subIndices[idx_n];
} }
...@@ -207,9 +205,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem ) ...@@ -207,9 +205,7 @@ PNS_INDEX::ItemShapeIndex* PNS_INDEX::getSubindex( const PNS_ITEM* aItem )
void PNS_INDEX::Add( PNS_ITEM* aItem ) void PNS_INDEX::Add( PNS_ITEM* aItem )
{ {
ItemShapeIndex* idx = getSubindex( aItem ); ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
idx->Add( aItem ); idx->Add( aItem );
m_allItems.insert( aItem ); m_allItems.insert( aItem );
...@@ -224,7 +220,7 @@ void PNS_INDEX::Add( PNS_ITEM* aItem ) ...@@ -224,7 +220,7 @@ void PNS_INDEX::Add( PNS_ITEM* aItem )
void PNS_INDEX::Remove( PNS_ITEM* aItem ) void PNS_INDEX::Remove( PNS_ITEM* aItem )
{ {
ItemShapeIndex* idx = getSubindex( aItem ); ITEM_SHAPE_INDEX* idx = getSubindex( aItem );
idx->Remove( aItem ); idx->Remove( aItem );
m_allItems.erase( aItem ); m_allItems.erase( aItem );
...@@ -303,7 +299,7 @@ void PNS_INDEX::Clear() ...@@ -303,7 +299,7 @@ void PNS_INDEX::Clear()
{ {
for( int i = 0; i < MaxSubIndices; ++i ) for( int i = 0; i < MaxSubIndices; ++i )
{ {
ItemShapeIndex* idx = m_subIndices[i]; ITEM_SHAPE_INDEX* idx = m_subIndices[i];
if( idx ) if( idx )
delete idx; delete idx;
...@@ -319,7 +315,7 @@ PNS_INDEX::~PNS_INDEX() ...@@ -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() ) if( m_netMap.find( aNet ) == m_netMap.end() )
return NULL; return NULL;
......
...@@ -50,8 +50,7 @@ bool PNS_ITEM::Collide( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, ...@@ -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 ); const PNS_LINE* line = static_cast<const PNS_LINE*>( aOther );
if( line->EndsWithVia() ) if( line->EndsWithVia() )
return collideSimple( &line->Via(), aClearance - line->Width() / 2, aNeedMTV, return collideSimple( &line->Via(), aClearance - line->Width() / 2, aNeedMTV, aMTV );
aMTV );
} }
return false; return false;
...@@ -85,5 +84,4 @@ const std::string PNS_ITEM::KindStr() const ...@@ -85,5 +84,4 @@ const std::string PNS_ITEM::KindStr() const
PNS_ITEM::~PNS_ITEM() PNS_ITEM::~PNS_ITEM()
{ {
} }
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
* *
* Returns a deep copy of the item * Returns a deep copy of the item
*/ */
virtual PNS_ITEM* Clone( ) const = 0; virtual PNS_ITEM* Clone() const = 0;
/* /*
* Function Hull() * Function Hull()
...@@ -104,7 +104,7 @@ public: ...@@ -104,7 +104,7 @@ public:
virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const virtual const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const
{ {
return SHAPE_LINE_CHAIN(); return SHAPE_LINE_CHAIN();
}; }
/** /**
* Function Kind() * Function Kind()
...@@ -123,7 +123,7 @@ public: ...@@ -123,7 +123,7 @@ public:
*/ */
bool OfKind( int aKindMask ) const bool OfKind( int aKindMask ) const
{ {
return (aKindMask & m_kind) != 0; return ( aKindMask & m_kind ) != 0;
} }
/** /**
...@@ -219,7 +219,7 @@ public: ...@@ -219,7 +219,7 @@ public:
* Returns true if the set of layers spanned by aOther overlaps our * Returns true if the set of layers spanned by aOther overlaps our
* layers. * layers.
*/ */
bool LayersOverlap( const PNS_ITEM *aOther ) const bool LayersOverlap( const PNS_ITEM* aOther ) const
{ {
return Layers().Overlaps( aOther->Layers() ); return Layers().Overlaps( aOther->Layers() );
} }
...@@ -252,7 +252,6 @@ public: ...@@ -252,7 +252,6 @@ public:
*/ */
PNS_NODE* Owner() const { return m_owner; } PNS_NODE* Owner() const { return m_owner; }
/** /**
* Function Collide() * Function Collide()
* *
...@@ -308,7 +307,7 @@ public: ...@@ -308,7 +307,7 @@ public:
return m_marker; return m_marker;
} }
virtual void SetRank ( int aRank ) virtual void SetRank( int aRank )
{ {
m_rank = aRank; m_rank = aRank;
} }
...@@ -318,10 +317,10 @@ public: ...@@ -318,10 +317,10 @@ public:
return m_rank; return m_rank;
} }
virtual VECTOR2I Anchor(int n) const virtual VECTOR2I Anchor( int n ) const
{ {
return VECTOR2I (); return VECTOR2I ();
}; }
virtual int AnchorCount() const virtual int AnchorCount() const
{ {
...@@ -329,15 +328,14 @@ public: ...@@ -329,15 +328,14 @@ public:
} }
private: private:
bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV, bool collideSimple( const PNS_ITEM* aOther, int aClearance, bool aNeedMTV,
VECTOR2I& aMTV ) const; VECTOR2I& aMTV ) const;
protected: protected:
PnsKind m_kind; PnsKind m_kind;
BOARD_CONNECTED_ITEM *m_parent; BOARD_CONNECTED_ITEM* m_parent;
PNS_NODE *m_owner; PNS_NODE* m_owner;
PNS_LAYERSET m_layers; PNS_LAYERSET m_layers;
bool m_movable; bool m_movable;
......
...@@ -22,8 +22,7 @@ ...@@ -22,8 +22,7 @@
#include "pns_itemset.h" #include "pns_itemset.h"
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM* aInitialItem )
PNS_ITEMSET::PNS_ITEMSET( PNS_ITEM *aInitialItem )
{ {
if(aInitialItem) if(aInitialItem)
m_items.push_back(aInitialItem); m_items.push_back(aInitialItem);
...@@ -38,7 +37,7 @@ PNS_ITEMSET::~PNS_ITEMSET() ...@@ -38,7 +37,7 @@ PNS_ITEMSET::~PNS_ITEMSET()
void PNS_ITEMSET::Clear() void PNS_ITEMSET::Clear()
{ {
BOOST_FOREACH(PNS_ITEM *item, m_ownedItems) BOOST_FOREACH(PNS_ITEM* item, m_ownedItems)
{ {
delete item; delete item;
} }
...@@ -47,9 +46,10 @@ void PNS_ITEMSET::Clear() ...@@ -47,9 +46,10 @@ void PNS_ITEMSET::Clear()
m_ownedItems.clear(); m_ownedItems.clear();
} }
PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd ) PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
{ {
ItemVector newItems; ITEM_VECTOR newItems;
PNS_LAYERSET l; PNS_LAYERSET l;
if( aEnd < 0 ) if( aEnd < 0 )
...@@ -57,39 +57,44 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd ) ...@@ -57,39 +57,44 @@ PNS_ITEMSET& PNS_ITEMSET::FilterLayers( int aStart, int aEnd )
else else
l = PNS_LAYERSET( aStart, aEnd ); l = PNS_LAYERSET( aStart, aEnd );
BOOST_FOREACH( PNS_ITEM * item, m_items ) BOOST_FOREACH( PNS_ITEM* item, m_items )
if( item->Layers().Overlaps( l ) ) if( item->Layers().Overlaps( l ) )
newItems.push_back( item ); newItems.push_back( item );
m_items = newItems; m_items = newItems;
return *this; return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask ) PNS_ITEMSET& PNS_ITEMSET::FilterKinds( int aKindMask )
{ {
ItemVector newItems; ITEM_VECTOR newItems;
BOOST_FOREACH( PNS_ITEM * item, m_items )
BOOST_FOREACH( PNS_ITEM* item, m_items )
{
if( item->OfKind ( aKindMask ) ) if( item->OfKind ( aKindMask ) )
newItems.push_back( item ); newItems.push_back( item );
}
m_items = newItems; m_items = newItems;
return *this; return *this;
} }
PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet ) PNS_ITEMSET& PNS_ITEMSET::FilterNet( int aNet )
{ {
ItemVector newItems; ITEM_VECTOR newItems;
BOOST_FOREACH( PNS_ITEM * item, m_items )
BOOST_FOREACH( PNS_ITEM* item, m_items )
{
if( item->Net() == aNet ) if( item->Net() == aNet )
newItems.push_back( item ); newItems.push_back( item );
}
m_items = newItems; m_items = newItems;
return *this; return *this;
} }
...@@ -35,27 +35,28 @@ ...@@ -35,27 +35,28 @@
class PNS_ITEMSET class PNS_ITEMSET
{ {
public: public:
typedef std::vector<PNS_ITEM*> ItemVector; typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
PNS_ITEMSET( PNS_ITEM *aInitialItem = NULL ); PNS_ITEMSET( PNS_ITEM* aInitialItem = NULL );
PNS_ITEMSET (const PNS_ITEMSET &aOther ) PNS_ITEMSET( const PNS_ITEMSET& aOther )
{ {
m_items = aOther.m_items; m_items = aOther.m_items;
m_ownedItems = ItemVector(); m_ownedItems = ITEM_VECTOR();
} }
const PNS_ITEMSET& operator= (const PNS_ITEMSET &aOther) const PNS_ITEMSET& operator=( const PNS_ITEMSET& aOther )
{ {
m_items = aOther.m_items; m_items = aOther.m_items;
m_ownedItems = ItemVector(); m_ownedItems = ITEM_VECTOR();
return *this; return *this;
} }
~PNS_ITEMSET(); ~PNS_ITEMSET();
ItemVector& Items() { return m_items; } ITEM_VECTOR& Items() { return m_items; }
const ItemVector& CItems() const { return m_items; } const ITEM_VECTOR& CItems() const { return m_items; }
PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1 ); PNS_ITEMSET& FilterLayers( int aStart, int aEnd = -1 );
PNS_ITEMSET& FilterKinds( int aKindMask ); PNS_ITEMSET& FilterKinds( int aKindMask );
...@@ -63,24 +64,24 @@ public: ...@@ -63,24 +64,24 @@ public:
int Size() { return m_items.size(); } 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]; } PNS_ITEM* Get( int index ) const { return m_items[index]; }
void Clear(); void Clear();
void AddOwned ( PNS_ITEM *aItem ) void AddOwned( PNS_ITEM *aItem )
{ {
m_items.push_back( aItem ); m_items.push_back( aItem );
m_ownedItems.push_back( aItem ); m_ownedItems.push_back( aItem );
} }
private: private:
ItemVector m_items; ITEM_VECTOR m_items;
ItemVector m_ownedItems; ITEM_VECTOR m_ownedItems;
}; };
#endif #endif
...@@ -40,11 +40,11 @@ ...@@ -40,11 +40,11 @@
class PNS_JOINT : public PNS_ITEM class PNS_JOINT : public PNS_ITEM
{ {
public: public:
typedef std::vector<PNS_ITEM*> LinkedItems; typedef std::vector<PNS_ITEM*> LINKED_ITEMS;
///> Joints are hashed by their position, layers and net. ///> Joints are hashed by their position, layers and net.
/// Linked items are, obviously, not hashed /// Linked items are, obviously, not hashed
struct HashTag struct HASH_TAG
{ {
VECTOR2I pos; VECTOR2I pos;
int net; int net;
...@@ -53,8 +53,7 @@ public: ...@@ -53,8 +53,7 @@ public:
PNS_JOINT() : PNS_JOINT() :
PNS_ITEM( JOINT ) {} PNS_ITEM( JOINT ) {}
PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, PNS_JOINT( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aNet = -1 ) :
int aNet = -1 ) :
PNS_ITEM( JOINT ) PNS_ITEM( JOINT )
{ {
m_tag.pos = aPos; m_tag.pos = aPos;
...@@ -62,14 +61,14 @@ public: ...@@ -62,14 +61,14 @@ public:
m_layers = aLayers; m_layers = aLayers;
} }
PNS_JOINT( const PNS_JOINT& b ) : PNS_JOINT( const PNS_JOINT& aB ) :
PNS_ITEM( JOINT ) PNS_ITEM( JOINT )
{ {
m_layers = b.m_layers; m_layers = aB.m_layers;
m_tag.pos = b.m_tag.pos; m_tag.pos = aB.m_tag.pos;
m_tag.net = b.m_tag.net; m_tag.net = aB.m_tag.net;
m_linkedItems = b.m_linkedItems; m_linkedItems = aB.m_linkedItems;
m_layers = b.m_layers; m_layers = aB.m_layers;
} }
PNS_ITEM* Clone ( ) const PNS_ITEM* Clone ( ) const
...@@ -85,8 +84,7 @@ public: ...@@ -85,8 +84,7 @@ public:
if( m_linkedItems.size() != 2 ) if( m_linkedItems.size() != 2 )
return false; return false;
if( m_linkedItems[0]->Kind() != SEGMENT || if( m_linkedItems[0]->Kind() != SEGMENT || m_linkedItems[1]->Kind() != SEGMENT )
m_linkedItems[1]->Kind() != SEGMENT )
return false; return false;
PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] ); PNS_SEGMENT* seg1 = static_cast<PNS_SEGMENT*>( m_linkedItems[0] );
...@@ -99,8 +97,7 @@ public: ...@@ -99,8 +97,7 @@ public:
///> Links the joint to a given board item (when it's added to the PNS_NODE) ///> Links the joint to a given board item (when it's added to the PNS_NODE)
void Link( PNS_ITEM* aItem ) void Link( PNS_ITEM* aItem )
{ {
LinkedItems::iterator f = std::find( m_linkedItems.begin(), LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem );
m_linkedItems.end(), aItem );
if( f != m_linkedItems.end() ) if( f != m_linkedItems.end() )
return; return;
...@@ -112,8 +109,7 @@ public: ...@@ -112,8 +109,7 @@ public:
///> Returns true if the joint became dangling after unlinking. ///> Returns true if the joint became dangling after unlinking.
bool Unlink( PNS_ITEM* aItem ) bool Unlink( PNS_ITEM* aItem )
{ {
LinkedItems::iterator f = std::find( m_linkedItems.begin(), LINKED_ITEMS::iterator f = std::find( m_linkedItems.begin(), m_linkedItems.end(), aItem );
m_linkedItems.end(), aItem );
if( f != m_linkedItems.end() ) if( f != m_linkedItems.end() )
m_linkedItems.erase( f ); m_linkedItems.erase( f );
...@@ -131,17 +127,19 @@ public: ...@@ -131,17 +127,19 @@ public:
return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] ); return static_cast<PNS_SEGMENT*>( m_linkedItems[m_linkedItems[0] == aCurrent ? 1 : 0] );
} }
PNS_VIA *Via() PNS_VIA* Via()
{
for( LINKED_ITEMS::iterator i = m_linkedItems.begin(); i != m_linkedItems.end(); ++i )
{ {
for( LinkedItems::iterator i = m_linkedItems.begin();
i != m_linkedItems.end(); ++i )
if( (*i)->Kind() == PNS_ITEM::VIA ) if( (*i)->Kind() == PNS_ITEM::VIA )
return (PNS_VIA *)(*i); return (PNS_VIA*)( *i );
}
return NULL; return NULL;
} }
/// trivial accessors /// trivial accessors
const HashTag& Tag() const const HASH_TAG& Tag() const
{ {
return m_tag; return m_tag;
} }
...@@ -156,7 +154,7 @@ public: ...@@ -156,7 +154,7 @@ public:
return m_tag.net; return m_tag.net;
} }
LinkedItems& LinkList() LINKED_ITEMS& LinkList()
{ {
return m_linkedItems; return m_linkedItems;
} }
...@@ -166,10 +164,12 @@ public: ...@@ -166,10 +164,12 @@ public:
{ {
int n = 0; 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 ) i != m_linkedItems.end(); ++i )
{
if( (*i)->Kind() & aMask ) if( (*i)->Kind() & aMask )
n++; n++;
}
return n; return n;
} }
...@@ -189,10 +189,12 @@ public: ...@@ -189,10 +189,12 @@ public:
m_layers.Merge( aJoint.m_layers ); m_layers.Merge( aJoint.m_layers );
// fixme: duplicate links (?) // 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 ) i != aJoint.m_linkedItems.end(); ++i )
{
m_linkedItems.push_back( *i ); m_linkedItems.push_back( *i );
} }
}
bool Overlaps( const PNS_JOINT& rhs ) const bool Overlaps( const PNS_JOINT& rhs ) const
{ {
...@@ -202,27 +204,27 @@ public: ...@@ -202,27 +204,27 @@ public:
private: private:
///> hash tag for unordered_multimap ///> hash tag for unordered_multimap
HashTag m_tag; HASH_TAG m_tag;
///> list of items linked to this joint ///> list of items linked to this joint
LinkedItems m_linkedItems; LINKED_ITEMS m_linkedItems;
}; };
// hash function & comparison operator for boost::unordered_map<> // hash function & comparison operator for boost::unordered_map<>
inline bool operator==( PNS_JOINT::HashTag const& p1, inline bool operator==( PNS_JOINT::HASH_TAG const& aP1,
PNS_JOINT::HashTag const& p2 ) 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; std::size_t seed = 0;
boost::hash_combine( seed, p.pos.x ); boost::hash_combine( seed, aP.pos.x );
boost::hash_combine( seed, p.pos.y ); boost::hash_combine( seed, aP.pos.y );
boost::hash_combine( seed, p.net ); boost::hash_combine( seed, aP.net );
return seed; return seed;
} }
......
...@@ -50,17 +50,17 @@ public: ...@@ -50,17 +50,17 @@ public:
m_start = m_end = aLayer; m_start = m_end = aLayer;
} }
PNS_LAYERSET( const PNS_LAYERSET& b ) : PNS_LAYERSET( const PNS_LAYERSET& aB ) :
m_start( b.m_start ), m_start( aB.m_start ),
m_end( b.m_end ) m_end( aB.m_end )
{} {}
~PNS_LAYERSET() {}; ~PNS_LAYERSET() {};
const PNS_LAYERSET& operator=( const PNS_LAYERSET& b ) const PNS_LAYERSET& operator=( const PNS_LAYERSET& aB )
{ {
m_start = b.m_start; m_start = aB.m_start;
m_end = b.m_end; m_end = aB.m_end;
return *this; return *this;
} }
......
...@@ -50,14 +50,15 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) : ...@@ -50,14 +50,15 @@ PNS_LINE::PNS_LINE( const PNS_LINE& aOther ) :
copyLinks ( &aOther ); copyLinks ( &aOther );
} }
PNS_LINE::~PNS_LINE() PNS_LINE::~PNS_LINE()
{ {
if( m_segmentRefs ) if( m_segmentRefs )
delete m_segmentRefs; delete m_segmentRefs;
}; }
const PNS_LINE& PNS_LINE :: operator= (const PNS_LINE& aOther) const PNS_LINE& PNS_LINE::operator=( const PNS_LINE& aOther )
{ {
m_line = aOther.m_line; m_line = aOther.m_line;
m_width = aOther.m_width; m_width = aOther.m_width;
...@@ -75,53 +76,62 @@ const PNS_LINE& PNS_LINE :: operator= (const PNS_LINE& aOther) ...@@ -75,53 +76,62 @@ const PNS_LINE& PNS_LINE :: operator= (const PNS_LINE& aOther)
return *this; return *this;
} }
PNS_LINE* PNS_LINE::Clone( ) const
PNS_LINE* PNS_LINE::Clone() const
{ {
PNS_LINE* l = new PNS_LINE( *this ); PNS_LINE* l = new PNS_LINE( *this );
return l; return l;
} }
void PNS_LINE::Mark(int aMarker)
void PNS_LINE::Mark( int aMarker )
{ {
m_marker = aMarker; m_marker = aMarker;
if(m_segmentRefs) if( m_segmentRefs )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs ) BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
s->Mark(aMarker); s->Mark( aMarker );
} }
} }
void PNS_LINE::Unmark () void PNS_LINE::Unmark ()
{ {
if(m_segmentRefs) if( m_segmentRefs )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs ) BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
s->Unmark(); s->Unmark();
} }
m_marker = 0; m_marker = 0;
} }
int PNS_LINE::Marker()const int PNS_LINE::Marker()const
{ {
int marker = m_marker; int marker = m_marker;
if(m_segmentRefs)
if( m_segmentRefs )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs ) BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
marker |= s->Marker(); marker |= s->Marker();
} }
return marker; return marker;
} }
void PNS_LINE::copyLinks( const PNS_LINE *aParent ) void PNS_LINE::copyLinks( const PNS_LINE *aParent )
{ {
if(aParent->m_segmentRefs == NULL) if( aParent->m_segmentRefs == NULL )
{ {
m_segmentRefs = NULL; m_segmentRefs = NULL;
return; return;
} }
m_segmentRefs = new SegmentRefs(); m_segmentRefs = new SEGMENT_REFS();
*m_segmentRefs = *aParent->m_segmentRefs; *m_segmentRefs = *aParent->m_segmentRefs;
} }
...@@ -140,6 +150,7 @@ PNS_SEGMENT* PNS_SEGMENT::Clone( ) const ...@@ -140,6 +150,7 @@ PNS_SEGMENT* PNS_SEGMENT::Clone( ) const
return s; return s;
} }
int PNS_LINE::CountCorners( int aAngles ) int PNS_LINE::CountCorners( int aAngles )
{ {
int count = 0; int count = 0;
...@@ -161,6 +172,7 @@ int PNS_LINE::CountCorners( int aAngles ) ...@@ -161,6 +172,7 @@ int PNS_LINE::CountCorners( int aAngles )
return count; return count;
} }
bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
SHAPE_LINE_CHAIN& aWalk, SHAPE_LINE_CHAIN& aPost, bool aCw ) const SHAPE_LINE_CHAIN& aWalk, SHAPE_LINE_CHAIN& aPost, bool aCw ) const
{ {
...@@ -171,38 +183,37 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, ...@@ -171,38 +183,37 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
if( line.SegmentCount() < 1 ) if( line.SegmentCount() < 1 )
return false; return false;
if( aObstacle.PointInside( line.CPoint( 0 ) ) || if( aObstacle.PointInside( line.CPoint( 0 ) ) || aObstacle.PointInside( line.CPoint( -1 ) ) )
aObstacle.PointInside( line.CPoint( -1 ) ) )
return false; return false;
SHAPE_LINE_CHAIN::INTERSECTIONS ips, ips2; SHAPE_LINE_CHAIN::INTERSECTIONS ips, ips2;
line.Intersect(aObstacle, ips); line.Intersect( aObstacle, ips );
int nearest_dist = INT_MAX; int nearest_dist = INT_MAX;
int farthest_dist = 0; int farthest_dist = 0;
SHAPE_LINE_CHAIN::INTERSECTION nearest, farthest; SHAPE_LINE_CHAIN::INTERSECTION nearest, farthest;
for(int i = 0; i < (int) ips.size(); i++) for( int i = 0; i < (int) ips.size(); i++ )
{ {
const VECTOR2I p = ips[i].p; const VECTOR2I p = ips[i].p;
int dist = line.PathLength(p); int dist = line.PathLength( p );
if(dist <= nearest_dist) if( dist <= nearest_dist )
{ {
nearest_dist = dist; nearest_dist = dist;
nearest = ips[i]; nearest = ips[i];
} }
if(dist >= farthest_dist) if( dist >= farthest_dist )
{ {
farthest_dist = dist; farthest_dist = dist;
farthest = ips[i]; farthest = ips[i];
} }
} }
if(ips.size() <= 1 || nearest.p == farthest.p) if( ips.size() <= 1 || nearest.p == farthest.p )
{ {
aPre = line; aPre = line;
return true; return true;
...@@ -213,13 +224,13 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, ...@@ -213,13 +224,13 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
aPre.Simplify(); aPre.Simplify();
aWalk.Clear(); aWalk.Clear();
aWalk.SetClosed(false); aWalk.SetClosed( false );
aWalk.Append( nearest.p ); aWalk.Append( nearest.p );
int i = nearest.their.Index(); int i = nearest.their.Index();
assert ( nearest.their.Index() >= 0 ); assert( nearest.their.Index() >= 0 );
assert ( farthest.their.Index() >= 0 ); assert( farthest.their.Index() >= 0 );
assert( nearest_dist <= farthest_dist ); assert( nearest_dist <= farthest_dist );
...@@ -231,14 +242,14 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, ...@@ -231,14 +242,14 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
i = i_first; i = i_first;
while (i != i_last) while( i != i_last )
{ {
aWalk.Append(aObstacle.CPoint(i)); aWalk.Append( aObstacle.CPoint( i ) );
i += (aCw ? 1 : -1); i += ( aCw ? 1 : -1 );
if (i < 0) if( i < 0 )
i = aObstacle.PointCount() - 1; i = aObstacle.PointCount() - 1;
else if (i == aObstacle.PointCount()) else if( i == aObstacle.PointCount() )
i = 0; i = 0;
} }
...@@ -249,9 +260,11 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre, ...@@ -249,9 +260,11 @@ bool PNS_LINE::Walkaround( SHAPE_LINE_CHAIN aObstacle, SHAPE_LINE_CHAIN& aPre,
aPost.Append( farthest.p ); aPost.Append( farthest.p );
aPost.Append( line.Slice( farthest.our.Index() + 1, -1 ) ); aPost.Append( line.Slice( farthest.our.Index() + 1, -1 ) );
aPost.Simplify(); aPost.Simplify();
return true; return true;
} }
void PNS_LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle, void PNS_LINE::Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
SHAPE_LINE_CHAIN& aPath, SHAPE_LINE_CHAIN& aPath,
bool aCw ) const bool aCw ) const
...@@ -298,12 +311,12 @@ const PNS_LINE PNS_LINE::ClipToNearestObstacle( PNS_NODE* aNode ) const ...@@ -298,12 +311,12 @@ const PNS_LINE PNS_LINE::ClipToNearestObstacle( PNS_NODE* aNode ) const
{ {
PNS_LINE l( *this ); PNS_LINE l( *this );
PNS_NODE::OptObstacle obs = aNode->NearestObstacle( &l ); PNS_NODE::OPT_OBSTACLE obs = aNode->NearestObstacle( &l );
if( obs ) if( obs )
{ {
l.RemoveVia(); l.RemoveVia();
int p = l.Line().Split( obs->ip_first ); int p = l.Line().Split( obs->m_ipFirst );
l.Line().Remove( p + 1, -1 ); l.Line().Remove( p + 1, -1 );
} }
...@@ -325,113 +338,121 @@ void PNS_LINE::ShowLinks() ...@@ -325,113 +338,121 @@ void PNS_LINE::ShowLinks()
printf( "seg %d: %p\n", i, (*m_segmentRefs)[i] ); 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; optional<SHAPE_LINE_CHAIN> picked;
int i; int i;
int d = 2; 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; d = 1;
for(i = origin.SegmentCount() - d; i >= 0; i--) for( i = aOrigin.SegmentCount() - d; i >= 0; i-- )
{ {
DIRECTION_45 d_start ( aOrigin.CSegment( i ) );
DIRECTION_45 d_start (origin.CSegment(i)); VECTOR2I p_start = aOrigin.CPoint( i );
VECTOR2I p_start = origin.CPoint(i); SHAPE_LINE_CHAIN paths[2];
SHAPE_LINE_CHAIN paths [2];
DIRECTION_45 dirs[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++) for( int j = 0; j < 2; j++ )
{ {
paths [j] = d_start.BuildInitialTrace( p_start, aP, j ); paths[j] = d_start.BuildInitialTrace( p_start, aP, j );
dirs [j] = DIRECTION_45(paths[j].CSegment(0)); dirs[j] = DIRECTION_45( paths[j].CSegment( 0 ) );
} }
for( int j = 0; j < 2; j++ )
for( int j = 0; j < 2; j++) {
if(dirs[j] == d_start) if( dirs[j] == d_start )
{ {
picked = paths[j]; picked = paths[j];
break; break;
} }
}
if(picked) if( picked )
break; break;
for(int j = 0; j < 2; j++) for( int j = 0; j < 2; j++ )
if (dirs[j].IsObtuse(d_prev)) {
if( dirs[j].IsObtuse( d_prev ) )
{ {
picked = paths[j]; picked = paths[j];
break; break;
} }
if(picked) }
if( picked )
break; break;
} }
if(picked) if( picked )
{ {
SHAPE_LINE_CHAIN path = origin.Slice(0, i); SHAPE_LINE_CHAIN path = aOrigin.Slice( 0, i );
path.Append(*picked); path.Append( *picked );
return path;
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 ) void PNS_LINE::DragCorner ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
{ {
SHAPE_LINE_CHAIN path; SHAPE_LINE_CHAIN path;
VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex, aSnappingThreshold ); VECTOR2I snapped = snapDraggedCorner( m_line, aP, aIndex, aSnappingThreshold );
if( aIndex == 0) if( aIndex == 0 )
path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse(); path = dragCornerInternal( m_line.Reverse(), snapped ).Reverse();
else if ( aIndex == m_line.SegmentCount() ) else if ( aIndex == m_line.SegmentCount() )
path = dragCornerInternal( m_line, snapped ); path = dragCornerInternal( m_line, snapped );
else { else
{
// fixme: awkward behaviour for "outwards" drags // fixme: awkward behaviour for "outwards" drags
path = dragCornerInternal( m_line.Slice (0, aIndex), snapped ); 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(),
path.Append(path_rev); snapped ).Reverse();
path.Append( path_rev );
} }
path.Simplify(); path.Simplify();
m_line = path; 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_start = std::max( aIndex - 2, 0 );
int s_end = std::min(aIndex + 2, aPath.SegmentCount() - 1); int s_end = std::min( aIndex + 2, aPath.SegmentCount() - 1 );
int i, j; int i, j;
int best_dist = INT_MAX; int best_dist = INT_MAX;
VECTOR2I best_snap = aP; VECTOR2I best_snap = aP;
if(aThreshold <= 0) if( aThreshold <= 0 )
return aP; return aP;
for(i = s_start; i <= s_end; i++) for( i = s_start; i <= s_end; i++ )
{ {
const SEG& a = aPath.CSegment(i); const SEG& a = aPath.CSegment( i );
for(j = s_start; j < i; j++) for( j = s_start; j < i; j++ )
{ {
const SEG& b = aPath.CSegment(j); const SEG& b = aPath.CSegment( j );
if( ! (DIRECTION_45(a).IsObtuse(DIRECTION_45(b))) ) if( !( DIRECTION_45( a ).IsObtuse(DIRECTION_45( b ) ) ) )
continue; continue;
OPT_VECTOR2I ip = a.IntersectLines(b); OPT_VECTOR2I ip = a.IntersectLines(b);
if(ip) if( ip )
{ {
int dist = (*ip - aP).EuclideanNorm(); int dist = ( *ip - aP ).EuclideanNorm();
if( dist < aThreshold && dist < best_dist ) if( dist < aThreshold && dist < best_dist )
{ {
best_dist = dist; best_dist = dist;
...@@ -444,40 +465,47 @@ VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTO ...@@ -444,40 +465,47 @@ VECTOR2I PNS_LINE::snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTO
return best_snap; 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]; VECTOR2I snap_p[2];
DIRECTION_45 dragDir ( aPath.CSegment(aIndex) ); DIRECTION_45 dragDir( aPath.CSegment( aIndex ) );
int snap_d[2] = {-1, -1}; int snap_d[2] = { -1, -1 };
if( aThreshold == 0 ) if( aThreshold == 0 )
return aP; return aP;
if(aIndex >= 2) if( aIndex >= 2 )
{ {
SEG s = aPath.CSegment(aIndex - 2); SEG s = aPath.CSegment( aIndex - 2 );
if(DIRECTION_45(s) == dragDir)
snap_d[0] = s.LineDistance(aP); if( DIRECTION_45( s ) == dragDir )
snap_d[0] = s.LineDistance( aP );
snap_p[0] = s.A; snap_p[0] = s.A;
} }
if(aIndex < aPath.SegmentCount() - 2) if( aIndex < aPath.SegmentCount() - 2 )
{ {
SEG s = aPath.CSegment(aIndex + 2); SEG s = aPath.CSegment( aIndex + 2 );
if(DIRECTION_45(s) == dragDir)
if( DIRECTION_45( s ) == dragDir )
snap_d[1] = s.LineDistance(aP); snap_d[1] = s.LineDistance(aP);
snap_p[1] = s.A; snap_p[1] = s.A;
} }
VECTOR2I best = aP; VECTOR2I best = aP;
int minDist = INT_MAX; int minDist = INT_MAX;
for(int i = 0; i < 2; i++) for( int i = 0; i < 2; i++ )
if(snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= aThreshold) {
if( snap_d[i] >= 0 && snap_d[i] < minDist && snap_d[i] <= aThreshold )
{ {
minDist = snap_d[i]; minDist = snap_d[i];
best = snap_p[i]; best = snap_p[i];
} }
}
return best; return best;
} }
...@@ -485,157 +513,166 @@ VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const ...@@ -485,157 +513,166 @@ VECTOR2I PNS_LINE::snapToNeighbourSegments( const SHAPE_LINE_CHAIN& aPath, const
void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold ) void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold )
{ {
SHAPE_LINE_CHAIN path (m_line); SHAPE_LINE_CHAIN path( m_line );
VECTOR2I target (aP) ; VECTOR2I target( aP );
SEG guideA[2], guideB[2]; SEG guideA[2], guideB[2];
int index = aIndex; int index = aIndex;
target = snapToNeighbourSegments( path, aP, aIndex, aSnappingThreshold ); target = snapToNeighbourSegments( path, aP, aIndex, aSnappingThreshold );
if(index == 0) if( index == 0 )
{ {
path.Insert (0, path.CPoint(0)); path.Insert( 0, path.CPoint( 0 ) );
index++; index++;
} }
if(index == path.SegmentCount()-1) if( index == path.SegmentCount() - 1 )
{ {
path.Insert(path.PointCount() - 1, path.CPoint(-1)); path.Insert( path.PointCount() - 1, path.CPoint( -1 ) );
} }
SEG dragged = path.CSegment(index); SEG dragged = path.CSegment( index );
DIRECTION_45 drag_dir (dragged); DIRECTION_45 drag_dir( dragged );
SEG s_prev = path.CSegment(index - 1); SEG s_prev = path.CSegment( index - 1 );
SEG s_next = path.CSegment(index + 1); SEG s_next = path.CSegment( index + 1 );
DIRECTION_45 dir_prev (s_prev); DIRECTION_45 dir_prev( s_prev );
DIRECTION_45 dir_next (s_next); DIRECTION_45 dir_next( s_next );
if(dir_prev == drag_dir) if( dir_prev == drag_dir )
{ {
dir_prev = dir_prev.Left(); dir_prev = dir_prev.Left();
path.Insert( index, path.CPoint(index) ); path.Insert( index, path.CPoint( index ) );
index++; index++;
} }
if(dir_next == drag_dir) if( dir_next == drag_dir )
{ {
dir_next = dir_next.Right(); dir_next = dir_next.Right();
path.Insert( index + 1, path.CPoint(index + 1) ); path.Insert( index + 1, path.CPoint( index + 1 ) );
} }
s_prev = path.CSegment( index - 1 );
s_prev = path.CSegment(index - 1); s_next = path.CSegment( index + 1 );
s_next = path.CSegment(index + 1); dragged = path.CSegment( index );
dragged = path.CSegment(index);
bool lockEndpointA = true; bool lockEndpointA = true;
bool lockEndpointB = true; bool lockEndpointB = true;
if(aIndex == 0) if( aIndex == 0 )
{ {
if(!lockEndpointA) if( !lockEndpointA )
guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Right().Right().ToVector() ); 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[0] = SEG( dragged.A, dragged.A + drag_dir.Right().ToVector() );
guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() ); guideA[1] = SEG( dragged.A, dragged.A + drag_dir.Left().ToVector() );
} }
} else { }
if(dir_prev.IsObtuse(drag_dir)) else
{
if( dir_prev.IsObtuse(drag_dir ) )
{ {
guideA[0] = SEG( s_prev.A, s_prev.A + drag_dir.Left().ToVector() ); 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() ); 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() ); guideA[0] = guideA[1] = SEG( dragged.A, dragged.A + dir_prev.ToVector() );
} }
if(aIndex == m_line.SegmentCount() - 1) if( aIndex == m_line.SegmentCount() - 1 )
{ {
if(!lockEndpointB) if( !lockEndpointB )
guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Right().Right().ToVector() ); 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[0] = SEG( dragged.B, dragged.B + drag_dir.Right().ToVector() );
guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() ); guideB[1] = SEG( dragged.B, dragged.B + drag_dir.Left().ToVector() );
} }
} else { }
if(dir_next.IsObtuse(drag_dir)) else
{
if( dir_next.IsObtuse( drag_dir ) )
{ {
guideB[0] = SEG( s_next.B, s_next.B + drag_dir.Left().ToVector() ); 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() ); 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() ); guideB[0] = guideB[1] = SEG( dragged.B, dragged.B + dir_next.ToVector() );
} }
SEG s_current (target, target + drag_dir.ToVector()); SEG s_current( target, target + drag_dir.ToVector() );
int best_len = INT_MAX; int best_len = INT_MAX;
SHAPE_LINE_CHAIN best; SHAPE_LINE_CHAIN best;
for(int i = 0; i < 2; i++) for( int i = 0; i < 2; i++ )
{ {
for(int j = 0; j < 2; j++) for( int j = 0; j < 2; j++ )
{ {
OPT_VECTOR2I ip1 = s_current.IntersectLines(guideA[i]); OPT_VECTOR2I ip1 = s_current.IntersectLines( guideA[i] );
OPT_VECTOR2I ip2 = s_current.IntersectLines(guideB[j]); OPT_VECTOR2I ip2 = s_current.IntersectLines( guideB[j] );
SHAPE_LINE_CHAIN np; SHAPE_LINE_CHAIN np;
if(!ip1 || !ip2) if( !ip1 || !ip2 )
continue; continue;
SEG s1 ( s_prev.A, *ip1 ); SEG s1( s_prev.A, *ip1 );
SEG s2 ( *ip1, *ip2 ); SEG s2( *ip1, *ip2 );
SEG s3 ( *ip2, s_next.B ); SEG s3( *ip2, s_next.B );
OPT_VECTOR2I ip; OPT_VECTOR2I ip;
if(ip = s1.Intersect(s_next)) if( ip = s1.Intersect( s_next ) )
{ {
np.Append ( s1.A ); np.Append ( s1.A );
np.Append ( *ip ); np.Append ( *ip );
np.Append ( s_next.B ); 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 ( s_prev.A );
np.Append ( *ip ); np.Append ( *ip );
np.Append ( s3.B ); np.Append ( s3.B );
} else if(ip = s1.Intersect(s3)) }
else if( ip = s1.Intersect( s3 ) )
{ {
np.Append( s_prev.A ); np.Append( s_prev.A );
np.Append( *ip ); np.Append( *ip );
np.Append( s_next.B ); np.Append( s_next.B );
} else { }
else
{
np.Append( s_prev.A ); np.Append( s_prev.A );
np.Append( *ip1 ); np.Append( *ip1 );
np.Append( *ip2 ); np.Append( *ip2 );
np.Append( s_next.B ); np.Append( s_next.B );
} }
if(np.Length() < best_len) if( np.Length() < best_len )
{ {
best_len = np.Length(); best_len = np.Length();
best = np; best = np;
} }
} }
} }
if(!lockEndpointA && aIndex == 0) if( !lockEndpointA && aIndex == 0 )
best.Remove(0, 0); best.Remove( 0, 0 );
if(!lockEndpointB && aIndex == m_line.SegmentCount() - 1) if( !lockEndpointB && aIndex == m_line.SegmentCount() - 1 )
best.Remove(-1, -1); best.Remove( -1, -1 );
if(m_line.PointCount() == 1) if( m_line.PointCount() == 1 )
m_line = best; m_line = best;
else if (aIndex == 0) else if( aIndex == 0 )
m_line.Replace(0, 1, best); m_line.Replace( 0, 1, best );
else if (aIndex == m_line.SegmentCount() - 1) else if( aIndex == m_line.SegmentCount() - 1 )
m_line.Replace(-2, -1, best); m_line.Replace( -2, -1, best );
else else
m_line.Replace(aIndex, aIndex + 1, best); m_line.Replace( aIndex, aIndex + 1, best );
m_line.Simplify(); m_line.Simplify();
} }
...@@ -643,21 +680,23 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh ...@@ -643,21 +680,23 @@ void PNS_LINE::DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThresh
bool PNS_LINE::CompareGeometry( const PNS_LINE& aOther ) bool PNS_LINE::CompareGeometry( const PNS_LINE& aOther )
{ {
return m_line.CompareGeometry(aOther.m_line); return m_line.CompareGeometry( aOther.m_line );
} }
void PNS_LINE::Reverse() void PNS_LINE::Reverse()
{ {
m_line = m_line.Reverse(); m_line = m_line.Reverse();
if(m_segmentRefs)
std::reverse(m_segmentRefs->begin(), m_segmentRefs->end() ); if( m_segmentRefs )
std::reverse( m_segmentRefs->begin(), m_segmentRefs->end() );
} }
void PNS_LINE::AppendVia(const PNS_VIA& aVia)
void PNS_LINE::AppendVia( const PNS_VIA& aVia )
{ {
if(aVia.Pos() == m_line.CPoint(0)) if( aVia.Pos() == m_line.CPoint( 0 ) )
{ {
Reverse(); Reverse();
} }
...@@ -666,62 +705,73 @@ void PNS_LINE::AppendVia(const PNS_VIA& aVia) ...@@ -666,62 +705,73 @@ void PNS_LINE::AppendVia(const PNS_VIA& aVia)
m_via.SetNet( m_net ); m_via.SetNet( m_net );
} }
void PNS_LINE::SetRank(int aRank)
void PNS_LINE::SetRank( int aRank )
{ {
m_rank = aRank; m_rank = aRank;
if(m_segmentRefs)
if( m_segmentRefs )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs ) BOOST_FOREACH( PNS_SEGMENT* s, *m_segmentRefs )
s->SetRank(aRank); s->SetRank( aRank );
} }
} }
int PNS_LINE::Rank() const int PNS_LINE::Rank() const
{ {
int min_rank = INT_MAX; int min_rank = INT_MAX;
int rank; int rank;
if(m_segmentRefs)
if( m_segmentRefs )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs ) BOOST_FOREACH( PNS_SEGMENT *s, *m_segmentRefs )
min_rank = std::min(min_rank, s->Rank()); min_rank = std::min( min_rank, s->Rank() );
rank = (min_rank == INT_MAX) ? -1 : min_rank; rank = ( min_rank == INT_MAX ) ? -1 : min_rank;
} else { }
else
{
rank = m_rank; rank = m_rank;
} }
return rank; return rank;
} }
void PNS_LINE::ClipVertexRange ( int aStart, int aEnd )
void PNS_LINE::ClipVertexRange( int aStart, int aEnd )
{ {
m_line = m_line.Slice (aStart, aEnd); m_line = m_line.Slice( aStart, aEnd );
if(m_segmentRefs) 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; delete m_segmentRefs;
m_segmentRefs = snew; m_segmentRefs = snew;
} }
} }
bool PNS_LINE::HasLoops() const bool PNS_LINE::HasLoops() const
{ {
for( int i = 0; i < PointCount(); i++ )
for(int i = 0; i < PointCount(); i++) {
for(int j = 0; j < PointCount(); j++) for( int j = 0; j < PointCount(); j++ )
{ {
if( (std::abs(i-j) > 1) && CPoint(i) == CPoint(j)) if( ( std::abs( i - j ) > 1 ) && CPoint( i ) == CPoint( j ) )
return true; return true;
} }
}
return false; return false;
} }
void PNS_LINE::ClearSegmentLinks() void PNS_LINE::ClearSegmentLinks()
{ {
if(m_segmentRefs) if( m_segmentRefs )
delete m_segmentRefs; delete m_segmentRefs;
m_segmentRefs = NULL; m_segmentRefs = NULL;
} }
...@@ -57,19 +57,18 @@ class PNS_VIA; ...@@ -57,19 +57,18 @@ class PNS_VIA;
class PNS_LINE : public PNS_ITEM class PNS_LINE : public PNS_ITEM
{ {
public: public:
typedef std::vector<PNS_SEGMENT*> SegmentRefs; typedef std::vector<PNS_SEGMENT*> SEGMENT_REFS;
/** /**
* Constructor * Constructor
* Makes an empty line. * Makes an empty line.
*/ */
PNS_LINE() : PNS_ITEM (LINE) PNS_LINE() : PNS_ITEM( LINE )
{ {
m_segmentRefs = NULL; m_segmentRefs = NULL;
m_hasVia = false; m_hasVia = false;
} }
PNS_LINE( const PNS_LINE& aOther ) ; PNS_LINE( const PNS_LINE& aOther ) ;
/** /**
...@@ -77,7 +76,6 @@ public: ...@@ -77,7 +76,6 @@ public:
* Copies properties (net, layers, etc.) from a base line and replaces the shape * Copies properties (net, layers, etc.) from a base line and replaces the shape
* by another * by another
**/ **/
PNS_LINE( const PNS_LINE& aBase, const SHAPE_LINE_CHAIN& aLine ) : PNS_LINE( const PNS_LINE& aBase, const SHAPE_LINE_CHAIN& aLine ) :
PNS_ITEM( aBase ), PNS_ITEM( aBase ),
m_line( aLine ), m_line( aLine ),
...@@ -92,12 +90,12 @@ public: ...@@ -92,12 +90,12 @@ public:
~PNS_LINE(); ~PNS_LINE();
/// @copydoc PNS_ITEM::Clone() /// @copydoc PNS_ITEM::Clone()
virtual PNS_LINE* Clone( ) const; virtual PNS_LINE* Clone() const;
const PNS_LINE& operator= (const PNS_LINE& aOther); const PNS_LINE& operator=( const PNS_LINE& aOther );
///> Assigns a shape to the line (a polyline/line chain) ///> Assigns a shape to the line (a polyline/line chain)
void SetShape ( const SHAPE_LINE_CHAIN& aLine ) void SetShape( const SHAPE_LINE_CHAIN& aLine )
{ {
m_line = aLine; m_line = aLine;
} }
...@@ -135,13 +133,13 @@ public: ...@@ -135,13 +133,13 @@ public:
///> Returns the aIdx-th point of the line ///> Returns the aIdx-th point of the line
const VECTOR2I& CPoint( int aIdx ) const const VECTOR2I& CPoint( int aIdx ) const
{ {
return m_line.CPoint(aIdx); return m_line.CPoint( aIdx );
} }
///> Returns the aIdx-th segment of the line ///> Returns the aIdx-th segment of the line
const SEG CSegment (int aIdx ) const const SEG CSegment( int aIdx ) const
{ {
return m_line.CSegment(aIdx); return m_line.CSegment( aIdx );
} }
///> Sets line width ///> Sets line width
...@@ -169,14 +167,14 @@ public: ...@@ -169,14 +167,14 @@ public:
void LinkSegment( PNS_SEGMENT* aSeg ) void LinkSegment( PNS_SEGMENT* aSeg )
{ {
if( !m_segmentRefs ) if( !m_segmentRefs )
m_segmentRefs = new SegmentRefs(); m_segmentRefs = new SEGMENT_REFS();
m_segmentRefs->push_back( aSeg ); m_segmentRefs->push_back( aSeg );
} }
///> Returns the list of segments from the owning node that constitute this ///> Returns the list of segments from the owning node that constitute this
///> line (or NULL if the line is not linked) ///> line (or NULL if the line is not linked)
SegmentRefs* LinkedSegments() SEGMENT_REFS* LinkedSegments()
{ {
return m_segmentRefs; return m_segmentRefs;
} }
...@@ -195,9 +193,11 @@ public: ...@@ -195,9 +193,11 @@ public:
void ClearSegmentLinks(); void ClearSegmentLinks();
///> Returns the number of segments that were assembled together to form this line. ///> Returns the number of segments that were assembled together to form this line.
int LinkCount() const { int LinkCount() const
if(!m_segmentRefs) {
if( !m_segmentRefs )
return -1; return -1;
return m_segmentRefs->size(); return m_segmentRefs->size();
} }
...@@ -208,7 +208,6 @@ public: ...@@ -208,7 +208,6 @@ public:
///> Clips the line to a given range of vertices. ///> Clips the line to a given range of vertices.
void ClipVertexRange ( int aStart, int aEnd ); void ClipVertexRange ( int aStart, int aEnd );
///> Returns the number of corners of angles specified by mask aAngles. ///> Returns the number of corners of angles specified by mask aAngles.
int CountCorners( int aAngles ); int CountCorners( int aAngles );
...@@ -218,12 +217,11 @@ public: ...@@ -218,12 +217,11 @@ public:
///> aWalkaroundPath = path around the obstacle ///> aWalkaroundPath = path around the obstacle
///> aPostPath = past from obstacle till the end ///> aPostPath = past from obstacle till the end
///> aCW = whether to walk around in clockwise or counter-clockwise direction. ///> aCW = whether to walk around in clockwise or counter-clockwise direction.
bool Walkaround( SHAPE_LINE_CHAIN aObstacle,
bool Walkaround( SHAPE_LINE_CHAIN obstacle, SHAPE_LINE_CHAIN& aPre,
SHAPE_LINE_CHAIN& pre, SHAPE_LINE_CHAIN& aWalk,
SHAPE_LINE_CHAIN& walk, SHAPE_LINE_CHAIN& aPost,
SHAPE_LINE_CHAIN& post, bool aCw ) const;
bool cw ) const;
void Walkaround( const SHAPE_LINE_CHAIN& aObstacle, void Walkaround( const SHAPE_LINE_CHAIN& aObstacle,
SHAPE_LINE_CHAIN& aPath, SHAPE_LINE_CHAIN& aPath,
...@@ -241,29 +239,31 @@ public: ...@@ -241,29 +239,31 @@ public:
const PNS_VIA& Via() const { return m_via; } const PNS_VIA& Via() const { return m_via; }
virtual void Mark(int aMarker); virtual void Mark( int aMarker );
virtual void Unmark (); virtual void Unmark ();
virtual int Marker() const; virtual int Marker() const;
void DragSegment ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 ); void DragSegment( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
void DragCorner ( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 ); void DragCorner( const VECTOR2I& aP, int aIndex, int aSnappingThreshold = 0 );
void SetRank ( int aRank ); void SetRank( int aRank );
int Rank() const; int Rank() const;
bool HasLoops() const; bool HasLoops() const;
private: 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,
VECTOR2I snapDraggedCorner( const SHAPE_LINE_CHAIN& aPath, const VECTOR2I &aP, int aIndex, int aThreshold ) const; int aIndex, int aThreshold ) const;
///> Copies m_segmentRefs from the line aParent. ///> Copies m_segmentRefs from the line aParent.
void copyLinks( const PNS_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 ///> 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. ///> if the line is not a part of any node.
SegmentRefs* m_segmentRefs; SEGMENT_REFS* m_segmentRefs;
///> The actual shape of the line ///> The actual shape of the line
SHAPE_LINE_CHAIN m_line; SHAPE_LINE_CHAIN m_line;
......
...@@ -44,7 +44,8 @@ PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) : ...@@ -44,7 +44,8 @@ PNS_LINE_PLACER::PNS_LINE_PLACER( PNS_ROUTER* aRouter ) :
m_world = NULL; m_world = NULL;
m_shove = NULL; m_shove = NULL;
m_currentNode = NULL; m_currentNode = NULL;
}; }
PNS_LINE_PLACER::~PNS_LINE_PLACER() PNS_LINE_PLACER::~PNS_LINE_PLACER()
{ {
...@@ -52,11 +53,13 @@ PNS_LINE_PLACER::~PNS_LINE_PLACER() ...@@ -52,11 +53,13 @@ PNS_LINE_PLACER::~PNS_LINE_PLACER()
delete m_shove; delete m_shove;
} }
void PNS_LINE_PLACER::setWorld ( PNS_NODE *aWorld )
void PNS_LINE_PLACER::setWorld ( PNS_NODE* aWorld )
{ {
m_world = aWorld; m_world = aWorld;
} }
void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill ) void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill )
{ {
m_viaDiameter = aDiameter; m_viaDiameter = aDiameter;
...@@ -64,11 +67,10 @@ void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill ) ...@@ -64,11 +67,10 @@ void PNS_LINE_PLACER::AddVia( bool aEnabled, int aDiameter, int aDrill )
m_placingVia = aEnabled; m_placingVia = aEnabled;
} }
void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet,
int aWidth, int aLayer )
{
assert(m_world != NULL); void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet, int aWidth, int aLayer )
{
assert( m_world != NULL );
m_direction = m_initial_direction; m_direction = m_initial_direction;
TRACE( 1, "world %p, intitial-direction %s layer %d\n", TRACE( 1, "world %p, intitial-direction %s layer %d\n",
...@@ -89,14 +91,14 @@ void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet, ...@@ -89,14 +91,14 @@ void PNS_LINE_PLACER::startPlacement( const VECTOR2I& aStart, int aNet,
m_currentMode = Settings().Mode(); m_currentMode = Settings().Mode();
if(m_shove) if( m_shove )
delete m_shove; delete m_shove;
m_shove = NULL; m_shove = NULL;
if(m_currentMode == RM_Shove || m_currentMode == RM_Smart) if( m_currentMode == RM_Shove || m_currentMode == RM_Smart )
{ {
m_shove = new PNS_SHOVE( m_world -> Branch(), Router() ); m_shove = new PNS_SHOVE( m_world->Branch(), Router() );
} }
m_placingVia = false; m_placingVia = false;
...@@ -107,7 +109,7 @@ void PNS_LINE_PLACER::setInitialDirection( const DIRECTION_45& aDirection ) ...@@ -107,7 +109,7 @@ void PNS_LINE_PLACER::setInitialDirection( const DIRECTION_45& aDirection )
{ {
m_initial_direction = aDirection; m_initial_direction = aDirection;
if( m_tail.SegmentCount() == 0 ) if( m_tail.SegmentCount() == 0 )
m_direction = aDirection; m_direction = aDirection;
} }
...@@ -154,6 +156,7 @@ bool PNS_LINE_PLACER::handleSelfIntersections() ...@@ -154,6 +156,7 @@ bool PNS_LINE_PLACER::handleSelfIntersections()
m_direction = m_initial_direction; m_direction = m_initial_direction;
tail.Clear(); tail.Clear();
head.Clear(); head.Clear();
return true; return true;
} }
else else
...@@ -176,7 +179,7 @@ bool PNS_LINE_PLACER::handlePullback() ...@@ -176,7 +179,7 @@ bool PNS_LINE_PLACER::handlePullback()
SHAPE_LINE_CHAIN& head = m_head.Line(); SHAPE_LINE_CHAIN& head = m_head.Line();
SHAPE_LINE_CHAIN& tail = m_tail.Line(); SHAPE_LINE_CHAIN& tail = m_tail.Line();
if(head.PointCount() < 2) if( head.PointCount() < 2 )
return false; return false;
int n = tail.PointCount(); int n = tail.PointCount();
...@@ -201,7 +204,7 @@ bool PNS_LINE_PLACER::handlePullback() ...@@ -201,7 +204,7 @@ bool PNS_LINE_PLACER::handlePullback()
// case 2: regardless of the current routing direction, if the tail/head // case 2: regardless of the current routing direction, if the tail/head
// extremities form an acute or right angle, reduce the tail by one segment // extremities form an acute or right angle, reduce the tail by one segment
// (and hope that further iterations) will result with a cleaner trace // (and hope that further iterations) will result with a cleaner trace
bool pullback_2 = (angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE); bool pullback_2 = ( angle == DIRECTION_45::ANG_RIGHT || angle == DIRECTION_45::ANG_ACUTE );
if( pullback_1 || pullback_2 ) if( pullback_1 || pullback_2 )
{ {
...@@ -237,7 +240,7 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd ) ...@@ -237,7 +240,7 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd )
int n = tail.SegmentCount(); int n = tail.SegmentCount();
if(head.SegmentCount() < 1) if( head.SegmentCount() < 1 )
return false; return false;
// Don't attempt this for too short tails // Don't attempt this for too short tails
...@@ -294,10 +297,10 @@ bool PNS_LINE_PLACER::reduceTail( const VECTOR2I& aEnd ) ...@@ -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_a( aA );
const DIRECTION_45 dir_b( b ); const DIRECTION_45 dir_b( aB );
return dir_a.IsObtuse( dir_b ) || dir_a == dir_b; return dir_a.IsObtuse( dir_b ) || dir_a == dir_b;
} }
...@@ -399,6 +402,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead ) ...@@ -399,6 +402,7 @@ bool PNS_LINE_PLACER::handleViaPlacement( PNS_LINE& aHead )
return false; return false;
} }
bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP ); SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP );
...@@ -412,27 +416,30 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -412,27 +416,30 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
walkaround.SetSolidsOnly( false ); walkaround.SetSolidsOnly( false );
walkaround.SetIterationLimit( Settings().WalkaroundIterationLimit() ); 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()) switch( Settings().OptimizerEffort() )
{ {
case OE_Low: case OE_LOW:
effort = 0; effort = 0;
break; break;
case OE_Medium:
case OE_Full: case OE_MEDIUM:
case OE_FULL:
effort = PNS_OPTIMIZER::MERGE_SEGMENTS; effort = PNS_OPTIMIZER::MERGE_SEGMENTS;
break; break;
} }
if(Settings().SmartPads())
if( Settings().SmartPads() )
effort |= PNS_OPTIMIZER::SMART_PADS; effort |= PNS_OPTIMIZER::SMART_PADS;
if( wf == PNS_WALKAROUND::STUCK ) if( wf == PNS_WALKAROUND::STUCK )
{ {
walkFull = walkFull.ClipToNearestObstacle( m_currentNode ); walkFull = walkFull.ClipToNearestObstacle( m_currentNode );
rv = true; rv = true;
}
} else if( m_placingVia && viaOk ) { else if( m_placingVia && viaOk )
{
PNS_LAYERSET allLayers( 0, 15 ); PNS_LAYERSET allLayers( 0, 15 );
PNS_VIA v1( walkFull.CPoint( -1 ), allLayers, m_viaDiameter ); PNS_VIA v1( walkFull.CPoint( -1 ), allLayers, m_viaDiameter );
walkFull.AppendVia( v1 ); walkFull.AppendVia( v1 );
...@@ -440,7 +447,7 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -440,7 +447,7 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
PNS_OPTIMIZER::Optimize( &walkFull, effort, m_currentNode ); PNS_OPTIMIZER::Optimize( &walkFull, effort, m_currentNode );
if( m_currentNode->CheckColliding(&walkFull) ) if( m_currentNode->CheckColliding( &walkFull ) )
{ {
TRACEn(0, "strange, walk line colliding\n"); TRACEn(0, "strange, walk line colliding\n");
} }
...@@ -451,9 +458,10 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -451,9 +458,10 @@ bool PNS_LINE_PLACER::rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return rv; return rv;
} }
bool PNS_LINE_PLACER::rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool PNS_LINE_PLACER::rhMarkObstacles( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
m_head.SetShape ( m_direction.BuildInitialTrace( m_p_start, aP ) ); m_head.SetShape( m_direction.BuildInitialTrace( m_p_start, aP ) );
if( m_placingVia ) if( m_placingVia )
{ {
...@@ -467,6 +475,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -467,6 +475,7 @@ bool PNS_LINE_PLACER::rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return m_currentNode->CheckColliding( &m_head ); return m_currentNode->CheckColliding( &m_head );
} }
bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
SHAPE_LINE_CHAIN line = m_direction.BuildInitialTrace( m_p_start, aP ); 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 ) ...@@ -482,7 +491,7 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
walkaround.SetSolidsOnly( true ); walkaround.SetSolidsOnly( true );
walkaround.SetIterationLimit( 10 ); 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.SetEffortLevel( PNS_OPTIMIZER::MERGE_SEGMENTS );
optimizer.SetCollisionMask ( PNS_ITEM::SOLID ); optimizer.SetCollisionMask ( PNS_ITEM::SOLID );
...@@ -513,13 +522,13 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -513,13 +522,13 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
// in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid // in certain, uncommon cases there may be loops in the head+tail, In such case, we don't shove to avoid
// screwing up the database. // screwing up the database.
if ( l.HasLoops() ) if( l.HasLoops() )
{ {
aNewHead = m_head; aNewHead = m_head;
return false; return false;
} }
PNS_SHOVE::ShoveStatus status = m_shove->ShoveLines( l ); PNS_SHOVE::SHOVE_STATUS status = m_shove->ShoveLines( l );
m_currentNode = m_shove->CurrentNode(); m_currentNode = m_shove->CurrentNode();
...@@ -546,10 +555,10 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -546,10 +555,10 @@ bool PNS_LINE_PLACER::rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead )
return false; return false;
} }
return false; return false;
} }
bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead ) bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
{ {
switch( m_currentMode ) switch( m_currentMode )
...@@ -570,18 +579,18 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead ) ...@@ -570,18 +579,18 @@ bool PNS_LINE_PLACER::routeHead( const VECTOR2I& aP, PNS_LINE& aNewHead )
bool PNS_LINE_PLACER::optimizeTailHeadTransition() bool PNS_LINE_PLACER::optimizeTailHeadTransition()
{ {
PNS_LINE tmp = Trace(); PNS_LINE tmp = Trace();
if(PNS_OPTIMIZER::Optimize(&tmp, PNS_OPTIMIZER::FANOUT_CLEANUP, m_currentNode)) if( PNS_OPTIMIZER::Optimize( &tmp, PNS_OPTIMIZER::FANOUT_CLEANUP, m_currentNode ) )
{ {
if(tmp.SegmentCount() < 1) if( tmp.SegmentCount() < 1 )
return false; return false;
m_head = tmp; m_head = tmp;
m_p_start = tmp.CLine().CPoint( 0 ); m_p_start = tmp.CLine().CPoint( 0 );
m_direction = DIRECTION_45( tmp.CSegment( 0 ) ); m_direction = DIRECTION_45( tmp.CSegment( 0 ) );
m_tail.Line().Clear(); m_tail.Line().Clear();
return true; return true;
} }
...@@ -611,7 +620,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition() ...@@ -611,7 +620,7 @@ bool PNS_LINE_PLACER::optimizeTailHeadTransition()
// If so, replace the (threshold) last tail points and the head with // If so, replace the (threshold) last tail points and the head with
// the optimized line // the optimized line
if(PNS_OPTIMIZER::Optimize(&new_head, PNS_OPTIMIZER::MERGE_OBTUSE, m_currentNode)) if( PNS_OPTIMIZER::Optimize( &new_head, PNS_OPTIMIZER::MERGE_OBTUSE, m_currentNode ) )
{ {
PNS_LINE tmp( m_tail, opt_line ); PNS_LINE tmp( m_tail, opt_line );
...@@ -702,22 +711,26 @@ const PNS_LINE PNS_LINE_PLACER::Trace() const ...@@ -702,22 +711,26 @@ const PNS_LINE PNS_LINE_PLACER::Trace() const
return tmp; return tmp;
} }
const PNS_ITEMSET PNS_LINE_PLACER::Traces() const PNS_ITEMSET PNS_LINE_PLACER::Traces()
{ {
m_currentTrace = Trace(); m_currentTrace = Trace();
return PNS_ITEMSET( &m_currentTrace ); return PNS_ITEMSET( &m_currentTrace );
} }
void PNS_LINE_PLACER::FlipPosture() void PNS_LINE_PLACER::FlipPosture()
{ {
m_initial_direction = m_initial_direction.Right(); m_initial_direction = m_initial_direction.Right();
m_direction = m_direction.Right(); m_direction = m_direction.Right();
} }
PNS_NODE* PNS_LINE_PLACER::CurrentNode(bool aLoopsRemoved) const
PNS_NODE* PNS_LINE_PLACER::CurrentNode( bool aLoopsRemoved ) const
{ {
if(aLoopsRemoved && m_lastNode) if( aLoopsRemoved && m_lastNode )
return m_lastNode; return m_lastNode;
return m_currentNode; return m_currentNode;
} }
...@@ -747,16 +760,19 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co ...@@ -747,16 +760,19 @@ void PNS_LINE_PLACER::splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, co
} }
} }
void PNS_LINE_PLACER::SetLayer(int aLayer) void PNS_LINE_PLACER::SetLayer(int aLayer)
{ {
m_currentLayer = aLayer; m_currentLayer = aLayer;
} }
void PNS_LINE_PLACER::SetWidth(int aWidth) void PNS_LINE_PLACER::SetWidth(int aWidth)
{ {
m_currentWidth = aWidth; m_currentWidth = aWidth;
} }
void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
VECTOR2I p( aP ); VECTOR2I p( aP );
...@@ -783,7 +799,6 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem ) ...@@ -783,7 +799,6 @@ void PNS_LINE_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
m_currentEnd = p; m_currentEnd = p;
m_currentNet = net; m_currentNet = net;
PNS_NODE *rootNode = Router()->GetWorld()->Branch(); PNS_NODE *rootNode = Router()->GetWorld()->Branch();
if( splitSeg ) if( splitSeg )
...@@ -801,7 +816,7 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) ...@@ -801,7 +816,7 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
VECTOR2I p = aP; VECTOR2I p = aP;
int eiDepth = -1; int eiDepth = -1;
if(aEndItem && aEndItem->Owner()) if( aEndItem && aEndItem->Owner() )
eiDepth = aEndItem->Owner()->Depth(); eiDepth = aEndItem->Owner()->Depth();
if( m_lastNode ) if( m_lastNode )
...@@ -814,26 +829,27 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem ) ...@@ -814,26 +829,27 @@ void PNS_LINE_PLACER::Move( const VECTOR2I& aP, PNS_ITEM* aEndItem )
current = Trace(); current = Trace();
if(!current.PointCount()) if( !current.PointCount() )
m_currentEnd = m_p_start; m_currentEnd = m_p_start;
else else
m_currentEnd = current.CLine().CPoint(-1); m_currentEnd = current.CLine().CPoint(-1);
PNS_NODE *latestNode = m_currentNode; PNS_NODE *latestNode = m_currentNode;
m_lastNode = latestNode->Branch(); m_lastNode = latestNode->Branch();
if( eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth &&
if(eiDepth >= 0 && aEndItem && latestNode->Depth() > eiDepth && current.SegmentCount() && current.CPoint(-1) == aP) current.SegmentCount() && current.CPoint( -1 ) == aP )
{ {
splitAdjacentSegments( m_lastNode, aEndItem, current.CPoint(-1) ); splitAdjacentSegments( m_lastNode, aEndItem, current.CPoint( -1 ) );
if(Settings().RemoveLoops())
if( Settings().RemoveLoops() )
removeLoops( m_lastNode, &current ); removeLoops( m_lastNode, &current );
} }
updateLeadingRatLine(); updateLeadingRatLine();
} }
bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
bool realEnd = false; bool realEnd = false;
...@@ -861,13 +877,11 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) ...@@ -861,13 +877,11 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() ) if( aEndItem && m_currentNet >= 0 && m_currentNet == aEndItem->Net() )
realEnd = true; realEnd = true;
if( realEnd || m_placingVia )
if(realEnd || m_placingVia)
lastV = l.SegmentCount(); lastV = l.SegmentCount();
else else
lastV = std::max( 1, l.SegmentCount() - 1 ); lastV = std::max( 1, l.SegmentCount() - 1 );
PNS_SEGMENT* lastSeg = NULL; PNS_SEGMENT* lastSeg = NULL;
for( int i = 0; i < lastV; i++ ) for( int i = 0; i < lastV; i++ )
...@@ -883,14 +897,14 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) ...@@ -883,14 +897,14 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
if( pl.EndsWithVia() ) if( pl.EndsWithVia() )
m_lastNode->Add( pl.Via().Clone() ); m_lastNode->Add( pl.Via().Clone() );
if(realEnd) if( realEnd )
simplifyNewLine ( m_lastNode, lastSeg ); simplifyNewLine ( m_lastNode, lastSeg );
Router()->CommitRouting ( m_lastNode ); Router()->CommitRouting ( m_lastNode );
m_lastNode = NULL; m_lastNode = NULL;
if(!realEnd) if( !realEnd )
{ {
setInitialDirection( d_last ); setInitialDirection( d_last );
VECTOR2I p_start = m_placingVia ? p_last : p_pre_last; VECTOR2I p_start = m_placingVia ? p_last : p_pre_last;
...@@ -908,20 +922,19 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) ...@@ -908,20 +922,19 @@ bool PNS_LINE_PLACER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
return realEnd; return realEnd;
} }
void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest ) void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
{ {
if(!aLatest->SegmentCount()) if( !aLatest->SegmentCount() )
return; return;
aNode->Add( aLatest, true ); aNode->Add( aLatest, true );
for(int s = 0; s < aLatest->SegmentCount(); s++ ) for( int s = 0; s < aLatest->SegmentCount(); s++ )
{ {
PNS_SEGMENT *seg = (*aLatest->LinkedSegments())[s]; PNS_SEGMENT *seg = ( *aLatest->LinkedSegments() )[s];
PNS_LINE* ourLine = aNode->AssembleLine( seg );
PNS_LINE* ourLine = aNode->AssembleLine( seg ) ;
PNS_JOINT a, b; PNS_JOINT a, b;
std::vector<PNS_LINE*> lines; std::vector<PNS_LINE*> lines;
aNode->FindLineEnds( ourLine, a, b ); aNode->FindLineEnds( ourLine, a, b );
...@@ -944,15 +957,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest ) ...@@ -944,15 +957,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
{ {
Router()->DisplayDebugLine ( line->CLine(), -1, 10000 ); Router()->DisplayDebugLine ( line->CLine(), -1, 10000 );
for(int i = 0; i < line->PointCount(); i++ ) for( int i = 0; i < line->PointCount(); i++ )
Router()->DisplayDebugPoint ( line->CPoint(i), -1 ); Router()->DisplayDebugPoint( line->CPoint( i ), -1 );
aNode->Remove( line ); aNode->Remove( line );
removedCount ++; removedCount ++;
} }
} }
TRACE(0, "total segs removed: %d/%d\n", removedCount % total); TRACE( 0, "total segs removed: %d/%d\n", removedCount % total );
delete ourLine; delete ourLine;
} }
...@@ -960,13 +973,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest ) ...@@ -960,13 +973,15 @@ void PNS_LINE_PLACER::removeLoops( PNS_NODE* aNode, PNS_LINE* aLatest )
aNode->Remove( aLatest ); aNode->Remove( aLatest );
} }
void PNS_LINE_PLACER::simplifyNewLine ( PNS_NODE *aNode, PNS_SEGMENT *aLatest )
void PNS_LINE_PLACER::simplifyNewLine( PNS_NODE* aNode, PNS_SEGMENT* aLatest )
{ {
PNS_LINE *l = aNode->AssembleLine( aLatest) ; PNS_LINE* l = aNode->AssembleLine( aLatest );
SHAPE_LINE_CHAIN simplified ( l->CLine() ); SHAPE_LINE_CHAIN simplified ( l->CLine() );
simplified.Simplify(); simplified.Simplify();
if(simplified.PointCount() != l->PointCount()) if( simplified.PointCount() != l->PointCount() )
{ {
std::auto_ptr<PNS_LINE> lnew ( l->Clone() ); std::auto_ptr<PNS_LINE> lnew ( l->Clone() );
aNode -> Remove(l); aNode -> Remove(l);
...@@ -975,6 +990,7 @@ void PNS_LINE_PLACER::simplifyNewLine ( PNS_NODE *aNode, PNS_SEGMENT *aLatest ) ...@@ -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 ) void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings )
{ {
int trackWidth = aSettings.GetTrackWidth(); int trackWidth = aSettings.GetTrackWidth();
...@@ -986,29 +1002,31 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings ) ...@@ -986,29 +1002,31 @@ void PNS_LINE_PLACER::UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings )
m_viaDrill = aSettings.GetViaDrill(); m_viaDrill = aSettings.GetViaDrill();
} }
void PNS_LINE_PLACER::updateLeadingRatLine() void PNS_LINE_PLACER::updateLeadingRatLine()
{ {
PNS_LINE current = Trace(); PNS_LINE current = Trace();
if(! current.PointCount() ) if( !current.PointCount() )
return; return;
std::auto_ptr<PNS_NODE> tmpNode ( m_lastNode->Branch() ); std::auto_ptr<PNS_NODE> tmpNode ( m_lastNode->Branch() );
tmpNode->Add( &current ); tmpNode->Add( &current );
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) if( !jt )
return; return;
int anchor; int anchor;
PNS_ITEM *it = tmpNode->NearestUnconnectedItem ( jt, &anchor ); PNS_ITEM *it = tmpNode->NearestUnconnectedItem( jt, &anchor );
if(it) if( it )
{ {
SHAPE_LINE_CHAIN lc; SHAPE_LINE_CHAIN lc;
lc.Append ( current.CPoint(-1) ); lc.Append ( current.CPoint( -1 ) );
lc.Append ( it->Anchor(anchor) ); lc.Append ( it->Anchor( anchor ) );
Router()->DisplayDebugLine( lc, 5, 10000 ); Router()->DisplayDebugLine( lc, 5, 10000 );
} }
} }
...@@ -46,7 +46,7 @@ class PNS_ROUTER_BASE; ...@@ -46,7 +46,7 @@ class PNS_ROUTER_BASE;
class PNS_LINE_PLACER : public PNS_ALGO_BASE class PNS_LINE_PLACER : public PNS_ALGO_BASE
{ {
public: public:
PNS_LINE_PLACER( PNS_ROUTER *aRouter ); PNS_LINE_PLACER( PNS_ROUTER* aRouter );
~PNS_LINE_PLACER(); ~PNS_LINE_PLACER();
/** /**
...@@ -92,14 +92,14 @@ public: ...@@ -92,14 +92,14 @@ public:
* *
* Sets the current routing layer. * Sets the current routing layer.
*/ */
void SetLayer ( int aLayer ); void SetLayer( int aLayer );
/** /**
* Function SetWidth() * Function SetWidth()
* *
* Sets the current track width. * Sets the current track width.
*/ */
void SetWidth ( int aWidth ); void SetWidth( int aWidth );
/** /**
* Function Head() * Function Head()
...@@ -167,7 +167,7 @@ public: ...@@ -167,7 +167,7 @@ public:
* *
* Returns the most recent world state. * Returns the most recent world state.
*/ */
PNS_NODE* CurrentNode(bool aLoopsRemoved = false) const; PNS_NODE* CurrentNode( bool aLoopsRemoved = false ) const;
/** /**
* Function FlipPosture() * Function FlipPosture()
...@@ -185,7 +185,6 @@ public: ...@@ -185,7 +185,6 @@ public:
*/ */
void UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings ); void UpdateSizes( const PNS_ROUTING_SETTINGS& aSettings );
private: private:
/** /**
* Function route() * Function route()
...@@ -197,7 +196,6 @@ private: ...@@ -197,7 +196,6 @@ private:
* @param aP ending point of current route. * @param aP ending point of current route.
* @return true, if the routing is complete. * @return true, if the routing is complete.
*/ */
bool route( const VECTOR2I& aP ); bool route( const VECTOR2I& aP );
/** /**
...@@ -214,7 +212,7 @@ private: ...@@ -214,7 +212,7 @@ private:
* *
* Sets the board to route. * Sets the board to route.
*/ */
void setWorld ( PNS_NODE *aWorld ); void setWorld ( PNS_NODE* aWorld );
/** /**
* Function startPlacement() * Function startPlacement()
...@@ -268,9 +266,9 @@ private: ...@@ -268,9 +266,9 @@ private:
* *
* Helper function, checking if segments a and b form an obtuse angle * Helper function, checking if segments a and b form an obtuse angle
* (in 45-degree regime). * (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() * Function handleSelfIntersections()
...@@ -339,16 +337,15 @@ private: ...@@ -339,16 +337,15 @@ private:
*/ */
void routeStep( const VECTOR2I& aP ); void routeStep( const VECTOR2I& aP );
///< route step, walkaround mode ///> route step, walkaround mode
bool rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead); bool rhWalkOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead);
///< route step, shove mode ///> route step, shove mode
bool rhShoveOnly ( const VECTOR2I& aP, PNS_LINE& aNewHead); 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 ); bool rhMarkObstacles ( const VECTOR2I& aP, PNS_LINE& aNewHead );
///> current routing direction ///> current routing direction
DIRECTION_45 m_direction; DIRECTION_45 m_direction;
...@@ -399,7 +396,6 @@ private: ...@@ -399,7 +396,6 @@ private:
PNS_LINE m_currentTrace; PNS_LINE m_currentTrace;
PNS_MODE m_currentMode; PNS_MODE m_currentMode;
}; };
#endif // __PNS_LINE_PLACER_H #endif // __PNS_LINE_PLACER_H
...@@ -38,69 +38,76 @@ PNS_LOGGER::PNS_LOGGER( ) ...@@ -38,69 +38,76 @@ PNS_LOGGER::PNS_LOGGER( )
PNS_LOGGER::~PNS_LOGGER() PNS_LOGGER::~PNS_LOGGER()
{ {
} }
void PNS_LOGGER::Clear() void PNS_LOGGER::Clear()
{ {
m_theLog.str(std::string()); m_theLog.str( std::string() );
m_groupOpened = false; 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) if( m_groupOpened )
m_theLog << "endgroup" << std::endl; m_theLog << "endgroup" << std::endl;
m_theLog << "group " << name << " " << iter << std::endl;
m_theLog << "group " << aName << " " << aIter << std::endl;
m_groupOpened = true; m_groupOpened = true;
} }
void PNS_LOGGER::EndGroup() void PNS_LOGGER::EndGroup()
{ {
if(!m_groupOpened) if( !m_groupOpened )
return; return;
m_groupOpened = false; m_groupOpened = false;
m_theLog << "endgroup" << std::endl; m_theLog << "endgroup" << std::endl;
} }
void PNS_LOGGER::Log ( const PNS_ITEM *item, int kind, const std::string name )
void PNS_LOGGER::Log ( const PNS_ITEM* aItem, int aKind, const std::string aName )
{ {
m_theLog << "item " << kind << " " << name << " "; m_theLog << "aItem " << aKind << " " << aName << " ";
m_theLog << item->Net() << " " << item->Layers().Start() << " " << item->Layers().End() << " " << item->Marker() << " " << item->Rank(); m_theLog << aItem->Net() << " " << aItem->Layers().Start() << " " <<
aItem->Layers().End() << " " << aItem->Marker() << " " << aItem->Rank();
switch(item->Kind()) switch( aItem->Kind() )
{ {
case PNS_ITEM::LINE: case PNS_ITEM::LINE:
{ {
PNS_LINE *l = (PNS_LINE *) item; PNS_LINE* l = (PNS_LINE*) aItem;
m_theLog << " line "; m_theLog << " line ";
m_theLog << l->Width() << " " << (l->EndsWithVia() ? 1 : 0) << " "; m_theLog << l->Width() << " " << ( l->EndsWithVia() ? 1 : 0 ) << " ";
dumpShape ( l->Shape() ); dumpShape ( l->Shape() );
m_theLog << std::endl; m_theLog << std::endl;
break; break;
} }
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
{ {
m_theLog << " via 0 0 "; m_theLog << " via 0 0 ";
dumpShape ( item->Shape() ); dumpShape ( aItem->Shape() );
m_theLog << std::endl; m_theLog << std::endl;
break; break;
} }
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
{ {
PNS_SEGMENT *s =(PNS_SEGMENT *) item; PNS_SEGMENT* s =(PNS_SEGMENT*) aItem;
m_theLog << " line "; 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; break;
} }
case PNS_ITEM::SOLID: case PNS_ITEM::SOLID:
{ {
PNS_SOLID *s = (PNS_SOLID*) item; PNS_SOLID* s = (PNS_SOLID*) aItem;
m_theLog << " solid 0 0 "; m_theLog << " solid 0 0 ";
dumpShape ( s->Shape() ); dumpShape( s->Shape() );
m_theLog << std::endl; m_theLog << std::endl;
break; break;
} }
...@@ -110,64 +117,74 @@ void PNS_LOGGER::Log ( const PNS_ITEM *item, int kind, const std::string name ) ...@@ -110,64 +117,74 @@ 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 << 0 << " " << 0 << " " << 0 << " " << 0 << " " << 0;
m_theLog << " line "; m_theLog << " line ";
m_theLog << 0 << " " << 0 << " "; m_theLog << 0 << " " << 0 << " ";
dumpShape ( l ); dumpShape( aL );
m_theLog << std::endl; 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: 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) << " "; 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 << " "; for( int i = 0; i < lc->PointCount(); i++ )
m_theLog << lc->CPoint( i ).x << " " << lc->CPoint( i ).y << " ";
break; break;
} }
case SH_CIRCLE: 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(); m_theLog << "circle " << c->GetCenter().x << " " << c->GetCenter().y << " " << c->GetRadius();
break; break;
} }
case SH_RECT: case SH_RECT:
{ {
const SHAPE_RECT *r = (const SHAPE_RECT *) sh; const SHAPE_RECT* r = (const SHAPE_RECT*) aSh;
m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " << r->GetSize().x << " " <<r->GetSize().y; m_theLog << "rect " << r->GetPosition().x << " " << r->GetPosition().y << " " <<
r->GetSize().x << " " <<r->GetSize().y;
break; break;
} }
case SH_SEGMENT: case SH_SEGMENT:
{ {
const SHAPE_SEGMENT *s = (const SHAPE_SEGMENT *) sh; 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; m_theLog << "linechain 2 0 " << s->GetSeg().A.x << " " << s->GetSeg().A.y << " " <<
s->GetSeg().B.x << " " << s->GetSeg().B.y;
break; break;
} }
default: default:
break; break;
} }
} }
void PNS_LOGGER::Save ( const std::string& filename ) void PNS_LOGGER::Save( const std::string& aFilename )
{ {
EndGroup(); EndGroup();
FILE *f=fopen(filename.c_str(),"wb"); FILE* f = fopen( aFilename.c_str(), "wb" );
printf("Saving to '%s' [%p]\n", filename.c_str(), f); printf( "Saving to '%s' [%p]\n", aFilename.c_str(), f );
const std::string s = m_theLog.str(); const std::string s = m_theLog.str();
fwrite(s.c_str(), 1, s.length(), f); fwrite( s.c_str(), 1, s.length(), f );
fclose(f); fclose( f );
} }
...@@ -32,24 +32,25 @@ class PNS_ITEM; ...@@ -32,24 +32,25 @@ class PNS_ITEM;
class SHAPE_LINE_CHAIN; class SHAPE_LINE_CHAIN;
class SHAPE; class SHAPE;
class PNS_LOGGER { class PNS_LOGGER
{
public: public:
PNS_LOGGER(); PNS_LOGGER();
~PNS_LOGGER(); ~PNS_LOGGER();
void Save ( const std::string& filename ); void Save( const std::string& aFilename );
void Clear(); void Clear();
void NewGroup ( const std::string& name, int iter = 0);
void NewGroup( const std::string& aName, int aIter = 0 );
void EndGroup(); 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 () );
private: 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() );
void dumpShape ( const SHAPE* sh ); private:
void dumpShape ( const SHAPE* aSh );
bool m_groupOpened; bool m_groupOpened;
std::stringstream m_theLog; std::stringstream m_theLog;
......
...@@ -53,11 +53,13 @@ PNS_NODE::PNS_NODE() ...@@ -53,11 +53,13 @@ PNS_NODE::PNS_NODE()
m_parent = NULL; m_parent = NULL;
m_maxClearance = 800000; // fixme: depends on how thick traces are. m_maxClearance = 800000; // fixme: depends on how thick traces are.
m_index = new PNS_INDEX; m_index = new PNS_INDEX;
#ifdef DEBUG #ifdef DEBUG
allocNodes.insert( this ); allocNodes.insert( this );
#endif #endif
} }
PNS_NODE::~PNS_NODE() PNS_NODE::~PNS_NODE()
{ {
TRACE( 0, "PNS_NODE::delete %p", this ); TRACE( 0, "PNS_NODE::delete %p", this );
...@@ -69,7 +71,6 @@ PNS_NODE::~PNS_NODE() ...@@ -69,7 +71,6 @@ PNS_NODE::~PNS_NODE()
} }
#ifdef DEBUG #ifdef DEBUG
if( allocNodes.find( this ) == allocNodes.end() ) if( allocNodes.find( this ) == allocNodes.end() )
{ {
TRACEn( 0, "attempting to free an already-free'd node.\n" ); TRACEn( 0, "attempting to free an already-free'd node.\n" );
...@@ -77,31 +78,31 @@ PNS_NODE::~PNS_NODE() ...@@ -77,31 +78,31 @@ PNS_NODE::~PNS_NODE()
} }
allocNodes.erase( this ); allocNodes.erase( this );
#endif #endif
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
i != m_index->end(); ++i ) {
if( (*i)->BelongsTo( this ) ) if( (*i)->BelongsTo( this ) )
delete *i; delete *i;
}
unlinkParent(); unlinkParent();
delete m_index; 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* PNS_NODE::Branch()
{ {
PNS_NODE* child = new PNS_NODE; PNS_NODE* child = new PNS_NODE;
TRACE( 0, "PNS_NODE::branch %p (parent %p)", child % this ); TRACE( 0, "PNS_NODE::branch %p (parent %p)", child % this );
m_children.push_back( child ); m_children.push_back( child );
child->m_depth = m_depth + 1; child->m_depth = m_depth + 1;
...@@ -114,10 +115,9 @@ PNS_NODE* PNS_NODE::Branch() ...@@ -114,10 +115,9 @@ PNS_NODE* PNS_NODE::Branch()
// to stored items. // to stored items.
if( !isRoot() ) if( !isRoot() )
{ {
JointMap::iterator j; JOINT_MAP::iterator j;
for( PNS_INDEX::ItemSet::iterator i = m_index->begin(); for( PNS_INDEX::ITEM_SET::iterator i = m_index->begin(); i != m_index->end(); ++i )
i != m_index->end(); ++i )
child->m_index->Add( *i ); child->m_index->Add( *i );
child->m_joints = m_joints; child->m_joints = m_joints;
...@@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent() ...@@ -150,7 +150,7 @@ void PNS_NODE::unlinkParent()
// function object that visits potential obstacles and performs // function object that visits potential obstacles and performs
// the actual collision refining // the actual collision refining
struct PNS_NODE::obstacleVisitor struct PNS_NODE::OBSTACLE_VISITOR
{ {
///> node we are searching in (either root or a branch) ///> node we are searching in (either root or a branch)
PNS_NODE* m_node; PNS_NODE* m_node;
...@@ -159,7 +159,7 @@ struct PNS_NODE::obstacleVisitor ...@@ -159,7 +159,7 @@ struct PNS_NODE::obstacleVisitor
PNS_NODE* m_override; PNS_NODE* m_override;
///> list of encountered obstacles ///> list of encountered obstacles
Obstacles& m_tab; OBSTACLES& m_tab;
///> the item we are looking for collisions with ///> the item we are looking for collisions with
const PNS_ITEM* m_item; const PNS_ITEM* m_item;
...@@ -176,8 +176,7 @@ struct PNS_NODE::obstacleVisitor ...@@ -176,8 +176,7 @@ struct PNS_NODE::obstacleVisitor
///> additional clearance ///> additional clearance
int m_extraClearance; int m_extraClearance;
obstacleVisitor( PNS_NODE::Obstacles& aTab, const PNS_ITEM* aItem, OBSTACLE_VISITOR( PNS_NODE::OBSTACLES& aTab, const PNS_ITEM* aItem, int aKindMask ) :
int aKindMask ) :
m_tab( aTab ), m_tab( aTab ),
m_item( aItem ), m_item( aItem ),
m_kindMask( aKindMask ), m_kindMask( aKindMask ),
...@@ -185,9 +184,9 @@ struct PNS_NODE::obstacleVisitor ...@@ -185,9 +184,9 @@ struct PNS_NODE::obstacleVisitor
m_matchCount( 0 ), m_matchCount( 0 ),
m_extraClearance( 0 ) m_extraClearance( 0 )
{ {
if(aItem->Kind() == PNS_ITEM::LINE) if( aItem->Kind() == PNS_ITEM::LINE )
m_extraClearance += static_cast<const PNS_LINE *>(aItem)->Width() / 2; m_extraClearance += static_cast<const PNS_LINE*>( aItem )->Width() / 2;
}; }
void SetCountLimit( int aLimit ) void SetCountLimit( int aLimit )
{ {
...@@ -212,7 +211,7 @@ struct PNS_NODE::obstacleVisitor ...@@ -212,7 +211,7 @@ struct PNS_NODE::obstacleVisitor
int clearance = m_extraClearance + m_node->GetClearance( aItem, m_item ); int clearance = m_extraClearance + m_node->GetClearance( aItem, m_item );
if(aItem->Kind() == PNS_ITEM::LINE) if( aItem->Kind() == PNS_ITEM::LINE )
clearance += static_cast<PNS_LINE *>(aItem)->Width() / 2; clearance += static_cast<PNS_LINE *>(aItem)->Width() / 2;
if( !aItem->Collide( m_item, clearance ) ) if( !aItem->Collide( m_item, clearance ) )
...@@ -220,7 +219,7 @@ struct PNS_NODE::obstacleVisitor ...@@ -220,7 +219,7 @@ struct PNS_NODE::obstacleVisitor
PNS_OBSTACLE obs; PNS_OBSTACLE obs;
obs.item = aItem; obs.m_item = aItem;
m_tab.push_back( obs ); m_tab.push_back( obs );
m_matchCount++; m_matchCount++;
...@@ -234,9 +233,9 @@ struct PNS_NODE::obstacleVisitor ...@@ -234,9 +233,9 @@ struct PNS_NODE::obstacleVisitor
int PNS_NODE::QueryColliding( const PNS_ITEM* aItem, 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 #ifdef DEBUG
assert( allocNodes.find( this ) != allocNodes.end() ); assert( allocNodes.find( this ) != allocNodes.end() );
...@@ -249,7 +248,7 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem, ...@@ -249,7 +248,7 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem,
m_index->Query( aItem, m_maxClearance, visitor ); m_index->Query( aItem, m_maxClearance, visitor );
// if we haven't found enough items, look in the root branch as well. // if we haven't found enough items, look in the root branch as well.
if( !isRoot() && ( visitor.m_matchCount < aLimitCount || aLimitCount < 0) ) if( !isRoot() && ( visitor.m_matchCount < aLimitCount || aLimitCount < 0 ) )
{ {
visitor.SetWorld( m_root, this ); visitor.SetWorld( m_root, this );
m_root->m_index->Query( aItem, m_maxClearance, visitor ); m_root->m_index->Query( aItem, m_maxClearance, visitor );
...@@ -259,9 +258,9 @@ int PNS_NODE::QueryColliding( const PNS_ITEM* aItem, ...@@ -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; bool found_isects = false;
const SHAPE_LINE_CHAIN& line = aItem->CLine(); const SHAPE_LINE_CHAIN& line = aItem->CLine();
...@@ -281,13 +280,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin ...@@ -281,13 +280,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
// if(! QueryColliding ( aItem, obs_list, aKindMask )) // if(! QueryColliding ( aItem, obs_list, aKindMask ))
if( !n ) if( !n )
return OptObstacle(); return OPT_OBSTACLE();
PNS_LINE& aLine = (PNS_LINE&) *aItem; PNS_LINE& aLine = (PNS_LINE&) *aItem;
PNS_OBSTACLE nearest; PNS_OBSTACLE nearest;
nearest.item = NULL; nearest.m_item = NULL;
nearest.dist_first = INT_MAX; nearest.m_distFirst = INT_MAX;
BOOST_FOREACH( PNS_OBSTACLE obs, obs_list ) BOOST_FOREACH( PNS_OBSTACLE obs, obs_list )
{ {
...@@ -296,13 +295,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin ...@@ -296,13 +295,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
std::vector<SHAPE_LINE_CHAIN::INTERSECTION> isect_list; 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() ) 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() ); 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 ...@@ -313,13 +312,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
int dist = aLine.CLine().Length() + int dist = aLine.CLine().Length() +
( isect.p - aLine.Via().Pos() ).EuclideanNorm(); ( isect.p - aLine.Via().Pos() ).EuclideanNorm();
if( dist < nearest.dist_first ) if( dist < nearest.m_distFirst )
{ {
found_isects = true; found_isects = true;
nearest.dist_first = dist; nearest.m_distFirst = dist;
nearest.ip_first = isect.p; nearest.m_ipFirst = isect.p;
nearest.item = obs.item; nearest.m_item = obs.m_item;
nearest.hull = hull; nearest.m_hull = hull;
} }
if( dist > dist_max ) if( dist > dist_max )
...@@ -338,13 +337,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin ...@@ -338,13 +337,13 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
{ {
int dist = aLine.CLine().PathLength( isect.p ); int dist = aLine.CLine().PathLength( isect.p );
if( dist < nearest.dist_first ) if( dist < nearest.m_distFirst )
{ {
found_isects = true; found_isects = true;
nearest.dist_first = dist; nearest.m_distFirst = dist;
nearest.ip_first = isect.p; nearest.m_ipFirst = isect.p;
nearest.item = obs.item; nearest.m_item = obs.m_item;
nearest.hull = hull; nearest.m_hull = hull;
} }
if( dist > dist_max ) if( dist > dist_max )
...@@ -354,37 +353,41 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin ...@@ -354,37 +353,41 @@ PNS_NODE::OptObstacle PNS_NODE::NearestObstacle( const PNS_LINE* aItem, int aKin
} }
} }
nearest.ip_last = ip_last; nearest.m_ipLast = ip_last;
nearest.dist_last = dist_max; nearest.m_distLast = dist_max;
} }
if(!found_isects) if( !found_isects )
nearest.item = obs_list[0].item; nearest.m_item = obs_list[0].m_item;
return nearest; 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() ) BOOST_FOREACH( const PNS_ITEM* item, aSet.CItems() )
{ {
OptObstacle obs = CheckColliding(item, aKindMask); OPT_OBSTACLE obs = CheckColliding( item, aKindMask );
if(obs)
if( obs )
return 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 ); obs.reserve( 100 );
if( aItemA->Kind() == PNS_ITEM::LINE ) if( aItemA->Kind() == PNS_ITEM::LINE )
{ {
int n = 0; int n = 0;
const PNS_LINE* line = static_cast<const PNS_LINE*>(aItemA); const PNS_LINE* line = static_cast<const PNS_LINE*>( aItemA );
const SHAPE_LINE_CHAIN& l = line->CLine(); const SHAPE_LINE_CHAIN& l = line->CLine();
for( int i = 0; i < l.SegmentCount(); i++ ) for( int i = 0; i < l.SegmentCount(); i++ )
...@@ -393,7 +396,7 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin ...@@ -393,7 +396,7 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
n += QueryColliding( &s, obs, aKindMask, 1 ); n += QueryColliding( &s, obs, aKindMask, 1 );
if( n ) if( n )
return OptObstacle( obs[0] ); return OPT_OBSTACLE( obs[0] );
} }
if( line->EndsWithVia() ) if( line->EndsWithVia() )
...@@ -401,13 +404,13 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin ...@@ -401,13 +404,13 @@ PNS_NODE::OptObstacle PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, int aKin
n += QueryColliding( &line->Via(), obs, aKindMask, 1 ); n += QueryColliding( &line->Via(), obs, aKindMask, 1 );
if( n ) if( n )
return OptObstacle( obs[0] ); return OPT_OBSTACLE( obs[0] );
} }
} }
else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 ) else if( QueryColliding( aItemA, obs, aKindMask, 1 ) > 0 )
return OptObstacle( obs[0] ); return OPT_OBSTACLE( obs[0] );
return OptObstacle(); return OPT_OBSTACLE();
} }
...@@ -417,23 +420,24 @@ bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, i ...@@ -417,23 +420,24 @@ bool PNS_NODE::CheckColliding( const PNS_ITEM* aItemA, const PNS_ITEM* aItemB, i
int clearance = GetClearance( aItemA, aItemB ); int clearance = GetClearance( aItemA, aItemB );
// fixme: refactor // fixme: refactor
if(aItemA->Kind() == PNS_ITEM::LINE) if( aItemA->Kind() == PNS_ITEM::LINE )
clearance += static_cast<const PNS_LINE *>(aItemA)->Width() / 2; clearance += static_cast<const PNS_LINE*>( aItemA )->Width() / 2;
if(aItemB->Kind() == PNS_ITEM::LINE) if( aItemB->Kind() == PNS_ITEM::LINE )
clearance += static_cast<const PNS_LINE *>(aItemB)->Width() / 2; clearance += static_cast<const PNS_LINE*>( aItemB )->Width() / 2;
return aItemA->Collide( aItemB, clearance ); return aItemA->Collide( aItemB, clearance );
} }
struct hitVisitor struct HIT_VISITOR
{ {
PNS_ITEMSET& m_items; PNS_ITEMSET& m_items;
const VECTOR2I& m_point; const VECTOR2I& m_point;
const PNS_NODE* m_world; const PNS_NODE* m_world;
hitVisitor( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) : HIT_VISITOR( PNS_ITEMSET& aTab, const VECTOR2I& aPoint, const PNS_NODE* aWorld ) :
m_items( aTab ), m_point( aPoint ), m_world( aWorld ) {}; m_items( aTab ), m_point( aPoint ), m_world( aWorld )
{}
bool operator()( PNS_ITEM* aItem ) bool operator()( PNS_ITEM* aItem )
{ {
...@@ -455,17 +459,17 @@ const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const ...@@ -455,17 +459,17 @@ const PNS_ITEMSET PNS_NODE::HitTest( const VECTOR2I& aPoint ) const
// fixme: we treat a point as an infinitely small circle - this is inefficient. // fixme: we treat a point as an infinitely small circle - this is inefficient.
SHAPE_CIRCLE s( aPoint, 0 ); SHAPE_CIRCLE s( aPoint, 0 );
hitVisitor visitor( items, aPoint, this ); HIT_VISITOR visitor( items, aPoint, this );
m_index->Query( &s, m_maxClearance, visitor ); m_index->Query( &s, m_maxClearance, visitor );
if( !isRoot() ) // fixme: could be made cleaner if( !isRoot() ) // fixme: could be made cleaner
{ {
PNS_ITEMSET items_root; 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 ); m_root->m_index->Query( &s, m_maxClearance, visitor_root );
BOOST_FOREACH( PNS_ITEM * item, items_root.Items() ) BOOST_FOREACH( PNS_ITEM* item, items_root.Items() )
{ {
if( !overrides( item ) ) if( !overrides( item ) )
items.Add( item ); items.Add( item );
...@@ -506,10 +510,10 @@ void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant ) ...@@ -506,10 +510,10 @@ void PNS_NODE::addLine( PNS_LINE* aLine, bool aAllowRedundant )
if ( !aAllowRedundant ) if ( !aAllowRedundant )
psegR = findRedundantSegment( pseg ); psegR = findRedundantSegment( pseg );
if(psegR) if( psegR )
aLine->LinkSegment(psegR); aLine->LinkSegment( psegR );
else { else
{
pseg->SetOwner( this ); pseg->SetOwner( this );
linkJoint( s.A, pseg->Layers(), aLine->Net(), pseg ); linkJoint( s.A, pseg->Layers(), aLine->Net(), pseg );
...@@ -532,7 +536,7 @@ void PNS_NODE::addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant ) ...@@ -532,7 +536,7 @@ void PNS_NODE::addSegment( PNS_SEGMENT* aSeg, bool aAllowRedundant )
return; return;
} }
if ( !aAllowRedundant && findRedundantSegment ( aSeg ) ) if( !aAllowRedundant && findRedundantSegment ( aSeg ) )
return; return;
aSeg->SetOwner( this ); aSeg->SetOwner( this );
...@@ -559,11 +563,11 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant ) ...@@ -559,11 +563,11 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
break; break;
case PNS_ITEM::LINE: case PNS_ITEM::LINE:
addLine( static_cast<PNS_LINE*> (aItem), aAllowRedundant ); addLine( static_cast<PNS_LINE*>( aItem ), aAllowRedundant );
break; break;
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
addVia( static_cast<PNS_VIA*>(aItem) ); addVia( static_cast<PNS_VIA*>( aItem ) );
break; break;
default: default:
...@@ -574,7 +578,6 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant ) ...@@ -574,7 +578,6 @@ void PNS_NODE::Add( PNS_ITEM* aItem, bool aAllowRedundant )
void PNS_NODE::doRemove( PNS_ITEM* aItem ) void PNS_NODE::doRemove( PNS_ITEM* aItem )
{ {
// assert(m_root->m_index->Contains(aItem) || m_index->Contains(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: // case 1: removing an item that is stored in the root node from any branch:
...@@ -612,7 +615,7 @@ void PNS_NODE::removeLine( PNS_LINE* aLine ) ...@@ -612,7 +615,7 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
assert (segRefs != NULL); assert (segRefs != NULL);
assert (aLine->Owner()); assert (aLine->Owner());
if ( (int)segRefs->size() != aLine->SegmentCount()) if ( (int) segRefs->size() != aLine->SegmentCount() )
{ {
//printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops()); //printf("******weird deletion: segrefs %d segcount %d hasloops %d\n", segRefs->size(), aLine->SegmentCount(), aLine->HasLoops());
} }
...@@ -627,20 +630,19 @@ void PNS_NODE::removeLine( PNS_LINE* aLine ) ...@@ -627,20 +630,19 @@ void PNS_NODE::removeLine( PNS_LINE* aLine )
} }
void PNS_NODE::removeVia( PNS_VIA* aVia ) void PNS_NODE::removeVia( PNS_VIA* aVia )
{ {
// We have to split a single joint (associated with a via, binding together multiple layers) // 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. // 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() ); VECTOR2I p( aVia->Pos() );
PNS_LAYERSET vLayers ( aVia->Layers() ); PNS_LAYERSET vLayers( aVia->Layers() );
int net = aVia->Net(); int net = aVia->Net();
PNS_JOINT *jt = FindJoint( p, vLayers.Start(), 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.net = net;
tag.pos = p; tag.pos = p;
...@@ -649,14 +651,14 @@ void PNS_NODE::removeVia( PNS_VIA* aVia ) ...@@ -649,14 +651,14 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
do do
{ {
split = false; 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() ) if( range.first == m_joints.end() )
break; break;
// find and remove all joints containing the via to be removed // 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 ) ) if( aVia->LayersOverlap ( &f->second ) )
{ {
...@@ -665,10 +667,10 @@ void PNS_NODE::removeVia( PNS_VIA* aVia ) ...@@ -665,10 +667,10 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
break; break;
} }
} }
} while (split); } while( split );
// and re-link them, using the former via's link list // and re-link them, using the former via's link list
BOOST_FOREACH(PNS_ITEM *item, links) BOOST_FOREACH(PNS_ITEM* item, links)
{ {
if( item != aVia ) if( item != aVia )
linkJoint ( p, item->Layers(), net, item ); linkJoint ( p, item->Layers(), net, item );
...@@ -677,6 +679,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia ) ...@@ -677,6 +679,7 @@ void PNS_NODE::removeVia( PNS_VIA* aVia )
doRemove( aVia ); doRemove( aVia );
} }
void PNS_NODE::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ) void PNS_NODE::Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem )
{ {
Remove( aOldItem ); Remove( aOldItem );
...@@ -711,37 +714,37 @@ void PNS_NODE::Remove( PNS_ITEM* aItem ) ...@@ -711,37 +714,37 @@ void PNS_NODE::Remove( PNS_ITEM* aItem )
} }
void PNS_NODE::followLine( PNS_SEGMENT* current, bool scanDirection, int& pos, void PNS_NODE::followLine( PNS_SEGMENT* aCurrent, bool aScanDirection, int& aPos,
int limit, VECTOR2I* corners, PNS_SEGMENT** segments ) int aLimit, VECTOR2I* aCorners, PNS_SEGMENT** aSegments )
{ {
bool prevReversed = false; bool prevReversed = false;
for( ; ; ) for( ; ; )
{ {
const VECTOR2I p = const VECTOR2I p =
(scanDirection ^ prevReversed) ? current->Seg().B : current->Seg().A; ( aScanDirection ^ prevReversed ) ? aCurrent->Seg().B : aCurrent->Seg().A;
const PNS_JOINT *jt = FindJoint( p, current ); const PNS_JOINT* jt = FindJoint( p, aCurrent );
assert( jt ); assert( jt );
assert( pos > 0 && pos < limit ); assert( aPos > 0 && aPos < aLimit );
corners[pos] = jt->Pos(); aCorners[aPos] = jt->Pos();
segments[pos] = current; aSegments[aPos] = aCurrent;
pos += (scanDirection ? 1 : -1); aPos += ( aScanDirection ? 1 : -1 );
if( !jt->IsLineCorner() ) if( !jt->IsLineCorner() )
break; break;
current = jt->NextSegment( current ); aCurrent = jt->NextSegment( aCurrent );
prevReversed = prevReversed =
( jt->Pos() == (scanDirection ? current->Seg().B : current->Seg().A ) ); ( jt->Pos() == (aScanDirection ? aCurrent->Seg().B : aCurrent->Seg().A ) );
} }
} }
PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex) PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int* aOriginSegmentIndex)
{ {
const int MaxVerts = 1024; const int MaxVerts = 1024;
...@@ -761,7 +764,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex) ...@@ -761,7 +764,7 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
int n = 0; int n = 0;
PNS_SEGMENT *prev_seg = NULL; PNS_SEGMENT* prev_seg = NULL;
for( int i = i_start + 1; i < i_end; i++ ) for( int i = i_start + 1; i < i_end; i++ )
{ {
...@@ -773,8 +776,9 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex) ...@@ -773,8 +776,9 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
{ {
pl->LinkSegment( segs[i] ); pl->LinkSegment( segs[i] );
if(segs[i] == aSeg && aOriginSegmentIndex) if( segs[i] == aSeg && aOriginSegmentIndex )
*aOriginSegmentIndex = n; *aOriginSegmentIndex = n;
n++; n++;
} }
...@@ -782,53 +786,57 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex) ...@@ -782,53 +786,57 @@ PNS_LINE* PNS_NODE::AssembleLine( PNS_SEGMENT* aSeg, int *aOriginSegmentIndex)
} }
assert (pl->SegmentCount() != 0); assert( pl->SegmentCount() != 0 );
assert (pl->SegmentCount() == (int) pl->LinkedSegments()->size()); assert( pl->SegmentCount() == (int) pl->LinkedSegments()->size() );
return pl; return pl;
} }
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 ); aA = *FindJoint( aLine->CPoint( 0 ), aLine );
b = *FindJoint( aLine->CPoint( -1 ), aLine ); aB = *FindJoint( aLine->CPoint( -1 ), aLine );
} }
void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*> & aFoundJoints )
void PNS_NODE::MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT*>& aFoundJoints )
{ {
std::deque<PNS_JOINT*> searchQueue; std::deque<PNS_JOINT*> searchQueue;
std::set<PNS_JOINT*> processed; std::set<PNS_JOINT*> processed;
searchQueue.push_back(aStart); searchQueue.push_back( aStart );
processed.insert ( aStart ); processed.insert( aStart );
while(!searchQueue.empty()) while( !searchQueue.empty() )
{ {
PNS_JOINT *current = searchQueue.front(); PNS_JOINT* current = searchQueue.front();
searchQueue.pop_front(); searchQueue.pop_front();
BOOST_FOREACH ( PNS_ITEM *item, current->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, current->LinkList() )
{
if ( item->OfKind( PNS_ITEM::SEGMENT ) ) if ( item->OfKind( PNS_ITEM::SEGMENT ) )
{ {
PNS_SEGMENT *seg = static_cast<PNS_SEGMENT *>(item); PNS_SEGMENT* seg = static_cast<PNS_SEGMENT *>( item );
PNS_JOINT *a = FindJoint( seg->Seg().A, seg ); PNS_JOINT* a = FindJoint( seg->Seg().A, seg );
PNS_JOINT *b = FindJoint( seg->Seg().B, seg ); PNS_JOINT* b = FindJoint( seg->Seg().B, seg );
PNS_JOINT *next = (*a == *current) ? b : a; PNS_JOINT* next = ( *a == *current ) ? b : a;
if( processed.find( next ) == processed.end() ) if( processed.find( next ) == processed.end() )
{ {
processed.insert ( next ); processed.insert( next );
searchQueue.push_back( next ); searchQueue.push_back( next );
} }
} }
} }
}
BOOST_FOREACH(PNS_JOINT *jt, processed) BOOST_FOREACH(PNS_JOINT* jt, processed)
aFoundJoints.push_back( jt ); aFoundJoints.push_back( jt );
} }
PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, int aKindMask )
PNS_ITEM* PNS_NODE::NearestUnconnectedItem( PNS_JOINT* aStart, int* aAnchor, int aKindMask )
{ {
std::set<PNS_ITEM*> disconnected; std::set<PNS_ITEM*> disconnected;
std::vector<PNS_JOINT*> joints; std::vector<PNS_JOINT*> joints;
...@@ -836,32 +844,33 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in ...@@ -836,32 +844,33 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
AllItemsInNet( aStart->Net(), disconnected ); AllItemsInNet( aStart->Net(), disconnected );
MapConnectivity ( aStart, joints ); MapConnectivity ( aStart, joints );
BOOST_FOREACH(PNS_JOINT *jt, joints) BOOST_FOREACH( PNS_JOINT *jt, joints )
{ {
BOOST_FOREACH (PNS_ITEM *link, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* link, jt->LinkList() )
{ {
if(disconnected.find(link) != disconnected.end() ) if( disconnected.find( link ) != disconnected.end() )
disconnected.erase(link); disconnected.erase( link );
} }
} }
int best_dist = INT_MAX; int best_dist = INT_MAX;
PNS_ITEM *best = NULL; PNS_ITEM* best = NULL;
BOOST_FOREACH (PNS_ITEM *item, disconnected ) BOOST_FOREACH( PNS_ITEM* item, disconnected )
{ {
if( item->OfKind ( aKindMask ) ) if( item->OfKind( aKindMask ) )
{ {
for(int i = 0; i < item->AnchorCount(); i++) for(int i = 0; i < item->AnchorCount(); i++)
{ {
VECTOR2I p = item->Anchor ( i ); VECTOR2I p = item->Anchor( i );
int d = (p - aStart->Pos()).EuclideanNorm(); int d = ( p - aStart->Pos() ).EuclideanNorm();
if(d < best_dist) if( d < best_dist )
{ {
best_dist = d; best_dist = d;
best = item; best = item;
if(aAnchor)
if( aAnchor )
*aAnchor = i; *aAnchor = i;
} }
} }
...@@ -871,31 +880,32 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in ...@@ -871,31 +880,32 @@ PNS_ITEM *PNS_NODE::NearestUnconnectedItem ( PNS_JOINT *aStart, int *aAnchor, in
return best; 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 ) if( item->Kind() == PNS_ITEM::SEGMENT )
{ {
PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>(item); PNS_SEGMENT* seg = static_cast<PNS_SEGMENT*>( item );
PNS_LINE* line = AssembleLine( seg ); PNS_LINE* line = AssembleLine( seg );
PNS_JOINT j_start, j_end; PNS_JOINT j_start, j_end;
FindLineEnds( line, j_start, j_end ); FindLineEnds( line, j_start, j_end );
int id_start = line->CLine().Find( aA.Pos() );
int id_end = line->CLine().Find( aB.Pos() );
int id_start = line->CLine().Find (a.Pos()); if( id_end < id_start )
int id_end = line->CLine().Find (b.Pos()); std::swap( id_end, id_start );
if(id_end < id_start) if( id_start >= 0 && id_end >= 0 )
std::swap(id_end, id_start);
if(id_start >= 0 && id_end >= 0)
{ {
line->ClipVertexRange ( id_start, id_end ); line->ClipVertexRange ( id_start, id_end );
aLines.push_back( line ); aLines.push_back( line );
} else }
else
delete line; delete line;
} }
} }
...@@ -906,12 +916,12 @@ int PNS_NODE::FindLinesBetweenJoints( PNS_JOINT& a, PNS_JOINT& b, std::vector<PN ...@@ -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* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet )
{ {
PNS_JOINT::HashTag tag; PNS_JOINT::HASH_TAG tag;
tag.net = aNet; tag.net = aNet;
tag.pos = aPos; 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() ) if( f == end && !isRoot() )
{ {
...@@ -936,15 +946,15 @@ PNS_JOINT* PNS_NODE::FindJoint( const VECTOR2I& aPos, int aLayer, int aNet ) ...@@ -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& 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.pos = aPos;
tag.net = aNet; tag.net = aNet;
// try to find the joint in this node. // 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. // not found and we are not root? find in the root and copy results here.
if( f == m_joints.end() && !isRoot() ) if( f == m_joints.end() && !isRoot() )
...@@ -978,7 +988,8 @@ PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLaye ...@@ -978,7 +988,8 @@ PNS_JOINT& PNS_NODE::touchJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLaye
break; break;
} }
} }
} while( merged ); }
while( merged );
return m_joints.insert( TagJointPair( tag, jt ) )->second; return m_joints.insert( TagJointPair( tag, jt ) )->second;
} }
...@@ -991,10 +1002,8 @@ void PNS_JOINT::Dump() const ...@@ -991,10 +1002,8 @@ void PNS_JOINT::Dump() const
} }
void PNS_NODE::linkJoint( const VECTOR2I& aPos, void PNS_NODE::linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
const PNS_LAYERSET& aLayers, int aNet, PNS_ITEM* aWhere )
int aNet,
PNS_ITEM* aWhere )
{ {
PNS_JOINT& jt = touchJoint( aPos, aLayers, aNet ); PNS_JOINT& jt = touchJoint( aPos, aLayers, aNet );
...@@ -1021,7 +1030,7 @@ void PNS_NODE::Dump( bool aLong ) ...@@ -1021,7 +1030,7 @@ void PNS_NODE::Dump( bool aLong )
for( i = m_items.begin(); i != m_items.end(); i++ ) for( i = m_items.begin(); i != m_items.end(); i++ )
{ {
if( (*i)->GetKind() == PNS_ITEM::SEGMENT ) if( (*i)->GetKind() == PNS_ITEM::SEGMENT )
all_segs.insert( static_cast<PNS_SEGMENT*>(*i) ); all_segs.insert( static_cast<PNS_SEGMENT*>( *i ) );
} }
if( !isRoot() ) if( !isRoot() )
...@@ -1033,24 +1042,24 @@ void PNS_NODE::Dump( bool aLong ) ...@@ -1033,24 +1042,24 @@ void PNS_NODE::Dump( bool aLong )
} }
} }
JointMap::iterator j; JOINT_MAP::iterator j;
if( aLong ) if( aLong )
for( j = m_joints.begin(); j!=m_joints.end(); ++j ) for( j = m_joints.begin(); j != m_joints.end(); ++j )
{ {
printf( "joint : %s, links : %d\n", printf( "joint : %s, links : %d\n",
j->second.GetPos().Format().c_str(), j->second.LinkCount() ); 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 ) 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: 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(), printf( " -> seg %s %s\n", seg->GetSeg().A.Format().c_str(),
seg->GetSeg().B.Format().c_str() ); seg->GetSeg().B.Format().c_str() );
break; break;
...@@ -1075,7 +1084,6 @@ void PNS_NODE::Dump( bool aLong ) ...@@ -1075,7 +1084,6 @@ void PNS_NODE::Dump( bool aLong )
if( aLong ) if( aLong )
printf( "Line: %s, net %d ", l->GetLine().Format().c_str(), l->GetNet() ); 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 ) for( std::vector<PNS_SEGMENT*>::iterator j = seg_refs->begin(); j != seg_refs->end(); ++j )
{ {
printf( "%s ", (*j)->GetSeg().A.Format().c_str() ); printf( "%s ", (*j)->GetSeg().A.Format().c_str() );
...@@ -1094,7 +1102,7 @@ void PNS_NODE::Dump( bool aLong ) ...@@ -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() ); aRemoved.reserve( m_override.size() );
aAdded.reserve( m_index->Size() ); aAdded.reserve( m_index->Size() );
...@@ -1102,10 +1110,10 @@ void PNS_NODE::GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded ) ...@@ -1102,10 +1110,10 @@ void PNS_NODE::GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded )
if( isRoot() ) if( isRoot() )
return; return;
BOOST_FOREACH( PNS_ITEM * item, m_override ) BOOST_FOREACH( PNS_ITEM* item, m_override )
aRemoved.push_back( item ); 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 ); aAdded.push_back( *i );
} }
...@@ -1115,7 +1123,8 @@ void PNS_NODE::releaseChildren() ...@@ -1115,7 +1123,8 @@ void PNS_NODE::releaseChildren()
// copy the kids as the PNS_NODE destructor erases the item from the parent node. // copy the kids as the PNS_NODE destructor erases the item from the parent node.
std::vector<PNS_NODE*> kids = m_children; std::vector<PNS_NODE*> kids = m_children;
BOOST_FOREACH( PNS_NODE * node, kids ) { BOOST_FOREACH( PNS_NODE * node, kids )
{
node->releaseChildren(); node->releaseChildren();
delete node; delete node;
} }
...@@ -1130,11 +1139,11 @@ void PNS_NODE::Commit( PNS_NODE* aNode ) ...@@ -1130,11 +1139,11 @@ void PNS_NODE::Commit( PNS_NODE* aNode )
BOOST_FOREACH( PNS_ITEM * item, aNode->m_override ) BOOST_FOREACH( PNS_ITEM * item, aNode->m_override )
Remove( item ); 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 != aNode->m_index->end(); ++i )
{ {
(*i)->SetRank ( -1 ); (*i)->SetRank( -1 );
(*i)->Unmark (); (*i)->Unmark();
Add( *i ); Add( *i );
} }
...@@ -1151,74 +1160,86 @@ void PNS_NODE::KillChildren() ...@@ -1151,74 +1160,86 @@ void PNS_NODE::KillChildren()
void PNS_NODE::AllItemsInNet( int aNet, std::set<PNS_ITEM*>& aItems ) 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) if( l_cur )
{ {
BOOST_FOREACH (PNS_ITEM *item, *l_cur ) BOOST_FOREACH( PNS_ITEM*item, *l_cur )
aItems.insert ( item ); aItems.insert( item );
} }
if( !isRoot() ) 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) 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 ) ) if( !overrides( *i ) )
aItems.insert( *i ); aItems.insert( *i );
} }
} }
void PNS_NODE::ClearRanks() 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)->SetRank( -1 );
(*i)->Mark(0); (*i)->Mark( 0 );
} }
} }
int PNS_NODE::FindByMarker ( int aMarker, PNS_ITEMSET& aItems )
int PNS_NODE::FindByMarker( int aMarker, PNS_ITEMSET& aItems )
{ {
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 ) aItems.Add(*i); {
if( (*i)->Marker() & aMarker )
aItems.Add( *i );
}
return 0; return 0;
} }
int PNS_NODE::RemoveByMarker ( int aMarker )
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 ) if ( (*i)->Marker() & aMarker )
{ {
Remove (*i); Remove( *i );
} }
}
return 0; return 0;
} }
PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg ) PNS_SEGMENT* PNS_NODE::findRedundantSegment ( PNS_SEGMENT *aSeg )
{ {
PNS_JOINT *jtStart = FindJoint ( aSeg->Seg().A, aSeg ); PNS_JOINT* jtStart = FindJoint ( aSeg->Seg().A, aSeg );
if(!jtStart) if( !jtStart )
return NULL; return NULL;
BOOST_FOREACH( PNS_ITEM *item, jtStart->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
if(item->OfKind(PNS_ITEM::SEGMENT))
{ {
PNS_SEGMENT *seg2 = (PNS_SEGMENT *) item; if( item->OfKind( PNS_ITEM::SEGMENT ) )
{
PNS_SEGMENT* seg2 = (PNS_SEGMENT*) item;
const VECTOR2I a1 ( aSeg->Seg().A ); const VECTOR2I a1( aSeg->Seg().A );
const VECTOR2I b1 ( aSeg->Seg().B ); const VECTOR2I b1( aSeg->Seg().B );
const VECTOR2I a2 ( seg2->Seg().A ); const VECTOR2I a2( seg2->Seg().A );
const VECTOR2I b2 ( seg2->Seg().B ); const VECTOR2I b2( seg2->Seg().B );
if( seg2->Layers().Start() == aSeg->Layers().Start() && if( seg2->Layers().Start() == aSeg->Layers().Start() &&
((a1 == a2 && b1 == b2) || (a1 == b2 && a2 == b1))) ( ( a1 == a2 && b1 == b2 ) || ( a1 == b2 && a2 == b1 ) ) )
return seg2; return seg2;
} }
}
return NULL; return NULL;
} }
...@@ -52,7 +52,7 @@ class PNS_INDEX; ...@@ -52,7 +52,7 @@ class PNS_INDEX;
class PNS_CLEARANCE_FUNC class PNS_CLEARANCE_FUNC
{ {
public: 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() {} virtual ~PNS_CLEARANCE_FUNC() {}
}; };
...@@ -65,20 +65,20 @@ public: ...@@ -65,20 +65,20 @@ public:
struct PNS_OBSTACLE struct PNS_OBSTACLE
{ {
///> Item we search collisions with ///> Item we search collisions with
PNS_ITEM* head; PNS_ITEM* m_head;
///> Item found to be colliding with head ///> Item found to be colliding with m_head
PNS_ITEM* item; PNS_ITEM* m_item;
///> Hull of the colliding item ///> Hull of the colliding m_item
SHAPE_LINE_CHAIN hull; SHAPE_LINE_CHAIN m_hull;
///> First and last intersection point between the head item and the hull ///> First and last intersection point between the head item and the hull
///> of the colliding item ///> of the colliding m_item
VECTOR2I ip_first, ip_last; VECTOR2I m_ipFirst, m_ipLast;
///> ... and the distance thereof ///> ... and the distance thereof
int dist_first, dist_last; int m_distFirst, m_distLast;
}; };
/** /**
...@@ -93,34 +93,33 @@ struct PNS_OBSTACLE ...@@ -93,34 +93,33 @@ struct PNS_OBSTACLE
* - lightweight cloning/branching (for recursive optimization and shove * - lightweight cloning/branching (for recursive optimization and shove
* springback) * springback)
**/ **/
class PNS_NODE class PNS_NODE
{ {
public: public:
typedef boost::optional<PNS_OBSTACLE> OptObstacle; typedef boost::optional<PNS_OBSTACLE> OPT_OBSTACLE;
typedef std::vector<PNS_ITEM*> ItemVector; typedef std::vector<PNS_ITEM*> ITEM_VECTOR;
typedef std::vector<PNS_OBSTACLE> Obstacles; typedef std::vector<PNS_OBSTACLE> OBSTACLES;
PNS_NODE (); PNS_NODE ();
~PNS_NODE (); ~PNS_NODE ();
///> Returns the expected clearance between items a and b. ///> 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 ///> Returns the pre-set worst case clearance between any pair of items
int GetMaxClearance () const int GetMaxClearance() const
{ {
return m_maxClearance; return m_maxClearance;
} }
///> Sets the worst-case clerance between any pair of items ///> Sets the worst-case clerance between any pair of items
void SetMaxClearance ( int aClearance ) void SetMaxClearance( int aClearance )
{ {
m_maxClearance = aClearance; m_maxClearance = aClearance;
} }
///> Assigns a clerance resolution function object ///> Assigns a clerance resolution function object
void SetClearanceFunctor ( PNS_CLEARANCE_FUNC* aFunc ) void SetClearanceFunctor( PNS_CLEARANCE_FUNC* aFunc )
{ {
m_clearanceFunctor = aFunc; m_clearanceFunctor = aFunc;
} }
...@@ -147,12 +146,11 @@ public: ...@@ -147,12 +146,11 @@ public:
* @param aLimitCount stop looking for collisions after finding this number of colliding items * @param aLimitCount stop looking for collisions after finding this number of colliding items
* @return number of obstacles found * @return number of obstacles found
*/ */
int QueryColliding ( const PNS_ITEM* aItem, int QueryColliding( const PNS_ITEM* aItem,
Obstacles& aObstacles, OBSTACLES& aObstacles,
int aKindMask = PNS_ITEM::ANY, int aKindMask = PNS_ITEM::ANY,
int aLimitCount = -1 ); int aLimitCount = -1 );
/** /**
* Function NearestObstacle() * Function NearestObstacle()
* *
...@@ -162,7 +160,7 @@ public: ...@@ -162,7 +160,7 @@ public:
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @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 ); int aKindMask = PNS_ITEM::ANY );
/** /**
...@@ -174,7 +172,7 @@ public: ...@@ -174,7 +172,7 @@ public:
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @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 ); int aKindMask = PNS_ITEM::ANY );
...@@ -187,7 +185,7 @@ public: ...@@ -187,7 +185,7 @@ public:
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @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 ); int aKindMask = PNS_ITEM::ANY );
...@@ -200,7 +198,7 @@ public: ...@@ -200,7 +198,7 @@ public:
* @param aKindMask mask of obstacle types to take into account * @param aKindMask mask of obstacle types to take into account
* @return the obstacle, if found, otherwise empty. * @return the obstacle, if found, otherwise empty.
*/ */
bool CheckColliding ( const PNS_ITEM* aItemA, bool CheckColliding( const PNS_ITEM* aItemA,
const PNS_ITEM* aItemB, const PNS_ITEM* aItemB,
int aKindMask = PNS_ITEM::ANY ); int aKindMask = PNS_ITEM::ANY );
...@@ -211,7 +209,7 @@ public: ...@@ -211,7 +209,7 @@ public:
* @param aPoint the point * @param aPoint the point
* @return the items * @return the items
*/ */
const PNS_ITEMSET HitTest ( const VECTOR2I& aPoint ) const; const PNS_ITEMSET HitTest( const VECTOR2I& aPoint ) const;
/** /**
* Function Add() * Function Add()
...@@ -221,7 +219,7 @@ public: ...@@ -221,7 +219,7 @@ public:
* @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via * @param aAllowRedundant if true, duplicate items are allowed (e.g. a segment or via
* at the same coordinates as an existing one) * at the same coordinates as an existing one)
*/ */
void Add ( PNS_ITEM* aItem, bool aAllowRedundant = false ); void Add( PNS_ITEM* aItem, bool aAllowRedundant = false );
/** /**
* Function Remove() * Function Remove()
...@@ -229,7 +227,7 @@ public: ...@@ -229,7 +227,7 @@ public:
* Just as the name says, removes an item from this branch. * Just as the name says, removes an item from this branch.
* @param aItem item to remove * @param aItem item to remove
*/ */
void Remove ( PNS_ITEM* aItem ); void Remove( PNS_ITEM* aItem );
/** /**
* Function Replace() * Function Replace()
...@@ -238,7 +236,7 @@ public: ...@@ -238,7 +236,7 @@ public:
* @param aOldItem item to be removed * @param aOldItem item to be removed
* @param aNewItem item add instead * @param aNewItem item add instead
*/ */
void Replace ( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem ); void Replace( PNS_ITEM* aOldItem, PNS_ITEM* aNewItem );
/** /**
* Function Branch() * Function Branch()
...@@ -248,7 +246,7 @@ public: ...@@ -248,7 +246,7 @@ public:
* any branches in use, their parents must NOT be deleted. * any branches in use, their parents must NOT be deleted.
* @return the new branch * @return the new branch
*/ */
PNS_NODE* Branch ( ); PNS_NODE* Branch();
/** /**
* Function AssembleLine() * Function AssembleLine()
...@@ -259,14 +257,10 @@ public: ...@@ -259,14 +257,10 @@ public:
* @param aOriginSegmentIndex index of aSeg in the resulting line * @param aOriginSegmentIndex index of aSeg in the resulting line
* @return the 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 ///> Prints the contents and joints structure
void Dump ( bool aLong = false ); void Dump( bool aLong = false );
/** /**
* Function GetUpdatedItems() * Function GetUpdatedItems()
...@@ -276,8 +270,7 @@ public: ...@@ -276,8 +270,7 @@ public:
* @param aRemoved removed items * @param aRemoved removed items
* @param aAdded added items * @param aAdded added items
*/ */
void GetUpdatedItems( ItemVector& aRemoved, ItemVector& aAdded ); void GetUpdatedItems( ITEM_VECTOR& aRemoved, ITEM_VECTOR& aAdded );
/** /**
* Function Commit() * Function Commit()
...@@ -302,23 +295,24 @@ public: ...@@ -302,23 +295,24 @@ public:
* Searches for a joint at a given position, linked to given item. * Searches for a joint at a given position, linked to given item.
* @return the joint, if found, otherwise empty * @return the joint, if found, otherwise empty
*/ */
PNS_JOINT* FindJoint( const VECTOR2I& aPos, PNS_ITEM *aItem ) PNS_JOINT* FindJoint( const VECTOR2I& aPos, PNS_ITEM* aItem )
{ {
return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() ); return FindJoint( aPos, aItem->Layers().Start(), aItem->Net() );
} }
void MapConnectivity ( PNS_JOINT* aStart, std::vector<PNS_JOINT *> & aFoundJoints ); 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. ///> finds all lines between a pair of joints. Used by the loop removal procedure.
int FindLinesBetweenJoints( PNS_JOINT& a, int FindLinesBetweenJoints( PNS_JOINT& aA,
PNS_JOINT& b, PNS_JOINT& aB,
std::vector<PNS_LINE*>& aLines ); std::vector<PNS_LINE*>& aLines );
///> finds the joints corresponding to the ends of line aLine ///> 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. ///> Destroys all child nodes. Applicable only to the root node.
void KillChildren(); void KillChildren();
...@@ -327,25 +321,24 @@ public: ...@@ -327,25 +321,24 @@ public:
void ClearRanks(); void ClearRanks();
int FindByMarker( int aMarker, PNS_ITEMSET& aItems );
int FindByMarker ( int aMarker, PNS_ITEMSET& aItems ); int RemoveByMarker( int aMarker );
int RemoveByMarker ( int aMarker );
private: private:
struct obstacleVisitor; struct OBSTACLE_VISITOR;
typedef boost::unordered_multimap<PNS_JOINT::HashTag, PNS_JOINT> JointMap; typedef boost::unordered_multimap<PNS_JOINT::HASH_TAG, PNS_JOINT> JOINT_MAP;
typedef JointMap::value_type TagJointPair; typedef JOINT_MAP::value_type TagJointPair;
/// nodes are not copyable /// nodes are not copyable
PNS_NODE ( const PNS_NODE& b ); PNS_NODE( const PNS_NODE& aB );
PNS_NODE& operator= ( const PNS_NODE& b ); PNS_NODE& operator=( const PNS_NODE& aB );
///> tries to find matching joint and creates a new one if not found ///> tries to find matching joint and creates a new one if not found
PNS_JOINT& touchJoint( const VECTOR2I& aPos, PNS_JOINT& touchJoint( const VECTOR2I& aPos,
const PNS_LAYERSET& aLayers, const PNS_LAYERSET& aLayers,
int aNet ); 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, void linkJoint( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers,
int aNet, PNS_ITEM* aWhere ); int aNet, PNS_ITEM* aWhere );
...@@ -372,26 +365,26 @@ private: ...@@ -372,26 +365,26 @@ private:
return m_parent == NULL; 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. ///> from the root branch.
bool overrides( PNS_ITEM* aItem ) const bool overrides( PNS_ITEM* aItem ) const
{ {
return m_override.find( aItem ) != m_override.end(); return m_override.find( aItem ) != m_override.end();
} }
PNS_SEGMENT *findRedundantSegment ( PNS_SEGMENT *aSeg ); PNS_SEGMENT *findRedundantSegment ( PNS_SEGMENT* aSeg );
///> scans the joint map, forming a line starting from segment (current). ///> scans the joint map, forming a line starting from segment (current).
void followLine ( PNS_SEGMENT* current, void followLine( PNS_SEGMENT* aCurrent,
bool scanDirection, bool aScanDirection,
int& pos, int& aPos,
int limit, int aLimit,
VECTOR2I* corners, VECTOR2I* aCorners,
PNS_SEGMENT** segments ); PNS_SEGMENT** aSegments );
///> hash table with the joints, linking the items. Joints are hashed by ///> hash table with the joints, linking the items. Joints are hashed by
///> their position, layer set and net. ///> their position, layer set and net.
JointMap m_joints; JOINT_MAP m_joints;
///> node this node was branched from ///> node this node was branched from
PNS_NODE* m_parent; PNS_NODE* m_parent;
......
...@@ -30,14 +30,11 @@ ...@@ -30,14 +30,11 @@
#include "pns_router.h" #include "pns_router.h"
/** /**
*
* Cost Estimator Methods * Cost Estimator Methods
*
*/ */
int PNS_COST_ESTIMATOR::CornerCost( const SEG& aA, const SEG& aB )
int PNS_COST_ESTIMATOR::CornerCost( const SEG& a, const SEG& b )
{ {
DIRECTION_45 dir_a( a ), dir_b( b ); DIRECTION_45 dir_a( aA ), dir_b( aB );
switch( dir_a.Angle( dir_b ) ) switch( dir_a.Angle( dir_b ) )
{ {
...@@ -109,8 +106,8 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther, ...@@ -109,8 +106,8 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost ) if( aOther.m_cornerCost < m_cornerCost && aOther.m_lengthCost < m_lengthCost )
return true; return true;
else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance && aOther.m_lengthCost < else if( aOther.m_cornerCost < m_cornerCost * aCornerTollerance &&
m_lengthCost * aLengthTollerance ) aOther.m_lengthCost < m_lengthCost * aLengthTollerance )
return true; return true;
return false; return false;
...@@ -118,9 +115,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther, ...@@ -118,9 +115,7 @@ bool PNS_COST_ESTIMATOR::IsBetter( PNS_COST_ESTIMATOR& aOther,
/** /**
*
* Optimizer * Optimizer
*
**/ **/
PNS_OPTIMIZER::PNS_OPTIMIZER( PNS_NODE* aWorld ) : PNS_OPTIMIZER::PNS_OPTIMIZER( PNS_NODE* aWorld ) :
m_world( aWorld ), m_collisionKindMask( PNS_ITEM::ANY ), m_effortLevel( MERGE_SEGMENTS ) m_world( aWorld ), m_collisionKindMask( PNS_ITEM::ANY ), m_effortLevel( MERGE_SEGMENTS )
...@@ -135,14 +130,14 @@ PNS_OPTIMIZER::~PNS_OPTIMIZER() ...@@ -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_ourItem( aOurItem ),
m_collidingItem( NULL ), m_collidingItem( NULL ),
m_node( aNode ), m_node( aNode ),
m_mask( aMask ) m_mask( aMask )
{}; {}
bool operator()( PNS_ITEM* aOtherItem ) bool operator()( PNS_ITEM* aOtherItem )
{ {
...@@ -171,14 +166,14 @@ void PNS_OPTIMIZER::cacheAdd( PNS_ITEM* aItem, bool aIsStatic = false ) ...@@ -171,14 +166,14 @@ void PNS_OPTIMIZER::cacheAdd( PNS_ITEM* aItem, bool aIsStatic = false )
return; return;
m_cache.Add( aItem ); m_cache.Add( aItem );
m_cacheTags[aItem].hits = 1; m_cacheTags[aItem].m_hits = 1;
m_cacheTags[aItem].isStatic = aIsStatic; m_cacheTags[aItem].m_isStatic = aIsStatic;
} }
void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int aEndVertex ) 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 ) if( !segs )
return; return;
...@@ -198,7 +193,7 @@ void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int ...@@ -198,7 +193,7 @@ void PNS_OPTIMIZER::removeCachedSegments( PNS_LINE* aLine, int aStartVertex, int
void PNS_OPTIMIZER::CacheRemove( PNS_ITEM* aItem ) void PNS_OPTIMIZER::CacheRemove( PNS_ITEM* aItem )
{ {
if( aItem->Kind() == PNS_ITEM::LINE ) if( aItem->Kind() == PNS_ITEM::LINE )
removeCachedSegments( static_cast<PNS_LINE*> (aItem) ); removeCachedSegments( static_cast<PNS_LINE*>( aItem ) );
} }
...@@ -219,7 +214,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly ) ...@@ -219,7 +214,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
for( CachedItemTags::iterator i = m_cacheTags.begin(); i!= m_cacheTags.end(); ++i ) 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_cache.Remove( i->first );
m_cacheTags.erase( i->first ); m_cacheTags.erase( i->first );
...@@ -230,7 +225,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly ) ...@@ -230,7 +225,7 @@ void PNS_OPTIMIZER::ClearCache( bool aStaticOnly )
bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache ) 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 ); return m_world->CheckColliding( aItem );
...@@ -239,19 +234,19 @@ bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache ) ...@@ -239,19 +234,19 @@ bool PNS_OPTIMIZER::checkColliding( PNS_ITEM* aItem, bool aUpdateCache )
if( !v.m_collidingItem ) if( !v.m_collidingItem )
{ {
PNS_NODE::OptObstacle obs = m_world->CheckColliding( aItem ); PNS_NODE::OPT_OBSTACLE obs = m_world->CheckColliding( aItem );
if( obs ) if( obs )
{ {
if( aUpdateCache ) if( aUpdateCache )
cacheAdd( obs->item ); cacheAdd( obs->m_item );
return true; return true;
} }
} }
else else
{ {
m_cacheTags[v.m_collidingItem].hits++; m_cacheTags[v.m_collidingItem].m_hits++;
return true; return true;
} }
...@@ -430,7 +425,6 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, ...@@ -430,7 +425,6 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath ); int cost_orig = PNS_COST_ESTIMATOR::CornerCost( aCurrentPath );
if( aLine->SegmentCount() < 4 ) if( aLine->SegmentCount() < 4 )
return false; return false;
...@@ -442,7 +436,8 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, ...@@ -442,7 +436,8 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath,
const SEG s1 = aCurrentPath.CSegment( n ); const SEG s1 = aCurrentPath.CSegment( n );
const SEG s2 = aCurrentPath.CSegment( n + step ); 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]; int cost[2];
for( int i = 0; i < 2; i++ ) for( int i = 0; i < 2; i++ )
...@@ -485,10 +480,10 @@ bool PNS_OPTIMIZER::mergeStep( PNS_LINE* aLine, SHAPE_LINE_CHAIN& aCurrentPath, ...@@ -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 const SHAPE* aShape, bool aPermitDiagonal ) const
{ {
BreakoutList breakouts; BREAKOUT_LIST breakouts;
for( int angle = 0; angle < 360; angle += 45 ) for( int angle = 0; angle < 360; angle += 45 )
{ {
...@@ -505,12 +500,12 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::circleBreakouts( int aWidth, ...@@ -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* aShape, bool aPermitDiagonal ) const
{ {
const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>(aShape); const SHAPE_RECT* rect = static_cast<const SHAPE_RECT*>(aShape);
VECTOR2I s = rect->GetSize(), c = rect->GetPosition() + VECTOR2I( s.x / 2, s.y / 2 ); VECTOR2I s = rect->GetSize(), c = rect->GetPosition() + VECTOR2I( s.x / 2, s.y / 2 );
BreakoutList breakouts; BREAKOUT_LIST breakouts;
VECTOR2I d_offset; VECTOR2I d_offset;
...@@ -520,7 +515,6 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth, ...@@ -520,7 +515,6 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth,
VECTOR2I d_vert = VECTOR2I( 0, s.y / 2 + aWidth ); VECTOR2I d_vert = VECTOR2I( 0, s.y / 2 + aWidth );
VECTOR2I d_horiz = VECTOR2I( s.x / 2 + aWidth, 0 ); 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_horiz ) ); breakouts.push_back( SHAPE_LINE_CHAIN( c, c - d_horiz ) );
breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_vert ) ); breakouts.push_back( SHAPE_LINE_CHAIN( c, c + d_vert ) );
...@@ -560,7 +554,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::rectBreakouts( int aWidth, ...@@ -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 const PNS_ITEM* aItem, bool aPermitDiagonal ) const
{ {
switch( aItem->Kind() ) switch( aItem->Kind() )
...@@ -582,7 +576,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth, ...@@ -582,7 +576,7 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
case SH_SEGMENT: case SH_SEGMENT:
{ {
const SHAPE_SEGMENT *seg = static_cast<const SHAPE_SEGMENT*> (shape); const SHAPE_SEGMENT* seg = static_cast<const SHAPE_SEGMENT*> (shape);
const SHAPE_RECT rect = ApproximateSegmentAsRect ( *seg ); const SHAPE_RECT rect = ApproximateSegmentAsRect ( *seg );
return rectBreakouts( aWidth, &rect, aPermitDiagonal ); return rectBreakouts( aWidth, &rect, aPermitDiagonal );
} }
...@@ -599,20 +593,20 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth, ...@@ -599,20 +593,20 @@ PNS_OPTIMIZER::BreakoutList PNS_OPTIMIZER::computeBreakouts( int aWidth,
break; break;
} }
return BreakoutList(); return BREAKOUT_LIST();
} }
PNS_ITEM* PNS_OPTIMIZER::findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const PNS_ITEM* PNS_OPTIMIZER::findPadOrVia( int aLayer, int aNet, const VECTOR2I& aP ) const
{ {
PNS_JOINT *jt = m_world->FindJoint( aP, aLayer, aNet ); PNS_JOINT* jt = m_world->FindJoint( aP, aLayer, aNet );
if( !jt ) if( !jt )
return NULL; return NULL;
BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
{ {
if( item->OfKind (PNS_ITEM::VIA | PNS_ITEM::SOLID ) ) if( item->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID ) )
return item; return item;
} }
...@@ -632,7 +626,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, ...@@ -632,7 +626,7 @@ int PNS_OPTIMIZER::smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd,
typedef std::pair<int, SHAPE_LINE_CHAIN> RtVariant; typedef std::pair<int, SHAPE_LINE_CHAIN> RtVariant;
std::vector<RtVariant> variants; 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() ); SHAPE_LINE_CHAIN line = ( aEnd ? aLine->CLine().Reverse() : aLine->CLine() );
...@@ -742,6 +736,7 @@ bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine ) ...@@ -742,6 +736,7 @@ bool PNS_OPTIMIZER::runSmartPads( PNS_LINE* aLine )
vtx < 0 ? line.PointCount() - 1 : line.PointCount() - 1 - vtx ); vtx < 0 ? line.PointCount() - 1 : line.PointCount() - 1 - vtx );
aLine->Line().Simplify(); aLine->Line().Simplify();
return true; return true;
} }
...@@ -756,7 +751,7 @@ bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorl ...@@ -756,7 +751,7 @@ bool PNS_OPTIMIZER::Optimize( PNS_LINE* aLine, int aEffortLevel, PNS_NODE* aWorl
} }
bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine ) bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE* aLine )
{ {
if( aLine->PointCount() < 3 ) if( aLine->PointCount() < 3 )
return false; return false;
...@@ -769,40 +764,35 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine ) ...@@ -769,40 +764,35 @@ bool PNS_OPTIMIZER::fanoutCleanup( PNS_LINE * aLine )
int thr = aLine->Width() * 10; int thr = aLine->Width() * 10;
int len = aLine->CLine().Length(); int len = aLine->CLine().Length();
if( !startPad )
if(!startPad)
return false; return false;
bool startMatch = startPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
bool startMatch = startPad->OfKind(PNS_ITEM::VIA | PNS_ITEM::SOLID);
bool endMatch = false; bool endMatch = false;
if(endPad) if(endPad)
{ {
endMatch = endPad->OfKind(PNS_ITEM::VIA | PNS_ITEM::SOLID); endMatch = endPad->OfKind( PNS_ITEM::VIA | PNS_ITEM::SOLID );
} else { } else {
endMatch = aLine->EndsWithVia(); endMatch = aLine->EndsWithVia();
} }
if( startMatch && endMatch && len < thr )
if(startMatch && endMatch && len < thr)
{ {
for(int i = 0; i < 2; i++ ) for(int i = 0; i < 2; i++ )
{ {
SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace(p_start, p_end, i); SHAPE_LINE_CHAIN l2 = DIRECTION_45().BuildInitialTrace( p_start, p_end, i );
PNS_ROUTER::GetInstance()->DisplayDebugLine (l2, 4, 10000); PNS_ROUTER::GetInstance()->DisplayDebugLine( l2, 4, 10000 );
PNS_LINE repl; PNS_LINE repl;
repl = PNS_LINE (*aLine, l2 ); repl = PNS_LINE( *aLine, l2 );
if( !m_world->CheckColliding( &repl ) )
if (!m_world->CheckColliding(&repl))
{ {
aLine->SetShape(repl.CLine()); aLine->SetShape( repl.CLine() );
return true; return true;
} }
} }
} }
return false; return false;
} }
...@@ -38,23 +38,22 @@ class PNS_ROUTER; ...@@ -38,23 +38,22 @@ class PNS_ROUTER;
* *
* Calculates the cost of a given line, taking corner angles and total length into account. * Calculates the cost of a given line, taking corner angles and total length into account.
**/ **/
class PNS_COST_ESTIMATOR class PNS_COST_ESTIMATOR
{ {
public: public:
PNS_COST_ESTIMATOR() : PNS_COST_ESTIMATOR() :
m_lengthCost( 0 ), m_lengthCost( 0 ),
m_cornerCost( 0 ) m_cornerCost( 0 )
{}; {}
PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& b ) : PNS_COST_ESTIMATOR( const PNS_COST_ESTIMATOR& aB ) :
m_lengthCost( b.m_lengthCost ), m_lengthCost( aB.m_lengthCost ),
m_cornerCost( b.m_cornerCost ) m_cornerCost( aB.m_cornerCost )
{}; {}
~PNS_COST_ESTIMATOR() {}; ~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 SHAPE_LINE_CHAIN& aLine );
static int CornerCost( const PNS_LINE& aLine ); static int CornerCost( const PNS_LINE& aLine );
...@@ -84,7 +83,6 @@ private: ...@@ -84,7 +83,6 @@ private:
* the procedure as long as the total cost of the line keeps decreasing * 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). * - "Smart Pads" - that is, rerouting pad/via exits to make them look nice (SMART_PADS).
**/ **/
class PNS_OPTIMIZER class PNS_OPTIMIZER
{ {
public: public:
...@@ -122,14 +120,14 @@ public: ...@@ -122,14 +120,14 @@ public:
private: private:
static const int MaxCachedItems = 256; 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; int m_hits;
bool isStatic; bool m_isStatic;
}; };
bool mergeObtuse( PNS_LINE* aLine ); bool mergeObtuse( PNS_LINE* aLine );
...@@ -142,15 +140,13 @@ private: ...@@ -142,15 +140,13 @@ private:
bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true ); bool checkColliding( PNS_ITEM* aItem, bool aUpdateCache = true );
bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath ); bool checkColliding( PNS_LINE* aLine, const SHAPE_LINE_CHAIN& aOptPath );
void cacheAdd( PNS_ITEM* aItem, bool aIsStatic ); void cacheAdd( PNS_ITEM* aItem, bool aIsStatic );
void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 ); void removeCachedSegments( PNS_LINE* aLine, int aStartVertex = 0, int aEndVertex = -1 );
BreakoutList circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; BREAKOUT_LIST circleBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; BREAKOUT_LIST rectBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const; BREAKOUT_LIST ovalBreakouts( int aWidth, const SHAPE* aShape, bool aPermitDiagonal ) const;
BreakoutList computeBreakouts( int aWidth, const PNS_ITEM* aItem, BREAKOUT_LIST computeBreakouts( int aWidth, const PNS_ITEM* aItem, bool aPermitDiagonal ) const;
bool aPermitDiagonal ) const;
int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex ); int smartPadsSingle( PNS_LINE* aLine, PNS_ITEM* aPad, bool aEnd, int aEndVertex );
...@@ -158,7 +154,7 @@ private: ...@@ -158,7 +154,7 @@ private:
SHAPE_INDEX_LIST<PNS_ITEM*> m_cache; 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; CachedItemTags m_cacheTags;
PNS_NODE* m_world; PNS_NODE* m_world;
int m_collisionKindMask; int m_collisionKindMask;
......
...@@ -82,28 +82,28 @@ public: ...@@ -82,28 +82,28 @@ public:
m_defaultClearance = 254000; // aBoard->m_NetClasses.Find ("Default clearance")->GetClearance(); 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; 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(); 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 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 cl_b = ( net_b >= 0 ? m_clearanceCache[net_b] : m_defaultClearance );
int pad_a = localPadClearance( a ); int pad_a = localPadClearance( aA );
int pad_b = localPadClearance( b ); int pad_b = localPadClearance( aB );
cl_a = std::max(cl_a, pad_a); cl_a = std::max( cl_a, pad_a );
cl_b = std::max(cl_b, pad_b); cl_b = std::max( cl_b, pad_b );
return std::max( cl_a, cl_b ); return std::max( cl_a, cl_b );
} }
...@@ -113,9 +113,10 @@ private: ...@@ -113,9 +113,10 @@ private:
int m_defaultClearance; int m_defaultClearance;
}; };
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
{ {
PNS_LAYERSET layers ( 0, 15 ); PNS_LAYERSET layers( 0, 15 );
switch( aPad->GetAttribute() ) switch( aPad->GetAttribute() )
{ {
...@@ -131,7 +132,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) ...@@ -131,7 +132,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
for( i = FIRST_COPPER_LAYER; i <= LAST_COPPER_LAYER; i++ ) for( i = FIRST_COPPER_LAYER; i <= LAST_COPPER_LAYER; i++ )
{ {
if( lmsk & (1 << i) ) if( lmsk & ( 1 << i ) )
{ {
layers = PNS_LAYERSET( i ); layers = PNS_LAYERSET( i );
break; break;
...@@ -162,17 +163,16 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) ...@@ -162,17 +163,16 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
double orient = aPad->GetOrientation() / 10.0; double orient = aPad->GetOrientation() / 10.0;
bool nonOrtho = false; bool nonOrtho = false;
if( orient == 90.0 || orient == 270.0 ) if( orient == 90.0 || orient == 270.0 )
sz = VECTOR2I( sz.y, sz.x ); sz = VECTOR2I( sz.y, sz.x );
else if( orient != 0.0 && orient != 180.0 ) else if( orient != 0.0 && orient != 180.0 )
{ {
// rotated pads are replaced by for the moment by circles due to my laziness ;) // rotated pads are replaced by for the moment by circles due to my laziness ;)
solid->SetShape ( new SHAPE_CIRCLE (c, std::min(sz.x, sz.y) / 2 ) ); solid->SetShape( new SHAPE_CIRCLE( c, std::min( sz.x, sz.y ) / 2 ) );
nonOrtho = true; nonOrtho = true;
} }
if(!nonOrtho) if( !nonOrtho )
{ {
switch( aPad->GetShape() ) switch( aPad->GetShape() )
{ {
...@@ -183,15 +183,17 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) ...@@ -183,15 +183,17 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
case PAD_OVAL: case PAD_OVAL:
if( sz.x == sz.y ) if( sz.x == sz.y )
solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
else { else
{
VECTOR2I delta; VECTOR2I delta;
if (sz.x > sz.y) if( sz.x > sz.y )
delta = VECTOR2I((sz.x - sz.y) / 2, 0); delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
else else
delta = VECTOR2I(0, (sz.y - sz.x) / 2); 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 ); solid->SetShape( shape );
} }
break; break;
...@@ -203,6 +205,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) ...@@ -203,6 +205,7 @@ PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
default: default:
TRACEn( 0, "unsupported pad shape" ); TRACEn( 0, "unsupported pad shape" );
delete solid; delete solid;
return NULL; return NULL;
} }
} }
...@@ -250,7 +253,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp ) ...@@ -250,7 +253,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
LAYER_MSK mask = m_board->GetEnabledLayers() & m_board->GetVisibleLayers(); LAYER_MSK mask = m_board->GetEnabledLayers() & m_board->GetVisibleLayers();
LAYER_NUM l = m_currentLayer; LAYER_NUM l = m_currentLayer;
do { do
{
l += ( aUp ? 1 : -1 ); l += ( aUp ? 1 : -1 );
if( l > LAST_COPPER_LAYER ) if( l > LAST_COPPER_LAYER )
...@@ -261,7 +265,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp ) ...@@ -261,7 +265,8 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
if( mask & GetLayerMask( l ) ) if( mask & GetLayerMask( l ) )
return l; return l;
} while( l != m_currentLayer ); }
while( l != m_currentLayer );
return l; return l;
} }
...@@ -269,7 +274,6 @@ int PNS_ROUTER::NextCopperLayer( bool aUp ) ...@@ -269,7 +274,6 @@ int PNS_ROUTER::NextCopperLayer( bool aUp )
void PNS_ROUTER::SyncWorld() void PNS_ROUTER::SyncWorld()
{ {
if( !m_board ) if( !m_board )
{ {
TRACEn( 0, "No board attached, aborting sync." ); TRACEn( 0, "No board attached, aborting sync." );
...@@ -379,13 +383,6 @@ void PNS_ROUTER::ClearWorld() ...@@ -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 bool PNS_ROUTER::RoutingInProgress() const
{ {
return m_state != IDLE; return m_state != IDLE;
...@@ -405,31 +402,31 @@ const PNS_ITEMSET PNS_ROUTER::QueryHoverItems( const VECTOR2I& aP ) ...@@ -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; VECTOR2I anchor;
if( !item ) if( !aItem )
{ {
aSplitsSegment = false; aSplitsSegment = false;
return aP; return aP;
} }
switch( item->Kind() ) switch( aItem->Kind() )
{ {
case PNS_ITEM::SOLID: case PNS_ITEM::SOLID:
anchor = static_cast<PNS_SOLID*>(item)->Pos(); anchor = static_cast<PNS_SOLID*>( aItem )->Pos();
aSplitsSegment = false; aSplitsSegment = false;
break; break;
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
anchor = static_cast<PNS_VIA*>(item)->Pos(); anchor = static_cast<PNS_VIA*>( aItem )->Pos();
aSplitsSegment = false; aSplitsSegment = false;
break; break;
case PNS_ITEM::SEGMENT: 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(); const SEG& s = seg->Seg();
int w = seg->Width(); int w = seg->Width();
...@@ -455,16 +452,19 @@ const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplit ...@@ -455,16 +452,19 @@ const VECTOR2I PNS_ROUTER::SnapToItem( PNS_ITEM* item, VECTOR2I aP, bool& aSplit
return anchor; return anchor;
} }
bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
if(!aStartItem || aStartItem->OfKind(PNS_ITEM::SOLID)) if( !aStartItem || aStartItem->OfKind( PNS_ITEM::SOLID ) )
return false; return false;
m_dragger = new PNS_DRAGGER ( this ); m_dragger = new PNS_DRAGGER ( this );
m_dragger->SetWorld( m_world ); m_dragger->SetWorld( m_world );
if( m_dragger->Start ( aP, aStartItem ) ) if( m_dragger->Start ( aP, aStartItem ) )
m_state = DRAG_SEGMENT; m_state = DRAG_SEGMENT;
else { else
{
delete m_dragger; delete m_dragger;
m_state = IDLE; m_state = IDLE;
return false; return false;
...@@ -476,8 +476,6 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem ) ...@@ -476,8 +476,6 @@ bool PNS_ROUTER::StartDragging( const VECTOR2I& aP, PNS_ITEM* aStartItem )
bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem ) bool PNS_ROUTER::StartRouting( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{ {
m_state = ROUTE_TRACK; m_state = ROUTE_TRACK;
m_placer = new PNS_LINE_PLACER( this ); m_placer = new PNS_LINE_PLACER( this );
...@@ -518,11 +516,11 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance ...@@ -518,11 +516,11 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance
{ {
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_previewItems ); ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( aItem, m_previewItems );
if(aColor >= 0) if( aColor >= 0 )
pitem->SetColor ( KIGFX::COLOR4D ( aColor )); pitem->SetColor( KIGFX::COLOR4D ( aColor ) );
if(aClearance >= 0) if( aClearance >= 0 )
pitem->SetClearance ( aClearance ); pitem->SetClearance( aClearance );
m_previewItems->Add( pitem ); m_previewItems->Add( pitem );
...@@ -530,12 +528,14 @@ void PNS_ROUTER::DisplayItem( const PNS_ITEM* aItem, int aColor, int aClearance ...@@ -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 ); m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
} }
void PNS_ROUTER::DisplayItems( const PNS_ITEMSET& aItems ) void PNS_ROUTER::DisplayItems( const PNS_ITEMSET& aItems )
{ {
BOOST_FOREACH(const PNS_ITEM *item, aItems.CItems()) BOOST_FOREACH( const PNS_ITEM *item, aItems.CItems() )
DisplayItem(item); DisplayItem( item );
} }
void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth ) void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int aWidth )
{ {
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems ); 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 ...@@ -547,18 +547,17 @@ void PNS_ROUTER::DisplayDebugLine( const SHAPE_LINE_CHAIN& aLine, int aType, int
} }
void PNS_ROUTER::DisplayDebugPoint( const VECTOR2I aPos, int aType )
void PNS_ROUTER::DisplayDebugPoint( const VECTOR2I pos, int aType )
{ {
ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems ); ROUTER_PREVIEW_ITEM* pitem = new ROUTER_PREVIEW_ITEM( NULL, m_previewItems );
pitem->Point( pos, aType ); pitem->Point( aPos, aType );
m_previewItems->Add( pitem ); m_previewItems->Add( pitem );
pitem->ViewSetVisible( true ); pitem->ViewSetVisible( true );
m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE ); m_previewItems->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY | KIGFX::VIEW_ITEM::APPEARANCE );
} }
void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem ) void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
{ {
m_currentEnd = aP; m_currentEnd = aP;
...@@ -573,57 +572,62 @@ void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem ) ...@@ -573,57 +572,62 @@ void PNS_ROUTER::Move( const VECTOR2I& aP, PNS_ITEM* endItem )
case DRAG_SEGMENT: case DRAG_SEGMENT:
moveDragging (aP, endItem ); moveDragging (aP, endItem );
break; break;
default: default:
break; break;
} }
} }
void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* endItem )
void PNS_ROUTER::moveDragging( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
eraseView(); eraseView();
m_dragger->Drag( aP ); m_dragger->Drag( aP );
PNS_ITEMSET dragged = m_dragger->Traces(); PNS_ITEMSET dragged = m_dragger->Traces();
updateView ( m_dragger->CurrentNode ( ), dragged ); updateView ( m_dragger->CurrentNode(), dragged );
} }
void PNS_ROUTER::markViolations( PNS_NODE *aNode, PNS_ITEMSET& aCurrent, PNS_NODE::ItemVector& aRemoved )
{
BOOST_FOREACH(PNS_ITEM *item, aCurrent.Items()) 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 ); aNode->QueryColliding( item, obstacles, PNS_ITEM::ANY );
if ( item->OfKind(PNS_ITEM::LINE ) ) if( item->OfKind( PNS_ITEM::LINE ) )
{ {
PNS_LINE *l = static_cast<PNS_LINE *> (item); PNS_LINE *l = static_cast<PNS_LINE*>( item );
if (l->EndsWithVia())
if( l->EndsWithVia() )
{ {
PNS_VIA v ( l->Via() ); PNS_VIA v ( l->Via() );
aNode->QueryColliding(&v , obstacles, PNS_ITEM::ANY ); aNode->QueryColliding( &v, obstacles, PNS_ITEM::ANY );
} }
} }
BOOST_FOREACH(PNS_OBSTACLE& obs, obstacles) BOOST_FOREACH( PNS_OBSTACLE& obs, obstacles )
{ {
int clearance = aNode->GetClearance( item, obs.item ); int clearance = aNode->GetClearance( item, obs.m_item );
std::auto_ptr<PNS_ITEM> tmp ( obs.item->Clone() ); std::auto_ptr<PNS_ITEM> tmp( obs.m_item->Clone() );
tmp->Mark ( MK_VIOLATION ); tmp->Mark( MK_VIOLATION );
DisplayItem( tmp.get(), -1, clearance ); 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 )
void PNS_ROUTER::updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent )
{ {
PNS_NODE::ItemVector removed, added; PNS_NODE::ITEM_VECTOR removed, added;
PNS_NODE::Obstacles obstacles; PNS_NODE::OBSTACLES obstacles;
if(!aNode) if( !aNode )
return; return;
if( Settings().Mode() == RM_MarkObstacles ) if( Settings().Mode() == RM_MarkObstacles )
...@@ -661,15 +665,14 @@ void PNS_ROUTER::ApplySettings() ...@@ -661,15 +665,14 @@ void PNS_ROUTER::ApplySettings()
m_placer->Move( m_currentEnd, m_currentEndItem ); m_placer->Move( m_currentEnd, m_currentEndItem );
movePlacing( 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(); eraseView();
m_placer->Move( aP, endItem ); m_placer->Move( aP, aEndItem );
PNS_LINE current = m_placer->Trace(); PNS_LINE current = m_placer->Trace();
DisplayItem( &current ); DisplayItem( &current );
...@@ -681,9 +684,10 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* endItem ) ...@@ -681,9 +684,10 @@ void PNS_ROUTER::movePlacing( const VECTOR2I& aP, PNS_ITEM* endItem )
updateView ( m_placer->CurrentNode ( true ), tmp ); updateView ( m_placer->CurrentNode ( true ), tmp );
} }
void PNS_ROUTER::CommitRouting( PNS_NODE* aNode ) void PNS_ROUTER::CommitRouting( PNS_NODE* aNode )
{ {
PNS_NODE::ItemVector removed, added; PNS_NODE::ITEM_VECTOR removed, added;
aNode->GetUpdatedItems( removed, added ); aNode->GetUpdatedItems( removed, added );
...@@ -770,34 +774,33 @@ PNS_VIA* PNS_ROUTER::checkLoneVia( PNS_JOINT* aJoint ) const ...@@ -770,34 +774,33 @@ PNS_VIA* PNS_ROUTER::checkLoneVia( PNS_JOINT* aJoint ) const
return NULL; return NULL;
} }
bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem ) bool PNS_ROUTER::FixRoute( const VECTOR2I& aP, PNS_ITEM* aEndItem )
{ {
bool rv = false; bool rv = false;
switch(m_state) switch( m_state )
{ {
case ROUTE_TRACK: case ROUTE_TRACK:
rv = m_placer->FixRoute (aP, aEndItem); rv = m_placer->FixRoute( aP, aEndItem );
m_placingVia = false; m_placingVia = false;
break; break;
case DRAG_SEGMENT: case DRAG_SEGMENT:
rv = m_dragger->FixRoute (); rv = m_dragger->FixRoute();
break; break;
default: default:
break; break;
} }
if( rv )
if(rv)
StopRouting(); StopRouting();
return rv; return rv;
} }
void PNS_ROUTER::StopRouting() void PNS_ROUTER::StopRouting()
{ {
// Update the ratsnest with new changes // Update the ratsnest with new changes
...@@ -806,10 +809,10 @@ void PNS_ROUTER::StopRouting() ...@@ -806,10 +809,10 @@ void PNS_ROUTER::StopRouting()
if( !RoutingInProgress() ) if( !RoutingInProgress() )
return; return;
if(m_placer) if( m_placer )
delete m_placer; delete m_placer;
if(m_dragger) if( m_dragger )
delete m_dragger; delete m_dragger;
m_placer = NULL; m_placer = NULL;
...@@ -825,7 +828,7 @@ void PNS_ROUTER::StopRouting() ...@@ -825,7 +828,7 @@ void PNS_ROUTER::StopRouting()
void PNS_ROUTER::FlipPosture() void PNS_ROUTER::FlipPosture()
{ {
if(m_state == ROUTE_TRACK) if( m_state == ROUTE_TRACK )
{ {
m_placer->FlipPosture(); m_placer->FlipPosture();
m_placer->Move ( m_currentEnd, m_currentEndItem ); m_placer->Move ( m_currentEnd, m_currentEndItem );
...@@ -833,22 +836,23 @@ void PNS_ROUTER::FlipPosture() ...@@ -833,22 +836,23 @@ void PNS_ROUTER::FlipPosture()
} }
void PNS_ROUTER::SwitchLayer( int layer ) void PNS_ROUTER::SwitchLayer( int aLayer )
{ {
switch( m_state ) switch( m_state )
{ {
case IDLE: case IDLE:
m_currentLayer = layer; m_currentLayer = aLayer;
break; break;
case ROUTE_TRACK: case ROUTE_TRACK:
if( m_startsOnVia ) if( m_startsOnVia )
{ {
m_currentLayer = layer; m_currentLayer = aLayer;
//m_placer->StartPlacement( m_currentStart, m_currentNet, m_currentWidth, //m_placer->StartPlacement( m_currentStart, m_currentNet, m_currentWidth,
// m_currentLayer ); // m_currentLayer );
} }
break; break;
default: default:
break; break;
} }
...@@ -864,32 +868,38 @@ void PNS_ROUTER::ToggleViaPlacement() ...@@ -864,32 +868,38 @@ void PNS_ROUTER::ToggleViaPlacement()
} }
} }
int PNS_ROUTER::GetCurrentNet() const int PNS_ROUTER::GetCurrentNet() const
{ {
switch(m_state) switch( m_state )
{ {
case ROUTE_TRACK: case ROUTE_TRACK:
return m_placer->CurrentNet(); return m_placer->CurrentNet();
default: default:
return m_currentNet; return m_currentNet;
} }
} }
int PNS_ROUTER::GetCurrentLayer() const int PNS_ROUTER::GetCurrentLayer() const
{ {
switch(m_state) switch( m_state )
{ {
case ROUTE_TRACK: case ROUTE_TRACK:
return m_placer->CurrentLayer(); return m_placer->CurrentLayer();
default: default:
return m_currentLayer; return m_currentLayer;
} }
} }
void PNS_ROUTER::DumpLog() void PNS_ROUTER::DumpLog()
{ {
PNS_LOGGER *logger = NULL; PNS_LOGGER* logger = NULL;
switch(m_state)
switch( m_state )
{ {
case DRAG_SEGMENT: case DRAG_SEGMENT:
logger = m_dragger->Logger(); logger = m_dragger->Logger();
...@@ -899,6 +909,6 @@ void PNS_ROUTER::DumpLog() ...@@ -899,6 +909,6 @@ void PNS_ROUTER::DumpLog()
break; break;
} }
if(logger) if( logger )
logger->Save ( "/tmp/shove.log" ); logger->Save ( "/tmp/shove.log" );
} }
...@@ -51,9 +51,10 @@ class PNS_CLEARANCE_FUNC; ...@@ -51,9 +51,10 @@ class PNS_CLEARANCE_FUNC;
class PNS_SHOVE; class PNS_SHOVE;
class PNS_DRAGGER; class PNS_DRAGGER;
namespace KIGFX { namespace KIGFX
class VIEW; {
class VIEW_GROUP; class VIEW;
class VIEW_GROUP;
}; };
...@@ -62,7 +63,6 @@ class VIEW_GROUP; ...@@ -62,7 +63,6 @@ class VIEW_GROUP;
* *
* Main router class. * Main router class.
*/ */
class PNS_ROUTER class PNS_ROUTER
{ {
private: private:
...@@ -94,7 +94,7 @@ public: ...@@ -94,7 +94,7 @@ public:
const VECTOR2I CurrentEnd() const; 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 PNS_NODE* GetWorld() const
{ {
...@@ -114,8 +114,8 @@ public: ...@@ -114,8 +114,8 @@ public:
void ToggleViaPlacement(); void ToggleViaPlacement();
int GetCurrentLayer() const;// { return m_currentLayer; } int GetCurrentLayer() const;
int GetCurrentNet() const;// { return m_currentNet; } int GetCurrentNet() const;
void DumpLog(); void DumpLog();
...@@ -134,14 +134,19 @@ public: ...@@ -134,14 +134,19 @@ public:
// typedef boost::optional<hoverItem> optHoverItem; // typedef boost::optional<hoverItem> optHoverItem;
const PNS_ITEMSET QueryHoverItems( const VECTOR2I& aP ); 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 ); bool StartDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
void SetIterLimit( int aX ) { m_iterLimit = aX; } void SetIterLimit( int aX ) { m_iterLimit = aX; }
int GetIterLimit() const { return m_iterLimit; }; 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; } bool GetShowIntermediateSteps() const { return m_showInterSteps; }
int GetShapshotIter() const { return m_snapshotIter; } int GetShapshotIter() const { return m_snapshotIter; }
...@@ -168,7 +173,7 @@ public: ...@@ -168,7 +173,7 @@ public:
/** /**
* Applies stored settings. * Applies stored settings.
* \see Settings() * @see Settings()
*/ */
void ApplySettings(); void ApplySettings();
...@@ -183,30 +188,29 @@ public: ...@@ -183,30 +188,29 @@ public:
ApplySettings(); ApplySettings();
} }
void EnableSnapping ( bool aEnable ) void EnableSnapping( bool aEnable )
{ {
m_snappingEnabled = aEnable; m_snappingEnabled = aEnable;
} }
bool SnappingEnabled () const bool SnappingEnabled() const
{ {
return m_snappingEnabled; return m_snappingEnabled;
} }
private: private:
void movePlacing ( const VECTOR2I& aP, PNS_ITEM* aItem ); void movePlacing( const VECTOR2I& aP, PNS_ITEM* aItem );
void moveDragging ( const VECTOR2I& aP, PNS_ITEM* aItem ); void moveDragging( const VECTOR2I& aP, PNS_ITEM* aItem );
void eraseView(); void eraseView();
void updateView( PNS_NODE *aNode, PNS_ITEMSET &aCurrent ); //PNS_LINE *aCurrent = NULL ); void updateView( PNS_NODE* aNode, PNS_ITEMSET& aCurrent );
void clearViewFlags(); void clearViewFlags();
// optHoverItem queryHoverItemEx(const VECTOR2I& aP); // optHoverItem queryHoverItemEx(const VECTOR2I& aP);
PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const; // std::vector<PNS_ITEM*> aItems) const; PNS_ITEM* pickSingleItem( PNS_ITEMSET& aItems ) const;
void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP ); // optHoverItem& aItem); void splitAdjacentSegments( PNS_NODE* aNode, PNS_ITEM* aSeg, const VECTOR2I& aP );
PNS_VIA* checkLoneVia( PNS_JOINT* aJoint ) const; PNS_VIA* checkLoneVia( PNS_JOINT* aJoint ) const;
PNS_ITEM* syncPad( D_PAD* aPad ); PNS_ITEM* syncPad( D_PAD* aPad );
...@@ -219,7 +223,7 @@ private: ...@@ -219,7 +223,7 @@ private:
void highlightCurrent( bool enabled ); 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_currentLayer;
int m_currentNet; int m_currentNet;
...@@ -241,8 +245,7 @@ private: ...@@ -241,8 +245,7 @@ private:
KIGFX::VIEW* m_view; KIGFX::VIEW* m_view;
KIGFX::VIEW_GROUP* m_previewItems; KIGFX::VIEW_GROUP* m_previewItems;
PNS_ITEM* m_currentEndItem;
PNS_ITEM *m_currentEndItem;
VECTOR2I m_currentEnd; VECTOR2I m_currentEnd;
VECTOR2I m_currentStart; VECTOR2I m_currentStart;
...@@ -252,7 +255,7 @@ private: ...@@ -252,7 +255,7 @@ private:
bool m_snappingEnabled; bool m_snappingEnabled;
bool m_violation; bool m_violation;
// optHoverItem m_startItem, m_endItem; // optHoverItem m_startItem, m_endItem;
PNS_ROUTING_SETTINGS m_settings; PNS_ROUTING_SETTINGS m_settings;
PNS_CLEARANCE_FUNC* m_clearanceFunc; PNS_CLEARANCE_FUNC* m_clearanceFunc;
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS() PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
{ {
m_routingMode = RM_Walkaround; m_routingMode = RM_Walkaround;
m_optimizerEffort = OE_Full; m_optimizerEffort = OE_FULL;
m_removeLoops = true; m_removeLoops = true;
m_smartPads = true; m_smartPads = true;
m_shoveVias = true; m_shoveVias = true;
...@@ -38,11 +38,13 @@ PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS() ...@@ -38,11 +38,13 @@ PNS_ROUTING_SETTINGS::PNS_ROUTING_SETTINGS()
m_canViolateDRC = false; m_canViolateDRC = false;
} }
TIME_LIMIT PNS_ROUTING_SETTINGS::ShoveTimeLimit() const TIME_LIMIT PNS_ROUTING_SETTINGS::ShoveTimeLimit() const
{ {
return TIME_LIMIT ( m_shoveTimeLimit ); return TIME_LIMIT ( m_shoveTimeLimit );
} }
int PNS_ROUTING_SETTINGS::ShoveIterationLimit() const int PNS_ROUTING_SETTINGS::ShoveIterationLimit() const
{ {
return m_shoveIterationLimit; return m_shoveIterationLimit;
......
...@@ -36,9 +36,9 @@ enum PNS_MODE ...@@ -36,9 +36,9 @@ enum PNS_MODE
///> Optimization effort ///> Optimization effort
enum PNS_OPTIMIZATION_EFFORT enum PNS_OPTIMIZATION_EFFORT
{ {
OE_Low = 0, OE_LOW = 0,
OE_Medium = 1, OE_MEDIUM = 1,
OE_Full = 2 OE_FULL = 2
}; };
/** /**
...@@ -91,7 +91,7 @@ public: ...@@ -91,7 +91,7 @@ public:
///> Returns true if follow mouse mode is active (permanently on for the moment). ///> Returns true if follow mouse mode is active (permanently on for the moment).
bool FollowMouse() const bool FollowMouse() const
{ {
return m_followMouse && !(Mode() == RM_MarkObstacles); return m_followMouse && !( Mode() == RM_MarkObstacles );
} }
///> Returns true if smoothing segments durign dragging is enabled. ///> Returns true if smoothing segments durign dragging is enabled.
...@@ -120,10 +120,10 @@ public: ...@@ -120,10 +120,10 @@ public:
const DIRECTION_45 InitialDirection() const const DIRECTION_45 InitialDirection() const
{ {
if(m_startDiagonal) if( m_startDiagonal )
return DIRECTION_45 (DIRECTION_45::NE); return DIRECTION_45( DIRECTION_45::NE );
else else
return DIRECTION_45 (DIRECTION_45::N); return DIRECTION_45( DIRECTION_45::N );
} }
int ShoveIterationLimit() const; int ShoveIterationLimit() const;
...@@ -133,7 +133,6 @@ public: ...@@ -133,7 +133,6 @@ public:
TIME_LIMIT WalkaroundTimeLimit() const; TIME_LIMIT WalkaroundTimeLimit() const;
private: private:
bool m_shoveVias; bool m_shoveVias;
bool m_startDiagonal; bool m_startDiagonal;
bool m_removeLoops; bool m_removeLoops;
......
...@@ -37,17 +37,17 @@ class PNS_SEGMENT : public PNS_ITEM ...@@ -37,17 +37,17 @@ class PNS_SEGMENT : public PNS_ITEM
public: public:
PNS_SEGMENT() : PNS_SEGMENT() :
PNS_ITEM( SEGMENT ) PNS_ITEM( SEGMENT )
{}; {}
PNS_SEGMENT( const SEG& aSeg, int aNet ) : PNS_SEGMENT( const SEG& aSeg, int aNet ) :
PNS_ITEM( SEGMENT ), m_seg(aSeg, 0) PNS_ITEM( SEGMENT ), m_seg( aSeg, 0 )
{ {
m_net = aNet; m_net = aNet;
}; }
PNS_SEGMENT( const PNS_LINE& aParentLine, const SEG& aSeg ) : PNS_SEGMENT( const PNS_LINE& aParentLine, const SEG& aSeg ) :
PNS_ITEM( SEGMENT ), PNS_ITEM( SEGMENT ),
m_seg(aSeg, aParentLine.Width()) m_seg( aSeg, aParentLine.Width() )
{ {
m_net = aParentLine.Net(); m_net = aParentLine.Net();
m_layers = aParentLine.Layers(); m_layers = aParentLine.Layers();
...@@ -55,7 +55,6 @@ public: ...@@ -55,7 +55,6 @@ public:
m_rank = aParentLine.Rank(); m_rank = aParentLine.Rank();
}; };
PNS_SEGMENT* Clone( ) const; PNS_SEGMENT* Clone( ) const;
const SHAPE* Shape() const const SHAPE* Shape() const
...@@ -101,14 +100,14 @@ public: ...@@ -101,14 +100,14 @@ public:
void SwapEnds() void SwapEnds()
{ {
SEG tmp = m_seg.GetSeg(); SEG tmp = m_seg.GetSeg();
m_seg.SetSeg( SEG (tmp.B , tmp.A )); m_seg.SetSeg( SEG (tmp.B , tmp.A ) );
} }
const SHAPE_LINE_CHAIN Hull( int aClearance, int aWalkaroundThickness ) const; const SHAPE_LINE_CHAIN Hull( int aClearance, int aWalkaroundThickness ) const;
virtual VECTOR2I Anchor(int n) const virtual VECTOR2I Anchor(int n) const
{ {
if(n == 0) if( n == 0 )
return m_seg.GetSeg().A; return m_seg.GetSeg().A;
else else
return m_seg.GetSeg().B; return m_seg.GetSeg().B;
......
...@@ -41,63 +41,70 @@ ...@@ -41,63 +41,70 @@
#include <profile.h> #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( aOld->CPoint( 0 ) == aNew->CPoint( 0 ) );
assert (l_old->CPoint(-1) == l_new->CPoint(-1 )); assert( aOld->CPoint( -1 ) == aNew->CPoint( -1 ) );
} }
PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER *aRouter ) :
PNS_SHOVE::PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
PNS_ALGO_BASE ( aRouter ) PNS_ALGO_BASE ( aRouter )
{ {
m_root = aWorld; m_root = aWorld;
}; }
PNS_SHOVE::~PNS_SHOVE() PNS_SHOVE::~PNS_SHOVE()
{ {
// free all the stuff we've created during routing/dragging operation. // free all the stuff we've created during routing/dragging operation.
BOOST_FOREACH(PNS_ITEM *item, m_gcItems) BOOST_FOREACH( PNS_ITEM *item, m_gcItems )
delete item; delete item;
} }
// garbage-collected line assembling // garbage-collected line assembling
PNS_LINE* PNS_SHOVE::assembleLine ( const PNS_SEGMENT *aSeg, int *aIndex ) PNS_LINE* PNS_SHOVE::assembleLine( const PNS_SEGMENT *aSeg, int *aIndex )
{ {
PNS_LINE *l = m_currentNode->AssembleLine( const_cast<PNS_SEGMENT* > (aSeg), aIndex); PNS_LINE* l = m_currentNode->AssembleLine( const_cast<PNS_SEGMENT*>( aSeg ), aIndex );
m_gcItems.push_back(l); m_gcItems.push_back(l);
return l; return l;
} }
// garbage-collected line cloning // garbage-collected line cloning
PNS_LINE *PNS_SHOVE::cloneLine ( const PNS_LINE *aLine ) PNS_LINE *PNS_SHOVE::cloneLine ( const PNS_LINE *aLine )
{ {
PNS_LINE *l = aLine->Clone(); PNS_LINE *l = aLine->Clone();
m_gcItems.push_back(l); m_gcItems.push_back( l );
return l; return l;
} }
// A dumb function that checks if the shoved line is shoved the right way, e.g. // 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 // 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: // mathematical concept of orientation of an open curve, so we use some primitive heuristics:
// if the shoved line wraps around the start of the "pusher", it's likely shoved in wrong direction. // if the shoved line wraps around the start of the "pusher", it's likely shoved in wrong direction.
bool PNS_SHOVE::checkBumpDirection ( PNS_LINE *aCurrent, PNS_LINE *aShoved ) const bool PNS_SHOVE::checkBumpDirection( PNS_LINE *aCurrent, PNS_LINE *aShoved ) const
{ {
const SEG ss = aCurrent->CSegment(0); const SEG ss = aCurrent->CSegment( 0 );
int dist = m_currentNode->GetClearance(aCurrent, aShoved) + PNS_HULL_MARGIN; int dist = m_currentNode->GetClearance( aCurrent, aShoved ) + PNS_HULL_MARGIN;
dist += aCurrent->Width() / 2; dist += aCurrent->Width() / 2;
dist += aShoved->Width() / 2; dist += aShoved->Width() / 2;
const VECTOR2I ps = ss.A - (ss.B - ss.A).Resize(dist); const VECTOR2I ps = ss.A - ( ss.B - ss.A ).Resize( dist );
return !aShoved->CLine().PointOnEdge(ps); 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 ); int clearance = m_currentNode->GetClearance( aCurrent, aObstacle );
const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() ); const SHAPE_LINE_CHAIN hull = aCurrent->Via().Hull( clearance, aObstacle->Width() );
...@@ -108,11 +115,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI ...@@ -108,11 +115,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw; const SHAPE_LINE_CHAIN& shortest = path_ccw.Length() < path_cw.Length() ? path_ccw : path_cw;
if(shortest.PointCount() < 2) if( shortest.PointCount() < 2 )
return SH_INCOMPLETE; return SH_INCOMPLETE;
if(aObstacle->CPoint(-1) != shortest.CPoint(-1))
if( aObstacle->CPoint( -1 ) != shortest.CPoint( -1 ) )
return SH_INCOMPLETE; return SH_INCOMPLETE;
if(aObstacle->CPoint(0) != shortest.CPoint(0))
if( aObstacle->CPoint( 0 ) != shortest.CPoint( 0 ) )
return SH_INCOMPLETE; return SH_INCOMPLETE;
aShoved->SetShape( shortest ); aShoved->SetShape( shortest );
...@@ -123,33 +132,35 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI ...@@ -123,33 +132,35 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::walkaroundLoneVia ( PNS_LINE *aCurrent, PNS_LI
return SH_OK; 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(); const SHAPE_LINE_CHAIN& obs = aObstacle->CLine();
bool failingDirCheck = false; bool failingDirCheck = false;
int attempt; int attempt;
for(attempt = 0; attempt < 4; attempt++) for( attempt = 0; attempt < 4; attempt++ )
{ {
bool invertTraversal = (attempt >= 2); bool invertTraversal = ( attempt >= 2 );
bool clockwise = attempt % 2; bool clockwise = attempt % 2;
int vFirst = -1, vLast = -1; int vFirst = -1, vLast = -1;
SHAPE_LINE_CHAIN path; SHAPE_LINE_CHAIN path;
PNS_LINE l ( *aObstacle ); 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 ); l.Walkaround( hull, path, clockwise );
path.Simplify(); path.Simplify();
l.SetShape( path ); l.SetShape( path );
} }
for(int i = 0; i < std::min ( path.PointCount(), obs.PointCount() ); i++) for( int i = 0; i < std::min ( path.PointCount(), obs.PointCount() ); i++ )
{ {
if(path.CPoint(i) != obs.CPoint(i)) if( path.CPoint( i ) != obs.CPoint( i ) )
{ {
vFirst = i; vFirst = i;
break; break;
...@@ -157,36 +168,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE ...@@ -157,36 +168,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
} }
int k = obs.PointCount() - 1; int k = obs.PointCount() - 1;
for(int i = path.PointCount() - 1; i >= 0 && k >= 0; i--, k--) for( int i = path.PointCount() - 1; i >= 0 && k >= 0; i--, k-- )
{ {
if(path.CPoint(i) != obs.CPoint(k)) if( path.CPoint( i ) != obs.CPoint( k ) )
{ {
vLast = i; vLast = i;
break; break;
} }
} }
if( ( vFirst < 0 || vLast < 0) && !path.CompareGeometry( aObstacle->CLine() )) if( ( vFirst < 0 || vLast < 0 ) && !path.CompareGeometry( aObstacle->CLine() ) )
{ {
TRACE( 100, "attempt %d fail vfirst-last", attempt ); TRACE( 100, "attempt %d fail vfirst-last", attempt );
continue; continue;
} }
if(path.CPoint(-1) != obs.CPoint(-1) || path.CPoint(0) != obs.CPoint(0)) if( path.CPoint( -1 ) != obs.CPoint( -1 ) || path.CPoint( 0 ) != obs.CPoint( 0 ) )
{ {
TRACE(100, "attempt %d fail vend-start\n", attempt); TRACE( 100, "attempt %d fail vend-start\n", attempt );
continue; continue;
} }
if(!checkBumpDirection(aCurrent, &l)) if( !checkBumpDirection( aCurrent, &l ) )
{ {
TRACE( 100, "attempt %d fail direction-check", attempt ); TRACE( 100, "attempt %d fail direction-check", attempt );
failingDirCheck = true; failingDirCheck = true;
aShoved->SetShape(l.CLine()); aShoved->SetShape( l.CLine() );
continue; continue;
} }
if(path.SelfIntersecting()) if( path.SelfIntersecting() )
{ {
TRACE( 100, "attempt %d fail self-intersect", attempt ); TRACE( 100, "attempt %d fail self-intersect", attempt );
continue; continue;
...@@ -194,13 +206,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE ...@@ -194,13 +206,13 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
bool colliding = m_currentNode->CheckColliding( &l, aCurrent ); bool colliding = m_currentNode->CheckColliding( &l, aCurrent );
if( (aCurrent->Marker() & MK_HEAD) && !colliding) if( ( aCurrent->Marker() & MK_HEAD ) && !colliding )
{ {
PNS_JOINT *jtStart = m_currentNode->FindJoint ( aCurrent->CPoint(0), aCurrent ); PNS_JOINT* jtStart = m_currentNode->FindJoint( aCurrent->CPoint( 0 ), aCurrent );
BOOST_FOREACH( PNS_ITEM *item, jtStart->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
{ {
if(m_currentNode->CheckColliding(item, &l)) if( m_currentNode->CheckColliding( item, &l ) )
colliding = true; colliding = true;
} }
} }
...@@ -219,7 +231,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE ...@@ -219,7 +231,9 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processHullSet ( PNS_LINE *aCurrent, PNS_LINE
return failingDirCheck ? SH_OK : SH_INCOMPLETE; 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(); aShoved->ClearSegmentLinks();
...@@ -227,73 +241,75 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI ...@@ -227,73 +241,75 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::processSingleLine ( PNS_LINE *aCurrent, PNS_LI
if( aObstacle->LinkedSegments() ) if( aObstacle->LinkedSegments() )
{ {
BOOST_FOREACH( PNS_SEGMENT *s, *aObstacle->LinkedSegments() ) BOOST_FOREACH( PNS_SEGMENT* s, *aObstacle->LinkedSegments() )
if(s->Marker() & MK_HEAD)
if( s->Marker() & MK_HEAD )
{ {
obstacleIsHead = true; obstacleIsHead = true;
break; break;
} }
} }
ShoveStatus rv; SHOVE_STATUS rv;
bool viaOnEnd = aCurrent->EndsWithVia(); bool viaOnEnd = aCurrent->EndsWithVia();
if( viaOnEnd && ( !aCurrent->LayersOverlap( aObstacle ) || aCurrent->SegmentCount() == 0 ) ) if( viaOnEnd && ( !aCurrent->LayersOverlap( aObstacle ) || aCurrent->SegmentCount() == 0 ) )
{ {
rv = walkaroundLoneVia( aCurrent, aObstacle, aShoved ); rv = walkaroundLoneVia( aCurrent, aObstacle, aShoved );
} else { }
else
{
int w = aObstacle->Width(); int w = aObstacle->Width();
int n_segs = aCurrent->SegmentCount(); int n_segs = aCurrent->SegmentCount();
int clearance = m_currentNode->GetClearance( aCurrent, aObstacle ); int clearance = m_currentNode->GetClearance( aCurrent, aObstacle );
HullSet hulls; HULL_SET hulls;
hulls.reserve( n_segs + 1 ); hulls.reserve( n_segs + 1 );
for( int i = 0; i < n_segs; i++ ) for( int i = 0; i < n_segs; i++ )
{ {
PNS_SEGMENT seg ( *aCurrent, aCurrent->CSegment(i) ); PNS_SEGMENT seg( *aCurrent, aCurrent->CSegment( i ) );
hulls.push_back ( seg.Hull( clearance, w ) ); hulls.push_back( seg.Hull( clearance, w ) );
} }
if( viaOnEnd ) if( viaOnEnd )
hulls.push_back ( aCurrent->Via().Hull( clearance, w ) ); hulls.push_back ( aCurrent->Via().Hull( clearance, w ) );
rv = processHullSet ( aCurrent, aObstacle, aShoved, hulls); rv = processHullSet ( aCurrent, aObstacle, aShoved, hulls );
} }
if(obstacleIsHead) if( obstacleIsHead )
aShoved->Mark( aShoved->Marker() | MK_HEAD ); aShoved->Mark( aShoved->Marker() | MK_HEAD );
return rv; return rv;
} }
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; int segIndex;
PNS_LINE *obstacleLine = assembleLine (aObstacleSeg, &segIndex); PNS_LINE* obstacleLine = assembleLine( aObstacleSeg, &segIndex );
PNS_LINE *shovedLine = cloneLine ( obstacleLine ); PNS_LINE* shovedLine = cloneLine( obstacleLine );
ShoveStatus rv = processSingleLine ( aCurrent, obstacleLine, shovedLine ); SHOVE_STATUS rv = processSingleLine( aCurrent, obstacleLine, shovedLine );
assert ( obstacleLine->LayersOverlap (shovedLine) ); assert ( obstacleLine->LayersOverlap( shovedLine ) );
if( rv == SH_OK )
if(rv == SH_OK)
{ {
if ( shovedLine->Marker() & MK_HEAD ) if ( shovedLine->Marker() & MK_HEAD )
m_newHead = *shovedLine; m_newHead = *shovedLine;
sanityCheck(obstacleLine, shovedLine); sanityCheck( obstacleLine, shovedLine );
m_currentNode->Replace (obstacleLine, shovedLine); m_currentNode->Replace( obstacleLine, shovedLine );
sanityCheck(obstacleLine, shovedLine); sanityCheck( obstacleLine, shovedLine );
int rank = aCurrent->Rank(); int rank = aCurrent->Rank();
shovedLine->SetRank ( rank - 1 ); shovedLine->SetRank( rank - 1 );
pushLine(shovedLine); pushLine( shovedLine );
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -307,64 +323,64 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSegment( PNS_LINE *aCurrent, PNS_SE ...@@ -307,64 +323,64 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSegment( PNS_LINE *aCurrent, PNS_SE
return rv; 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); PNS_LINE* shovedLine = cloneLine( aObstacle );
ShoveStatus rv = processSingleLine ( aCurrent, aObstacle, shovedLine ); SHOVE_STATUS rv = processSingleLine( aCurrent, aObstacle, shovedLine );
if(rv == SH_OK) if( rv == SH_OK )
{ {
if ( shovedLine->Marker() & MK_HEAD ) if ( shovedLine->Marker() & MK_HEAD )
m_newHead = *shovedLine; m_newHead = *shovedLine;
sanityCheck(aObstacle,shovedLine); sanityCheck( aObstacle, shovedLine );
m_currentNode->Replace( aObstacle, shovedLine ); m_currentNode->Replace( aObstacle, shovedLine );
sanityCheck(aObstacle,shovedLine); sanityCheck( aObstacle, shovedLine );
int rank = aObstacle->Rank(); int rank = aObstacle->Rank();
shovedLine->SetRank ( rank ); shovedLine->SetRank ( rank );
pushLine(shovedLine); pushLine( shovedLine );
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("on-colliding-line", m_iter); m_logger.NewGroup( "on-colliding-line", m_iter );
m_logger.Log ( aObstacle, 0, "obstacle-line"); m_logger.Log( aObstacle, 0, "obstacle-line" );
m_logger.Log ( aCurrent, 1, "current-line"); m_logger.Log( aCurrent, 1, "current-line" );
m_logger.Log ( shovedLine, 3, "shoved-line"); m_logger.Log( shovedLine, 3, "shoved-line" );
#endif #endif
} }
return rv; 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_WALKAROUND walkaround( m_currentNode, Router() );
PNS_LINE* walkaroundLine = cloneLine(aCurrent); PNS_LINE* walkaroundLine = cloneLine( aCurrent );
if(aCurrent->EndsWithVia()) if( aCurrent->EndsWithVia() )
{ {
PNS_VIA vh = aCurrent->Via(); PNS_VIA vh = aCurrent->Via();
PNS_VIA *via = NULL; PNS_VIA* via = NULL;
PNS_JOINT *jtStart = m_currentNode->FindJoint ( vh.Pos(), aCurrent ); PNS_JOINT* jtStart = m_currentNode->FindJoint ( vh.Pos(), aCurrent );
if(!jtStart) if( !jtStart )
return SH_INCOMPLETE; return SH_INCOMPLETE;
BOOST_FOREACH( PNS_ITEM *item, jtStart->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jtStart->LinkList() )
if(item->OfKind(PNS_ITEM::VIA)) {
if( item->OfKind( PNS_ITEM::VIA ) )
{ {
via = (PNS_VIA *) item; via = (PNS_VIA*) item;
break; break;
} }
}
if( via && m_currentNode->CheckColliding(via, aObstacleSolid) ) if( via && m_currentNode->CheckColliding( via, aObstacleSolid ) )
return onCollidingVia ( aObstacleSolid, via ); return onCollidingVia( aObstacleSolid, via );
} }
walkaround.SetSolidsOnly( true ); walkaround.SetSolidsOnly( true );
...@@ -373,45 +389,45 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI ...@@ -373,45 +389,45 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLI
int currentRank = aCurrent->Rank(); int currentRank = aCurrent->Rank();
int nextRank; int nextRank;
if (!Settings().JumpOverObstacles() ) if( !Settings().JumpOverObstacles() )
{ {
nextRank = currentRank + 10000; nextRank = currentRank + 10000;
walkaround.SetSingleDirection( false ); walkaround.SetSingleDirection( false );
} else { }
else
{
nextRank = currentRank - 1; nextRank = currentRank - 1;
walkaround.SetSingleDirection( true ); walkaround.SetSingleDirection( true );
} }
if( walkaround.Route( *aCurrent, *walkaroundLine, false ) != PNS_WALKAROUND::DONE )
if (walkaround.Route( *aCurrent, *walkaroundLine, false ) != PNS_WALKAROUND::DONE )
return SH_INCOMPLETE; return SH_INCOMPLETE;
walkaroundLine->ClearSegmentLinks(); walkaroundLine->ClearSegmentLinks();
walkaroundLine->Unmark(); walkaroundLine->Unmark();
walkaroundLine->Line().Simplify(); walkaroundLine->Line().Simplify();
if(walkaroundLine->HasLoops()) if( walkaroundLine->HasLoops() )
return SH_INCOMPLETE; return SH_INCOMPLETE;
if (aCurrent->Marker() & MK_HEAD) if( aCurrent->Marker() & MK_HEAD )
{ {
walkaroundLine->Mark(MK_HEAD); walkaroundLine->Mark( MK_HEAD );
m_newHead = *walkaroundLine; m_newHead = *walkaroundLine;
} }
m_currentNode->Replace( aCurrent, walkaroundLine ); m_currentNode->Replace( aCurrent, walkaroundLine );
walkaroundLine->SetRank ( nextRank ); walkaroundLine->SetRank ( nextRank );
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("on-colliding-solid", m_iter); m_logger.NewGroup( "on-colliding-solid", m_iter );
m_logger.Log ( aObstacleSolid, 0, "obstacle-solid"); m_logger.Log( aObstacleSolid, 0, "obstacle-solid" );
m_logger.Log ( aCurrent, 1, "current-line"); m_logger.Log( aCurrent, 1, "current-line" );
m_logger.Log ( walkaroundLine, 3, "walk-line"); m_logger.Log( walkaroundLine, 3, "walk-line" );
#endif #endif
popLine(); popLine();
pushLine(walkaroundLine); pushLine( walkaroundLine );
return SH_OK; return SH_OK;
} }
...@@ -423,13 +439,13 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet ) ...@@ -423,13 +439,13 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
while( !m_nodeStack.empty() ) 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; rv = true;
delete spTag.node; delete spTag.m_node;
m_nodeStack.pop_back(); m_nodeStack.pop_back();
} }
else else
...@@ -440,98 +456,99 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet ) ...@@ -440,98 +456,99 @@ bool PNS_SHOVE::reduceSpringback( const PNS_ITEMSET& aHeadSet )
} }
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems,
bool PNS_SHOVE::pushSpringback( PNS_NODE* aNode, const PNS_ITEMSET& aHeadItems, const PNS_COST_ESTIMATOR& aCost ) const PNS_COST_ESTIMATOR& aCost )
{ {
SpringbackTag st; SPRINGBACK_TAG st;
st.node = aNode; st.m_node = aNode;
st.cost = aCost; st.m_cost = aCost;
st.headItems = aHeadItems; st.m_headItems = aHeadItems;
m_nodeStack.push_back( st ); m_nodeStack.push_back( st );
return true; 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 )
{ {
LINE_PAIR_VEC draggedLines;
LinePairVec draggedLines;
VECTOR2I p0 ( aVia->Pos() ); VECTOR2I p0 ( aVia->Pos() );
PNS_JOINT *jt = m_currentNode->FindJoint( p0, 1, aVia->Net() ); PNS_JOINT* jt = m_currentNode->FindJoint( p0, 1, aVia->Net() );
PNS_VIA *pushedVia = aVia -> Clone(); PNS_VIA* pushedVia = aVia -> Clone();
pushedVia->SetPos( p0 + aForce ); pushedVia->SetPos( p0 + aForce );
pushedVia->Mark( aVia->Marker() ) ; pushedVia->Mark( aVia->Marker() );
if(aVia->Marker() & MK_HEAD) if( aVia->Marker() & MK_HEAD )
{ {
m_draggedVia = pushedVia; m_draggedVia = pushedVia;
} }
if(!jt) if( !jt )
{ {
TRACEn(1, "weird, can't find the center-of-via joint\n"); TRACEn( 1, "weird, can't find the center-of-via joint\n" );
return SH_INCOMPLETE; return SH_INCOMPLETE;
} }
BOOST_FOREACH(PNS_ITEM *item, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
{ {
if(item->OfKind( PNS_ITEM::SEGMENT )) if( item->OfKind( PNS_ITEM::SEGMENT ) )
{ {
PNS_SEGMENT *seg = (PNS_SEGMENT *) item; PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
LinePair lp; LINE_PAIR lp;
int segIndex; int segIndex;
lp.first = assembleLine(seg, &segIndex); lp.first = assembleLine( seg, &segIndex );
assert(segIndex == 0 || (segIndex == (lp.first->SegmentCount() - 1) )); assert( segIndex == 0 || ( segIndex == ( lp.first->SegmentCount() - 1 ) ) );
if(segIndex == 0) if( segIndex == 0 )
lp.first->Reverse(); lp.first->Reverse();
lp.second = cloneLine( lp.first ); lp.second = cloneLine( lp.first );
lp.second->ClearSegmentLinks(); lp.second->ClearSegmentLinks();
lp.second->DragCorner( p0 + aForce, lp.second->CLine().Find( p0 )); lp.second->DragCorner( p0 + aForce, lp.second->CLine().Find( p0 ) );
lp.second->AppendVia ( *pushedVia ); lp.second->AppendVia ( *pushedVia );
draggedLines.push_back(lp); draggedLines.push_back( lp );
} }
} }
m_currentNode->Remove( aVia ); m_currentNode->Remove( aVia );
m_currentNode->Add ( pushedVia ); m_currentNode->Add ( pushedVia );
if(aVia->BelongsTo(m_currentNode)) if( aVia->BelongsTo( m_currentNode ) )
delete aVia; delete aVia;
pushedVia -> SetRank (aCurrentRank - 1); pushedVia->SetRank( aCurrentRank - 1 );
#ifdef DEBUG #ifdef DEBUG
m_logger.Log ( aVia, 0, "obstacle-via"); m_logger.Log ( aVia, 0, "obstacle-via");
m_logger.Log ( pushedVia, 1, "pushed-via"); m_logger.Log ( pushedVia, 1, "pushed-via");
#endif #endif
BOOST_FOREACH( LinePair lp, draggedLines ) BOOST_FOREACH( LINE_PAIR lp, draggedLines )
{ {
if(lp.first->Marker() & MK_HEAD) if( lp.first->Marker() & MK_HEAD )
{ {
lp.second->Mark ( MK_HEAD ); lp.second->Mark( MK_HEAD );
m_newHead = *lp.second; m_newHead = *lp.second;
} }
unwindStack(lp.first); unwindStack(lp.first);
if(lp.second->SegmentCount()) if( lp.second->SegmentCount() )
{ {
m_currentNode->Replace ( lp.first, lp.second ); m_currentNode->Replace( lp.first, lp.second );
lp.second->SetRank( aCurrentRank - 1); lp.second->SetRank( aCurrentRank - 1 );
pushLine(lp.second); pushLine( lp.second );
} else }
m_currentNode->Remove(lp.first); else
m_currentNode->Remove( lp.first );
#ifdef DEBUG #ifdef DEBUG
m_logger.Log ( lp.first, 2, "fan-pre"); m_logger.Log( lp.first, 2, "fan-pre" );
m_logger.Log ( lp.second, 3, "fan-post"); m_logger.Log( lp.second, 3, "fan-post" );
#endif #endif
} }
...@@ -539,108 +556,112 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::pushVia ( PNS_VIA *aVia, const VECTOR2I& aForc ...@@ -539,108 +556,112 @@ 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 ) ; int clearance = m_currentNode->GetClearance( aCurrent, aObstacleVia ) ;
LinePairVec draggedLines; LINE_PAIR_VEC draggedLines;
VECTOR2I p0 ( aObstacleVia->Pos() ); VECTOR2I p0( aObstacleVia->Pos() );
bool colLine = false, colVia = false; bool colLine = false, colVia = false;
PNS_LINE *currentLine = NULL; PNS_LINE *currentLine = NULL;
VECTOR2I mtvLine, mtvVia, mtv, mtvSolid; VECTOR2I mtvLine, mtvVia, mtv, mtvSolid;
int rank = -1; int rank = -1;
if( aCurrent->OfKind (PNS_ITEM::LINE)) if( aCurrent->OfKind( PNS_ITEM::LINE ) )
{ {
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("push-via-by-line", m_iter); m_logger.NewGroup( "push-via-by-line", m_iter );
m_logger.Log(aCurrent, 4, "current"); m_logger.Log( aCurrent, 4, "current" );
#endif #endif
currentLine = (PNS_LINE*) aCurrent; 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()) 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) if( !colLine && !colVia )
return SH_OK; return SH_OK;
if(colLine && colVia) if( colLine && colVia )
mtv = mtvVia.EuclideanNorm() > mtvLine.EuclideanNorm() ? mtvVia : mtvLine; mtv = mtvVia.EuclideanNorm() > mtvLine.EuclideanNorm() ? mtvVia : mtvLine;
else if (colLine) else if( colLine )
mtv = mtvLine; mtv = mtvLine;
else else
mtv = mtvVia; mtv = mtvVia;
rank = currentLine->Rank(); rank = currentLine->Rank();
} }
else if (aCurrent->OfKind(PNS_ITEM::SOLID)) 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; mtv = mtvSolid;
rank = aCurrent->Rank() + 10000; rank = aCurrent->Rank() + 10000;
} }
return pushVia ( aObstacleVia, mtv, rank ); 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; std::vector<PNS_LINE*> steps;
int n = 0; int n = 0;
PNS_LINE *cur = cloneLine( aCurrent ); PNS_LINE* cur = cloneLine( aCurrent );
cur->ClearSegmentLinks(); cur->ClearSegmentLinks();
PNS_JOINT *jt = m_currentNode->FindJoint ( aObstacleVia->Pos(), aObstacleVia ); PNS_JOINT* jt = m_currentNode->FindJoint( aObstacleVia->Pos(), aObstacleVia );
PNS_LINE *shoved = cloneLine( aCurrent ); PNS_LINE* shoved = cloneLine( aCurrent );
shoved->ClearSegmentLinks(); shoved->ClearSegmentLinks();
cur->RemoveVia(); cur->RemoveVia();
unwindStack(aCurrent); unwindStack(aCurrent);
BOOST_FOREACH( PNS_ITEM *item, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
{ {
if( item->OfKind( PNS_ITEM::SEGMENT ) && item->LayersOverlap( aCurrent ) )
if (item->OfKind(PNS_ITEM::SEGMENT) && item->LayersOverlap (aCurrent) )
{ {
PNS_SEGMENT *seg = (PNS_SEGMENT *) item; PNS_SEGMENT* seg = (PNS_SEGMENT*) item;
PNS_LINE *head = assembleLine( seg ); PNS_LINE* head = assembleLine( seg );
head->AppendVia( *aObstacleVia ); head->AppendVia( *aObstacleVia );
ShoveStatus st = processSingleLine ( head, cur, shoved ); SHOVE_STATUS st = processSingleLine ( head, cur, shoved );
if( st != SH_OK ) if( st != SH_OK )
{ {
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("on-reverse-via-fail-shove", m_iter); m_logger.NewGroup( "on-reverse-via-fail-shove", m_iter );
m_logger.Log ( aObstacleVia, 0, "the-via"); m_logger.Log( aObstacleVia, 0, "the-via" );
m_logger.Log ( aCurrent, 1, "current-line"); m_logger.Log( aCurrent, 1, "current-line" );
m_logger.Log ( shoved, 3, "shoved-line"); m_logger.Log( shoved, 3, "shoved-line" );
#endif #endif
return st; return st;
} }
cur->SetShape ( shoved->CLine() );
cur->SetShape( shoved->CLine() );
n++; n++;
} }
} }
if(!n) if( !n )
{ {
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("on-reverse-via-fail-lonevia", m_iter); m_logger.NewGroup( "on-reverse-via-fail-lonevia", m_iter );
m_logger.Log ( aObstacleVia, 0, "the-via"); m_logger.Log( aObstacleVia, 0, "the-via" );
m_logger.Log ( aCurrent, 1, "current-line"); m_logger.Log( aCurrent, 1, "current-line" );
#endif #endif
PNS_LINE head(*aCurrent); PNS_LINE head( *aCurrent );
head.Line().Clear(); head.Line().Clear();
head.AppendVia( *aObstacleVia ); head.AppendVia( *aObstacleVia );
head.ClearSegmentLinks(); head.ClearSegmentLinks();
ShoveStatus st = processSingleLine ( &head, aCurrent, shoved ); SHOVE_STATUS st = processSingleLine( &head, aCurrent, shoved );
if( st != SH_OK ) if( st != SH_OK )
return st; return st;
...@@ -648,96 +669,103 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS ...@@ -648,96 +669,103 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::onReverseCollidingVia (PNS_LINE *aCurrent, PNS
cur->SetShape ( shoved->CLine() ); cur->SetShape ( shoved->CLine() );
} }
if(aCurrent->EndsWithVia()) if( aCurrent->EndsWithVia() )
shoved->AppendVia( aCurrent->Via( )); shoved->AppendVia( aCurrent->Via() );
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup ("on-reverse-via", m_iter); m_logger.NewGroup( "on-reverse-via", m_iter );
m_logger.Log ( aObstacleVia, 0, "the-via"); m_logger.Log( aObstacleVia, 0, "the-via" );
m_logger.Log ( aCurrent, 1, "current-line"); m_logger.Log( aCurrent, 1, "current-line" );
m_logger.Log ( shoved, 3, "shoved-line"); m_logger.Log( shoved, 3, "shoved-line" );
#endif #endif
int currentRank = aCurrent->Rank(); int currentRank = aCurrent->Rank();
m_currentNode->Replace ( aCurrent, shoved ); m_currentNode->Replace ( aCurrent, shoved );
pushLine(shoved); pushLine( shoved );
shoved->SetRank( currentRank ); shoved->SetRank( currentRank );
return SH_OK; return SH_OK;
} }
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(); ) 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 ); i = m_lineStack.erase( i );
else else
i++; i++;
} }
for (std::vector<PNS_LINE *>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); ) for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
{ {
if( (*i)->ContainsSegment ( seg ) ) if( (*i)->ContainsSegment( aSeg ) )
i = m_optimizerQueue.erase( i ); i = m_optimizerQueue.erase( i );
else else
i++; i++;
} }
} }
void PNS_SHOVE::unwindStack ( PNS_ITEM *item )
void PNS_SHOVE::unwindStack( PNS_ITEM* aItem )
{ {
if (item->OfKind(PNS_ITEM::SEGMENT)) if( aItem->OfKind( PNS_ITEM::SEGMENT ) )
unwindStack(static_cast<PNS_SEGMENT *>(item)); unwindStack( static_cast<PNS_SEGMENT*>( aItem ) );
else if (item->OfKind(PNS_ITEM::LINE)) { else if( aItem->OfKind( PNS_ITEM::LINE ) )
PNS_LINE *l = static_cast<PNS_LINE *>( item ); {
PNS_LINE* l = static_cast<PNS_LINE*>( aItem );
if (!l->LinkedSegments()) if ( !l->LinkedSegments() )
return; return;
BOOST_FOREACH(PNS_SEGMENT *seg, *l->LinkedSegments() ) BOOST_FOREACH( PNS_SEGMENT* seg, *l->LinkedSegments() )
unwindStack(seg); unwindStack( seg );
} }
} }
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); assert( false );
m_lineStack.push_back(l); m_lineStack.push_back( aL );
m_optimizerQueue.push_back(l); m_optimizerQueue.push_back( aL );
} }
void PNS_SHOVE::popLine( ) void PNS_SHOVE::popLine( )
{ {
PNS_LINE *l = m_lineStack.back(); PNS_LINE* l = m_lineStack.back();
for (std::vector<PNS_LINE *>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); ) for( std::vector<PNS_LINE*>::iterator i = m_optimizerQueue.begin(); i != m_optimizerQueue.end(); )
{ {
if( (*i) == l ) if( ( *i ) == l )
{ {
i = m_optimizerQueue.erase( i ); i = m_optimizerQueue.erase( i );
} else }
else
i++; i++;
} }
m_lineStack.pop_back(); 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_LINE* currentLine = m_lineStack.back();
PNS_NODE::OptObstacle nearest; PNS_NODE::OPT_OBSTACLE nearest;
ShoveStatus st; SHOVE_STATUS st;
PNS_ITEM::PnsKind search_order[] = { PNS_ITEM::SOLID, PNS_ITEM::VIA, PNS_ITEM::SEGMENT }; PNS_ITEM::PnsKind search_order[] = { PNS_ITEM::SOLID, PNS_ITEM::VIA, PNS_ITEM::SEGMENT };
for(int i = 0; i < 3; i++) for( int i = 0; i < 3; i++ )
{ {
nearest = m_currentNode->NearestObstacle( currentLine, search_order[i] ); nearest = m_currentNode->NearestObstacle( currentLine, search_order[i] );
if(nearest)
if( nearest )
break; break;
} }
...@@ -747,23 +775,25 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter) ...@@ -747,23 +775,25 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
return SH_OK; return SH_OK;
} }
PNS_ITEM *ni = nearest->item; PNS_ITEM* ni = nearest->m_item;
unwindStack(ni); unwindStack( ni );
if( !ni->OfKind(PNS_ITEM::SOLID) && ni->Rank() >= 0 && ni->Rank() > currentLine->Rank() ) if( !ni->OfKind( PNS_ITEM::SOLID ) && ni->Rank() >= 0 && ni->Rank() > currentLine->Rank() )
{ {
switch( ni->Kind() ) switch( ni->Kind() )
{ {
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
{ {
PNS_VIA *revVia = (PNS_VIA *) ni; PNS_VIA* revVia = (PNS_VIA*) ni;
TRACE( 2, "iter %d: reverse-collide-via", aIter ); TRACE( 2, "iter %d: reverse-collide-via", aIter );
if (currentLine->EndsWithVia() && m_currentNode->CheckColliding(&currentLine->Via(), revVia)) if( currentLine->EndsWithVia() && m_currentNode->CheckColliding( &currentLine->Via(), revVia ) )
{ {
st = SH_INCOMPLETE; st = SH_INCOMPLETE;
} else { }
else
{
st = onReverseCollidingVia ( currentLine, revVia ); st = onReverseCollidingVia ( currentLine, revVia );
} }
...@@ -772,35 +802,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter) ...@@ -772,35 +802,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
{ {
PNS_SEGMENT *seg = (PNS_SEGMENT* ) ni; PNS_SEGMENT* seg = (PNS_SEGMENT*) ni;
TRACE( 2, "iter %d: reverse-collide-segment ", aIter ); TRACE( 2, "iter %d: reverse-collide-segment ", aIter );
PNS_LINE *revLine = assembleLine ( seg ); PNS_LINE* revLine = assembleLine( seg );
popLine(); popLine();
st = onCollidingLine( revLine, currentLine ); st = onCollidingLine( revLine, currentLine );
pushLine(revLine); pushLine( revLine );
break; break;
} }
default: default:
assert(false); assert( false );
} }
} else { // "forward" collisoins }
else
{ // "forward" collisoins
switch( ni->Kind() ) switch( ni->Kind() )
{ {
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
TRACE( 2, "iter %d: collide-segment ", aIter ); TRACE( 2, "iter %d: collide-segment ", aIter );
st = onCollidingSegment( currentLine, (PNS_SEGMENT* ) ni ); st = onCollidingSegment( currentLine, (PNS_SEGMENT*) ni );
break; break;
case PNS_ITEM::VIA: case PNS_ITEM::VIA:
TRACE( 2, "iter %d: shove-via ", aIter ); TRACE( 2, "iter %d: shove-via ", aIter );
st = onCollidingVia ( currentLine, (PNS_VIA *) ni ); st = onCollidingVia( currentLine, (PNS_VIA*) ni );
break; break;
case PNS_ITEM::SOLID: case PNS_ITEM::SOLID:
TRACE( 2, "iter %d: walk-solid ", aIter ); TRACE( 2, "iter %d: walk-solid ", aIter );
st = onCollidingSolid ( currentLine, (PNS_SOLID *) ni ); st = onCollidingSolid( currentLine, (PNS_SOLID*) ni );
break; break;
default: default:
...@@ -811,9 +843,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter) ...@@ -811,9 +843,10 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveIteration(int aIter)
return st; 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() % TRACE( 1, "ShoveStart [root: %d jts, current: %d jts]", m_root->JointCount() %
m_currentNode->JointCount() ); m_currentNode->JointCount() );
...@@ -827,7 +860,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop() ...@@ -827,7 +860,7 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop()
while( !m_lineStack.empty() ) while( !m_lineStack.empty() )
{ {
st = shoveIteration(m_iter); st = shoveIteration( m_iter );
m_iter++; m_iter++;
...@@ -842,37 +875,37 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::shoveMainLoop() ...@@ -842,37 +875,37 @@ 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... // empty head? nothing to shove...
if( ! aCurrentHead.SegmentCount() ) if( !aCurrentHead.SegmentCount() )
return SH_INCOMPLETE; return SH_INCOMPLETE;
PNS_LINE* head = cloneLine ( &aCurrentHead ); PNS_LINE* head = cloneLine( &aCurrentHead );
head->ClearSegmentLinks(); head->ClearSegmentLinks();
m_lineStack.clear(); m_lineStack.clear();
m_optimizerQueue.clear(); m_optimizerQueue.clear();
m_newHead = OptLine(); m_newHead = OPT_LINE();
m_logger.Clear(); m_logger.Clear();
PNS_ITEMSET headSet ( cloneLine( &aCurrentHead ) ); PNS_ITEMSET headSet( cloneLine( &aCurrentHead ) );
reduceSpringback( headSet ); 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 = parent->Branch();
m_currentNode->ClearRanks(); m_currentNode->ClearRanks();
m_currentNode->Add( head ); m_currentNode->Add( head );
head->Mark ( MK_HEAD ); head->Mark( MK_HEAD );
head->SetRank ( 100000 ); head->SetRank( 100000 );
m_logger.NewGroup ("initial", 0); m_logger.NewGroup( "initial", 0 );
m_logger.Log ( head, 0, "head"); m_logger.Log( head, 0, "head" );
PNS_VIA* headVia = NULL; PNS_VIA* headVia = NULL;
...@@ -881,24 +914,24 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead ) ...@@ -881,24 +914,24 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
headVia = head->Via().Clone(); headVia = head->Via().Clone();
m_currentNode->Add( headVia ); m_currentNode->Add( headVia );
headVia->Mark( MK_HEAD ); headVia->Mark( MK_HEAD );
headVia->SetRank ( 100000 ); headVia->SetRank( 100000 );
m_logger.Log ( headVia, 0, "head-via"); m_logger.Log( headVia, 0, "head-via" );
} }
pushLine (head); pushLine( head );
st = shoveMainLoop(); st = shoveMainLoop();
runOptimizer ( m_currentNode, head ); runOptimizer( m_currentNode, head );
if( m_newHead && st == SH_OK ) if( m_newHead && st == SH_OK )
{ {
st = SH_HEAD_MODIFIED; st = SH_HEAD_MODIFIED;
Router()->DisplayDebugLine ( m_newHead->CLine(), 3, 20000 ); Router()->DisplayDebugLine( m_newHead->CLine(), 3, 20000 );
} }
m_currentNode->RemoveByMarker ( MK_HEAD ); 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 ) if( st == SH_OK || st == SH_HEAD_MODIFIED )
{ {
...@@ -909,34 +942,34 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead ) ...@@ -909,34 +942,34 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveLines( const PNS_LINE& aCurrentHead )
delete m_currentNode; delete m_currentNode;
m_currentNode = parent; m_currentNode = parent;
m_newHead = OptLine(); m_newHead = OPT_LINE();
} }
return st; 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_lineStack.clear();
m_optimizerQueue.clear(); m_optimizerQueue.clear();
m_newHead = OptLine(); m_newHead = OPT_LINE();
m_draggedVia = NULL; m_draggedVia = NULL;
//reduceSpringback( aCurrentHead ); //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 = parent->Branch();
m_currentNode->ClearRanks(); m_currentNode->ClearRanks();
aVia->Mark( MK_HEAD ); aVia->Mark( MK_HEAD );
st = pushVia( aVia, ( aWhere - aVia->Pos() ), 0 );
st = pushVia ( aVia, (aWhere - aVia->Pos()), 0 );
st = shoveMainLoop(); st = shoveMainLoop();
runOptimizer ( m_currentNode, NULL ); runOptimizer( m_currentNode, NULL );
if( st == SH_OK || st == SH_HEAD_MODIFIED ) if( st == SH_OK || st == SH_HEAD_MODIFIED )
{ {
...@@ -948,64 +981,69 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR ...@@ -948,64 +981,69 @@ PNS_SHOVE::ShoveStatus PNS_SHOVE::ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR
m_currentNode = parent; m_currentNode = parent;
} }
if(aNewVia) if( aNewVia )
*aNewVia = m_draggedVia; *aNewVia = m_draggedVia;
return st; 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; int optFlags = 0, n_passes = 0, extend = 0;
PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort(); PNS_OPTIMIZATION_EFFORT effort = Settings().OptimizerEffort();
switch( effort )
switch(effort)
{ {
case OE_Low: case OE_LOW:
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE; optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
n_passes = 1; n_passes = 1;
extend = 0; extend = 0;
break; break;
case OE_Medium:
case OE_MEDIUM:
optFlags = PNS_OPTIMIZER::MERGE_OBTUSE; optFlags = PNS_OPTIMIZER::MERGE_OBTUSE;
n_passes = 2; n_passes = 2;
extend = 1; extend = 1;
break; break;
case OE_Full:
case OE_FULL:
optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS; optFlags = PNS_OPTIMIZER::MERGE_SEGMENTS;
n_passes = 2; n_passes = 2;
break; break;
default: default:
break; break;
} }
if(Settings().SmartPads()) if( Settings().SmartPads() )
optFlags |= PNS_OPTIMIZER::SMART_PADS ; optFlags |= PNS_OPTIMIZER::SMART_PADS ;
optimizer.SetEffortLevel( optFlags ); optimizer.SetEffortLevel( optFlags );
optimizer.SetCollisionMask( PNS_ITEM::ANY ); optimizer.SetCollisionMask( PNS_ITEM::ANY );
for(int pass = 0; pass < n_passes; pass ++) for( int pass = 0; pass < n_passes; pass++ )
{ {
std::reverse ( m_optimizerQueue.begin(), m_optimizerQueue.end() ); 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; PNS_LINE* line = *i;
if( ! (line -> Marker() & MK_HEAD ) ) if( !( line -> Marker() & MK_HEAD ) )
{ {
if(effort == OE_Medium || effort == OE_Low ) if( effort == OE_MEDIUM || effort == OE_LOW )
{ {
RANGE<int> r = findShovedVertexRange ( line ); RANGE<int> r = findShovedVertexRange( line );
if (r.Defined()) if( r.Defined() )
{ {
int start_v = std::max(0, r.MinV() - extend); int start_v = std::max( 0, r.MinV() - extend );
int end_v = std::min(line->PointCount() - 1 , r.MaxV() + extend ); int end_v = std::min( line->PointCount() - 1 , r.MaxV() + extend );
line->ClipVertexRange ( start_v, end_v ); line->ClipVertexRange( start_v, end_v );
} }
} }
...@@ -1013,9 +1051,9 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head ) ...@@ -1013,9 +1051,9 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head )
if( optimizer.Optimize( line, &optimized ) ) if( optimizer.Optimize( line, &optimized ) )
{ {
node->Remove( line ); aNode->Remove( line );
line->SetShape(optimized.CLine()); line->SetShape( optimized.CLine() );
node->Add( line ); aNode->Add( line );
} }
} }
} }
...@@ -1024,23 +1062,24 @@ void PNS_SHOVE::runOptimizer ( PNS_NODE *node, PNS_LINE *head ) ...@@ -1024,23 +1062,24 @@ 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; 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() ); PNS_JOINT* jt = m_root->FindJoint( s->Seg().A, s->Layer(), s->Net() );
bool found = false; bool found = false;
if(jt) if( jt )
{ {
BOOST_FOREACH( PNS_ITEM *item, jt->LinkList() ) BOOST_FOREACH( PNS_ITEM* item, jt->LinkList() )
{ {
if(item->OfKind(PNS_ITEM::SEGMENT)) if( item->OfKind( PNS_ITEM::SEGMENT ) )
{ {
PNS_SEGMENT *s_old = (PNS_SEGMENT *) item; PNS_SEGMENT* s_old = (PNS_SEGMENT*) item;
if( s_old->Net() == s->Net() && if( s_old->Net() == s->Net() &&
s_old->Layer() == s->Layer() && s_old->Layer() == s->Layer() &&
...@@ -1054,27 +1093,31 @@ const RANGE<int> PNS_SHOVE::findShovedVertexRange ( PNS_LINE *l ) ...@@ -1054,27 +1093,31 @@ const RANGE<int> PNS_SHOVE::findShovedVertexRange ( PNS_LINE *l )
} }
} }
if(!found) if( !found )
{ {
r.Grow(i); r.Grow( i );
r.Grow(i + 1); r.Grow( i + 1 );
} }
} }
return r; return r;
} }
PNS_NODE* PNS_SHOVE::CurrentNode() 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 const PNS_LINE PNS_SHOVE::NewHead() const
{ {
assert(m_newHead); assert( m_newHead );
return *m_newHead; return *m_newHead;
} }
void PNS_SHOVE::SetInitialLine ( PNS_LINE *aInitial ) void PNS_SHOVE::SetInitialLine( PNS_LINE* aInitial )
{ {
m_root = m_root->Branch(); m_root = m_root->Branch();
m_root->Remove ( aInitial ); m_root->Remove ( aInitial );
......
...@@ -44,7 +44,7 @@ class PNS_SHOVE : public PNS_ALGO_BASE ...@@ -44,7 +44,7 @@ class PNS_SHOVE : public PNS_ALGO_BASE
{ {
public: public:
enum ShoveStatus enum SHOVE_STATUS
{ {
SH_OK = 0, SH_OK = 0,
SH_NULL, SH_NULL,
...@@ -52,72 +52,74 @@ public: ...@@ -52,72 +52,74 @@ public:
SH_HEAD_MODIFIED SH_HEAD_MODIFIED
}; };
PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER *aRouter ); PNS_SHOVE( PNS_NODE* aWorld, PNS_ROUTER* aRouter );
~PNS_SHOVE(); ~PNS_SHOVE();
virtual PNS_LOGGER *Logger() virtual PNS_LOGGER* Logger()
{ {
return &m_logger; return &m_logger;
} }
ShoveStatus ShoveLines( const PNS_LINE& aCurrentHead ); SHOVE_STATUS ShoveLines( const PNS_LINE& aCurrentHead );
ShoveStatus ShoveDraggingVia ( PNS_VIA *aVia, const VECTOR2I& aWhere, PNS_VIA **aNewVia ); SHOVE_STATUS ShoveDraggingVia( PNS_VIA*aVia, const VECTOR2I& aWhere, PNS_VIA** aNewVia );
PNS_NODE* CurrentNode(); PNS_NODE* CurrentNode();
const PNS_LINE NewHead() const; const PNS_LINE NewHead() const;
void SetInitialLine ( PNS_LINE *aInitial ); void SetInitialLine ( PNS_LINE* aInitial );
private: private:
typedef std::vector<SHAPE_LINE_CHAIN> HullSet; typedef std::vector<SHAPE_LINE_CHAIN> HULL_SET;
typedef boost::optional<PNS_LINE> OptLine; typedef boost::optional<PNS_LINE> OPT_LINE;
typedef std::pair <PNS_LINE *, PNS_LINE *> LinePair; typedef std::pair <PNS_LINE*, PNS_LINE*> LINE_PAIR;
typedef std::vector<LinePair> LinePairVec; typedef std::vector<LINE_PAIR> LINE_PAIR_VEC;
struct SpringbackTag struct SPRINGBACK_TAG
{ {
int64_t length; int64_t m_length;
int segments; int m_segments;
VECTOR2I p; VECTOR2I m_p;
PNS_NODE *node; PNS_NODE* m_node;
PNS_ITEMSET headItems; PNS_ITEMSET m_headItems;
PNS_COST_ESTIMATOR cost; PNS_COST_ESTIMATOR m_cost;
}; };
ShoveStatus processSingleLine(PNS_LINE *aCurrent, PNS_LINE* aObstacle, PNS_LINE *aShoved ); SHOVE_STATUS 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 processHullSet( PNS_LINE* aCurrent, PNS_LINE* aObstacle,
PNS_LINE* aShoved, const HULL_SET& hulls );
bool reduceSpringback( const PNS_ITEMSET &aHeadItems ); 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; bool checkBumpDirection( PNS_LINE* aCurrent, PNS_LINE* aShoved ) const;
ShoveStatus onCollidingLine( PNS_LINE *aCurrent, PNS_LINE *aObstacle ); SHOVE_STATUS onCollidingLine( PNS_LINE* aCurrent, PNS_LINE* aObstacle );
ShoveStatus onCollidingSegment( PNS_LINE *aCurrent, PNS_SEGMENT *aObstacleSeg ); SHOVE_STATUS onCollidingSegment( PNS_LINE* aCurrent, PNS_SEGMENT* aObstacleSeg );
ShoveStatus onCollidingSolid( PNS_LINE *aCurrent, PNS_SOLID *aObstacleSolid ); SHOVE_STATUS onCollidingSolid( PNS_LINE* aCurrent, PNS_SOLID* aObstacleSolid );
ShoveStatus onCollidingVia( PNS_ITEM *aCurrent, PNS_VIA *aObstacleVia ); SHOVE_STATUS onCollidingVia( PNS_ITEM* aCurrent, PNS_VIA* aObstacleVia );
ShoveStatus onReverseCollidingVia( PNS_LINE *aCurrent, PNS_VIA *aObstacleVia ); SHOVE_STATUS onReverseCollidingVia( PNS_LINE* aCurrent, PNS_VIA* aObstacleVia );
ShoveStatus pushVia ( PNS_VIA *aVia, const VECTOR2I& aForce, int aCurrentRank ); SHOVE_STATUS pushVia( PNS_VIA* aVia, const VECTOR2I& aForce, int aCurrentRank );
void unwindStack ( PNS_SEGMENT *seg ); void unwindStack( PNS_SEGMENT* aSeg );
void unwindStack ( PNS_ITEM *item ); 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(); 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* assembleLine( const PNS_SEGMENT* aSeg, int* aIndex = NULL );
PNS_LINE *cloneLine ( const PNS_LINE *aLine ); PNS_LINE* cloneLine( const PNS_LINE* aLine );
ShoveStatus shoveIteration(int aIter); SHOVE_STATUS shoveIteration( int aIter );
ShoveStatus shoveMainLoop(); 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_lineStack;
std::vector<PNS_LINE*> m_optimizerQueue; std::vector<PNS_LINE*> m_optimizerQueue;
std::vector<PNS_ITEM*> m_gcItems; std::vector<PNS_ITEM*> m_gcItems;
...@@ -127,7 +129,7 @@ private: ...@@ -127,7 +129,7 @@ private:
PNS_LINE* m_currentHead; PNS_LINE* m_currentHead;
PNS_LINE* m_collidingLine; PNS_LINE* m_collidingLine;
OptLine m_newHead; OPT_LINE m_newHead;
PNS_LOGGER m_logger; PNS_LOGGER m_logger;
PNS_VIA* m_draggedVia; PNS_VIA* m_draggedVia;
......
...@@ -37,8 +37,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness ...@@ -37,8 +37,7 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
case SH_RECT: case SH_RECT:
{ {
SHAPE_RECT* rect = static_cast<SHAPE_RECT*>( m_shape ); SHAPE_RECT* rect = static_cast<SHAPE_RECT*>( m_shape );
return OctagonalHull( rect->GetPosition(), rect->GetSize(), return OctagonalHull( rect->GetPosition(), rect->GetSize(), cl + 1, 0.2 * cl );
cl + 1, 0.2 * cl );
} }
case SH_CIRCLE: case SH_CIRCLE:
...@@ -46,12 +45,13 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness ...@@ -46,12 +45,13 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
SHAPE_CIRCLE* circle = static_cast<SHAPE_CIRCLE*>( m_shape ); SHAPE_CIRCLE* circle = static_cast<SHAPE_CIRCLE*>( m_shape );
int r = circle->GetRadius(); int r = circle->GetRadius();
return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ), return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ),
cl + 1, 0.52 * (r + cl) ); cl + 1, 0.52 * ( r + cl ) );
} }
case SH_SEGMENT: case SH_SEGMENT:
{ {
SHAPE_SEGMENT *seg = static_cast<SHAPE_SEGMENT *> ( m_shape ); SHAPE_SEGMENT* seg = static_cast<SHAPE_SEGMENT*> ( m_shape );
return SegmentHull (*seg, aClearance, aWalkaroundThickness ); return SegmentHull( *seg, aClearance, aWalkaroundThickness );
} }
default: default:
...@@ -64,6 +64,6 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness ...@@ -64,6 +64,6 @@ const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness
PNS_ITEM* PNS_SOLID::Clone ( ) const PNS_ITEM* PNS_SOLID::Clone ( ) const
{ {
PNS_ITEM *solid = new PNS_SOLID ( *this ); PNS_ITEM* solid = new PNS_SOLID( *this );
return solid; return solid;
} }
...@@ -49,7 +49,7 @@ public: ...@@ -49,7 +49,7 @@ public:
m_pos = aSolid.m_pos; m_pos = aSolid.m_pos;
} }
PNS_ITEM* Clone( ) const; PNS_ITEM* Clone() const;
const SHAPE* Shape() const { return m_shape; } const SHAPE* Shape() const { return m_shape; }
...@@ -73,7 +73,7 @@ public: ...@@ -73,7 +73,7 @@ public:
m_pos = aCenter; m_pos = aCenter;
} }
virtual VECTOR2I Anchor(int n) const virtual VECTOR2I Anchor( int aN ) const
{ {
return m_pos; return m_pos;
} }
...@@ -83,7 +83,6 @@ public: ...@@ -83,7 +83,6 @@ public:
return 1; return 1;
} }
private: private:
VECTOR2I m_pos; VECTOR2I m_pos;
SHAPE* m_shape; SHAPE* m_shape;
......
...@@ -24,10 +24,8 @@ ...@@ -24,10 +24,8 @@
#include <geometry/shape_segment.h> #include <geometry/shape_segment.h>
const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
const VECTOR2I& aSize, int aClearance, int aChamfer )
int aClearance,
int aChamfer )
{ {
SHAPE_LINE_CHAIN s; SHAPE_LINE_CHAIN s;
...@@ -45,8 +43,8 @@ const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, ...@@ -45,8 +43,8 @@ const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0,
return s; 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 aWalkaroundThickness )
{ {
int d = aSeg.GetWidth() / 2 + aClearance + aWalkaroundThickness / 2 + HULL_MARGIN; int d = aSeg.GetWidth() / 2 + aClearance + aWalkaroundThickness / 2 + HULL_MARGIN;
...@@ -81,14 +79,15 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, ...@@ -81,14 +79,15 @@ const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg,
return s; return s;
} }
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg ) SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg )
{ {
SHAPE_RECT r; SHAPE_RECT r;
VECTOR2I delta ( aSeg.GetWidth() / 2, aSeg.GetWidth() / 2 ); VECTOR2I delta( aSeg.GetWidth() / 2, aSeg.GetWidth() / 2 );
VECTOR2I p0 ( aSeg.GetSeg().A - delta ); VECTOR2I p0( aSeg.GetSeg().A - delta );
VECTOR2I p1 ( aSeg.GetSeg().B + delta ); VECTOR2I p1( aSeg.GetSeg().B + delta );
return SHAPE_RECT ( std::min(p0.x, p1.x), std::min(p0.y, p1.y), return SHAPE_RECT( std::min( p0.x, p1.x ), std::min( p0.y, p1.y ),
std::abs(p1.x - p0.x), std::abs(p1.y - p0.y )); std::abs( p1.x - p0.x ), std::abs( p1.y - p0.y ) );
} }
...@@ -33,8 +33,7 @@ ...@@ -33,8 +33,7 @@
const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize, const SHAPE_LINE_CHAIN OctagonalHull( const VECTOR2I& aP0, const VECTOR2I& aSize,
int aClearance, int aChamfer ); int aClearance, int aChamfer );
const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, const SHAPE_LINE_CHAIN SegmentHull ( const SHAPE_SEGMENT& aSeg, int aClearance,
int aClearance,
int aWalkaroundThickness ); int aWalkaroundThickness );
SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg ); SHAPE_RECT ApproximateSegmentAsRect( const SHAPE_SEGMENT& aSeg );
......
...@@ -25,26 +25,22 @@ ...@@ -25,26 +25,22 @@
#include <geometry/shape_rect.h> #include <geometry/shape_rect.h>
bool PNS_VIA::PushoutForce( PNS_NODE* aNode, bool PNS_VIA::PushoutForce( PNS_NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForce,
const VECTOR2I& aDirection, bool aSolidsOnly, int aMaxIterations )
VECTOR2I& aForce,
bool aSolidsOnly,
int aMaxIterations )
{ {
int iter = 0; int iter = 0;
PNS_VIA mv( *this ); PNS_VIA mv( *this );
VECTOR2I force, totalForce, force2; VECTOR2I force, totalForce, force2;
while( iter < aMaxIterations ) while( iter < aMaxIterations )
{ {
PNS_NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv,
PNS_NODE::OptObstacle obs = aNode->CheckColliding( &mv, aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY ); aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY );
if( !obs ) if( !obs )
break; break;
int clearance = aNode->GetClearance( obs->item, &mv ); int clearance = aNode->GetClearance( obs->m_item, &mv );
if( iter > aMaxIterations / 2 ) if( iter > aMaxIterations / 2 )
{ {
...@@ -53,14 +49,13 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode, ...@@ -53,14 +49,13 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
mv.SetPos( mv.Pos() + l ); 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) { if( col ) {
totalForce += force2; totalForce += force2;
mv.SetPos( mv.Pos() + force2 ); mv.SetPos( mv.Pos() + force2 );
} }
iter++; iter++;
} }
...@@ -68,19 +63,21 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode, ...@@ -68,19 +63,21 @@ bool PNS_VIA::PushoutForce( PNS_NODE* aNode,
return false; return false;
aForce = totalForce; aForce = totalForce;
return true; return true;
} }
const SHAPE_LINE_CHAIN PNS_VIA::Hull( int aClearance, int aWalkaroundThickness ) const const SHAPE_LINE_CHAIN PNS_VIA::Hull( int aClearance, int aWalkaroundThickness ) const
{ {
int cl = (aClearance + aWalkaroundThickness / 2); int cl = ( aClearance + aWalkaroundThickness / 2 );
return OctagonalHull( m_pos - return OctagonalHull( m_pos -
VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter, VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter, m_diameter ),
m_diameter ), cl + 1, (2 * cl + m_diameter) * 0.26 ); cl + 1, ( 2 * cl + m_diameter ) * 0.26 );
} }
PNS_VIA* PNS_VIA::Clone ( ) const PNS_VIA* PNS_VIA::Clone ( ) const
{ {
PNS_VIA* v = new PNS_VIA(); PNS_VIA* v = new PNS_VIA();
......
...@@ -32,7 +32,8 @@ class PNS_VIA : public PNS_ITEM ...@@ -32,7 +32,8 @@ class PNS_VIA : public PNS_ITEM
{ {
public: public:
PNS_VIA() : PNS_VIA() :
PNS_ITEM( VIA ) {}; PNS_ITEM( VIA )
{}
PNS_VIA( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aDiameter, int aNet = -1 ) : PNS_VIA( const VECTOR2I& aPos, const PNS_LAYERSET& aLayers, int aDiameter, int aNet = -1 ) :
PNS_ITEM( VIA ) PNS_ITEM( VIA )
...@@ -42,21 +43,21 @@ public: ...@@ -42,21 +43,21 @@ public:
m_pos = aPos; m_pos = aPos;
m_diameter = aDiameter; m_diameter = aDiameter;
m_shape = SHAPE_CIRCLE( aPos, aDiameter / 2 ); m_shape = SHAPE_CIRCLE( aPos, aDiameter / 2 );
}; }
PNS_VIA( const PNS_VIA& b ) : PNS_VIA( const PNS_VIA& aB ) :
PNS_ITEM( VIA ) PNS_ITEM( VIA )
{ {
SetNet( b.Net() ); SetNet( aB.Net() );
SetLayers( b.Layers() ); SetLayers( aB.Layers() );
m_pos = b.m_pos; m_pos = aB.m_pos;
m_diameter = b.m_diameter; m_diameter = aB.m_diameter;
m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 ); m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
m_marker = b.m_marker; m_marker = aB.m_marker;
m_rank = b.m_rank; m_rank = aB.m_rank;
m_owner = b.m_owner; m_owner = aB.m_owner;
m_drill = b.m_drill; m_drill = aB.m_drill;
} }
const VECTOR2I& Pos() const const VECTOR2I& Pos() const
...@@ -106,7 +107,7 @@ public: ...@@ -106,7 +107,7 @@ public:
const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const; const SHAPE_LINE_CHAIN Hull( int aClearance = 0, int aWalkaroundThickness = 0 ) const;
virtual VECTOR2I Anchor(int n) const virtual VECTOR2I Anchor( int n ) const
{ {
return m_pos; return m_pos;
} }
...@@ -117,7 +118,6 @@ public: ...@@ -117,7 +118,6 @@ public:
} }
private: private:
int m_diameter; int m_diameter;
int m_drill; int m_drill;
VECTOR2I m_pos; VECTOR2I m_pos;
......
...@@ -32,22 +32,22 @@ using boost::optional; ...@@ -32,22 +32,22 @@ using boost::optional;
void PNS_WALKAROUND::start( const PNS_LINE& aInitialPath ) void PNS_WALKAROUND::start( const PNS_LINE& aInitialPath )
{ {
m_iteration = 0; 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 ) bool aWindingDirection )
{ {
optional<PNS_OBSTACLE>& current_obs = optional<PNS_OBSTACLE>& current_obs =
aWindingDirection ? m_currentObstacle[0] : m_currentObstacle[1]; aWindingDirection ? m_currentObstacle[0] : m_currentObstacle[1];
bool& prev_recursive = aWindingDirection ? m_recursiveCollision[0] : m_recursiveCollision[1]; bool& prev_recursive = aWindingDirection ? m_recursiveCollision[0] : m_recursiveCollision[1];
if( !current_obs ) if( !current_obs )
...@@ -55,15 +55,14 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath, ...@@ -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]; 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++; m_recursiveBlockageCount++;
if( m_recursiveBlockageCount < 3 ) if( m_recursiveBlockageCount < 3 )
aPath.Line().Append( current_obs->hull.NearestPoint( last ) ); aPath.Line().Append( current_obs->m_hull.NearestPoint( last ) );
else else
{ {
aPath = aPath.ClipToNearestObstacle( m_world ); aPath = aPath.ClipToNearestObstacle( m_world );
...@@ -71,17 +70,18 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath, ...@@ -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 ); 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 ); path_post[1], !aWindingDirection );
#ifdef DEBUG #ifdef DEBUG
m_logger.NewGroup (aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration); m_logger.NewGroup( aWindingDirection ? "walk-cw" : "walk-ccw", m_iteration );
m_logger.Log ( &path_walk[0], 0, "path-walk"); m_logger.Log( &path_walk[0], 0, "path-walk" );
m_logger.Log ( &path_pre[0], 1, "path-pre"); m_logger.Log( &path_pre[0], 1, "path-pre" );
m_logger.Log ( &path_post[0], 4, "path-post"); m_logger.Log( &path_post[0], 4, "path-post" );
m_logger.Log ( &current_obs->hull, 2, "hull"); m_logger.Log( &current_obs->m_hull, 2, "hull" );
m_logger.Log ( current_obs->item, 3, "item"); m_logger.Log( current_obs->m_item, 3, "item" );
#endif #endif
int len_pre = path_walk[0].Length(); int len_pre = path_walk[0].Length();
...@@ -89,8 +89,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath, ...@@ -89,8 +89,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
PNS_LINE walk_path( aPath, path_walk[1] ); 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; SHAPE_LINE_CHAIN pnew;
...@@ -127,15 +126,13 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath, ...@@ -127,15 +126,13 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::singleStep( PNS_LINE& aPath,
} }
PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitialPath, PNS_WALKAROUND::WALKAROUND_STATUS PNS_WALKAROUND::Route( const PNS_LINE& aInitialPath,
PNS_LINE& aWalkPath, PNS_LINE& aWalkPath, bool aOptimize )
bool aOptimize )
{ {
PNS_LINE path_cw( aInitialPath ), path_ccw( aInitialPath ); 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; SHAPE_LINE_CHAIN best_path;
start( aInitialPath ); start( aInitialPath );
m_currentObstacle[0] = m_currentObstacle[1] = nearestObstacle( aInitialPath ); m_currentObstacle[0] = m_currentObstacle[1] = nearestObstacle( aInitialPath );
...@@ -143,7 +140,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial ...@@ -143,7 +140,7 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
aWalkPath = aInitialPath; aWalkPath = aInitialPath;
while( m_iteration < m_iteration_limit ) while( m_iteration < m_iterationLimit )
{ {
if( s_cw != STUCK ) if( s_cw != STUCK )
s_cw = singleStep( path_cw, true ); s_cw = singleStep( path_cw, true );
...@@ -156,7 +153,6 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial ...@@ -156,7 +153,6 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
int len_cw = path_cw.CLine().Length(); int len_cw = path_cw.CLine().Length();
int len_ccw = path_ccw.CLine().Length(); int len_ccw = path_ccw.CLine().Length();
if( m_forceLongerPath ) if( m_forceLongerPath )
aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw); aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw);
else else
...@@ -178,16 +174,15 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial ...@@ -178,16 +174,15 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
m_iteration++; m_iteration++;
} }
if( m_iteration == m_iteration_limit ) if( m_iteration == m_iterationLimit )
{ {
int len_cw = path_cw.CLine().Length(); int len_cw = path_cw.CLine().Length();
int len_ccw = path_ccw.CLine().Length(); int len_ccw = path_ccw.CLine().Length();
if( m_forceLongerPath ) if( m_forceLongerPath )
aWalkPath = (len_cw > len_ccw ? path_cw : path_ccw); aWalkPath = ( len_cw > len_ccw ? path_cw : path_ccw );
else else
aWalkPath = (len_cw < len_ccw ? path_cw : path_ccw); aWalkPath = ( len_cw < len_ccw ? path_cw : path_ccw );
} }
if( m_cursorApproachMode ) if( m_cursorApproachMode )
...@@ -226,16 +221,16 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial ...@@ -226,16 +221,16 @@ PNS_WALKAROUND::WalkaroundStatus PNS_WALKAROUND::Route( const PNS_LINE& aInitial
aWalkPath.Line().Simplify(); aWalkPath.Line().Simplify();
if(aWalkPath.SegmentCount() < 1) if( aWalkPath.SegmentCount() < 1 )
return STUCK; return STUCK;
if(aWalkPath.CPoint(-1) != aInitialPath.CPoint(-1)) if( aWalkPath.CPoint( -1 ) != aInitialPath.CPoint( -1 ) )
return STUCK; return STUCK;
if(aWalkPath.CPoint(0) != aInitialPath.CPoint(0)) if( aWalkPath.CPoint( 0 ) != aInitialPath.CPoint( 0 ) )
return STUCK; 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 ) if( aOptimize && st == DONE )
PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world ); PNS_OPTIMIZER::Optimize( &aWalkPath, PNS_OPTIMIZER::MERGE_OBTUSE, m_world );
......
...@@ -32,20 +32,20 @@ class PNS_WALKAROUND : public PNS_ALGO_BASE ...@@ -32,20 +32,20 @@ class PNS_WALKAROUND : public PNS_ALGO_BASE
static const int DefaultIterationLimit = 50; static const int DefaultIterationLimit = 50;
public: public:
PNS_WALKAROUND( PNS_NODE* aWorld, PNS_ROUTER *aRouter ) : PNS_WALKAROUND( PNS_NODE* aWorld, PNS_ROUTER* aRouter ) :
PNS_ALGO_BASE ( aRouter ), PNS_ALGO_BASE ( aRouter ),
m_world( aWorld ), m_world( aWorld ),
m_iteration_limit( DefaultIterationLimit ) m_iterationLimit( DefaultIterationLimit )
{ {
m_forceSingleDirection = false; m_forceSingleDirection = false;
m_forceLongerPath = false; m_forceLongerPath = false;
m_cursorApproachMode = false; m_cursorApproachMode = false;
m_item_mask = PNS_ITEM::ANY; m_itemMask = PNS_ITEM::ANY;
}; }
~PNS_WALKAROUND() {}; ~PNS_WALKAROUND() {};
enum WalkaroundStatus enum WALKAROUND_STATUS
{ {
IN_PROGRESS = 0, IN_PROGRESS = 0,
DONE, DONE,
...@@ -59,20 +59,20 @@ public: ...@@ -59,20 +59,20 @@ public:
void SetIterationLimit( const int aIterLimit ) void SetIterationLimit( const int aIterLimit )
{ {
m_iteration_limit = aIterLimit; m_iterationLimit = aIterLimit;
} }
void SetSolidsOnly( bool aSolidsOnly ) void SetSolidsOnly( bool aSolidsOnly )
{ {
if(aSolidsOnly) if( aSolidsOnly )
m_item_mask = PNS_ITEM::SOLID; m_itemMask = PNS_ITEM::SOLID;
else else
m_item_mask = PNS_ITEM::ANY; m_itemMask = PNS_ITEM::ANY;
} }
void SetItemMask ( int aMask ) void SetItemMask( int aMask )
{ {
m_item_mask = aMask; m_itemMask = aMask;
} }
void SetSingleDirection( bool aForceSingleDirection ) void SetSingleDirection( bool aForceSingleDirection )
...@@ -88,29 +88,30 @@ public: ...@@ -88,29 +88,30 @@ public:
m_cursorApproachMode = aEnabled; 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 ); bool aOptimize = true );
virtual PNS_LOGGER *Logger() { virtual PNS_LOGGER* Logger()
{
return &m_logger; return &m_logger;
} }
private: private:
void start( const PNS_LINE& aInitialPath ); void start( const PNS_LINE& aInitialPath );
WalkaroundStatus singleStep( PNS_LINE& aPath, bool aWindingDirection ); WALKAROUND_STATUS singleStep( PNS_LINE& aPath, bool aWindingDirection );
PNS_NODE::OptObstacle nearestObstacle( const PNS_LINE& aPath ); PNS_NODE::OPT_OBSTACLE nearestObstacle( const PNS_LINE& aPath );
PNS_NODE* m_world; PNS_NODE* m_world;
int m_recursiveBlockageCount; int m_recursiveBlockageCount;
int m_iteration; int m_iteration;
int m_iteration_limit; int m_iterationLimit;
int m_item_mask; int m_itemMask;
bool m_forceSingleDirection, m_forceLongerPath; bool m_forceSingleDirection, m_forceLongerPath;
bool m_cursorApproachMode; bool m_cursorApproachMode;
VECTOR2I m_cursorPos; VECTOR2I m_cursorPos;
PNS_NODE::OptObstacle m_currentObstacle[2]; PNS_NODE::OPT_OBSTACLE m_currentObstacle[2];
bool m_recursiveCollision[2]; bool m_recursiveCollision[2];
PNS_LOGGER m_logger; PNS_LOGGER m_logger;
}; };
......
...@@ -21,16 +21,17 @@ ...@@ -21,16 +21,17 @@
#ifndef __RANGE_H #ifndef __RANGE_H
#define __RANGE_H #define __RANGE_H
template<class T> class RANGE { template<class T>
class RANGE
{
public: public:
RANGE (T aMin, T aMax) : RANGE( T aMin, T aMax ) :
m_min(aMin), m_min( aMin ),
m_max(aMax), m_max( aMax ),
m_defined(true) {} m_defined( true ) {}
RANGE (): RANGE():
m_defined (false) {}; m_defined( false ) {}
T MinV() const T MinV() const
{ {
...@@ -42,36 +43,38 @@ template<class T> class RANGE { ...@@ -42,36 +43,38 @@ template<class T> class RANGE {
return m_max; return m_max;
} }
void Set ( T aMin, T aMax ) const void Set( T aMin, T aMax ) const
{ {
m_max = aMax; m_max = aMax;
m_min = aMin; m_min = aMin;
} }
void Grow ( T value ) void Grow( T aValue )
{ {
if(!m_defined) if( !m_defined )
{ {
m_min = value; m_min = aValue;
m_max = value; m_max = aValue;
m_defined = true; m_defined = true;
} else { }
m_min = std::min(m_min, value); else
m_max = std::max(m_max, value); {
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) if( !m_defined )
return true; return true;
return value >= m_min && value <= m_max; return aValue >= m_min && aValue <= m_max;
} }
bool Overlaps ( const RANGE<T> &aOther ) const bool Overlaps ( const RANGE<T>& aOther ) const
{ {
if(!m_defined || !aOther.m_defined) if( !m_defined || !aOther.m_defined )
return true; return true;
return m_max >= aOther.m_min && m_min <= aOther.m_max; return m_max >= aOther.m_min && m_min <= aOther.m_max;
...@@ -85,7 +88,6 @@ template<class T> class RANGE { ...@@ -85,7 +88,6 @@ template<class T> class RANGE {
private: private:
T m_min, m_max; T m_min, m_max;
bool m_defined; bool m_defined;
}; };
#endif #endif
...@@ -43,7 +43,6 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aPa ...@@ -43,7 +43,6 @@ ROUTER_PREVIEW_ITEM::ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem, VIEW_GROUP* aPa
m_clearance = -1; m_clearance = -1;
m_originLayer = m_layer = ITEM_GAL_LAYER ( GP_OVERLAY ); m_originLayer = m_layer = ITEM_GAL_LAYER ( GP_OVERLAY );
if( aItem ) if( aItem )
Update( aItem ); Update( aItem );
} }
...@@ -56,29 +55,27 @@ ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM() ...@@ -56,29 +55,27 @@ ROUTER_PREVIEW_ITEM::~ROUTER_PREVIEW_ITEM()
void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem ) void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
{ {
m_originLayer = aItem->Layers().Start(); m_originLayer = aItem->Layers().Start();
assert (m_originLayer >= 0); assert( m_originLayer >= 0 );
m_layer = m_originLayer; m_layer = m_originLayer;
m_color = getLayerColor( m_originLayer ); m_color = getLayerColor( m_originLayer );
m_color.a = 0.8; m_color.a = 0.8;
m_depth = BaseOverlayDepth - aItem->Layers().Start(); m_depth = BaseOverlayDepth - aItem->Layers().Start();
m_shape = aItem->Shape()->Clone(); m_shape = aItem->Shape()->Clone();
switch( aItem->Kind() ) switch( aItem->Kind() )
{ {
case PNS_ITEM::LINE: case PNS_ITEM::LINE:
m_type = PR_SHAPE; m_type = PR_SHAPE;
m_width = ((PNS_LINE *) aItem)->Width(); m_width = ( (PNS_LINE*) aItem )->Width();
break; break;
case PNS_ITEM::SEGMENT: case PNS_ITEM::SEGMENT:
{ {
PNS_SEGMENT *seg = (PNS_SEGMENT *)aItem; PNS_SEGMENT* seg = (PNS_SEGMENT*) aItem;
m_type = PR_SHAPE; m_type = PR_SHAPE;
m_width = seg->Width(); m_width = seg->Width();
break; break;
...@@ -100,16 +97,17 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem ) ...@@ -100,16 +97,17 @@ void ROUTER_PREVIEW_ITEM::Update( const PNS_ITEM* aItem )
break; break;
} }
if(aItem->Marker() & MK_VIOLATION) if( aItem->Marker() & MK_VIOLATION )
m_color = COLOR4D (0, 1, 0, 1); m_color = COLOR4D( 0, 1, 0, 1 );
if(aItem->Marker() & MK_HEAD) if( aItem->Marker() & MK_HEAD )
m_color.Brighten(0.7); m_color.Brighten( 0.7 );
ViewSetVisible( true ); ViewSetVisible( true );
ViewUpdate( GEOMETRY | APPEARANCE ); ViewUpdate( GEOMETRY | APPEARANCE );
} }
const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
{ {
BOX2I bbox; BOX2I bbox;
...@@ -122,7 +120,7 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const ...@@ -122,7 +120,7 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
return bbox; return bbox;
case PR_POINT: case PR_POINT:
bbox = BOX2I ( m_pos - VECTOR2I(100000, 100000), VECTOR2I( 200000, 200000 )); bbox = BOX2I ( m_pos - VECTOR2I( 100000, 100000 ), VECTOR2I( 200000, 200000 ) );
return bbox; return bbox;
default: default:
...@@ -132,20 +130,23 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const ...@@ -132,20 +130,23 @@ const BOX2I ROUTER_PREVIEW_ITEM::ViewBBox() const
return bbox; 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++ ) for( int s = 0; s < aL.SegmentCount(); s++ )
aGal->DrawLine( l.CSegment( s ).A, l.CSegment( s ).B ); aGal->DrawLine( aL.CSegment( s ).A, aL.CSegment( s ).B );
if( l.IsClosed() )
aGal->DrawLine( l.CSegment( -1 ).B, l.CSegment( 0 ).A ); if( aL.IsClosed() )
aGal->DrawLine( aL.CSegment( -1 ).B, aL.CSegment( 0 ).A );
} }
void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
{ {
//col.Brighten(0.7); //col.Brighten(0.7);
aGal->SetLayerDepth( m_depth ); aGal->SetLayerDepth( m_depth );
if(m_type == PR_SHAPE) if( m_type == PR_SHAPE )
{ {
aGal->SetLineWidth( m_width ); aGal->SetLineWidth( m_width );
aGal->SetStrokeColor( m_color ); aGal->SetStrokeColor( m_color );
...@@ -153,31 +154,29 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const ...@@ -153,31 +154,29 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
aGal->SetIsStroke( m_width ? true : false ); aGal->SetIsStroke( m_width ? true : false );
aGal->SetIsFill( true ); aGal->SetIsFill( true );
if( !m_shape )
if(!m_shape)
return; return;
switch( m_shape->Type() ) switch( m_shape->Type() )
{ {
case SH_LINE_CHAIN: case SH_LINE_CHAIN:
{ {
const SHAPE_LINE_CHAIN *l = (const SHAPE_LINE_CHAIN *) m_shape; const SHAPE_LINE_CHAIN* l = (const SHAPE_LINE_CHAIN*) m_shape;
drawLineChain(*l, aGal); drawLineChain( *l, aGal );
break; break;
} }
case SH_SEGMENT: case SH_SEGMENT:
{ {
const SHAPE_SEGMENT *s = (const SHAPE_SEGMENT *) m_shape; const SHAPE_SEGMENT* s = (const SHAPE_SEGMENT*) m_shape;
aGal->DrawLine( s->GetSeg().A, s->GetSeg().B ); aGal->DrawLine( s->GetSeg().A, s->GetSeg().B );
if(m_clearance > 0) if( m_clearance > 0 )
{ {
aGal->SetLayerDepth ( ClearanceOverlayDepth ); aGal->SetLayerDepth( ClearanceOverlayDepth );
aGal->SetStrokeColor ( COLOR4D( DARKDARKGRAY )); aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ));
aGal->SetLineWidth( m_width + 2 * m_clearance ); aGal->SetLineWidth( m_width + 2 * m_clearance );
aGal->DrawLine( s->GetSeg().A, s->GetSeg().B ); aGal->DrawLine( s->GetSeg().A, s->GetSeg().B );
} }
break; break;
...@@ -185,13 +184,13 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const ...@@ -185,13 +184,13 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
case SH_CIRCLE: case SH_CIRCLE:
{ {
const SHAPE_CIRCLE *c = (const SHAPE_CIRCLE *) m_shape; const SHAPE_CIRCLE* c = (const SHAPE_CIRCLE*) m_shape;
aGal->DrawCircle( c->GetCenter(), c->GetRadius() ); aGal->DrawCircle( c->GetCenter(), c->GetRadius() );
if(m_clearance > 0) if( m_clearance > 0 )
{ {
aGal->SetLayerDepth ( ClearanceOverlayDepth ); aGal->SetLayerDepth( ClearanceOverlayDepth );
aGal->SetFillColor ( COLOR4D( DARKDARKGRAY )); aGal->SetFillColor( COLOR4D( DARKDARKGRAY ) );
aGal->SetIsStroke( false ); aGal->SetIsStroke( false );
aGal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance ); aGal->DrawCircle( c->GetCenter(), c->GetRadius() + m_clearance );
} }
...@@ -201,20 +200,20 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const ...@@ -201,20 +200,20 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
case SH_RECT: case SH_RECT:
{ {
const SHAPE_RECT *r = (const SHAPE_RECT *) m_shape; const SHAPE_RECT* r = (const SHAPE_RECT*) m_shape;
aGal->DrawRectangle (r->GetPosition(), r->GetPosition() + r->GetSize()); aGal->DrawRectangle( r->GetPosition(), r->GetPosition() + r->GetSize() );
if(m_clearance > 0) if( m_clearance > 0 )
{ {
aGal->SetLayerDepth ( ClearanceOverlayDepth ); aGal->SetLayerDepth( ClearanceOverlayDepth );
VECTOR2I p0 (r -> GetPosition() ), s ( r->GetSize() ); VECTOR2I p0( r->GetPosition() ), s( r->GetSize() );
aGal->SetStrokeColor ( COLOR4D( DARKDARKGRAY )); aGal->SetStrokeColor( COLOR4D( DARKDARKGRAY ) );
aGal->SetIsStroke( true ); aGal->SetIsStroke( true );
aGal->SetLineWidth ( 2 * m_clearance ); aGal->SetLineWidth( 2 * m_clearance );
aGal->DrawLine( p0, VECTOR2I(p0.x + s.x, p0.y) ); aGal->DrawLine( p0, VECTOR2I( p0.x + s.x, p0.y ) );
aGal->DrawLine( p0, VECTOR2I(p0.x, p0.y + s.y) ); aGal->DrawLine( p0, VECTOR2I( p0.x, p0.y + s.y ) );
aGal->DrawLine( p0 + s , VECTOR2I(p0.x + s.x, p0.y) ); aGal->DrawLine( p0 + s , VECTOR2I( p0.x + s.x, p0.y ) );
aGal->DrawLine( p0 + s, VECTOR2I(p0.x, p0.y + s.y) ); aGal->DrawLine( p0 + s, VECTOR2I( p0.x, p0.y + s.y ) );
} }
break; break;
...@@ -226,7 +225,6 @@ void ROUTER_PREVIEW_ITEM::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const ...@@ -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 ) void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int aStyle )
{ {
m_originLayer = m_layer = 0; m_originLayer = m_layer = 0;
m_width = aWidth; m_width = aWidth;
m_color = assignColor( aStyle ); m_color = assignColor( aStyle );
...@@ -234,15 +232,16 @@ void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int a ...@@ -234,15 +232,16 @@ void ROUTER_PREVIEW_ITEM::Line( const SHAPE_LINE_CHAIN& aLine, int aWidth, int a
m_depth = -2047; m_depth = -2047;
m_shape = aLine.Clone(); m_shape = aLine.Clone();
ViewSetVisible(true); ViewSetVisible( true );
ViewUpdate( GEOMETRY | APPEARANCE ); ViewUpdate( GEOMETRY | APPEARANCE );
} }
void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle ) void ROUTER_PREVIEW_ITEM::Point( const VECTOR2I& aPos, int aStyle )
{ {
} }
void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle ) void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
{ {
} }
...@@ -251,7 +250,7 @@ void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle ) ...@@ -251,7 +250,7 @@ void ROUTER_PREVIEW_ITEM::Box( const BOX2I& aBox, int aStyle )
const COLOR4D ROUTER_PREVIEW_ITEM::getLayerColor( int aLayer ) const const COLOR4D ROUTER_PREVIEW_ITEM::getLayerColor( int aLayer ) const
{ {
PCB_RENDER_SETTINGS* settings = PCB_RENDER_SETTINGS* settings =
static_cast <PCB_RENDER_SETTINGS*> ( m_parent->GetView()->GetPainter()->GetSettings() ); static_cast<PCB_RENDER_SETTINGS*>( m_parent->GetView()->GetPainter()->GetSettings() );
return settings->GetLayerColor( aLayer ); return settings->GetLayerColor( aLayer );
} }
......
...@@ -44,14 +44,13 @@ class PNS_ROUTER; ...@@ -44,14 +44,13 @@ class PNS_ROUTER;
class ROUTER_PREVIEW_ITEM : public EDA_ITEM class ROUTER_PREVIEW_ITEM : public EDA_ITEM
{ {
public: public:
enum ItemType enum ITEM_TYPE
{ {
PR_STUCK_MARKER = 0, PR_STUCK_MARKER = 0,
PR_POINT, PR_POINT,
PR_SHAPE PR_SHAPE
}; };
ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem = NULL, KIGFX::VIEW_GROUP* aParent = NULL ); ROUTER_PREVIEW_ITEM( const PNS_ITEM* aItem = NULL, KIGFX::VIEW_GROUP* aParent = NULL );
~ROUTER_PREVIEW_ITEM(); ~ROUTER_PREVIEW_ITEM();
...@@ -68,12 +67,12 @@ public: ...@@ -68,12 +67,12 @@ public:
m_color = aColor; m_color = aColor;
} }
void SetClearance ( int aClearance ) void SetClearance( int aClearance )
{ {
m_clearance = aClearance; m_clearance = aClearance;
} }
void Show( int a, std::ostream& b ) const {}; void Show( int aA, std::ostream& aB ) const {};
const BOX2I ViewBBox() const; const BOX2I ViewBBox() const;
...@@ -85,7 +84,7 @@ public: ...@@ -85,7 +84,7 @@ public:
aCount = 1; 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: private:
const KIGFX::COLOR4D assignColor( int aStyle ) const; const KIGFX::COLOR4D assignColor( int aStyle ) const;
...@@ -94,9 +93,9 @@ private: ...@@ -94,9 +93,9 @@ private:
KIGFX::VIEW_GROUP* m_parent; KIGFX::VIEW_GROUP* m_parent;
PNS_ROUTER* m_router; PNS_ROUTER* m_router;
SHAPE *m_shape; SHAPE* m_shape;
ItemType m_type; ITEM_TYPE m_type;
int m_style; int m_style;
int m_width; int m_width;
......
...@@ -82,35 +82,35 @@ ROUTER_TOOL::ROUTER_TOOL() : ...@@ -82,35 +82,35 @@ ROUTER_TOOL::ROUTER_TOOL() :
m_router = NULL; m_router = NULL;
} }
class CONTEXT_TRACK_WIDTH_MENU: public CONTEXT_MENU class CONTEXT_TRACK_WIDTH_MENU: public CONTEXT_MENU
{ {
public: public:
CONTEXT_TRACK_WIDTH_MENU() 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 ) void SetBoard( BOARD* aBoard )
{ {
BOARD_DESIGN_SETTINGS &bds = aBoard->GetDesignSettings(); BOARD_DESIGN_SETTINGS& bds = aBoard->GetDesignSettings();
wxString msg; wxString msg;
m_board = aBoard; 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" ), Append( ID_POPUP_PCB_SELECT_AUTO_WIDTH, _( "Use the starting track width" ),
_( "Route using the width of the starting track." ), _( "Route using the width of the starting track." ), wxITEM_CHECK );
wxITEM_CHECK );
Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, Append( ID_POPUP_PCB_SELECT_USE_NETCLASS_VALUES, _( "Use netclass values" ),
_( "Use netclass values" ), _( "Use track and via sizes from the net class" ), wxITEM_CHECK );
_( "Use track and via sizes from the net class" ),
wxITEM_CHECK );
for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ ) for( unsigned i = 0; i < bds.m_TrackWidthList.size(); i++ )
{ {
msg = _ ("Track "); msg = _( "Track ");
msg << StringFromValue( g_UserUnit, bds.m_TrackWidthList[i], true ); msg << StringFromValue( g_UserUnit, bds.m_TrackWidthList[i], true );
if( i == 0 ) if( i == 0 )
...@@ -123,9 +123,8 @@ public: ...@@ -123,9 +123,8 @@ public:
for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ ) for( unsigned i = 0; i < bds.m_ViasDimensionsList.size(); i++ )
{ {
msg = _ ("Via "); msg = _("Via ");
msg << StringFromValue( g_UserUnit, bds.m_ViasDimensionsList[i].m_Diameter, msg << StringFromValue( g_UserUnit, bds.m_ViasDimensionsList[i].m_Diameter, true );
true );
wxString drill = StringFromValue( g_UserUnit, wxString drill = StringFromValue( g_UserUnit,
bds.m_ViasDimensionsList[i].m_Drill, bds.m_ViasDimensionsList[i].m_Drill,
true ); true );
...@@ -133,7 +132,9 @@ public: ...@@ -133,7 +132,9 @@ public:
if( bds.m_ViasDimensionsList[i].m_Drill <= 0 ) if( bds.m_ViasDimensionsList[i].m_Drill <= 0 )
{ {
msg << _ (", drill: default"); msg << _ (", drill: default");
} else { }
else
{
msg << _ (", drill: ") << drill; msg << _ (", drill: ") << drill;
} }
...@@ -148,7 +149,7 @@ protected: ...@@ -148,7 +149,7 @@ protected:
OPT_TOOL_EVENT handleCustomEvent( const wxEvent& aEvent ) OPT_TOOL_EVENT handleCustomEvent( const wxEvent& aEvent )
{ {
#if ID_POPUP_PCB_SELECT_VIASIZE1 < ID_POPUP_PCB_SELECT_WIDTH1 #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 // 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. // within a specific range. If ranges of event ids changes, then the following is not valid anymore.
#endif #endif
...@@ -156,7 +157,7 @@ protected: ...@@ -156,7 +157,7 @@ protected:
int id = aEvent.GetId(); int id = aEvent.GetId();
// General settings, to be modified below // Initial settings, to be modified below
bds.m_UseConnectedTrackWidth = false; bds.m_UseConnectedTrackWidth = false;
bds.UseCustomTrackViaSize( false ); bds.UseCustomTrackViaSize( false );
...@@ -198,13 +199,10 @@ protected: ...@@ -198,13 +199,10 @@ protected:
}; };
class CONTEXT_GRID_MENU: public CONTEXT_MENU { }; class ROUTER_TOOL_MENU: public CONTEXT_MENU
{
class ROUTER_TOOL_MENU: public CONTEXT_MENU {
public: public:
ROUTER_TOOL_MENU( BOARD *aBoard ) ROUTER_TOOL_MENU( BOARD* aBoard )
{ {
SetTitle( wxT( "Interactive Router" ) ); SetTitle( wxT( "Interactive Router" ) );
Add( ACT_NewTrack ); Add( ACT_NewTrack );
...@@ -227,6 +225,7 @@ public: ...@@ -227,6 +225,7 @@ public:
} }
}; };
ROUTER_TOOL::~ROUTER_TOOL() ROUTER_TOOL::~ROUTER_TOOL()
{ {
delete m_router; delete m_router;
...@@ -259,12 +258,13 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode ) ...@@ -259,12 +258,13 @@ int ROUTER_TOOL::getDefaultWidth( int aNetCode )
int w, d1, d2; int w, d1, d2;
getNetclassDimensions( aNetCode, w, d1, d2 ); getNetclassDimensions( aNetCode, w, d1, d2 );
return w; return w;
} }
void ROUTER_TOOL::getNetclassDimensions( int aNetCode, int& aWidth, void ROUTER_TOOL::getNetclassDimensions( int aNetCode, int& aWidth,
int& aViaDiameter, int& aViaDrill ) int& aViaDiameter, int& aViaDrill )
{ {
BOARD* board = getModel<BOARD>( PCB_T ); BOARD* board = getModel<BOARD>( PCB_T );
BOARD_DESIGN_SETTINGS &bds = board->GetDesignSettings(); BOARD_DESIGN_SETTINGS &bds = board->GetDesignSettings();
...@@ -316,29 +316,29 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa ...@@ -316,29 +316,29 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa
{ {
if( !prioritized[2] ) if( !prioritized[2] )
prioritized[2] = item; prioritized[2] = item;
if( item->Layers().Overlaps( tl )) if( item->Layers().Overlaps( tl ) )
prioritized[0] = item; prioritized[0] = item;
} }
else else
{ {
if( !prioritized[3] ) if( !prioritized[3] )
prioritized[3] = item; prioritized[3] = item;
if (item->Layers().Overlaps( tl )) if( item->Layers().Overlaps( tl ) )
prioritized[1] = item; prioritized[1] = item;
} }
} }
} }
PNS_ITEM *rv = NULL; PNS_ITEM* rv = NULL;
for(int i = 0; i < 4; i++) for( int i = 0; i < 4; i++ )
{ {
PNS_ITEM *item = prioritized[i]; PNS_ITEM* item = prioritized[i];
if( DisplayOpt.ContrastModeDisplay ) if( DisplayOpt.ContrastModeDisplay )
if( item && !item->Layers().Overlaps( tl ) ) if( item && !item->Layers().Overlaps( tl ) )
item = NULL; item = NULL;
if(item) if( item )
{ {
rv = item; rv = item;
break; break;
...@@ -349,12 +349,12 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa ...@@ -349,12 +349,12 @@ PNS_ITEM* ROUTER_TOOL::pickSingleItem( const VECTOR2I& aWhere, int aNet, int aLa
rv = NULL; rv = NULL;
if( rv ) if( rv )
TRACE( 0, "%s, layer : %d, tl: %d", rv->KindStr().c_str() % rv->Layers().Start() % TRACE( 0, "%s, layer : %d, tl: %d", rv->KindStr().c_str() % rv->Layers().Start() % tl );
tl );
return rv; return rv;
} }
void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode ) void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
{ {
RENDER_SETTINGS* rs = getView()->GetPainter()->GetSettings(); RENDER_SETTINGS* rs = getView()->GetPainter()->GetSettings();
...@@ -367,22 +367,23 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode ) ...@@ -367,22 +367,23 @@ void ROUTER_TOOL::highlightNet( bool aEnabled, int aNetcode )
getView()->UpdateAllLayersColor(); getView()->UpdateAllLayersColor();
} }
void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& aEvent )
{ {
#ifdef DEBUG #ifdef DEBUG
if( evt.IsKeyPressed() ) if( aEvent.IsKeyPressed() )
{ {
switch( evt.KeyCode() ) switch( aEvent.KeyCode() )
{ {
case 'S': case 'S':
TRACEn(2, "saving drag/route log...\n"); TRACEn( 2, "saving drag/route log...\n" );
m_router->DumpLog(); m_router->DumpLog();
break; break;
} }
} }
else else
#endif #endif
if( evt.IsAction( &ACT_RouterOptions ) ) if( aEvent.IsAction( &ACT_RouterOptions ) )
{ {
DIALOG_PNS_SETTINGS settingsDlg( m_toolMgr->GetEditFrame(), m_router->Settings() ); DIALOG_PNS_SETTINGS settingsDlg( m_toolMgr->GetEditFrame(), m_router->Settings() );
...@@ -390,7 +391,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt ) ...@@ -390,7 +391,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
m_router->ApplySettings(); 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() ); DIALOG_TRACK_VIA_SIZE sizeDlg( m_toolMgr->GetEditFrame(), m_router->Settings() );
BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>( PCB_T )->GetDesignSettings(); BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>( PCB_T )->GetDesignSettings();
...@@ -410,7 +411,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt ) ...@@ -410,7 +411,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
handleCommonEvents( event ); 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(); BOARD_DESIGN_SETTINGS& bds = getModel<BOARD>( PCB_T )->GetDesignSettings();
...@@ -421,6 +422,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt ) ...@@ -421,6 +422,7 @@ void ROUTER_TOOL::handleCommonEvents( TOOL_EVENT& evt )
} }
} }
void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent ) void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
{ {
VIEW_CONTROLS* ctls = getViewControls(); VIEW_CONTROLS* ctls = getViewControls();
...@@ -431,14 +433,11 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent ) ...@@ -431,14 +433,11 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
if( aEvent.IsMotion() || aEvent.IsClick() ) if( aEvent.IsMotion() || aEvent.IsClick() )
{ {
VECTOR2I p = aEvent.Position(); VECTOR2I p = aEvent.Position();
startItem = pickSingleItem( p ); startItem = pickSingleItem( p );
bool snapEnabled = !aEvent.Modifier(MD_SHIFT); bool snapEnabled = !aEvent.Modifier(MD_SHIFT);
m_router->EnableSnapping ( snapEnabled ); m_router->EnableSnapping ( snapEnabled );
if(!snapEnabled && startItem && !startItem->Layers().Overlaps( tl ) ) if( !snapEnabled && startItem && !startItem->Layers().Overlaps( tl ) )
startItem = NULL; startItem = NULL;
if( startItem && startItem->Net() >= 0 ) if( startItem && startItem->Net() >= 0 )
...@@ -446,10 +445,13 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent ) ...@@ -446,10 +445,13 @@ void ROUTER_TOOL::updateStartItem( TOOL_EVENT& aEvent )
bool dummy; bool dummy;
VECTOR2I psnap = m_router->SnapToItem( startItem, p, dummy ); VECTOR2I psnap = m_router->SnapToItem( startItem, p, dummy );
if (snapEnabled) { if( snapEnabled )
{
m_startSnapPoint = psnap; m_startSnapPoint = psnap;
ctls->ForceCursorPosition( true, psnap ); ctls->ForceCursorPosition( true, psnap );
} else { }
else
{
m_startSnapPoint = cp; m_startSnapPoint = cp;
ctls->ForceCursorPosition( false ); ctls->ForceCursorPosition( false );
} }
...@@ -514,8 +516,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent ) ...@@ -514,8 +516,7 @@ void ROUTER_TOOL::updateEndItem( TOOL_EVENT& aEvent )
} }
if( m_endItem ) if( m_endItem )
TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % TRACE( 0, "%s, layer : %d", m_endItem->KindStr().c_str() % m_endItem->Layers().Start() );
m_endItem->Layers().Start() );
} }
...@@ -573,7 +574,8 @@ void ROUTER_TOOL::performRouting() ...@@ -573,7 +574,8 @@ void ROUTER_TOOL::performRouting()
break; break;
m_router->Move( m_endSnapPoint, m_endItem ); m_router->Move( m_endSnapPoint, m_endItem );
} else if( evt->IsAction( &ACT_PlaceThroughVia ) ) }
else if( evt->IsAction( &ACT_PlaceThroughVia ) )
{ {
m_router->ToggleViaPlacement(); m_router->ToggleViaPlacement();
frame->SetTopLayer( m_router->GetCurrentLayer() ); frame->SetTopLayer( m_router->GetCurrentLayer() );
...@@ -636,7 +638,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent ) ...@@ -636,7 +638,8 @@ int ROUTER_TOOL::Main( TOOL_EVENT& aEvent )
// Deselect all items // Deselect all items
m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear ); 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->SetSnapping( true );
ctls->ShowCursor( true ); ctls->ShowCursor( true );
...@@ -700,7 +703,7 @@ void ROUTER_TOOL::performDragging() ...@@ -700,7 +703,7 @@ void ROUTER_TOOL::performDragging()
bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem ); bool dragStarted = m_router->StartDragging( m_startSnapPoint, m_startItem );
if(!dragStarted) if( !dragStarted )
return; return;
if( m_startItem && m_startItem->Net() >= 0 ) if( m_startItem && m_startItem->Net() >= 0 )
...@@ -725,12 +728,11 @@ void ROUTER_TOOL::performDragging() ...@@ -725,12 +728,11 @@ void ROUTER_TOOL::performDragging()
} }
else if( evt->IsClick( BUT_LEFT ) ) else if( evt->IsClick( BUT_LEFT ) )
{ {
if( m_router->FixRoute( m_endSnapPoint, m_endItem ) ) if( m_router->FixRoute( m_endSnapPoint, m_endItem ) )
break; break;
} }
handleCommonEvents(*evt);
handleCommonEvents( *evt );
} }
if( m_router->RoutingInProgress() ) if( m_router->RoutingInProgress() )
......
...@@ -49,7 +49,6 @@ public: ...@@ -49,7 +49,6 @@ public:
int Main( TOOL_EVENT& aEvent ); int Main( TOOL_EVENT& aEvent );
private: private:
PNS_ITEM* pickSingleItem( const VECTOR2I& aWhere, int aNet = -1, int aLayer = -1 ); PNS_ITEM* pickSingleItem( const VECTOR2I& aWhere, int aNet = -1, int aLayer = -1 );
int getDefaultWidth( int aNetCode ); int getDefaultWidth( int aNetCode );
...@@ -57,7 +56,7 @@ private: ...@@ -57,7 +56,7 @@ private:
void performRouting(); void performRouting();
void performDragging(); void performDragging();
void highlightNet( bool enabled, int netcode = -1 ); void highlightNet( bool aEnabled, int aNetcode = -1 );
void updateStartItem( TOOL_EVENT& aEvent ); void updateStartItem( TOOL_EVENT& aEvent );
void updateEndItem( TOOL_EVENT& aEvent ); void updateEndItem( TOOL_EVENT& aEvent );
...@@ -78,7 +77,6 @@ private: ...@@ -78,7 +77,6 @@ private:
PNS_ITEM* m_endItem; PNS_ITEM* m_endItem;
VECTOR2I m_endSnapPoint; VECTOR2I m_endSnapPoint;
CONTEXT_MENU* m_menu; CONTEXT_MENU* m_menu;
///> Flag marking that the router's world needs syncing. ///> Flag marking that the router's world needs syncing.
......
...@@ -24,23 +24,28 @@ ...@@ -24,23 +24,28 @@
TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) : TIME_LIMIT::TIME_LIMIT( int aMilliseconds ) :
m_limitMs( aMilliseconds ) m_limitMs( aMilliseconds )
{ {
Restart(); Restart();
}; }
TIME_LIMIT::~TIME_LIMIT()
{}
TIME_LIMIT::~TIME_LIMIT () {}
bool TIME_LIMIT::Expired() const bool TIME_LIMIT::Expired() const
{ {
return ( wxGetLocalTimeMillis().GetValue() - m_startTics ) >= m_limitMs; return ( wxGetLocalTimeMillis().GetValue() - m_startTics ) >= m_limitMs;
} }
void TIME_LIMIT::Restart() void TIME_LIMIT::Restart()
{ {
m_startTics = wxGetLocalTimeMillis().GetValue(); m_startTics = wxGetLocalTimeMillis().GetValue();
} }
void TIME_LIMIT::Set ( int aMilliseconds )
void TIME_LIMIT::Set( int aMilliseconds )
{ {
m_limitMs = aMilliseconds; m_limitMs = aMilliseconds;
} }
...@@ -23,22 +23,20 @@ ...@@ -23,22 +23,20 @@
#include <stdint.h> #include <stdint.h>
class TIME_LIMIT { class TIME_LIMIT
{
public: public:
TIME_LIMIT( int aMilliseconds = 0); TIME_LIMIT( int aMilliseconds = 0 );
~TIME_LIMIT (); ~TIME_LIMIT();
bool Expired() const; bool Expired() const;
void Restart(); void Restart();
void Set ( int aMilliseconds ); void Set( int aMilliseconds );
private: private:
int m_limitMs; int m_limitMs;
int64_t m_startTics; int64_t m_startTics;
}; };
#endif #endif
...@@ -25,10 +25,10 @@ ...@@ -25,10 +25,10 @@
#include <iostream> #include <iostream>
#include <boost/format.hpp> #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 #ifdef DEBUG
std::cerr << "trace[" << level << "]: " << aFuncName << ": " << aMsg << std::endl; std::cerr << "trace[" << aLevel << "]: " << aFuncName << ": " << aMsg << std::endl;
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment