// -*- mode: C++; explicit-buffer-name: "Edges.cpp" -*- // // This file is part of the Coriolis Software. // Copyright (c) UPMC 2016-2018, All Rights Reserved // // +-----------------------------------------------------------------+ // | C O R I O L I S | // | A n a b a t i c - Global Routing Toolbox | // | | // | Author : Jean-Paul CHAPUT | // | E-mail : Jean-Paul.Chaput@lip6.fr | // | =============================================================== | // | C++ Module : "./anabatic/Edges.cpp" | // +-----------------------------------------------------------------+ #include "anabatic/Edges.h" #include "anabatic/GCell.h" namespace Anabatic { using std::cerr; using std::endl; // ------------------------------------------------------------------- // Class : "Anabatic::GCell_Edges". GCell_Edges::Locator::Locator ( const GCell* gcell, Flags filterFlags ) : EdgesHL() , _gcell (gcell) , _stateFlags (Flags::EastSide) , _filterFlags(filterFlags) , _iedge (0) { // cdebug_log(110,0) << "GCell_Edges::Locator::Locator() " << isValid() << endl; if (_gcell->getEastEdges().empty() or not _filterFlags.contains(Flags::EastSide)) progress(); } EdgesHL* GCell_Edges::Locator::getClone () const { // cdebug_log(110,0) << "GCell_Edges::Locator::getClone()" << endl; return new Locator (*this); } Edge* GCell_Edges::Locator::getElement () const { if (_stateFlags.contains(Flags::EastSide )) return _gcell->getEastEdges ()[_iedge]; if (_stateFlags.contains(Flags::NorthSide)) return _gcell->getNorthEdges()[_iedge]; if (_stateFlags.contains(Flags::WestSide )) return _gcell->getWestEdges ()[_iedge]; if (_stateFlags.contains(Flags::SouthSide)) return _gcell->getSouthEdges()[_iedge]; return NULL; } bool GCell_Edges::Locator::isValid () const { return _stateFlags; } void GCell_Edges::Locator::progress () { cdebug_log(110,0) << "GCell_Edges::Locator::progress() [from] " << _stateFlags << " iedge:" << _iedge << endl; cdebug_log(110,0) << " _filterFlags:" << _filterFlags << endl; cdebug_log(110,0) << " East:" << _gcell->getEastEdges ().size() << " North:" << _gcell->getNorthEdges().size() << " West:" << _gcell->getWestEdges ().size() << " South:" << _gcell->getSouthEdges().size() << endl; cdebug_log(110,0) << this << endl; ++_iedge; while (_stateFlags) { if (_stateFlags.contains(Flags::EastSide)) { if ( (_iedge < _gcell->getEastEdges().size()) and _filterFlags.contains(Flags::EastSide)) break; //cdebug_log(110,0) << "Switching to North side." << endl; _stateFlags = Flags::NorthSide; _iedge = 0; // cdebug_log(110,0) << this << endl; continue; } if (_stateFlags.contains(Flags::NorthSide)) { if ( (_iedge < _gcell->getNorthEdges().size()) and _filterFlags.contains(Flags::NorthSide)) break; //cdebug_log(110,0) << "Switching to West side." << endl; _stateFlags = Flags::WestSide; _iedge = 0; // cdebug_log(110,0) << this << endl; continue; } if (_stateFlags.contains(Flags::WestSide)) { if ( (_iedge < _gcell->getWestEdges().size()) and _filterFlags.contains(Flags::WestSide)) break; //cdebug_log(110,0) << "Switching to South side." << endl; _stateFlags = Flags::SouthSide; _iedge = 0; continue; } if (_stateFlags.contains(Flags::SouthSide)) { if ( (_iedge < _gcell->getSouthEdges().size()) and _filterFlags.contains(Flags::SouthSide)) break; //cdebug_log(110,0) << "All edges done." << endl; _stateFlags = 0; _iedge = 0; break;; } } cdebug_log(110,0) << "GCell_Edges::Locator::progress() [to] " << _stateFlags << " iedge:" << _iedge << endl; } string GCell_Edges::Locator::_getString () const { string s = ""; return s; } // ------------------------------------------------------------------- // Class : "Anabatic::Path_Edges". Path_Edges::Locator::Locator ( const GCell* source, const GCell* target, Flags pathFlags ) : EdgesHL() , _source (source) , _target (target) , _stateFlags(Flags::NoFlags) , _uprobe (0) , _edge (NULL) { if (_source == _target) return; Interval hoverlap = _source->getHSide().getIntersection( _target->getHSide() ); Interval voverlap = _source->getVSide().getIntersection( _target->getVSide() ); if (not voverlap.isEmpty()) { if (_source->getXMin() > _target->getXMin()) std::swap( _source, _target ); _stateFlags |= Flags::EastSide; _uprobe = voverlap.getCenter(); } else if (not hoverlap.isEmpty()) { if (_source->getYMin() > _target->getYMin()) std::swap( _source, _target ); _stateFlags |= Flags::NorthSide; _uprobe = hoverlap.getCenter(); } else { if (_source->getXMin() > _target->getXMin()) { std::swap( _source, _target ); } if (_source->getYMin() < _target->getYMin()) { if (pathFlags & Flags::NorthPath) { _stateFlags |= Flags::NorthSide; _uprobe = _source->getXCenter(); } else { _stateFlags |= Flags::EastSide; _uprobe = _source->getYCenter(); } } else { if (pathFlags & Flags::NorthPath) { _stateFlags |= Flags::EastSide; _uprobe = _source->getYCenter(); } else { _stateFlags |= Flags::SouthSide; _uprobe = _source->getXCenter(); } } } _edge = _source->getEdgeAt( _stateFlags, _uprobe ); } EdgesHL* Path_Edges::Locator::getClone () const { return new Locator (*this); } Edge* Path_Edges::Locator::getElement () const { return _edge; } bool Path_Edges::Locator::isValid () const { return (_edge != NULL); } void Path_Edges::Locator::progress () { if (not _edge) return; GCell* neighbor = NULL; if (_stateFlags.contains(Flags::SouthSide) or _stateFlags.contains(Flags::WestSide)) neighbor = _edge->getSource(); if (_stateFlags.contains(Flags::NorthSide) or _stateFlags.contains(Flags::EastSide)) neighbor = _edge->getTarget(); if (neighbor == _target) { _edge = NULL; return; } if (_stateFlags.contains(Flags::EastSide)) { Interval overlap = neighbor->getHSide().getIntersection( _target->getHSide() ); if (not overlap.isEmpty()) { overlap = neighbor->getVSide().getIntersection( _target->getVSide() ); if (not overlap.isEmpty()) { _edge = NULL; return; } _stateFlags.reset( Flags::EastSide ); _stateFlags |= (_target->getYMin() < _source->getYMin()) ? Flags::SouthSide : Flags::NorthSide; _uprobe = overlap.getCenter(); } } else if (_stateFlags.contains(Flags::SouthSide)) { Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() ); if (not overlap.isEmpty()) { overlap = neighbor->getHSide().getIntersection( _target->getHSide() ); if (not overlap.isEmpty()) { _edge = NULL; return; } _stateFlags.reset( Flags::SouthSide ); _stateFlags |= Flags::EastSide; _uprobe = overlap.getCenter(); } } else if (_stateFlags.contains(Flags::NorthSide)) { Interval overlap = neighbor->getVSide().getIntersection( _target->getVSide() ); if (not overlap.isEmpty()) { overlap = neighbor->getHSide().getIntersection( _target->getHSide() ); if (not overlap.isEmpty()) { _edge = NULL; return; } _stateFlags.reset( Flags::NorthSide ); _stateFlags |= Flags::EastSide; _uprobe = overlap.getCenter(); } } _edge = neighbor->getEdgeAt( _stateFlags, _uprobe ); } string Path_Edges::Locator::_getString () const { string s = ""; return s; } EdgesHC* Path_Edges::getClone () const { return new Path_Edges( *this ); } EdgesHL* Path_Edges::getLocator () const { return new Locator (_source,_target,_pathFlags); } string Path_Edges::_getString () const { string s = ""; return s; } } // Anabatic namespace.