Search in sources :

Example 11 with SelfHyperLoop

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop in project elk by eclipse.

the class OrthogonalSelfLoopRouter method addOuterBendPoint.

// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Actual Bend Point Computation
private void addOuterBendPoint(final SelfLoopEdge slEdge, final SelfLoopPort slPort, final double[][] routingSlotPositions, final KVectorChain bendPoints) {
    SelfHyperLoop slLoop = slEdge.getSLHyperLoop();
    LPort lPort = slPort.getLPort();
    PortSide portSide = lPort.getSide();
    // We'll start by computing the coordinate of the level we're on
    KVector result = getBaseVector(portSide, slLoop.getRoutingSlot(portSide), routingSlotPositions);
    // Now take care of the port anchor
    KVector anchor = lPort.getPosition().clone().add(lPort.getAnchor());
    switch(lPort.getSide()) {
        case NORTH:
        case SOUTH:
            result.x += anchor.x;
            break;
        case EAST:
        case WEST:
            result.y += anchor.y;
            break;
        default:
            assert false;
    }
    bendPoints.add(result);
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) PortSide(org.eclipse.elk.core.options.PortSide) KVector(org.eclipse.elk.core.math.KVector) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Example 12 with SelfHyperLoop

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop in project elk by eclipse.

the class OrthogonalSelfLoopRouter method initializeWithMaxLabelHeight.

/**
 * Initializes the entry for each routing slot on the north or south sides with the maximum height of labels it
 * houses.
 */
private void initializeWithMaxLabelHeight(final double[][] positions, final SelfLoopHolder slHolder, final PortSide portSide) {
    assert portSide == PortSide.NORTH || portSide == PortSide.SOUTH;
    double[] sidePositions = positions[portSide.ordinal()];
    for (SelfHyperLoop slLoop : slHolder.getSLHyperLoops()) {
        SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
        if (slLabels != null && slLabels.getSide() == portSide) {
            int routingSlot = slLoop.getRoutingSlot(portSide);
            sidePositions[routingSlot] = Math.max(sidePositions[routingSlot], slLabels.getSize().y);
        }
    }
}
Also used : SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Example 13 with SelfHyperLoop

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop in project elk by eclipse.

the class OrthogonalSelfLoopRouter method addCornerBendPoints.

private void addCornerBendPoints(final SelfLoopEdge slEdge, final EdgeRoutingDirection routingDirection, final double[][] routingSlotPositions, final KVectorChain bendPoints) {
    // Check if we even need corner bend points
    LPort lSourcePort = slEdge.getSLSource().getLPort();
    LPort lTargetPort = slEdge.getSLTarget().getLPort();
    if (lSourcePort.getSide() == lTargetPort.getSide()) {
        return;
    }
    SelfHyperLoop slLoop = slEdge.getSLHyperLoop();
    // Compute corner points
    PortSide currPortSide = lSourcePort.getSide();
    PortSide nextPortSide = null;
    while (currPortSide != lTargetPort.getSide()) {
        // Next port side depends on the direction we're going
        nextPortSide = routingDirection == EdgeRoutingDirection.CLOCKWISE ? currPortSide.right() : currPortSide.left();
        // Compute the coordinates contributes by the current and next port sides
        KVector currPortSideComponent = getBaseVector(currPortSide, slLoop.getRoutingSlot(currPortSide), routingSlotPositions);
        KVector nextPortSideComponent = getBaseVector(nextPortSide, slLoop.getRoutingSlot(nextPortSide), routingSlotPositions);
        // One has its x coordinate set, the other has its y coordinate set -- their sum is our final bend point
        bendPoints.add(currPortSideComponent.add(nextPortSideComponent));
        // Advance to next port side
        currPortSide = nextPortSide;
    }
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) PortSide(org.eclipse.elk.core.options.PortSide) KVector(org.eclipse.elk.core.math.KVector) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Example 14 with SelfHyperLoop

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop in project elk by eclipse.

the class OrthogonalSelfLoopRouter method routeSelfLoops.

@Override
public void routeSelfLoops(final SelfLoopHolder slHolder) {
    LNode lNode = slHolder.getLNode();
    KVector nodeSize = lNode.getSize();
    LMargin nodeMargins = lNode.getMargin();
    double edgeEdgeDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_EDGE_EDGE);
    double edgeLabelDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_EDGE_LABEL);
    double nodeSLDistance = LGraphUtil.getIndividualOrInherited(lNode, LayeredOptions.SPACING_NODE_SELF_LOOP);
    LMargin newNodeMargins = new LMargin();
    newNodeMargins.set(nodeMargins);
    // Compute how far away from the node each routing slot on each side is (this takes labels into account)
    double[][] routingSlotPositions = computeRoutingSlotPositions(slHolder, edgeEdgeDistance, edgeLabelDistance, nodeSLDistance);
    for (SelfHyperLoop slLoop : slHolder.getSLHyperLoops()) {
        for (SelfLoopEdge slEdge : slLoop.getSLEdges()) {
            LEdge lEdge = slEdge.getLEdge();
            EdgeRoutingDirection routingDirection = computeEdgeRoutingDirection(slEdge);
            // Compute orthogonal bend points and give subclasses a chance to modify them to suit their particular
            // routing style. The default implementation in this class won't change the bend points.
            KVectorChain bendPoints = computeOrthogonalBendPoints(slEdge, routingDirection, routingSlotPositions);
            bendPoints = modifyBendPoints(slEdge, routingDirection, bendPoints);
            lEdge.getBendPoints().clear();
            lEdge.getBendPoints().addAll(bendPoints);
            bendPoints.stream().forEach(bp -> updateNewNodeMargins(nodeSize, newNodeMargins, bp));
        }
        // Place the self loop's labels (the edges were routed such that there is enough space available)
        SelfHyperLoopLabels slLabels = slLoop.getSLLabels();
        if (slLabels != null) {
            placeLabels(slLoop, slLabels, routingSlotPositions, edgeLabelDistance);
            updateNewNodeMargins(nodeSize, newNodeMargins, slLabels);
        }
    }
    // Update the node's margins to include the space required for self loops
    nodeMargins.set(newNodeMargins);
}
Also used : LMargin(org.eclipse.elk.alg.layered.graph.LMargin) LEdge(org.eclipse.elk.alg.layered.graph.LEdge) KVectorChain(org.eclipse.elk.core.math.KVectorChain) SelfLoopEdge(org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopEdge) SelfHyperLoopLabels(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels) LNode(org.eclipse.elk.alg.layered.graph.LNode) KVector(org.eclipse.elk.core.math.KVector) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Example 15 with SelfHyperLoop

use of org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop in project elk by eclipse.

the class OrthogonalSelfLoopRouter method computeEdgeRoutingDirection.

/**
 * Computes how the edge reaches its target.
 */
private EdgeRoutingDirection computeEdgeRoutingDirection(final SelfLoopEdge slEdge) {
    LPort sourceLPort = slEdge.getSLSource().getLPort();
    PortSide sourcePortSide = sourceLPort.getSide();
    LPort targetLPort = slEdge.getSLTarget().getLPort();
    PortSide targetPortSide = targetLPort.getSide();
    if (sourcePortSide == targetPortSide) {
        // on port IDs
        return sourceLPort.id < targetLPort.id ? EdgeRoutingDirection.CLOCKWISE : EdgeRoutingDirection.COUNTER_CLOCKWISE;
    } else if (sourcePortSide.right() == targetPortSide) {
        return EdgeRoutingDirection.CLOCKWISE;
    } else if (sourcePortSide.left() == targetPortSide) {
        return EdgeRoutingDirection.COUNTER_CLOCKWISE;
    } else {
        assert sourcePortSide.opposed() == targetPortSide;
        // What we do here totally depends on the port sides occupied by the self hyper loop. We prefer clockwise
        // routing.
        SelfHyperLoop slLoop = slEdge.getSLHyperLoop();
        if (slLoop.getOccupiedPortSides().contains(sourcePortSide.right())) {
            return EdgeRoutingDirection.CLOCKWISE;
        } else {
            assert slLoop.getOccupiedPortSides().contains(sourcePortSide.left());
            return EdgeRoutingDirection.COUNTER_CLOCKWISE;
        }
    }
}
Also used : LPort(org.eclipse.elk.alg.layered.graph.LPort) PortSide(org.eclipse.elk.core.options.PortSide) SelfHyperLoop(org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)

Aggregations

SelfHyperLoop (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoop)18 PortSide (org.eclipse.elk.core.options.PortSide)10 LPort (org.eclipse.elk.alg.layered.graph.LPort)6 ArrayList (java.util.ArrayList)4 SelfHyperLoopLabels (org.eclipse.elk.alg.layered.intermediate.loops.SelfHyperLoopLabels)4 SelfLoopPort (org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopPort)4 KVector (org.eclipse.elk.core.math.KVector)3 List (java.util.List)2 Collectors (java.util.stream.Collectors)2 SelfLoopHolder (org.eclipse.elk.alg.layered.intermediate.loops.SelfLoopHolder)2 InternalProperties (org.eclipse.elk.alg.layered.options.InternalProperties)2 HyperEdgeSegment (org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment)2 Arrays (java.util.Arrays)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 LinkedList (java.util.LinkedList)1 Map (java.util.Map)1 Queue (java.util.Queue)1 Set (java.util.Set)1 Stream (java.util.stream.Stream)1