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/shape.cpp | 280 ++++++++++++++++++++++++++++ 1 file changed, 280 insertions(+) create mode 100644 src/3rdparty/adaptagrams/libavoid/shape.cpp (limited to 'src/3rdparty/adaptagrams/libavoid/shape.cpp') diff --git a/src/3rdparty/adaptagrams/libavoid/shape.cpp b/src/3rdparty/adaptagrams/libavoid/shape.cpp new file mode 100644 index 0000000..7a80907 --- /dev/null +++ b/src/3rdparty/adaptagrams/libavoid/shape.cpp @@ -0,0 +1,280 @@ +/* + * vim: ts=4 sw=4 et tw=0 wm=0 + * + * libavoid - Fast, Incremental, Object-avoiding Line Router + * + * Copyright (C) 2004-2013 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 + +#include "libavoid/shape.h" +#include "libavoid/vertices.h" +#include "libavoid/router.h" +#include "libavoid/connend.h" +#include "libavoid/debug.h" +#include "libavoid/assertions.h" +#include "libavoid/connectionpin.h" + + +namespace Avoid { + + +ShapeRef::ShapeRef(Router *router, Polygon& ply, const unsigned int id) + : Obstacle(router, ply, id) +{ + m_router->addShape(this); +} + + +ShapeRef::~ShapeRef() +{ + if (m_router->m_currently_calling_destructors == false) + { + err_printf("ERROR: ShapeRef::~ShapeRef() shouldn't be called directly.\n"); + err_printf(" It is owned by the router. Call Router::deleteShape() instead.\n"); + abort(); + } +} + + +void ShapeRef::moveAttachedConns(const Polygon& newPoly) +{ + // Update positions of attached connector ends. + for (std::set::iterator curr = m_following_conns.begin(); + curr != m_following_conns.end(); ++curr) + { + ConnEnd *connEnd = *curr; + COLA_ASSERT(connEnd->m_conn_ref != nullptr); + bool connPinUpdate = true; + m_router->modifyConnector(connEnd->m_conn_ref, connEnd->endpointType(), + *connEnd, connPinUpdate); + } + for (ShapeConnectionPinSet::iterator curr = + m_connection_pins.begin(); curr != m_connection_pins.end(); ++curr) + { + ShapeConnectionPin *pin = *curr; + pin->updatePosition(newPoly); + } +} + +static double absoluteOffsetInverse(double offset, + const Box& shapeBox, size_t toDim) +{ + if (offset == ATTACH_POS_MIN_OFFSET) + { + return ATTACH_POS_MAX_OFFSET; + } + + if (offset == ATTACH_POS_MAX_OFFSET) + { + return ATTACH_POS_MIN_OFFSET; + } + + return shapeBox.length(toDim) - offset; +} + +void ShapeRef::transformConnectionPinPositions( + ShapeTransformationType transform) +{ + for (ShapeConnectionPinSet::iterator curr = + m_connection_pins.begin(); curr != m_connection_pins.end(); ++curr) + { + ShapeConnectionPin *pin = *curr; + double usingProportionalOffsets = pin->m_using_proportional_offsets; + double& xOffset = pin->m_x_offset; + double& yOffset = pin->m_y_offset; + ConnDirFlags& visDirs = pin->m_visibility_directions; + double tmpOffset; + + // Number of clockwise 90 degree rotations; + unsigned int rotationN = 0; + + if (usingProportionalOffsets) + { + // Translate to Origin. + xOffset -= 0.5; + yOffset -= 0.5; + + switch (transform) + { + case TransformationType_CW90: + rotationN = 3; + // Y <- inverse X, X <- inverse Y + tmpOffset = yOffset; + yOffset = xOffset; + xOffset = -tmpOffset; + break; + case TransformationType_CW180: + rotationN = 2; + // Y <- inverse Y, X <- inverse X + yOffset = -yOffset; + xOffset = -xOffset; + break; + case TransformationType_CW270: + rotationN = 1; + // Y <- X, X <- Y + tmpOffset = yOffset; + yOffset = -xOffset; + xOffset = tmpOffset; + break; + case TransformationType_FlipX: + // Y <- Y, X <- inverse X + xOffset = -xOffset; + break; + case TransformationType_FlipY: + // X <- inverse X, Y <- Y + yOffset = -yOffset; + break; + } + // Translate back. + xOffset += 0.5; + yOffset += 0.5; + } + else + { + // Using absolute offsets for pin. + + const Box shapeBox = pin->m_shape->polygon().offsetBoundingBox(0.0); + switch (transform) + { + case TransformationType_CW90: + rotationN = 3; + // Y <- inverse X, X <- inverse Y + tmpOffset = yOffset; + yOffset = xOffset; + xOffset = absoluteOffsetInverse(tmpOffset, shapeBox, XDIM); + break; + case TransformationType_CW180: + rotationN = 2; + // Y <- inverse Y, X <- inverse X + yOffset = absoluteOffsetInverse(yOffset, shapeBox, YDIM); + xOffset = absoluteOffsetInverse(xOffset, shapeBox, XDIM); + break; + case TransformationType_CW270: + rotationN = 1; + // Y <- X, X <- Y + tmpOffset = yOffset; + yOffset = absoluteOffsetInverse(xOffset, shapeBox, YDIM); + xOffset = tmpOffset; + break; + case TransformationType_FlipX: + // Y <- Y, X <- inverse X + xOffset = absoluteOffsetInverse(xOffset, shapeBox, XDIM); + break; + case TransformationType_FlipY: + // X <- inverse X, Y <- Y + yOffset = absoluteOffsetInverse(yOffset, shapeBox, YDIM); + break; + } + } + + if ( (visDirs & ConnDirAll) && (visDirs != ConnDirAll) ) + { + // Visibility is set, but not in all directions. + + const unsigned int dirU = 0; + const unsigned int dirR = 1; + const unsigned int dirD = 2; + const unsigned int dirL = 3; + + bool visInDir[4] = { false }; + if (visDirs & ConnDirUp) visInDir[dirU] = true; + if (visDirs & ConnDirRight) visInDir[dirR] = true; + if (visDirs & ConnDirDown) visInDir[dirD] = true; + if (visDirs & ConnDirLeft) visInDir[dirL] = true; + + if (transform == TransformationType_FlipY) + { + bool tmpBool = visInDir[dirU]; + visInDir[dirU] = visInDir[dirD]; + visInDir[dirD] = tmpBool; + } + else if (transform == TransformationType_FlipX) + { + bool tmpBool = visInDir[dirL]; + visInDir[dirL] = visInDir[dirR]; + visInDir[dirR] = tmpBool; + } + + visDirs = ConnDirNone; + if (visInDir[(rotationN + dirU) % 4]) visDirs |= ConnDirUp; + if (visInDir[(rotationN + dirR) % 4]) visDirs |= ConnDirRight; + if (visInDir[(rotationN + dirD) % 4]) visDirs |= ConnDirDown; + if (visInDir[(rotationN + dirL) % 4]) visDirs |= ConnDirLeft; + } + pin->updatePositionAndVisibility(); + m_router->modifyConnectionPin(pin); + } +} + + +const Polygon& ShapeRef::polygon(void) const +{ + return m_polygon; +} + + +void ShapeRef::outputCode(FILE *fp) const +{ + fprintf(fp, " // shapeRef%u\n", id()); + fprintf(fp, " polygon = Polygon(%lu);\n", (unsigned long) polygon().size()); + for (size_t i = 0; i < polygon().size(); ++i) + { + fprintf(fp, " polygon.ps[%lu] = Point(%" PREC "g, %" PREC "g);\n", + (unsigned long) i, polygon().at(i).x, polygon().at(i).y); + } + + fprintf(fp, " "); + if (!m_connection_pins.empty()) + { + fprintf(fp, "ShapeRef *shapeRef%u = ", id()); + } + fprintf(fp, "new ShapeRef(router, polygon, %u);\n", id()); + for (ShapeConnectionPinSet::const_iterator curr = + m_connection_pins.begin(); + curr != m_connection_pins.end(); ++curr) + { + (*curr)->outputCode(fp); + } + fprintf(fp, "\n"); +} + + +Point ShapeRef::position(void) const +{ + Box bBox = routingBox(); + + Point centre; + + centre.x = bBox.min.x + (0.5 * (bBox.max.x - bBox.min.x)); + centre.y = bBox.min.y + (0.5 * (bBox.max.y - bBox.min.y)); + + return centre; +} + + +void ShapeRef::setCentrePos(const Point& newCentre) +{ + Point diff = newCentre - position(); + m_polygon.translate(diff.x, diff.y); +} + +} + -- cgit v1.2.3