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);
}
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);
}
}
}
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;
}
}
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);
}
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;
}
}
}
Aggregations