use of org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment in project elk by eclipse.
the class SouthToNorthRoutingStrategy method calculateBendPoints.
@Override
public void calculateBendPoints(final HyperEdgeSegment segment, final double startPos, final double edgeSpacing) {
// We don't do anything with dummy segments; they are dealt with when their partner is processed
if (segment.isDummy()) {
return;
}
// Calculate coordinates for each port's bend points
double segmentY = startPos - segment.getRoutingSlot() * edgeSpacing;
for (LPort port : segment.getPorts()) {
double sourceX = port.getAbsoluteAnchor().x;
for (LEdge edge : port.getOutgoingEdges()) {
if (!edge.isSelfLoop()) {
LPort target = edge.getTarget();
double targetX = target.getAbsoluteAnchor().x;
if (Math.abs(sourceX - targetX) > OrthogonalRoutingGenerator.TOLERANCE) {
// We'll update these if we find that the segment was split
double currentY = segmentY;
HyperEdgeSegment currentSegment = segment;
KVector bend = new KVector(sourceX, currentY);
edge.getBendPoints().add(bend);
addJunctionPointIfNecessary(edge, currentSegment, bend, false);
// If this segment was split, we need two additional bend points
HyperEdgeSegment splitPartner = segment.getSplitPartner();
if (splitPartner != null) {
double splitX = splitPartner.getIncomingConnectionCoordinates().get(0);
bend = new KVector(splitX, currentY);
edge.getBendPoints().add(bend);
addJunctionPointIfNecessary(edge, currentSegment, bend, false);
// Advance to the split partner's routing slot
currentY = startPos - splitPartner.getRoutingSlot() * edgeSpacing;
currentSegment = splitPartner;
bend = new KVector(splitX, currentY);
edge.getBendPoints().add(bend);
addJunctionPointIfNecessary(edge, currentSegment, bend, false);
}
bend = new KVector(targetX, currentY);
edge.getBendPoints().add(bend);
addJunctionPointIfNecessary(edge, currentSegment, bend, false);
}
}
}
}
}
use of org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment in project elk by eclipse.
the class RoutingSlotAssigner method createDependencies.
/**
* Creates the necessary dependencies between the {@link SelfHyperLoop}s with the given indices. The lists must have
* a one-to-one correspondence between loops and segments, that is, the i-th loop must be represented by the i-th
* segment. The array says at which ports each loop is active.
*/
private void createDependencies(final SelfHyperLoop slLoop1, final SelfHyperLoop slLoop2, final boolean[][] labelCrossingMatrix) {
// Count the numbers of crossings that would ensue if placing to first segment above the second segment and
// vice versa
int firstAboveSecondCrossings = countCrossings(slLoop1, slLoop2);
int secondAboveFirstCrossings = countCrossings(slLoop2, slLoop1);
// Create dependencies
HyperEdgeSegment segment1 = slLoopToSegmentMap.get(slLoop1);
HyperEdgeSegment segment2 = slLoopToSegmentMap.get(slLoop2);
if (firstAboveSecondCrossings < secondAboveFirstCrossings) {
// The first loop should be above the second loop
HyperEdgeSegmentDependency.createAndAddRegular(segment1, segment2, secondAboveFirstCrossings - firstAboveSecondCrossings);
} else if (secondAboveFirstCrossings < firstAboveSecondCrossings) {
// The second loop should be above the first loop
HyperEdgeSegmentDependency.createAndAddRegular(segment2, segment1, firstAboveSecondCrossings - secondAboveFirstCrossings);
} else if (firstAboveSecondCrossings != 0 || labelsOverlap(slLoop1, slLoop2, labelCrossingMatrix)) {
// Either both orders cause the same number of crossings (and at least one), or the labels of the two loops
// overlap and the loops must thus be forced onto different slots
HyperEdgeSegmentDependency.createAndAddRegular(segment1, segment2, 0);
HyperEdgeSegmentDependency.createAndAddRegular(segment2, segment1, 0);
}
}
use of org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment in project elk by eclipse.
the class RoutingSlotAssigner method createCrossingGraph.
// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Crossing Graph
/**
* Create the crossing graph by creating one {@link HyperEdgeSegment} for each {@link SelfHyperLoop} and computing
* the proper dependencies between them.
*/
private void createCrossingGraph(final SelfLoopHolder slHolder, final boolean[][] labelCrossingMatrix) {
List<SelfHyperLoop> slLoops = slHolder.getSLHyperLoops();
// Create an edge segment for each loop
hyperEdgeSegments = new ArrayList<>(slLoops.size());
slLoopToSegmentMap = new HashMap<>();
for (SelfHyperLoop slLoop : slLoops) {
HyperEdgeSegment segment = new HyperEdgeSegment(null);
hyperEdgeSegments.add(segment);
slLoopToSegmentMap.put(slLoop, segment);
}
// To be able to quickly count crossings later, we remember for each loop whether it's active at a given port
// ID or not
slLoopActivityOverPorts = new HashMap<>();
computeLoopActivity(slHolder);
// collisions on sides without ports. The routing space will be compacted at a later step.
for (int firstIdx = 0; firstIdx < slLoops.size() - 1; firstIdx++) {
SelfHyperLoop slLoop1 = slHolder.getSLHyperLoops().get(firstIdx);
for (int secondIdx = firstIdx + 1; secondIdx < slLoops.size(); secondIdx++) {
createDependencies(slLoop1, slHolder.getSLHyperLoops().get(secondIdx), labelCrossingMatrix);
}
}
}
use of org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment in project elk by eclipse.
the class JsonDebugUtil method createDebugGraph.
/**
* Writes a debug graph for the given list of hypernodes.
*
* @param layeredGraph
* the layered graph
* @param hypernodes
* a list of hypernodes
* @return hypernode graph in JSON format.
*/
public static String createDebugGraph(final LGraph layeredGraph, final List<HyperEdgeSegment> hypernodes) {
StringWriter writer = new StringWriter();
beginGraph(writer, layeredGraph);
beginChildNodeList(writer, 1);
String indent1 = Strings.repeat(INDENT, 2);
// SUPPRESS CHECKSTYLE MagicNumber
String indent2 = Strings.repeat(INDENT, 3);
int edgeId = 0;
Iterator<HyperEdgeSegment> hypernodeIterator = hypernodes.iterator();
StringBuffer edges = new StringBuffer();
while (hypernodeIterator.hasNext()) {
HyperEdgeSegment hypernode = hypernodeIterator.next();
writer.write("\n" + indent1 + "{\n" + indent2 + "\"id\": \"n" + System.identityHashCode(hypernode) + "\",\n" + indent2 + "\"labels\": [ { \"text\": \"" + hypernode.toString() + "\" } ],\n" + indent2 + "\"width\": 50,\n" + indent2 + "\"height\": 25\n" + indent1 + "}");
if (hypernodeIterator.hasNext()) {
writer.write(",");
}
Iterator<HyperEdgeSegmentDependency> dependencyIterator = hypernode.getOutgoingSegmentDependencies().iterator();
while (dependencyIterator.hasNext()) {
HyperEdgeSegmentDependency dependency = dependencyIterator.next();
edges.append("\n" + indent1 + "{\n" + indent2 + "\"id\": \"e" + edgeId++ + "\",\n" + indent2 + "\"source\": \"n" + System.identityHashCode(hypernode) + "\",\n" + indent2 + "\"target\": \"n" + System.identityHashCode(dependency.getTarget()) + "\"\n" + indent1 + "},");
}
}
endChildNodeList(writer, 1);
if (edges.length() > 0) {
edges.deleteCharAt(edges.length() - 1);
}
writer.write(INDENT + "\"edges\": [" + edges + "\n" + INDENT + "]");
endGraph(writer);
return writer.toString();
}
use of org.eclipse.elk.alg.layered.p5edges.orthogonal.HyperEdgeSegment in project elk by eclipse.
the class DotDebugUtil method createDebugGraph.
/**
* Writes a debug graph for the given list of hypernodes.
*
* @param layeredGraph the layered graph
* @param hypernodes a list of hypernodes
* @return hypernodes graph in DOT format.
*/
public static String createDebugGraph(final LGraph layeredGraph, final List<HyperEdgeSegment> hypernodes) {
StringWriter writer = new StringWriter();
writer.write("digraph {\n");
// Write hypernode information
for (HyperEdgeSegment hypernode : hypernodes) {
writer.write(" " + hypernode.hashCode() + "[label=\"" + hypernode.toString() + "\"]\n");
}
// Write dependency information
for (HyperEdgeSegment hypernode : hypernodes) {
for (HyperEdgeSegmentDependency dependency : hypernode.getOutgoingSegmentDependencies()) {
writer.write(" " + hypernode.hashCode() + "->" + dependency.getTarget().hashCode() + "[label=\"" + dependency.getType().name() + " (" + dependency.getWeight() + ")\"]\n");
}
}
writer.write("}\n");
return writer.toString();
}
Aggregations