From 0cf189f9ab1ac334b55e9059ad3905bed9edffc6 Mon Sep 17 00:00:00 2001 From: "Arcadie M. Cracan" Date: Wed, 2 Dec 2009 22:26:44 +0200 Subject: Merge GSoC2009 Connectors into trunk (bzr r8855) --- src/libavoid/router.cpp | 1541 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 1298 insertions(+), 243 deletions(-) (limited to 'src/libavoid/router.cpp') diff --git a/src/libavoid/router.cpp b/src/libavoid/router.cpp index df0bacd02..754c464b4 100644 --- a/src/libavoid/router.cpp +++ b/src/libavoid/router.cpp @@ -2,302 +2,667 @@ * vim: ts=4 sw=4 et tw=0 wm=0 * * libavoid - Fast, Incremental, Object-avoiding Line Router - * Copyright (C) 2004-2006 Michael Wybrow + * + * Copyright (C) 2004-2009 Monash University * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. + * See the file LICENSE.LGPL distributed with the library. + * + * Licensees holding a valid commercial license may use this file in + * accordance with the commercial license agreement provided with the + * library. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * Author(s): Michael Wybrow */ -#include + +#include +#include + #include "libavoid/shape.h" #include "libavoid/router.h" #include "libavoid/visibility.h" #include "libavoid/connector.h" -#include "libavoid/polyutil.h" #include "libavoid/debug.h" -#include "libavoid/region.h" -#include "math.h" - -//#define ORTHOGONAL_ROUTING +#include "libavoid/orthogonal.h" +#include "libavoid/assertions.h" namespace Avoid { -static const unsigned int infoAdd = 1; -static const unsigned int infoDel = 2; -static const unsigned int infoMov = 3; +enum ActionType { + ShapeMove, + ShapeAdd, + ShapeRemove, + ConnChange +}; +typedef std::list > ConnUpdateList; -class MoveInfo { +class ActionInfo { public: - MoveInfo(ShapeRef *s, Polygn *p, bool fM) - : shape(s) - , newPoly(copyPoly(*p)) - , firstMove(fM) - { } - ~MoveInfo() + ActionInfo(ActionType t, ShapeRef *s, const Polygon& p, bool fM) + : type(t), + objPtr(s), + newPoly(p), + firstMove(fM) + { + COLA_ASSERT(type == ShapeMove); + } + ActionInfo(ActionType t, ShapeRef *s) + : type(t), + objPtr(s) + { + COLA_ASSERT(type != ConnChange); + } + ActionInfo(ActionType t, ConnRef *c) + : type(t), + objPtr(c) + { + COLA_ASSERT(type == ConnChange); + } + ~ActionInfo() + { + } + ShapeRef *shape(void) const + { + COLA_ASSERT((type == ShapeMove) || (type == ShapeAdd) || + (type == ShapeRemove)); + return (static_cast (objPtr)); + } + ConnRef *conn(void) const + { + COLA_ASSERT(type == ConnChange); + return (static_cast (objPtr)); + } + bool operator==(const ActionInfo& rhs) const + { + return (type == rhs.type) && (objPtr == rhs.objPtr); + } + bool operator<(const ActionInfo& rhs) const { - freePoly(newPoly); + if (type != rhs.type) + { + return type < rhs.type; + } + return objPtr < rhs.objPtr; } - ShapeRef *shape; - Polygn newPoly; + ActionType type; + void *objPtr; + Polygon newPoly; bool firstMove; + ConnUpdateList conns; }; - -Router::Router() - : PartialTime(false) - , SimpleRouting(false) - , segmt_penalty(0) - , angle_penalty(0) - , crossing_penalty(200) - // Algorithm options: - , UseAStarSearch(true) - , IgnoreRegions(true) - , SelectiveReroute(true) - , IncludeEndpoints(true) - , UseLeesAlgorithm(false) - , InvisibilityGrph(true) - , ConsolidateMoves(true) - , PartialFeedback(false) - // Instrumentation: - , st_checked_edges(0) -#ifdef LINEDEBUG - , avoid_screen(NULL) +Router::Router(const unsigned int flags) + : visOrthogGraph(true), + PartialTime(false), + SimpleRouting(false), + ClusteredRouting(true), + // Poly-line algorithm options: + IgnoreRegions(true), + UseLeesAlgorithm(true), + InvisibilityGrph(true), + // General algorithm options: + SelectiveReroute(true), + PartialFeedback(false), + RubberBandRouting(false), + // Instrumentation: + st_checked_edges(0), +#ifdef LIBAVOID_SDL + avoid_screen(NULL), #endif -{ } + _largestAssignedId(0), + _consolidateActions(true), + _orthogonalNudgeDistance(4.0), + // Mode options: + _polyLineRouting(false), + _orthogonalRouting(false), + _staticGraphInvalidated(true), + _inCrossingPenaltyReroutingStage(false) +{ + // At least one of the Routing modes must be set. + COLA_ASSERT(flags & (PolyLineRouting | OrthogonalRouting)); + if (flags & PolyLineRouting) + { + _polyLineRouting = true; + } + if (flags & OrthogonalRouting) + { + _orthogonalRouting = true; + } + for (size_t p = 0; p < lastPenaltyMarker; ++p) + { + _routingPenalties[p] = 0.0; + } + _routingPenalties[clusterCrossingPenalty] = 4000; +} -void Router::addShape(ShapeRef *shape) +Router::~Router() { - unsigned int pid = shape->id(); - Polygn poly = shape->poly(); + // Delete remaining connectors. + ConnRefList::iterator conn = connRefs.begin(); + while (conn != connRefs.end()) + { + db_printf("Deleting connector %u in ~Router()\n", (*conn)->id()); + delete *conn; + conn = connRefs.begin(); + } - adjustContainsWithAdd(poly, pid); - - // o Check all visibility edges to see if this one shape - // blocks them. - newBlockingShape(&poly, pid); + // Remove remaining shapes. + ShapeRefList::iterator shape = shapeRefs.begin(); + while (shape != shapeRefs.end()) + { + ShapeRef *shapePtr = *shape; + db_printf("Deleting shape %u in ~Router()\n", shapePtr->id()); + if (shapePtr->isActive()) + { + shapePtr->removeFromGraph(); + shapePtr->makeInactive(); + } + delete shapePtr; + shape = shapeRefs.begin(); + } + + // Cleanup orphaned orthogonal graph vertices. + destroyOrthogonalVisGraph(); + + COLA_ASSERT(connRefs.size() == 0); + COLA_ASSERT(shapeRefs.size() == 0); + COLA_ASSERT(visGraph.size() == 0); + COLA_ASSERT(invisGraph.size() == 0); +} -#ifdef ORTHOGONAL_ROUTING - Region::addShape(shape); -#endif - // o Calculate visibility for the new vertices. - if (UseLeesAlgorithm) +void Router::modifyConnector(ConnRef *conn, const unsigned int type, + const ConnEnd& connEnd) +{ + ActionInfo modInfo(ConnChange, conn); + + ActionInfoList::iterator found = + find(actionList.begin(), actionList.end(), modInfo); + if (found == actionList.end()) { - shapeVisSweep(shape); + modInfo.conns.push_back(std::make_pair(type, connEnd)); + actionList.push_back(modInfo); } else { - shapeVis(shape); + found->conns.push_back(std::make_pair(type, connEnd)); + } + + if (!_consolidateActions) + { + processTransaction(); } - callbackAllInvalidConnectors(); } -void Router::delShape(ShapeRef *shape) +void Router::modifyConnector(ConnRef *conn) { - unsigned int pid = shape->id(); + ActionInfo modInfo(ConnChange, conn); + + ActionInfoList::iterator found = + find(actionList.begin(), actionList.end(), modInfo); + if (found == actionList.end()) + { + actionList.push_back(modInfo); + } - // Delete items that are queued in the movList. - for (MoveInfoList::iterator it = moveList.begin(); it != moveList.end(); ) + if (!_consolidateActions) { - if ((*it)->shape->id() == pid) - { - MoveInfoList::iterator doomed = it; - ++it; - moveList.erase(doomed); - } - else - { - ++it; - } + processTransaction(); } +} - // o Remove entries related to this shape's vertices - shape->removeFromGraph(); - - if (SelectiveReroute) + +void Router::removeQueuedConnectorActions(ConnRef *conn) +{ + ActionInfo modInfo(ConnChange, conn); + + ActionInfoList::iterator found = + find(actionList.begin(), actionList.end(), modInfo); + if (found != actionList.end()) { - markConnectors(shape); + actionList.erase(found); } +} - adjustContainsWithDel(pid); - -#ifdef ORTHOGONAL_ROUTING - Region::removeShape(shape); -#endif - delete shape; +void Router::addShape(ShapeRef *shape) +{ + // There shouldn't be remove events or move events for the same shape + // already in the action list. + // XXX: Possibly we could handle this by ordering them intelligently. + COLA_ASSERT(find(actionList.begin(), actionList.end(), + ActionInfo(ShapeRemove, shape)) == actionList.end()); + COLA_ASSERT(find(actionList.begin(), actionList.end(), + ActionInfo(ShapeMove, shape)) == actionList.end()); + + ActionInfo addInfo(ShapeAdd, shape); - // o Check all edges that were blocked by this shape. - if (InvisibilityGrph) + ActionInfoList::iterator found = + find(actionList.begin(), actionList.end(), addInfo); + if (found == actionList.end()) { - checkAllBlockedEdges(pid); + actionList.push_back(addInfo); } - else + + if (!_consolidateActions) { - // check all edges not in graph - checkAllMissingEdges(); + processTransaction(); } - callbackAllInvalidConnectors(); } -void Router::moveShape(ShapeRef *shape, Polygn *newPoly, const bool first_move) +void Router::removeShape(ShapeRef *shape) { + // There shouldn't be add events events for the same shape already + // in the action list. + // XXX: Possibly we could handle this by ordering them intelligently. + COLA_ASSERT(find(actionList.begin(), actionList.end(), + ActionInfo(ShapeAdd, shape)) == actionList.end()); + + // Delete any ShapeMove entries for this shape in the action list. + ActionInfoList::iterator found = find(actionList.begin(), + actionList.end(), ActionInfo(ShapeMove, shape)); + if (found != actionList.end()) + { + actionList.erase(found); + } + + // Add the ShapeRemove entry. + ActionInfo remInfo(ShapeRemove, shape); + found = find(actionList.begin(), actionList.end(), remInfo); + if (found == actionList.end()) + { + actionList.push_back(remInfo); + } + + if (!_consolidateActions) + { + processTransaction(); + } +} + + +void Router::moveShape(ShapeRef *shape, const double xDiff, const double yDiff) +{ + Polygon newPoly = shape->polygon(); + newPoly.translate(xDiff, yDiff); + + moveShape(shape, newPoly); +} + + +void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, + const bool first_move) +{ + // There shouldn't be remove events or add events for the same shape + // already in the action list. + // XXX: Possibly we could handle this by ordering them intelligently. + COLA_ASSERT(find(actionList.begin(), actionList.end(), + ActionInfo(ShapeRemove, shape)) == actionList.end()); + + if (find(actionList.begin(), actionList.end(), + ActionInfo(ShapeAdd, shape)) != actionList.end()) + { + // The Add is enough, no need for the Move action too. + return; + } + + ActionInfo moveInfo(ShapeMove, shape, newPoly, first_move); // Sanely cope with the case where the user requests moving the same // shape multiple times before rerouting connectors. - bool alreadyThere = false; - unsigned int id = shape->id(); - MoveInfoList::iterator finish = moveList.end(); - for (MoveInfoList::iterator it = moveList.begin(); it != finish; ++it) + ActionInfoList::iterator found = + find(actionList.begin(), actionList.end(), moveInfo); + + if (found != actionList.end()) { - if ((*it)->shape->id() == id) + if (!SimpleRouting) { - if (!SimpleRouting) - { - fprintf(stderr, - "warning: multiple moves requested for shape %d.\n", - (int) id); - } - // Just update the MoveInfo with the second polygon, but - // leave the firstMove setting alone. - (*it)->newPoly = copyPoly(*newPoly); - alreadyThere = true; + db_printf("warning: multiple moves requested for shape %d " + "within a single transaction.\n", (int) shape->id()); } + // Just update the ActionInfo with the second polygon, but + // leave the firstMove setting alone. + found->newPoly = newPoly; + } + else + { + actionList.push_back(moveInfo); } - if (!alreadyThere) + if (!_consolidateActions) { - MoveInfo *moveInfo = new MoveInfo(shape, newPoly, first_move); - moveList.push_back(moveInfo); + processTransaction(); } +} + + +void Router::setStaticGraphInvalidated(const bool invalidated) +{ + _staticGraphInvalidated = invalidated; +} + + +void Router::destroyOrthogonalVisGraph(void) +{ + // Remove orthogonal visibility graph edges. + visOrthogGraph.clear(); - if (!ConsolidateMoves) + // Remove the now orphaned vertices. + VertInf *curr = vertices.shapesBegin(); + while (curr) { - processMoves(); + if (curr->orphaned() && (curr->id == dummyOrthogID)) + { + VertInf *following = vertices.removeVertex(curr); + delete curr; + curr = following; + continue; + } + curr = curr->lstNext; } } -void Router::processMoves(void) +void Router::regenerateStaticBuiltGraph(void) { - // If SimpleRouting, then don't update yet. - if (moveList.empty() || SimpleRouting) + // Here we do talks involved in updating the static-built visibility + // graph (if necessary) before we do any routing. + if (_staticGraphInvalidated) { - return; + if (_orthogonalRouting) + { + destroyOrthogonalVisGraph(); + + timers.Register(tmOrthogGraph, timerStart); + // Regenerate a new visibility graph. + generateStaticOrthogonalVisGraph(this); + + timers.Stop(); + } + _staticGraphInvalidated = false; } +} + - MoveInfoList::iterator curr; - MoveInfoList::iterator finish = moveList.end(); - for (curr = moveList.begin(); curr != finish; ++curr) +bool Router::shapeInQueuedActionList(ShapeRef *shape) const +{ + bool foundAdd = find(actionList.begin(), actionList.end(), + ActionInfo(ShapeAdd, shape)) != actionList.end(); + bool foundRem = find(actionList.begin(), actionList.end(), + ActionInfo(ShapeRemove, shape)) != actionList.end(); + bool foundMove = find(actionList.begin(), actionList.end(), + ActionInfo(ShapeMove, shape)) != actionList.end(); + + return (foundAdd || foundRem || foundMove); +} + + +bool Router::transactionUse(void) const +{ + return _consolidateActions; +} + + +void Router::setTransactionUse(const bool transactions) +{ + _consolidateActions = transactions; +} + + +bool Router::processTransaction(void) +{ + bool notPartialTime = !(PartialFeedback && PartialTime); + bool seenShapeMovesOrDeletes = false; + + // If SimpleRouting, then don't update here. + if (actionList.empty() || SimpleRouting) + { + return false; + } + + actionList.sort(); + ActionInfoList::iterator curr; + ActionInfoList::iterator finish = actionList.end(); + for (curr = actionList.begin(); curr != finish; ++curr) { - MoveInfo *moveInf = *curr; - ShapeRef *shape = moveInf->shape; - Polygn *newPoly = &(moveInf->newPoly); - bool first_move = moveInf->firstMove; + ActionInfo& actInf = *curr; + if (!((actInf.type == ShapeRemove) || (actInf.type == ShapeMove))) + { + // Not a move or remove action, so don't do anything. + continue; + } + seenShapeMovesOrDeletes = true; + + ShapeRef *shape = actInf.shape(); + bool isMove = (actInf.type == ShapeMove); + bool first_move = actInf.firstMove; unsigned int pid = shape->id(); - bool notPartialTime = !(PartialFeedback && PartialTime); // o Remove entries related to this shape's vertices shape->removeFromGraph(); - if (SelectiveReroute && (notPartialTime || first_move)) + if (SelectiveReroute && (!isMove || notPartialTime || first_move)) { markConnectors(shape); } adjustContainsWithDel(pid); -#ifdef ORTHOGONAL_ROUTING - Region::removeShape(shape); -#endif - - shape->setNewPoly(*newPoly); - - adjustContainsWithAdd(*newPoly, pid); - // Ignore this shape for visibility. // XXX: We don't really need to do this if we're not using Partial // Feedback. Without this the blocked edges still route // around the shape until it leaves the connector. shape->makeInactive(); - } - if (InvisibilityGrph) + if (seenShapeMovesOrDeletes && _polyLineRouting) { - for (curr = moveList.begin(); curr != finish; ++curr) + if (InvisibilityGrph) { - MoveInfo *moveInf = *curr; - ShapeRef *shape = moveInf->shape; - unsigned int pid = shape->id(); - - // o Check all edges that were blocked by this shape. - checkAllBlockedEdges(pid); + for (curr = actionList.begin(); curr != finish; ++curr) + { + ActionInfo& actInf = *curr; + if (!((actInf.type == ShapeRemove) || + (actInf.type == ShapeMove))) + { + // Not a move or remove action, so don't do anything. + continue; + } + + // o Check all edges that were blocked by this shape. + checkAllBlockedEdges(actInf.shape()->id()); + } + } + else + { + // check all edges not in graph + checkAllMissingEdges(); } - } - else - { - // check all edges not in graph - checkAllMissingEdges(); } - while ( ! moveList.empty() ) + for (curr = actionList.begin(); curr != finish; ++curr) { - MoveInfo *moveInf = moveList.front(); - ShapeRef *shape = moveInf->shape; - Polygn *newPoly = &(moveInf->newPoly); + ActionInfo& actInf = *curr; + if (!((actInf.type == ShapeAdd) || (actInf.type == ShapeMove))) + { + // Not a move or add action, so don't do anything. + continue; + } + + ShapeRef *shape = actInf.shape(); + Polygon& newPoly = actInf.newPoly; + bool isMove = (actInf.type == ShapeMove); unsigned int pid = shape->id(); - bool notPartialTime = !(PartialFeedback && PartialTime); // Restore this shape for visibility. shape->makeActive(); + + if (isMove) + { + shape->setNewPoly(newPoly); + } + const Polygon& shapePoly = shape->polygon(); -#ifdef ORTHOGONAL_ROUTING - Region::addShape(shape); -#endif + adjustContainsWithAdd(shapePoly, pid); - // o Check all visibility edges to see if this one shape - // blocks them. - if (notPartialTime) + if (_polyLineRouting) { - newBlockingShape(newPoly, pid); + // o Check all visibility edges to see if this one shape + // blocks them. + if (!isMove || notPartialTime) + { + newBlockingShape(shapePoly, pid); + } + + // o Calculate visibility for the new vertices. + if (UseLeesAlgorithm) + { + shapeVisSweep(shape); + } + else + { + shapeVis(shape); + } } + } - // o Calculate visibility for the new vertices. - if (UseLeesAlgorithm) + // Update connector endpoints. + for (curr = actionList.begin(); curr != finish; ++curr) + { + ActionInfo& actInf = *curr; + if (actInf.type != ConnChange) { - shapeVisSweep(shape); + continue; } - else + for (ConnUpdateList::iterator conn = actInf.conns.begin(); + conn != actInf.conns.end(); ++conn) { - shapeVis(shape); + actInf.conn()->updateEndPoint(conn->first, conn->second); } - - moveList.pop_front(); - delete moveInf; } - callbackAllInvalidConnectors(); + // Clear the actionList. + actionList.clear(); + + _staticGraphInvalidated = true; + rerouteAndCallbackConnectors(); + + return true; +} + + +void Router::addCluster(ClusterRef *cluster) +{ + cluster->makeActive(); + + unsigned int pid = cluster->id(); + ReferencingPolygon& poly = cluster->polygon(); + + adjustClustersWithAdd(poly, pid); +} + + +void Router::delCluster(ClusterRef *cluster) +{ + cluster->makeInactive(); + + unsigned int pid = cluster->id(); + + adjustClustersWithDel(pid); +} + + +void Router::setOrthogonalNudgeDistance(const double dist) +{ + COLA_ASSERT(dist >= 0); + _orthogonalNudgeDistance = dist; +} + + +double Router::orthogonalNudgeDistance(void) const +{ + return _orthogonalNudgeDistance; +} + + +unsigned int Router::assignId(const unsigned int suggestedId) +{ + // If the suggestedId is zero, then we assign the object the next + // smallest unassigned ID, otherwise we trust the ID given is unique. + unsigned int assignedId = (suggestedId == 0) ? + (_largestAssignedId + 1) : suggestedId; + + // Have the router record if this ID is larger than the _largestAssignedId. + _largestAssignedId = std::max(_largestAssignedId, assignedId); + + // If assertions are enabled, then we check that this ID really is unique. + COLA_ASSERT(idIsUnique(assignedId)); + + return assignedId; +} + + + // Returns whether the given ID is unique among all objects known by the + // router. Outputs a warning if the ID is found ore than once. + // It is expected this is only going to be called from assertions while + // debugging, so efficiency is not an issue and we just iterate over all + // objects. +bool Router::idIsUnique(const unsigned int id) const +{ + unsigned int count = 0; + + // Examine shapes. + for (ShapeRefList::const_iterator i = shapeRefs.begin(); + i != shapeRefs.end(); ++i) + { + if ((*i)->id() == id) + { + count++; + } + } + + // Examine connectors. + for (ConnRefList::const_iterator i = connRefs.begin(); + i != connRefs.end(); ++i) + { + if ((*i)->id() == id) + { + count++; + } + } + + // Examine clusters. + for (ClusterRefList::const_iterator i = clusterRefs.begin(); + i != clusterRefs.end(); ++i) + { + if ((*i)->id() == id) + { + count++; + } + } + + if (count > 1) + { + db_printf("Warning:\tlibavoid object ID %d not unique.\n", id); + return false; + } + return true; } @@ -313,13 +678,15 @@ void Router::processMoves(void) void Router::attachedConns(IntList &conns, const unsigned int shapeId, const unsigned int type) { - ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { - - if ((type & runningTo) && ((*i)->_dstId == shapeId)) { + ConnRefList::const_iterator fin = connRefs.end(); + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + { + if ((type & runningTo) && ((*i)->_dstId == shapeId)) + { conns.push_back((*i)->_id); } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + { conns.push_back((*i)->_id); } } @@ -331,16 +698,19 @@ void Router::attachedConns(IntList &conns, const unsigned int shapeId, void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, const unsigned int type) { - ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { - if ((type & runningTo) && ((*i)->_dstId == shapeId)) { + ConnRefList::const_iterator fin = connRefs.end(); + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + { + if ((type & runningTo) && ((*i)->_dstId == shapeId)) + { if ((*i)->_srcId != 0) { // Only if there is a shape attached to the other end. shapes.push_back((*i)->_srcId); } } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + { if ((*i)->_dstId != 0) { // Only if there is a shape attached to the other end. @@ -351,18 +721,127 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, } - // It's intended this function is called after shape movement has - // happened to alert connectors that they need to be rerouted. -void Router::callbackAllInvalidConnectors(void) + // It's intended this function is called after visibility changes + // resulting from shape movement have happened. It will alert + // rerouted connectors (via a callback) that they need to be redrawn. +void Router::rerouteAndCallbackConnectors(void) +{ + std::set reroutedConns; + ConnRefList::const_iterator fin = connRefs.end(); + + // Updating the orthogonal visibility graph if necessary. + regenerateStaticBuiltGraph(); + + timers.Register(tmOrthogRoute, timerStart); + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + { + (*i)->_needs_repaint = false; + bool rerouted = (*i)->generatePath(); + if (rerouted) + { + reroutedConns.insert(*i); + } + } + timers.Stop(); + + // Find and reroute crossing connectors if crossing penalties are set. + improveCrossings(); + + // Perform centring and nudging for othogonal routes. + improveOrthogonalRoutes(this); + + // Alert connectors that they need redrawing. + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + { + (*i)->_needs_repaint = true; + (*i)->performCallback(); + } +} + + +typedef std::set ConnRefSet; + +void Router::improveCrossings(void) { + const double crossing_penalty = routingPenalty(crossingPenalty); + const double shared_path_penalty = routingPenalty(fixedSharedPathPenalty); + if ((crossing_penalty == 0) && (shared_path_penalty == 0)) + { + // No penalties, return. + return; + } + + // Find crossings and reroute connectors. + _inCrossingPenaltyReroutingStage = true; + ConnRefSet crossingConns; ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { - (*i)->handleInvalid(); + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + { + Avoid::Polygon& iRoute = (*i)->routeRef(); + ConnRefList::iterator j = i; + for (++j; j != fin; ++j) + { + if ((crossingConns.find(*i) != crossingConns.end()) && + (crossingConns.find(*j) != crossingConns.end())) + { + // We already know both these have crossings. + continue; + } + // Determine if this pair cross. + Avoid::Polygon& jRoute = (*j)->routeRef(); + CrossingsInfoPair crossingInfo = std::make_pair(0, 0); + bool meetsPenaltyCriteria = false; + for (size_t jInd = 1; jInd < jRoute.size(); ++jInd) + { + const bool finalSegment = ((jInd + 1) == jRoute.size()); + CrossingsInfoPair crossingInfo = countRealCrossings( + iRoute, true, jRoute, jInd, false, + finalSegment, NULL, NULL, *i, *j); + + if ((shared_path_penalty > 0) && + (crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + { + // We are penalising fixedSharedPaths and there is a + // fixedSharedPath. + meetsPenaltyCriteria = true; + break; + } + else if ((crossing_penalty > 0) && (crossingInfo.first > 0)) + { + // We are penalising crossings and this is a crossing. + meetsPenaltyCriteria = true; + break; + } + } + if (meetsPenaltyCriteria) + { + crossingConns.insert(*i); + crossingConns.insert(*j); + } + } + } + + for (ConnRefSet::iterator i = crossingConns.begin(); + i != crossingConns.end(); ++i) + { + ConnRef *conn = *i; + conn->makePathInvalid(); + // XXX: Could we free these routes here for extra savings? + // conn->freeRoutes(); + } + for (ConnRefSet::iterator i = crossingConns.begin(); + i != crossingConns.end(); ++i) + { + ConnRef *conn = *i; + conn->generatePath(); } + _inCrossingPenaltyReroutingStage = false; } -void Router::newBlockingShape(Polygn *poly, int pid) +void Router::newBlockingShape(const Polygon& poly, int pid) { // o Check all visibility edges to see if this one shape // blocks them. @@ -382,8 +861,11 @@ void Router::newBlockingShape(Polygn *poly, int pid) Point e2 = points.second; bool blocked = false; - bool ep_in_poly1 = !(eID1.isShape) ? inPoly(*poly, e1) : false; - bool ep_in_poly2 = !(eID2.isShape) ? inPoly(*poly, e2) : false; + bool countBorder = false; + bool ep_in_poly1 = !(eID1.isShape) ? + inPoly(poly, e1, countBorder) : false; + bool ep_in_poly2 = !(eID2.isShape) ? + inPoly(poly, e2, countBorder) : false; if (ep_in_poly1 || ep_in_poly2) { // Don't check edges that have a connector endpoint @@ -391,10 +873,14 @@ void Router::newBlockingShape(Polygn *poly, int pid) continue; } - for (int pt_i = 0; pt_i < poly->pn; pt_i++) + bool seenIntersectionAtEndpoint = false; + for (size_t pt_i = 0; pt_i < poly.size(); ++pt_i) { - int pt_n = (pt_i == (poly->pn - 1)) ? 0 : pt_i + 1; - if (segmentIntersect(e1, e2, poly->ps[pt_i], poly->ps[pt_n])) + size_t pt_n = (pt_i == (poly.size() - 1)) ? 0 : pt_i + 1; + const Point& pi = poly.ps[pt_i]; + const Point& pn = poly.ps[pt_n]; + if (segmentShapeIntersect(e1, e2, pi, pn, + seenIntersectionAtEndpoint)) { blocked = true; break; @@ -422,7 +908,7 @@ void Router::newBlockingShape(Polygn *poly, int pid) void Router::checkAllBlockedEdges(int pid) { - assert(InvisibilityGrph); + COLA_ASSERT(InvisibilityGrph); for (EdgeInf *iter = invisGraph.begin(); iter != invisGraph.end() ; ) { @@ -444,18 +930,9 @@ void Router::checkAllBlockedEdges(int pid) void Router::checkAllMissingEdges(void) { - assert(!InvisibilityGrph); + COLA_ASSERT(!InvisibilityGrph); - VertInf *first = NULL; - - if (IncludeEndpoints) - { - first = vertices.connsBegin(); - } - else - { - first = vertices.shapesBegin(); - } + VertInf *first = vertices.connsBegin(); VertInf *pend = vertices.end(); for (VertInf *i = first; i != pend; i = i->lstNext) @@ -489,39 +966,79 @@ void Router::checkAllMissingEdges(void) void Router::generateContains(VertInf *pt) { contains[pt->id].clear(); + enclosingClusters[pt->id].clear(); - ShapeRefList::iterator finish = shapeRefs.end(); - for (ShapeRefList::iterator i = shapeRefs.begin(); i != finish; ++i) + // Don't count points on the border as being inside. + bool countBorder = false; + + // Compute enclosing shapes. + ShapeRefList::const_iterator finish = shapeRefs.end(); + for (ShapeRefList::const_iterator i = shapeRefs.begin(); i != finish; ++i) { - Polygn poly = copyPoly(*i); - if (inPoly(poly, pt->point)) + if (inPoly((*i)->polygon(), pt->point, countBorder)) { contains[pt->id].insert((*i)->id()); } - freePoly(poly); + } + + // Computer enclosing Clusters + ClusterRefList::const_iterator clFinish = clusterRefs.end(); + for (ClusterRefList::const_iterator i = clusterRefs.begin(); + i != clFinish; ++i) + { + if (inPolyGen((*i)->polygon(), pt->point)) + { + enclosingClusters[pt->id].insert((*i)->id()); + } } } -void Router::adjustContainsWithAdd(const Polygn& poly, const int p_shape) +void Router::adjustClustersWithAdd(const PolygonInterface& poly, + const int p_cluster) { for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); k = k->lstNext) { - if (inPoly(poly, k->point)) + if (inPolyGen(poly, k->point)) { - contains[k->id].insert(p_shape); + enclosingClusters[k->id].insert(p_cluster); } } } -void Router::adjustContainsWithDel(const int p_shape) +void Router::adjustClustersWithDel(const int p_cluster) +{ + for (ContainsMap::iterator k = enclosingClusters.begin(); + k != enclosingClusters.end(); ++k) + { + (*k).second.erase(p_cluster); + } +} + + +void Router::adjustContainsWithAdd(const Polygon& poly, const int p_shape) { + // Don't count points on the border as being inside. + bool countBorder = false; + for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); k = k->lstNext) { - contains[k->id].erase(p_shape); + if (inPoly(poly, k->point, countBorder)) + { + contains[k->id].insert(p_shape); + } + } +} + + +void Router::adjustContainsWithDel(const int p_shape) +{ + for (ContainsMap::iterator k = contains.begin(); k != contains.end(); ++k) + { + (*k).second.erase(p_shape); } } @@ -537,14 +1054,21 @@ static double AngleAFromThreeSides(const double a, const double b, void Router::markConnectors(ShapeRef *shape) { - assert(SelectiveReroute); + if (RubberBandRouting) + { + // When rubber-band routing, we do no reroute connectors that + // may have a better route, only invalid connectors. + return; + } + + COLA_ASSERT(SelectiveReroute); - ConnRefList::iterator end = connRefs.end(); - for (ConnRefList::iterator it = connRefs.begin(); it != end; ++it) + ConnRefList::const_iterator end = connRefs.end(); + for (ConnRefList::const_iterator it = connRefs.begin(); it != end; ++it) { ConnRef *conn = (*it); - if (conn->_route.pn == 0) + if (conn->_route.empty()) { // Ignore uninitialised connectors. continue; @@ -556,7 +1080,7 @@ void Router::markConnectors(ShapeRef *shape) } Point start = conn->_route.ps[0]; - Point end = conn->_route.ps[conn->_route.pn - 1]; + Point end = conn->_route.ps[conn->_route.size() - 1]; double conndist = conn->_route_dist; @@ -609,12 +1133,12 @@ void Router::markConnectors(ShapeRef *shape) Point n_p2(p2.x - p1.x, p2.y - p1.y); Point n_start(start.x - p1.x, start.y - p1.y); Point n_end(end.x - p1.x, end.y - p1.y); - //printf("n_p2: (%.1f, %.1f)\n", n_p2.x, n_p2.y); - //printf("n_start: (%.1f, %.1f)\n", n_start.x, n_start.y); - //printf("n_end: (%.1f, %.1f)\n", n_end.x, n_end.y); + //db_printf("n_p2: (%.1f, %.1f)\n", n_p2.x, n_p2.y); + //db_printf("n_start: (%.1f, %.1f)\n", n_start.x, n_start.y); + //db_printf("n_end: (%.1f, %.1f)\n", n_end.x, n_end.y); double theta = 0 - atan2(n_p2.y, n_p2.x); - //printf("theta = %.2f\n", theta * (180 / PI)); + //db_printf("theta = %.2f\n", theta * (180 / PI)); Point r_p1(0, 0); Point r_p2 = n_p2; @@ -630,16 +1154,15 @@ void Router::markConnectors(ShapeRef *shape) start.y = cosv * n_start.y + sinv * n_start.x; end.x = cosv * n_end.x - sinv * n_end.y; end.y = cosv * n_end.y + sinv * n_end.x; - //printf("r_p2: (%.1f, %.1f)\n", r_p2.x, r_p2.y); - //printf("r_start: (%.1f, %.1f)\n", start.x, start.y); - //printf("r_end: (%.1f, %.1f)\n", end.x, end.y); + //db_printf("r_p2: (%.1f, %.1f)\n", r_p2.x, r_p2.y); + //db_printf("r_start: (%.1f, %.1f)\n", start.x, start.y); + //db_printf("r_end: (%.1f, %.1f)\n", end.x, end.y); - if (((int) r_p2.y) != 0) + // This might be slightly off. + if (fabs(r_p2.y) > 0.0001) { - printf("r_p2.y: %f != 0\n", r_p2.y); - std::abort(); + db_printf("r_p2.y: %f != 0\n", r_p2.y); } - // This might be slightly off. r_p2.y = 0; offy = r_p1.y; @@ -679,13 +1202,13 @@ void Router::markConnectors(ShapeRef *shape) x = ((b*c) + (a*d)) / (b + d); } - //printf("%.1f, %.1f, %.1f, %.1f\n", a, b, c, d); - //printf("x = %.1f\n", x); + //db_printf("%.1f, %.1f, %.1f, %.1f\n", a, b, c, d); + //db_printf("x = %.1f\n", x); x = std::max(min, x); x = std::min(max, x); - //printf("x = %.1f\n", x); + //db_printf("x = %.1f\n", x); Point xp; if (p1.x == p2.x) @@ -698,20 +1221,20 @@ void Router::markConnectors(ShapeRef *shape) xp.x = x; xp.y = offy; } - //printf("(%.1f, %.1f)\n", xp.x, xp.y); + //db_printf("(%.1f, %.1f)\n", xp.x, xp.y); - e1 = dist(start, xp); - e2 = dist(xp, end); + e1 = euclideanDist(start, xp); + e2 = euclideanDist(xp, end); estdist = e1 + e2; - //printf("is %.1f < %.1f\n", estdist, conndist); + //db_printf("is %.1f < %.1f\n", estdist, conndist); if (estdist < conndist) { #ifdef SELECTIVE_DEBUG //double angle = AngleAFromThreeSides(dist(start, end), // e1, e2); - printf("[%3d] - Possible better path found (%.1f < %.1f)\n", + db_printf("[%3d] - Possible better path found (%.1f < %.1f)\n", conn->_id, estdist, conndist); #endif conn->_needs_reroute_flag = true; @@ -723,6 +1246,81 @@ void Router::markConnectors(ShapeRef *shape) } +ConnType Router::validConnType(const ConnType select) const +{ + if (select != ConnType_None) + { + if ((select == ConnType_Orthogonal) && _orthogonalRouting) + { + return ConnType_Orthogonal; + } + else if ((select == ConnType_PolyLine) && _polyLineRouting) + { + return ConnType_PolyLine; + } + } + + if (_polyLineRouting) + { + return ConnType_PolyLine; + } + else if (_orthogonalRouting) + { + return ConnType_Orthogonal; + } + return ConnType_None; +} + + +void Router::setRoutingPenalty(const PenaltyType penType, const double penVal) +{ + COLA_ASSERT(penType < lastPenaltyMarker); + if (penVal < 0) + { + // Set some sensible penalty. + switch (penType) + { + case segmentPenalty: + _routingPenalties[penType] = 50; + break; + case fixedSharedPathPenalty: + _routingPenalties[penType] = 110; + break; + case anglePenalty: + _routingPenalties[penType] = 50; + break; + case crossingPenalty: + _routingPenalties[penType] = 200; + break; + case clusterCrossingPenalty: + _routingPenalties[penType] = 4000; + break; + default: + _routingPenalties[penType] = 50; + break; + } + } + else + { + _routingPenalties[penType] = penVal; + } +} + + +double Router::routingPenalty(const PenaltyType penType) const +{ + COLA_ASSERT(penType < lastPenaltyMarker); + return _routingPenalties[penType]; +} + + +double& Router::penaltyRef(const PenaltyType penType) +{ + COLA_ASSERT(penType < lastPenaltyMarker); + return _routingPenalties[penType]; +} + + void Router::printInfo(void) { FILE *fp = stdout; @@ -735,6 +1333,7 @@ void Router::printInfo(void) int st_endpoints = 0; int st_valid_shape_visedges = 0; int st_valid_endpt_visedges = 0; + int st_orthogonal_visedges = 0; int st_invalid_visedges = 0; VertInf *finish = vertices.end(); for (VertInf *t = vertices.connsBegin(); t != finish; t = t->lstNext) @@ -775,9 +1374,15 @@ void Router::printInfo(void) { st_invalid_visedges++; } + for (EdgeInf *t = visOrthogGraph.begin(); t != visOrthogGraph.end(); + t = t->lstNext) + { + st_orthogonal_visedges++; + } fprintf(fp, "Number of shapes: %d\n", st_shapes); fprintf(fp, "Number of vertices: %d (%d real, %d endpoints)\n", st_vertices + st_endpoints, st_vertices, st_endpoints); + fprintf(fp, "Number of orhtog_vis_edges: %d\n", st_orthogonal_visedges); fprintf(fp, "Number of vis_edges: %d (%d valid [%d normal, %d endpt], " "%d invalid)\n", st_valid_shape_visedges + st_invalid_visedges + st_valid_endpt_visedges, st_valid_shape_visedges + @@ -787,12 +1392,462 @@ void Router::printInfo(void) fprintf(fp, "checkVisEdge tally: %d\n", st_checked_edges); fprintf(fp, "----------------------\n"); - fprintf(fp, "ADDS: "); timers.Print(tmAdd); - fprintf(fp, "DELS: "); timers.Print(tmDel); - fprintf(fp, "MOVS: "); timers.Print(tmMov); - fprintf(fp, "***S: "); timers.Print(tmSev); - fprintf(fp, "PTHS: "); timers.Print(tmPth); + fprintf(fp, "ADDS: "); timers.Print(tmAdd, fp); + fprintf(fp, "DELS: "); timers.Print(tmDel, fp); + fprintf(fp, "MOVS: "); timers.Print(tmMov, fp); + fprintf(fp, "***S: "); timers.Print(tmSev, fp); + fprintf(fp, "PTHS: "); timers.Print(tmPth, fp); + fprintf(fp, "OrthogGraph: "); timers.Print(tmOrthogGraph, fp); + fprintf(fp, "OrthogRoute: "); timers.Print(tmOrthogRoute, fp); + fprintf(fp, "OrthogCentre: "); timers.Print(tmOrthogCentre, fp); + fprintf(fp, "OrthogNudge: "); timers.Print(tmOrthogNudge, fp); fprintf(fp, "\n"); + timers.Reset(); +} + + +static const double LIMIT = 100000000; + +static void reduceRange(double& val) +{ + val = std::min(val, LIMIT); + val = std::max(val, -LIMIT); +} + + +//============================================================================= +// The following methods are for testing and debugging. + + +bool Router::existsOrthogonalPathOverlap(void) +{ + ConnRefList::iterator fin = connRefs.end(); + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + { + Avoid::Polygon iRoute = (*i)->displayRoute(); + ConnRefList::iterator j = i; + for (++j; j != fin; ++j) + { + // Determine if this pair overlap + Avoid::Polygon jRoute = (*j)->displayRoute(); + CrossingsInfoPair crossingInfo = std::make_pair(0, 0); + for (size_t jInd = 1; jInd < jRoute.size(); ++jInd) + { + const bool finalSegment = ((jInd + 1) == jRoute.size()); + CrossingsInfoPair crossingInfo = countRealCrossings( + iRoute, true, jRoute, jInd, true, + finalSegment, NULL, NULL, *i, *j); + + if ((crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + { + // We looking for fixedSharedPaths and there is a + // fixedSharedPath. + return true; + } + } + } + } + return false; +} + + +bool Router::existsOrthogonalTouchingCorners(void) +{ + ConnRefList::iterator fin = connRefs.end(); + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + { + Avoid::Polygon iRoute = (*i)->displayRoute(); + ConnRefList::iterator j = i; + for (++j; j != fin; ++j) + { + // Determine if this pair overlap + Avoid::Polygon jRoute = (*j)->displayRoute(); + CrossingsInfoPair crossingInfo = std::make_pair(0, 0); + for (size_t jInd = 1; jInd < jRoute.size(); ++jInd) + { + const bool finalSegment = ((jInd + 1) == jRoute.size()); + CrossingsInfoPair crossingInfo = countRealCrossings( + iRoute, true, jRoute, jInd, true, + finalSegment, NULL, NULL, *i, *j); + + if (crossingInfo.second & CROSSING_TOUCHES) + { + return true; + } + } + } + } + return false; +} + + +void Router::outputInstanceToSVG(std::string instanceName) +{ + std::string filename; + if (!instanceName.empty()) + { + filename = instanceName; + } + else + { + filename = "libavoid-debug"; + } + filename += ".svg"; + FILE *fp = fopen(filename.c_str(), "w"); + + if (fp == NULL) + { + return; + } + + double minX = LIMIT; + double minY = LIMIT; + double maxX = -LIMIT; + double maxY = -LIMIT; + + VertInf *curr = vertices.connsBegin(); + while (curr) + { + Point p = curr->point; + + reduceRange(p.x); + reduceRange(p.y); + + if (p.x > -LIMIT) + { + minX = std::min(minX, p.x); + } + if (p.x < LIMIT) + { + maxX = std::max(maxX, p.x); + } + if (p.y > -LIMIT) + { + minY = std::min(minY, p.y); + } + if (p.y < LIMIT) + { + maxY = std::max(maxY, p.y); + } + curr = curr->lstNext; + } + minX -= 50; + minY -= 50; + maxX += 50; + maxY += 50; + + fprintf(fp, "\n"); + fprintf(fp, "\n", minX, minY, maxX - minX, maxY - minY); + + // Output source code to generate this instance of the router. + fprintf(fp, "\n"); + + + fprintf(fp, "\n"); + shRefIt = shapeRefs.begin(); + while (shRefIt != shapeRefs.end()) + { + ShapeRef *shRef = *shRefIt; + + fprintf(fp, "id()); + for (size_t i = 0; i < shRef->polygon().size(); ++i) + { + fprintf(fp, "%c %g,%g ", ((i == 0) ? 'M' : 'L'), + shRef->polygon().at(i).x, shRef->polygon().at(i).y); + } + fprintf(fp, "Z\" />\n"); + ++shRefIt; + } + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + shRefIt = shapeRefs.begin(); + while (shRefIt != shapeRefs.end()) + { + ShapeRef *shRef = *shRefIt; + double minX, minY, maxX, maxY; + shRef->polygon().getBoundingRect(&minX, &minY, &maxX, &maxY); + + fprintf(fp, "\n", + shRef->id(), minX, minY, maxX - minX, maxY - minY); + ++shRefIt; + } + fprintf(fp, "\n"); + + + fprintf(fp, "\n"); + EdgeInf *finish = NULL; + fprintf(fp, "\n"); + finish = visGraph.end(); + for (EdgeInf *t = visGraph.begin(); t != finish; t = t->lstNext) + { + std::pair ids = t->ids(); + bool isShape = (ids.first.isShape) && (ids.second.isShape); + if (!isShape) + { + continue; + } + std::pair ptpair = t->points(); + Point p1 = ptpair.first; + Point p2 = ptpair.second; + + reduceRange(p1.x); + reduceRange(p1.y); + reduceRange(p2.x); + reduceRange(p2.y); + + fprintf(fp, "\n", + p1.x, p1.y, p2.x, p2.y, + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + "red"); + } + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + finish = visGraph.end(); + for (EdgeInf *t = visGraph.begin(); t != finish; t = t->lstNext) + { + std::pair ids = t->ids(); + bool isShape = (ids.first.isShape) && (ids.second.isShape); + if (isShape) + { + continue; + } + std::pair ptpair = t->points(); + Point p1 = ptpair.first; + Point p2 = ptpair.second; + + reduceRange(p1.x); + reduceRange(p1.y); + reduceRange(p2.x); + reduceRange(p2.y); + + fprintf(fp, "\n", + p1.x, p1.y, p2.x, p2.y, + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + "red"); + } + fprintf(fp, "\n"); + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + finish = visOrthogGraph.end(); + for (EdgeInf *t = visOrthogGraph.begin(); t != finish; t = t->lstNext) + { + std::pair ptpair = t->points(); + Point p1 = ptpair.first; + Point p2 = ptpair.second; + + reduceRange(p1.x); + reduceRange(p1.y); + reduceRange(p2.x); + reduceRange(p2.y); + + std::pair ids = t->ids(); + + fprintf(fp, "\n", + p1.x, p1.y, p2.x, p2.y, + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + "red"); + } + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + ConnRefList::iterator connRefIt = connRefs.begin(); + while (connRefIt != connRefs.end()) + { + ConnRef *connRef = *connRefIt; + + PolyLine route = connRef->route(); + if (!route.empty()) + { + fprintf(fp, "id(), + route.ps[0].x, route.ps[0].y); + for (size_t i = 1; i < route.size(); ++i) + { + fprintf(fp, "L %g,%g ", route.ps[i].x, route.ps[i].y); + } + fprintf(fp, "\" "); + if (connRef->src() && connRef->dst()) + { + fprintf(fp, "debug=\"src: %d dst: %d\" ", + connRef->src()->visDirections, + connRef->dst()->visDirections); + } + fprintf(fp, "style=\"fill: none; stroke: black; " + "stroke-width: 1px;\" />\n"); + } + + ++connRefIt; + } + fprintf(fp, "\n"); + + fprintf(fp, "\n"); + connRefIt = connRefs.begin(); + while (connRefIt != connRefs.end()) + { + ConnRef *connRef = *connRefIt; + + PolyLine route = connRef->displayRoute().curvedPolyline(8); + if (!route.empty()) + { + fprintf(fp, "id(), + route.ps[0].x, route.ps[0].y); + for (size_t i = 1; i < route.size(); ++i) + { + if (route.ts[i] == 'C') + { + fprintf(fp, "%c %g,%g %g,%g %g,%g", route.ts[i], + route.ps[i].x, route.ps[i].y, + route.ps[i+1].x, route.ps[i+1].y, + route.ps[i+2].x, route.ps[i+2].y); + i += 2; + } + else + { + fprintf(fp, "%c %g,%g ", route.ts[i], + route.ps[i].x, route.ps[i].y); + } + } + fprintf(fp, "\" "); + if (connRef->src() && connRef->dst()) + { + fprintf(fp, "debug=\"src: %d dst: %d\" ", + connRef->src()->visDirections, + connRef->dst()->visDirections); + } + fprintf(fp, "style=\"fill: none; stroke: black; " + "stroke-width: 1px;\" />\n"); + } + + ++connRefIt; + } + fprintf(fp, "\n"); + + + fprintf(fp, "\n"); + connRefIt = connRefs.begin(); + while (connRefIt != connRefs.end()) + { + ConnRef *connRef = *connRefIt; + + PolyLine route = connRef->displayRoute(); + if (!route.empty()) + { + fprintf(fp, "id(), + route.ps[0].x, route.ps[0].y); + for (size_t i = 1; i < route.size(); ++i) + { + fprintf(fp, "L %g,%g ", route.ps[i].x, route.ps[i].y); + } + fprintf(fp, "\" "); + if (connRef->src() && connRef->dst()) + { + fprintf(fp, "debug=\"src: %d dst: %d\" ", + connRef->src()->visDirections, + connRef->dst()->visDirections); + } + fprintf(fp, "style=\"fill: none; stroke: black; " + "stroke-width: 1px;\" />\n"); + } + + ++connRefIt; + } + fprintf(fp, "\n"); + + + fprintf(fp, "\n"); + fclose(fp); } -- cgit v1.2.3 From e29cecc01b6fa0a8984ef780819e8e812b5505fc Mon Sep 17 00:00:00 2001 From: "Jon A. Cruz" Date: Sun, 20 Dec 2009 01:40:55 -0800 Subject: Warning cleanup (bzr r8895) --- src/libavoid/router.cpp | 238 ++++++++++++++++++++++++------------------------ 1 file changed, 119 insertions(+), 119 deletions(-) (limited to 'src/libavoid/router.cpp') diff --git a/src/libavoid/router.cpp b/src/libavoid/router.cpp index 754c464b4..ab13a981b 100644 --- a/src/libavoid/router.cpp +++ b/src/libavoid/router.cpp @@ -12,12 +12,12 @@ * See the file LICENSE.LGPL distributed with the library. * * Licensees holding a valid commercial license may use this file in - * accordance with the commercial license agreement provided with the + * accordance with the commercial license agreement provided with the * library. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * * Author(s): Michael Wybrow */ @@ -73,7 +73,7 @@ class ActionInfo { } ShapeRef *shape(void) const { - COLA_ASSERT((type == ShapeMove) || (type == ShapeAdd) || + COLA_ASSERT((type == ShapeMove) || (type == ShapeAdd) || (type == ShapeRemove)); return (static_cast (objPtr)); } @@ -189,8 +189,8 @@ void Router::modifyConnector(ConnRef *conn, const unsigned int type, const ConnEnd& connEnd) { ActionInfo modInfo(ConnChange, conn); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found == actionList.end()) { @@ -212,8 +212,8 @@ void Router::modifyConnector(ConnRef *conn, const unsigned int type, void Router::modifyConnector(ConnRef *conn) { ActionInfo modInfo(ConnChange, conn); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found == actionList.end()) { @@ -231,7 +231,7 @@ void Router::removeQueuedConnectorActions(ConnRef *conn) { ActionInfo modInfo(ConnChange, conn); - ActionInfoList::iterator found = + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), modInfo); if (found != actionList.end()) { @@ -245,14 +245,14 @@ void Router::addShape(ShapeRef *shape) // There shouldn't be remove events or move events for the same shape // already in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) == actionList.end()); - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)) == actionList.end()); ActionInfo addInfo(ShapeAdd, shape); - - ActionInfoList::iterator found = + + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), addInfo); if (found == actionList.end()) { @@ -268,14 +268,14 @@ void Router::addShape(ShapeRef *shape) void Router::removeShape(ShapeRef *shape) { - // There shouldn't be add events events for the same shape already + // There shouldn't be add events events for the same shape already // in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) == actionList.end()); // Delete any ShapeMove entries for this shape in the action list. - ActionInfoList::iterator found = find(actionList.begin(), + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)); if (found != actionList.end()) { @@ -306,16 +306,16 @@ void Router::moveShape(ShapeRef *shape, const double xDiff, const double yDiff) } -void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, +void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, const bool first_move) { // There shouldn't be remove events or add events for the same shape // already in the action list. // XXX: Possibly we could handle this by ordering them intelligently. - COLA_ASSERT(find(actionList.begin(), actionList.end(), + COLA_ASSERT(find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) == actionList.end()); - - if (find(actionList.begin(), actionList.end(), + + if (find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) != actionList.end()) { // The Add is enough, no need for the Move action too. @@ -325,7 +325,7 @@ void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, ActionInfo moveInfo(ShapeMove, shape, newPoly, first_move); // Sanely cope with the case where the user requests moving the same // shape multiple times before rerouting connectors. - ActionInfoList::iterator found = + ActionInfoList::iterator found = find(actionList.begin(), actionList.end(), moveInfo); if (found != actionList.end()) @@ -339,7 +339,7 @@ void Router::moveShape(ShapeRef *shape, const Polygon& newPoly, // leave the firstMove setting alone. found->newPoly = newPoly; } - else + else { actionList.push_back(moveInfo); } @@ -380,7 +380,7 @@ void Router::destroyOrthogonalVisGraph(void) void Router::regenerateStaticBuiltGraph(void) { - // Here we do talks involved in updating the static-built visibility + // Here we do talks involved in updating the static-built visibility // graph (if necessary) before we do any routing. if (_staticGraphInvalidated) { @@ -391,7 +391,7 @@ void Router::regenerateStaticBuiltGraph(void) timers.Register(tmOrthogGraph, timerStart); // Regenerate a new visibility graph. generateStaticOrthogonalVisGraph(this); - + timers.Stop(); } _staticGraphInvalidated = false; @@ -401,11 +401,11 @@ void Router::regenerateStaticBuiltGraph(void) bool Router::shapeInQueuedActionList(ShapeRef *shape) const { - bool foundAdd = find(actionList.begin(), actionList.end(), + bool foundAdd = find(actionList.begin(), actionList.end(), ActionInfo(ShapeAdd, shape)) != actionList.end(); - bool foundRem = find(actionList.begin(), actionList.end(), + bool foundRem = find(actionList.begin(), actionList.end(), ActionInfo(ShapeRemove, shape)) != actionList.end(); - bool foundMove = find(actionList.begin(), actionList.end(), + bool foundMove = find(actionList.begin(), actionList.end(), ActionInfo(ShapeMove, shape)) != actionList.end(); return (foundAdd || foundRem || foundMove); @@ -456,21 +456,21 @@ bool Router::processTransaction(void) // o Remove entries related to this shape's vertices shape->removeFromGraph(); - + if (SelectiveReroute && (!isMove || notPartialTime || first_move)) { markConnectors(shape); } adjustContainsWithDel(pid); - + // Ignore this shape for visibility. // XXX: We don't really need to do this if we're not using Partial // Feedback. Without this the blocked edges still route // around the shape until it leaves the connector. shape->makeInactive(); } - + if (seenShapeMovesOrDeletes && _polyLineRouting) { if (InvisibilityGrph) @@ -478,7 +478,7 @@ bool Router::processTransaction(void) for (curr = actionList.begin(); curr != finish; ++curr) { ActionInfo& actInf = *curr; - if (!((actInf.type == ShapeRemove) || + if (!((actInf.type == ShapeRemove) || (actInf.type == ShapeMove))) { // Not a move or remove action, so don't do anything. @@ -513,7 +513,7 @@ bool Router::processTransaction(void) // Restore this shape for visibility. shape->makeActive(); - + if (isMove) { shape->setNewPoly(newPoly); @@ -559,7 +559,7 @@ bool Router::processTransaction(void) } // Clear the actionList. actionList.clear(); - + _staticGraphInvalidated = true; rerouteAndCallbackConnectors(); @@ -570,7 +570,7 @@ bool Router::processTransaction(void) void Router::addCluster(ClusterRef *cluster) { cluster->makeActive(); - + unsigned int pid = cluster->id(); ReferencingPolygon& poly = cluster->polygon(); @@ -581,9 +581,9 @@ void Router::addCluster(ClusterRef *cluster) void Router::delCluster(ClusterRef *cluster) { cluster->makeInactive(); - + unsigned int pid = cluster->id(); - + adjustClustersWithDel(pid); } @@ -605,9 +605,9 @@ unsigned int Router::assignId(const unsigned int suggestedId) { // If the suggestedId is zero, then we assign the object the next // smallest unassigned ID, otherwise we trust the ID given is unique. - unsigned int assignedId = (suggestedId == 0) ? + unsigned int assignedId = (suggestedId == 0) ? (_largestAssignedId + 1) : suggestedId; - + // Have the router record if this ID is larger than the _largestAssignedId. _largestAssignedId = std::max(_largestAssignedId, assignedId); @@ -619,17 +619,17 @@ unsigned int Router::assignId(const unsigned int suggestedId) // Returns whether the given ID is unique among all objects known by the - // router. Outputs a warning if the ID is found ore than once. + // router. Outputs a warning if the ID is found ore than once. // It is expected this is only going to be called from assertions while // debugging, so efficiency is not an issue and we just iterate over all // objects. -bool Router::idIsUnique(const unsigned int id) const +bool Router::idIsUnique(const unsigned int id) const { unsigned int count = 0; // Examine shapes. - for (ShapeRefList::const_iterator i = shapeRefs.begin(); - i != shapeRefs.end(); ++i) + for (ShapeRefList::const_iterator i = shapeRefs.begin(); + i != shapeRefs.end(); ++i) { if ((*i)->id() == id) { @@ -638,8 +638,8 @@ bool Router::idIsUnique(const unsigned int id) const } // Examine connectors. - for (ConnRefList::const_iterator i = connRefs.begin(); - i != connRefs.end(); ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); + i != connRefs.end(); ++i) { if ((*i)->id() == id) { @@ -648,8 +648,8 @@ bool Router::idIsUnique(const unsigned int id) const } // Examine clusters. - for (ClusterRefList::const_iterator i = clusterRefs.begin(); - i != clusterRefs.end(); ++i) + for (ClusterRefList::const_iterator i = clusterRefs.begin(); + i != clusterRefs.end(); ++i) { if ((*i)->id() == id) { @@ -679,13 +679,13 @@ void Router::attachedConns(IntList &conns, const unsigned int shapeId, const unsigned int type) { ConnRefList::const_iterator fin = connRefs.end(); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { - if ((type & runningTo) && ((*i)->_dstId == shapeId)) + if ((type & runningTo) && ((*i)->_dstId == shapeId)) { conns.push_back((*i)->_id); } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { conns.push_back((*i)->_id); } @@ -699,9 +699,9 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, const unsigned int type) { ConnRefList::const_iterator fin = connRefs.end(); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { - if ((type & runningTo) && ((*i)->_dstId == shapeId)) + if ((type & runningTo) && ((*i)->_dstId == shapeId)) { if ((*i)->_srcId != 0) { @@ -709,7 +709,7 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, shapes.push_back((*i)->_srcId); } } - else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) + else if ((type & runningFrom) && ((*i)->_srcId == shapeId)) { if ((*i)->_dstId != 0) { @@ -721,19 +721,19 @@ void Router::attachedShapes(IntList &shapes, const unsigned int shapeId, } - // It's intended this function is called after visibility changes - // resulting from shape movement have happened. It will alert + // It's intended this function is called after visibility changes + // resulting from shape movement have happened. It will alert // rerouted connectors (via a callback) that they need to be redrawn. void Router::rerouteAndCallbackConnectors(void) { std::set reroutedConns; ConnRefList::const_iterator fin = connRefs.end(); - - // Updating the orthogonal visibility graph if necessary. + + // Updating the orthogonal visibility graph if necessary. regenerateStaticBuiltGraph(); timers.Register(tmOrthogRoute, timerStart); - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { (*i)->_needs_repaint = false; bool rerouted = (*i)->generatePath(); @@ -751,7 +751,7 @@ void Router::rerouteAndCallbackConnectors(void) improveOrthogonalRoutes(this); // Alert connectors that they need redrawing. - for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::const_iterator i = connRefs.begin(); i != fin; ++i) { (*i)->_needs_repaint = true; (*i)->performCallback(); @@ -770,18 +770,18 @@ void Router::improveCrossings(void) // No penalties, return. return; } - + // Find crossings and reroute connectors. _inCrossingPenaltyReroutingStage = true; ConnRefSet crossingConns; ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon& iRoute = (*i)->routeRef(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { - if ((crossingConns.find(*i) != crossingConns.end()) && + if ((crossingConns.find(*i) != crossingConns.end()) && (crossingConns.find(*j) != crossingConns.end())) { // We already know both these have crossings. @@ -795,13 +795,13 @@ void Router::improveCrossings(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, false, + iRoute, true, jRoute, jInd, false, finalSegment, NULL, NULL, *i, *j); - - if ((shared_path_penalty > 0) && - (crossingInfo.second & CROSSING_SHARES_PATH) && - (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && - !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + + if ((shared_path_penalty > 0) && + (crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) { // We are penalising fixedSharedPaths and there is a // fixedSharedPath. @@ -823,7 +823,7 @@ void Router::improveCrossings(void) } } - for (ConnRefSet::iterator i = crossingConns.begin(); + for (ConnRefSet::iterator i = crossingConns.begin(); i != crossingConns.end(); ++i) { ConnRef *conn = *i; @@ -831,7 +831,7 @@ void Router::improveCrossings(void) // XXX: Could we free these routes here for extra savings? // conn->freeRoutes(); } - for (ConnRefSet::iterator i = crossingConns.begin(); + for (ConnRefSet::iterator i = crossingConns.begin(); i != crossingConns.end(); ++i) { ConnRef *conn = *i; @@ -862,9 +862,9 @@ void Router::newBlockingShape(const Polygon& poly, int pid) bool blocked = false; bool countBorder = false; - bool ep_in_poly1 = !(eID1.isShape) ? + bool ep_in_poly1 = !(eID1.isShape) ? inPoly(poly, e1, countBorder) : false; - bool ep_in_poly2 = !(eID2.isShape) ? + bool ep_in_poly2 = !(eID2.isShape) ? inPoly(poly, e2, countBorder) : false; if (ep_in_poly1 || ep_in_poly2) { @@ -879,7 +879,7 @@ void Router::newBlockingShape(const Polygon& poly, int pid) size_t pt_n = (pt_i == (poly.size() - 1)) ? 0 : pt_i + 1; const Point& pi = poly.ps[pt_i]; const Point& pn = poly.ps[pt_n]; - if (segmentShapeIntersect(e1, e2, pi, pn, + if (segmentShapeIntersect(e1, e2, pi, pn, seenIntersectionAtEndpoint)) { blocked = true; @@ -983,7 +983,7 @@ void Router::generateContains(VertInf *pt) // Computer enclosing Clusters ClusterRefList::const_iterator clFinish = clusterRefs.end(); - for (ClusterRefList::const_iterator i = clusterRefs.begin(); + for (ClusterRefList::const_iterator i = clusterRefs.begin(); i != clFinish; ++i) { if (inPolyGen((*i)->polygon(), pt->point)) @@ -994,7 +994,7 @@ void Router::generateContains(VertInf *pt) } -void Router::adjustClustersWithAdd(const PolygonInterface& poly, +void Router::adjustClustersWithAdd(const PolygonInterface& poly, const int p_cluster) { for (VertInf *k = vertices.connsBegin(); k != vertices.shapesBegin(); @@ -1422,11 +1422,11 @@ static void reduceRange(double& val) bool Router::existsOrthogonalPathOverlap(void) { ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon iRoute = (*i)->displayRoute(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { // Determine if this pair overlap Avoid::Polygon jRoute = (*j)->displayRoute(); @@ -1435,12 +1435,12 @@ bool Router::existsOrthogonalPathOverlap(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, true, + iRoute, true, jRoute, jInd, true, finalSegment, NULL, NULL, *i, *j); - - if ((crossingInfo.second & CROSSING_SHARES_PATH) && - (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && - !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) + + if ((crossingInfo.second & CROSSING_SHARES_PATH) && + (crossingInfo.second & CROSSING_SHARES_FIXED_SEGMENT) && + !(crossingInfo.second & CROSSING_SHARES_PATH_AT_END)) { // We looking for fixedSharedPaths and there is a // fixedSharedPath. @@ -1456,11 +1456,11 @@ bool Router::existsOrthogonalPathOverlap(void) bool Router::existsOrthogonalTouchingCorners(void) { ConnRefList::iterator fin = connRefs.end(); - for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) + for (ConnRefList::iterator i = connRefs.begin(); i != fin; ++i) { Avoid::Polygon iRoute = (*i)->displayRoute(); ConnRefList::iterator j = i; - for (++j; j != fin; ++j) + for (++j; j != fin; ++j) { // Determine if this pair overlap Avoid::Polygon jRoute = (*j)->displayRoute(); @@ -1469,10 +1469,10 @@ bool Router::existsOrthogonalTouchingCorners(void) { const bool finalSegment = ((jInd + 1) == jRoute.size()); CrossingsInfoPair crossingInfo = countRealCrossings( - iRoute, true, jRoute, jInd, true, + iRoute, true, jRoute, jInd, true, finalSegment, NULL, NULL, *i, *j); - - if (crossingInfo.second & CROSSING_TOUCHES) + + if (crossingInfo.second & CROSSING_TOUCHES) { return true; } @@ -1514,7 +1514,7 @@ void Router::outputInstanceToSVG(std::string instanceName) reduceRange(p.x); reduceRange(p.y); - + if (p.x > -LIMIT) { minX = std::min(minX, p.x); @@ -1550,8 +1550,8 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, " PolyLineRouting | OrthogonalRouting);\n"); for (size_t p = 0; p < lastPenaltyMarker; ++p) { - fprintf(fp, " router->setRoutingPenalty((PenaltyType)%lu, %g);\n", - p, _routingPenalties[p]); + fprintf(fp, " router->setRoutingPenalty((PenaltyType)%lu, %g);\n", + static_cast(p), _routingPenalties[p]); } fprintf(fp, " router->setOrthogonalNudgeDistance(%g);\n\n", orthogonalNudgeDistance()); @@ -1559,12 +1559,12 @@ void Router::outputInstanceToSVG(std::string instanceName) while (shRefIt != shapeRefs.end()) { ShapeRef *shRef = *shRefIt; - fprintf(fp, " Polygon poly%u(%lu);\n", - shRef->id(), shRef->polygon().size()); + fprintf(fp, " Polygon poly%u(%lu);\n", + shRef->id(), static_cast(shRef->polygon().size())); for (size_t i = 0; i < shRef->polygon().size(); ++i) { - fprintf(fp, " poly%u.ps[%lu] = Point(%g, %g);\n", - shRef->id(), i, shRef->polygon().at(i).x, + fprintf(fp, " poly%u.ps[%lu] = Point(%g, %g);\n", + shRef->id(), static_cast(i), shRef->polygon().at(i).x, shRef->polygon().at(i).y); } fprintf(fp, " ShapeRef *shapeRef%u = new ShapeRef(router, poly%u, " @@ -1594,7 +1594,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, " connRef%u->setDestEndpoint(dstPt%u);\n", connRef->id(), connRef->id()); } - fprintf(fp, " connRef%u->setRoutingType((ConnType)%u);\n\n", + fprintf(fp, " connRef%u->setRoutingType((ConnType)%u);\n\n", connRef->id(), connRef->routingType()); ++revConnRefIt; } @@ -1605,20 +1605,20 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "};\n"); fprintf(fp, "-->\n"); - + fprintf(fp, "\n"); shRefIt = shapeRefs.begin(); while (shRefIt != shapeRefs.end()) { ShapeRef *shRef = *shRefIt; - + fprintf(fp, "id()); for (size_t i = 0; i < shRef->polygon().size(); ++i) { - fprintf(fp, "%c %g,%g ", ((i == 0) ? 'M' : 'L'), + fprintf(fp, "%c %g,%g ", ((i == 0) ? 'M' : 'L'), shRef->polygon().at(i).x, shRef->polygon().at(i).y); } fprintf(fp, "Z\" />\n"); @@ -1635,7 +1635,7 @@ void Router::outputInstanceToSVG(std::string instanceName) ShapeRef *shRef = *shRefIt; double minX, minY, maxX, maxY; shRef->polygon().getBoundingRect(&minX, &minY, &maxX, &maxY); - + fprintf(fp, "\n", shRef->id(), minX, minY, maxX - minX, maxY - minY); @@ -1664,16 +1664,16 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + fprintf(fp, "\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "\n"); @@ -1694,16 +1694,16 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + fprintf(fp, "\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "\n"); @@ -1718,18 +1718,18 @@ void Router::outputInstanceToSVG(std::string instanceName) std::pair ptpair = t->points(); Point p1 = ptpair.first; Point p2 = ptpair.second; - + reduceRange(p1.x); reduceRange(p1.y); reduceRange(p2.x); reduceRange(p2.y); - + std::pair ids = t->ids(); fprintf(fp, "\n", + "style=\"fill: none; stroke: %s; stroke-width: 1px;\" />\n", p1.x, p1.y, p2.x, p2.y, - (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : + (!(ids.first.isShape) || !(ids.second.isShape)) ? "green" : "red"); } fprintf(fp, "\n"); @@ -1742,7 +1742,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->route(); if (!route.empty()) { @@ -1762,7 +1762,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "\n"); @@ -1775,7 +1775,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->displayRoute().curvedPolyline(8); if (!route.empty()) { @@ -1785,7 +1785,7 @@ void Router::outputInstanceToSVG(std::string instanceName) { if (route.ts[i] == 'C') { - fprintf(fp, "%c %g,%g %g,%g %g,%g", route.ts[i], + fprintf(fp, "%c %g,%g %g,%g %g,%g", route.ts[i], route.ps[i].x, route.ps[i].y, route.ps[i+1].x, route.ps[i+1].y, route.ps[i+2].x, route.ps[i+2].y); @@ -1793,7 +1793,7 @@ void Router::outputInstanceToSVG(std::string instanceName) } else { - fprintf(fp, "%c %g,%g ", route.ts[i], + fprintf(fp, "%c %g,%g ", route.ts[i], route.ps[i].x, route.ps[i].y); } } @@ -1807,7 +1807,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "\n"); @@ -1820,7 +1820,7 @@ void Router::outputInstanceToSVG(std::string instanceName) while (connRefIt != connRefs.end()) { ConnRef *connRef = *connRefIt; - + PolyLine route = connRef->displayRoute(); if (!route.empty()) { @@ -1840,7 +1840,7 @@ void Router::outputInstanceToSVG(std::string instanceName) fprintf(fp, "style=\"fill: none; stroke: black; " "stroke-width: 1px;\" />\n"); } - + ++connRefIt; } fprintf(fp, "\n"); -- cgit v1.2.3