diff --git a/anabatic/src/Dijkstra.cpp b/anabatic/src/Dijkstra.cpp index 2561b772..fb0fc1bb 100644 --- a/anabatic/src/Dijkstra.cpp +++ b/anabatic/src/Dijkstra.cpp @@ -55,6 +55,13 @@ namespace Anabatic { { return _stamp == getAnabatic()->getStamp(); } + void Vertex::setPathPoint( DbU::Unit x, DbU::Unit y ) + { + _xpath = x; + _ypath = y; + } + + string Vertex::_getString () const { if (not _gcell) { @@ -114,18 +121,48 @@ namespace Anabatic { } - DbU::Unit Dijkstra::_distance ( const Vertex* a, const Vertex* b, const Edge* e ) + DbU::Unit Dijkstra::_distance ( const Vertex* current, const Vertex* vneighbour, const Edge* e ) { cdebug_log(112,0) << "Calcul _distance "<< endl; - cdebug_log(112,0) << "a: "<< b->hasRestrictions() << ", " << a << endl; - cdebug_log(112,0) << "b: "<< b->hasRestrictions() << ", " << b << endl; - DbU::Unit distance = a->getDistance() + e->getDistance(); + cdebug_log(112,0) << "current : "<< current->hasRestrictions() << ", " << current << endl; + cdebug_log(112,0) << "vneighbour: "<< vneighbour->hasRestrictions() << ", " << vneighbour << endl; - if ( (a->hasRestrictions()) || (b->hasRestrictions()) ) { - if (isRestricted(a, b)) { + DbU::Unit distance = current->getDistance(); + DbU::Unit addedDistance = 0; + + /* + if ((current->getGCell()->isMatrix())&&(vneighbour->getGCell()->isMatrix())) addedDistance = e->getDistance(); + else { + Point pneighbour = _getNextPathPoint( current, vneighbour ); + addedDistance = abs(pneighbour.getX() - current->getXPath()) + abs(pneighbour.getY() - current->getXPath()); + }*/ + addedDistance = e->getDistance(); + distance += addedDistance; + + if ( (current->hasRestrictions()) || (vneighbour->hasRestrictions()) ) { + if (isRestricted(current, vneighbour)) { distance = Vertex::unreachable; } } + + if ((!current->getGCell()->isMatrix()) || (!vneighbour->getGCell()->isMatrix())){ + if (distance != Vertex::unreachable) { + if (current->getFrom() != NULL){ + GCell* gprevious = current->getFrom()->getOpposite(current->getGCell()); + GCell* gcurrent = current->getGCell(); + GCell* gneighbour = vneighbour->getGCell(); + float cost = 0; + + if ( ( gcurrent->isNorth(gprevious) && (!gcurrent->isSouth(gneighbour)) ) + || ( gcurrent->isEast (gprevious) && (!gcurrent->isWest (gneighbour)) ) + || ( gcurrent->isSouth(gprevious) && (!gcurrent->isNorth(gneighbour)) ) + || ( gcurrent->isWest (gprevious) && (!gcurrent->isEast (gneighbour)) ) + ){ + distance += cost * addedDistance; + } + } + } + } // Edge* aFrom = a->getFrom(); // if (aFrom) { // distance += (aFrom->isHorizontal() xor e->isHorizontal()) ? 3.0 : 0.0; @@ -134,6 +171,62 @@ namespace Anabatic { } + Point Dijkstra::_getNextPathPoint( const Vertex* current, const Vertex* next ) + { + if ((current == NULL) || (next == NULL)){ + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unvalid NULL argument."<< endl; + return Point(0,0); + } + + if (next->getGCell()->isMatrix()) return Point(next->getGCell()->getXCenter(), next->getGCell()->getYCenter()); + if (next->getGCell()->isDevice()) return next->getPathPoint(); + + if (next->isNorth(current)){ + if (next->getGCell()->isHChannel()){ + return Point(current->getXPath(), next->getGCell()->getYCenter()); + } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { + return Point(current->getXPath(), next->getGCell()->getYMax()); + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; + return Point(0,0); + } + + } else if (next->isSouth(current)){ + if (next->getGCell()->isHChannel()){ + return Point(current->getXPath(), next->getGCell()->getYCenter()); + } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { + return Point(current->getXPath(), next->getGCell()->getYMin()); + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; + return Point(0,0); + } + + } else if (next->isEast (current)){ + if (next->getGCell()->isHChannel()){ + return Point(next->getGCell()->getXMax(), current->getYPath()); + } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { + return Point(next->getGCell()->getXCenter(), current->getYPath()); + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; + return Point(0,0); + } + + } else if (next->isWest (current)){ + if (next->getGCell()->isHChannel()){ + return Point(next->getGCell()->getXMin(), current->getYPath()); + } else if ( (next->getGCell()->isVChannel()) || (next->getGCell()->isStrut())) { + return Point(next->getGCell()->getXCenter(), current->getYPath()); + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Unknown GCell type."<< endl; + return Point(0,0); + } + } else { + cdebug_log(112,0) << "Error(Point Dijkstra::_getNextPathPoint( const Vertex*, const Vertex* )): Vertex are not neighbours."<< endl; + return Point(0,0); + } + } + + bool Dijkstra::isRestricted ( const Vertex* v1, const Vertex* v2 ) { bool restricted = true; @@ -251,6 +344,7 @@ namespace Anabatic { cdebug_log(112,0) << "New Search area: " << _searchArea << endl; Vertex* seed = gcell->getObserver(GCell::Observable::Vertex); + seed->setPathPoint(rp->getBoundingBox().getCenter().getX(), rp->getBoundingBox().getCenter().getY()); if (seed->getConnexId() < 0) { VertexSet connecteds; _getConnecteds( seed, connecteds ); @@ -417,7 +511,9 @@ namespace Anabatic { vneighbor->setBranchId( current->getBranchId() ); vneighbor->setDistance( distance ); - vneighbor->setFrom ( edge ); + Point pathPoint =_getNextPathPoint( current, vneighbor ); + vneighbor->setPathPoint( pathPoint.getX(), pathPoint.getY() ); + vneighbor->setFrom ( edge ); _queue.push( vneighbor ); cdebug_log(111,0) << "Push: (size:" << _queue.size() << ") " << vneighbor << endl; @@ -461,6 +557,7 @@ namespace Anabatic { if (not from) break; current->setDistance( 0.0 ); + if (!current->getGCell()->isDevice()) current->setPathPoint( current->getGCell()->getXCenter(), current->getGCell()->getYCenter() ); current->setConnexId( _connectedsId ); current->setBranchId( branchId ); _sources.insert( current ); diff --git a/anabatic/src/anabatic/Dijkstra.h b/anabatic/src/anabatic/Dijkstra.h index 35982112..95525405 100644 --- a/anabatic/src/anabatic/Dijkstra.h +++ b/anabatic/src/anabatic/Dijkstra.h @@ -92,10 +92,10 @@ namespace Anabatic { inline void clearRps (); inline Contact* breakGoThrough ( Net* ); - inline bool isNorth ( Vertex* ) const; - inline bool isSouth ( Vertex* ) const; - inline bool isEast ( Vertex* ) const; - inline bool isWest ( Vertex* ) const; + inline bool isNorth ( const Vertex* ) const; + inline bool isSouth ( const Vertex* ) const; + inline bool isEast ( const Vertex* ) const; + inline bool isWest ( const Vertex* ) const; inline bool isNRestricted () const; inline bool isSRestricted () const; inline bool isERestricted () const; @@ -109,6 +109,10 @@ namespace Anabatic { inline void setERestricted (); inline void setWRestricted (); inline unsigned int getFlags () const; + void setPathPoint ( DbU::Unit, DbU::Unit ); + inline DbU::Unit getXPath () const; + inline DbU::Unit getYPath () const; + inline Point getPathPoint () const; // Inspector support. string _getString () const; @@ -128,7 +132,9 @@ namespace Anabatic { DbU::Unit _distance; Edge* _from; unsigned int _flags; - }; + DbU::Unit _xpath; + DbU::Unit _ypath; + }; inline Vertex::Vertex ( GCell* gcell ) @@ -143,6 +149,8 @@ namespace Anabatic { , _distance(unreached) , _from (NULL) , _flags (NoRestriction) + , _xpath (0) + , _ypath (0) { gcell->setObserver( GCell::Observable::Vertex, &_observer ); } @@ -182,10 +190,10 @@ namespace Anabatic { typedef set VertexSet; - inline bool Vertex::isNorth ( Vertex* v ) const { return _gcell->isNorth(v->getGCell()); } - inline bool Vertex::isSouth ( Vertex* v ) const { return _gcell->isSouth(v->getGCell()); } - inline bool Vertex::isEast ( Vertex* v ) const { return _gcell->isEast (v->getGCell()); } - inline bool Vertex::isWest ( Vertex* v ) const { return _gcell->isWest (v->getGCell()); } + inline bool Vertex::isNorth ( const Vertex* v ) const { return _gcell->isNorth(v->getGCell()); } + inline bool Vertex::isSouth ( const Vertex* v ) const { return _gcell->isSouth(v->getGCell()); } + inline bool Vertex::isEast ( const Vertex* v ) const { return _gcell->isEast (v->getGCell()); } + inline bool Vertex::isWest ( const Vertex* v ) const { return _gcell->isWest (v->getGCell()); } inline bool Vertex::isNRestricted () const { return (_flags & NRestricted); } inline bool Vertex::isSRestricted () const { return (_flags & SRestricted); } inline bool Vertex::isERestricted () const { return (_flags & ERestricted); } @@ -199,7 +207,9 @@ namespace Anabatic { inline void Vertex::setERestricted () { _flags |= 0x4; } inline void Vertex::setWRestricted () { _flags |= 0x8; } inline unsigned int Vertex::getFlags () const { return _flags; } - + inline DbU::Unit Vertex::getXPath () const { return _xpath; } + inline DbU::Unit Vertex::getYPath () const { return _ypath; } + inline Point Vertex::getPathPoint () const { return Point(_xpath, _ypath); } // ------------------------------------------------------------------- // Class : "Anabatic::PriorityQueue". @@ -303,6 +313,7 @@ namespace Anabatic { Dijkstra ( const Dijkstra& ); Dijkstra& operator= ( const Dijkstra& ); static DbU::Unit _distance ( const Vertex*, const Vertex*, const Edge* ); + static Point _getNextPathPoint ( const Vertex*, const Vertex* ); void _cleanup (); bool _propagate ( Flags enabledSides ); void _traceback ( Vertex* ); diff --git a/anabatic/src/anabatic/GCell.h b/anabatic/src/anabatic/GCell.h index 32158756..ae8edcf7 100644 --- a/anabatic/src/anabatic/GCell.h +++ b/anabatic/src/anabatic/GCell.h @@ -153,6 +153,8 @@ namespace Anabatic { inline DbU::Unit getYMin () const; inline DbU::Unit getXMax ( int shrink=0 ) const; inline DbU::Unit getYMax ( int shrink=0 ) const; + inline DbU::Unit getXCenter () const; + inline DbU::Unit getYCenter () const; inline DbU::Unit getConstraintXMax () const; inline DbU::Unit getConstraintYMax () const; inline Interval getSide ( Flags direction ) const; @@ -346,6 +348,9 @@ namespace Anabatic { { return _northEdges.empty() ? getCell()->getAbutmentBox().getYMax() - shrink : _northEdges[0]->getOpposite(this)->getYMin() - shrink; } + inline DbU::Unit GCell::getXCenter () const { return (getXMin()+getXMax())/2; } + inline DbU::Unit GCell::getYCenter () const { return (getYMin()+getYMax())/2; } + inline DbU::Unit GCell::getConstraintXMax () const { return getXMax( _eastEdges.empty() ? 0 : 1 ); }