From cca66b9ec4e494c1d919bff0f71a820d8afab1fa Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:24:48 +0200 Subject: Adding upstream version 1.2.2. Signed-off-by: Daniel Baumann --- src/3rdparty/adaptagrams/libavoid/obstacle.cpp | 355 +++++++++++++++++++++++++ 1 file changed, 355 insertions(+) create mode 100644 src/3rdparty/adaptagrams/libavoid/obstacle.cpp (limited to 'src/3rdparty/adaptagrams/libavoid/obstacle.cpp') diff --git a/src/3rdparty/adaptagrams/libavoid/obstacle.cpp b/src/3rdparty/adaptagrams/libavoid/obstacle.cpp new file mode 100644 index 0000000..ac7139b --- /dev/null +++ b/src/3rdparty/adaptagrams/libavoid/obstacle.cpp @@ -0,0 +1,355 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * + * Copyright (C) 2004-2014 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. + * + * Author(s): Michael Wybrow +*/ + + +#include "libavoid/obstacle.h" +#include "libavoid/router.h" +#include "libavoid/connectionpin.h" +#include "libavoid/debug.h" + +namespace Avoid { + + +Obstacle::Obstacle(Router *router, Polygon ply, const unsigned int id) + : m_router(router), + m_polygon(ply), + m_active(false), + m_first_vert(nullptr), + m_last_vert(nullptr) +{ + COLA_ASSERT(m_router != nullptr); + m_id = m_router->assignId(id); + + VertID i = VertID(m_id, 0); + + Polygon routingPoly = routingPolygon(); + const bool addToRouterNow = false; + VertInf *last = nullptr; + VertInf *node = nullptr; + for (size_t pt_i = 0; pt_i < routingPoly.size(); ++pt_i) + { + node = new VertInf(m_router, i, routingPoly.ps[pt_i], addToRouterNow); + + if (!m_first_vert) + { + m_first_vert = node; + } + else + { + node->shPrev = last; + last->shNext = node; + //node->lstPrev = last; + //last->lstNext = node; + } + + last = node; + i++; + } + m_last_vert = node; + + m_last_vert->shNext = m_first_vert; + m_first_vert->shPrev = m_last_vert; +} + + +Obstacle::~Obstacle() +{ + COLA_ASSERT(m_active == false); + COLA_ASSERT(m_first_vert != nullptr); + + VertInf *it = m_first_vert; + do + { + VertInf *tmp = it; + it = it->shNext; + + delete tmp; + } + while (it != m_first_vert); + m_first_vert = m_last_vert = nullptr; + + // Free and clear any connection pins. + while (!m_connection_pins.empty()) + { + delete *(m_connection_pins.begin()); + } +} + + +void Obstacle::setNewPoly(const Polygon& poly) +{ + COLA_ASSERT(m_first_vert != nullptr); + COLA_ASSERT(m_polygon.size() == poly.size()); + + m_polygon = poly; + Polygon routingPoly = routingPolygon(); + + VertInf *curr = m_first_vert; + for (size_t pt_i = 0; pt_i < routingPoly.size(); ++pt_i) + { + COLA_ASSERT(curr->visListSize == 0); + COLA_ASSERT(curr->invisListSize == 0); + + // Reset with the new polygon point. + curr->Reset(routingPoly.ps[pt_i]); + curr->pathNext = nullptr; + + curr = curr->shNext; + } + COLA_ASSERT(curr == m_first_vert); + + // It may be that the polygon for the obstacle has been updated after + // creating the shape. These events may have been combined for a single + // transaction, so update pin positions. + for (ShapeConnectionPinSet::iterator curr = + m_connection_pins.begin(); curr != m_connection_pins.end(); ++curr) + { + ShapeConnectionPin *pin = *curr; + pin->updatePosition(m_polygon); + } +} + + +void Obstacle::makeActive(void) +{ + COLA_ASSERT(!m_active); + + // Add to shapeRefs list. + m_router_obstacles_pos = m_router->m_obstacles.insert( + m_router->m_obstacles.begin(), this); + + // Add points to vertex list. + VertInf *it = m_first_vert; + do + { + VertInf *tmp = it; + it = it->shNext; + + m_router->vertices.addVertex(tmp); + } + while (it != m_first_vert); + + m_active = true; +} + + +void Obstacle::makeInactive(void) +{ + COLA_ASSERT(m_active); + + // Remove from shapeRefs list. + m_router->m_obstacles.erase(m_router_obstacles_pos); + + // Remove points from vertex list. + VertInf *it = m_first_vert; + do + { + VertInf *tmp = it; + it = it->shNext; + + m_router->vertices.removeVertex(tmp); + } + while (it != m_first_vert); + + m_active = false; + + // Turn attached ConnEnds into manual points. + bool deletedShape = true; + while (!m_following_conns.empty()) + { + ConnEnd *connEnd = *(m_following_conns.begin()); + connEnd->disconnect(deletedShape); + } +} + + +void Obstacle::updatePinPolyLineVisibility(void) +{ + for (ShapeConnectionPinSet::iterator curr = + m_connection_pins.begin(); + curr != m_connection_pins.end(); ++curr) + { + (*curr)->updateVisibility(); + } +} + + +std::vector Obstacle::possiblePinPoints(unsigned int pinClassId) const +{ + std::vector points; + for (ShapeConnectionPinSet::const_iterator curr = + m_connection_pins.begin(); + curr != m_connection_pins.end(); ++curr) + { + ShapeConnectionPin *currPin = *curr; + if ((currPin->m_class_id == pinClassId) && + (!currPin->m_exclusive || currPin->m_connend_users.empty())) + { + points.push_back(currPin->m_vertex->point); + } + } + return points; +} + + +size_t Obstacle::addConnectionPin(ShapeConnectionPin *pin) +{ + m_connection_pins.insert(pin); + m_router->modifyConnectionPin(pin); + + return m_connection_pins.size(); +} + +void Obstacle::removeConnectionPin(ShapeConnectionPin *pin) +{ + m_connection_pins.erase(pin); + m_router->modifyConnectionPin(pin); +} + + +bool Obstacle::isActive(void) const +{ + return m_active; +} + + +VertInf *Obstacle::firstVert(void) +{ + return m_first_vert; +} + + +VertInf *Obstacle::lastVert(void) +{ + return m_last_vert; +} + + +unsigned int Obstacle::id(void) const +{ + return m_id; +} + + +const Polygon& Obstacle::polygon(void) const +{ + return m_polygon; +} + + +Router *Obstacle::router(void) const +{ + return m_router; +} + + +Box Obstacle::routingBox(void) const +{ + COLA_ASSERT(!m_polygon.empty()); + COLA_ASSERT(m_router); + + double bufferSpace = m_router->routingParameter(shapeBufferDistance); + return m_polygon.offsetBoundingBox(bufferSpace); +} + + +Polygon Obstacle::routingPolygon(void) const +{ + COLA_ASSERT(!m_polygon.empty()); + COLA_ASSERT(m_router); + + double bufferSpace = m_router->routingParameter(shapeBufferDistance); + return m_polygon.offsetPolygon(bufferSpace); +} + + +Point Obstacle::shapeCentre(void) +{ + Box bb = routingBox(); + + Point centre; + centre.x = bb.min.x + (0.5 * (bb.max.x - bb.min.x)); + centre.y = bb.min.y + (0.5 * (bb.max.y - bb.min.y)); + return centre; +} + + +void Obstacle::removeFromGraph(void) +{ + bool isConnPt = false; + for (VertInf *iter = firstVert(); iter != lastVert()->lstNext; ) + { + VertInf *tmp = iter; + iter = iter->lstNext; + + tmp->removeFromGraph(isConnPt); + } +} + + +VertInf *Obstacle::getPointVertex(const Point& point) +{ + VertInf *curr = m_first_vert; + do + { + if (curr->point == point) + { + return curr; + } + curr = curr->shNext; + } + while (curr != m_first_vert); + + return nullptr; +} + + +void Obstacle::addFollowingConnEnd(ConnEnd *connEnd) +{ + m_following_conns.insert(connEnd); +} + + +void Obstacle::removeFollowingConnEnd(ConnEnd *connEnd) +{ + m_following_conns.erase(connEnd); +} + + +ConnRefList Obstacle::attachedConnectors(void) const +{ + ConnRefList attachedConns; + for (std::set::const_iterator curr = m_following_conns.begin(); + curr != m_following_conns.end(); ++curr) + { + ConnEnd *connEnd = *curr; + COLA_ASSERT(connEnd->m_conn_ref != nullptr); + attachedConns.push_back(connEnd->m_conn_ref); + } + return attachedConns; +} + +} + + -- cgit v1.2.3