use of org.eclipse.elk.alg.layered.intermediate.wrapping.BreakingPointInserter.BPInfo in project elk by eclipse.
the class BreakingPointProcessor method improveUnneccesarilyLongEdges.
/**
* Improvement step, reducing the length of edges that were wrapped back.
*/
private void improveUnneccesarilyLongEdges(final LGraph graph, final boolean forwards) {
final Predicate<LNode> check = forwards ? BPInfo::isEnd : BPInfo::isStart;
boolean didsome = false;
do {
didsome = false;
List<Layer> layers = forwards ? Lists.reverse(graph.getLayers()) : graph.getLayers();
for (Layer layer : layers) {
List<LNode> nodes = Lists.newArrayList(layer.getNodes());
if (!forwards) {
Lists.reverse(nodes);
}
for (LNode n : nodes) {
if (check.test(n)) {
LNode bpNode = n;
BPInfo bpInfo = n.getProperty(InternalProperties.BREAKING_POINT_INFO);
LNode dummy = forwards ? bpInfo.endInLayerDummy : bpInfo.startInLayerDummy;
didsome = dropDummies(bpNode, dummy, forwards, false);
}
}
}
} while (didsome);
}
use of org.eclipse.elk.alg.layered.intermediate.wrapping.BreakingPointInserter.BPInfo in project elk by eclipse.
the class BreakingPointProcessor method performWrapping.
/**
* Main wrapping procedure, placing the determined chunks one below the other.
*/
private void performWrapping(final LGraph graph) {
final List<Layer> layers = graph.getLayers();
final ListIterator<Layer> layerIt = layers.listIterator();
// add initial empty layer to account for break point start dummies
layerIt.add(new Layer(graph));
// iterate the layers from left to right
// as soon as a layer with a BREAKING POINT start dummy is encountered,
// the nodes of the next layer should be moved to the very first layer
// consequently 'wrapping' the graph
boolean reverse = false;
int idx = 1;
while (layerIt.hasNext()) {
Layer layer = layerIt.next();
Layer newLayer = layers.get(idx);
List<LNode> nodesToMove = Lists.newArrayList(layer.getNodes());
// remember an offset used for adding in-layer dummies later
int offset = nodesToMove.size();
// move the nodes to their new layer
for (LNode n : nodesToMove) {
n.setLayer(newLayer);
}
if (reverse) {
// important to introduce the chains of long edge dummies in reversed order
for (LNode n : Lists.reverse(nodesToMove)) {
for (LEdge e : Lists.newArrayList(n.getIncomingEdges())) {
// reverse the edge
e.reverse(graph, true);
graph.setProperty(InternalProperties.CYCLIC, true);
// insert proper dummy nodes for the newly created long edge
List<LEdge> dummyEdges = CuttingUtils.insertDummies(graph, e, offset);
// ameliorate breaking point info
BPInfo bpi = n.getProperty(InternalProperties.BREAKING_POINT_INFO);
LEdge startInLayerEdge = dummyEdges.get(dummyEdges.size() - 1);
bpi.startInLayerDummy = startInLayerEdge.getSource().getNode();
bpi.startInLayerEdge = startInLayerEdge;
bpi.endInLayerDummy = e.getTarget().getNode();
bpi.endInLayerEdge = e;
}
}
reverse = false;
} else {
if (!nodesToMove.isEmpty()) {
LNode aNode = nodesToMove.get(0);
if (aNode.getType() == NodeType.BREAKING_POINT) {
// next layer should be moved (it contains the breaking point end dummies)
reverse = true;
// start moving nodes to the very first layer
idx = -1;
}
}
}
idx++;
}
// remove old layers that are now empty
ListIterator<Layer> it = graph.getLayers().listIterator();
while (it.hasNext()) {
Layer l = it.next();
if (l.getNodes().isEmpty()) {
it.remove();
}
}
}
use of org.eclipse.elk.alg.layered.intermediate.wrapping.BreakingPointInserter.BPInfo in project elk by eclipse.
the class BreakingPointProcessor method improveMultiCutIndexEdges.
/**
* Improvement step, reducing the overall edge length of edges
* that span multiple cut indexes.
*/
private void improveMultiCutIndexEdges(final LGraph graph) {
for (Layer l : graph.getLayers()) {
for (LNode n : Lists.newArrayList(l.getNodes())) {
if (BPInfo.isStart(n)) {
BPInfo info = n.getProperty(InternalProperties.BREAKING_POINT_INFO);
if (info.prev == null && info.next != null) {
BPInfo current = info;
BPInfo next = info.next;
while (next != null) {
// drop the dummy chain
dropDummies(next.start, next.startInLayerDummy, false, true);
// update the in-layer indexes of subsequent nodes
updateIndexesAfter(current.end);
updateIndexesAfter(next.start);
updateIndexesAfter(next.startInLayerDummy);
updateIndexesAfter(next.endInLayerDummy);
// reconnect the edge
next.endInLayerEdge.setTarget(current.endInLayerEdge.getTarget());
current.endInLayerEdge.setTarget(null);
// throw out all the unnecessary stuff
current.end.setLayer(null);
next.start.setLayer(null);
next.startInLayerDummy.setLayer(null);
next.endInLayerDummy.setLayer(null);
// update BPInfo
BPInfo newInfo = new BPInfo(current.start, next.end, current.nodeStartEdge, next.startEndEdge, next.originalEdge);
newInfo.startInLayerDummy = current.startInLayerDummy;
newInfo.startInLayerEdge = current.startInLayerEdge;
newInfo.endInLayerDummy = current.endInLayerDummy;
newInfo.endInLayerEdge = next.endInLayerEdge;
newInfo.prev = current.prev;
newInfo.next = next.next;
current.start.setProperty(InternalProperties.BREAKING_POINT_INFO, newInfo);
next.end.setProperty(InternalProperties.BREAKING_POINT_INFO, newInfo);
next = next.next;
// continue with the newly assembled one (_not_ 'next')
current = newInfo;
}
}
}
}
}
}
use of org.eclipse.elk.alg.layered.intermediate.wrapping.BreakingPointInserter.BPInfo in project elk by eclipse.
the class BreakingPointRemover method process.
@Override
public void process(final LGraph graph, final IElkProgressMonitor progressMonitor) {
progressMonitor.begin("Breaking Point Removing", 1);
edgeRouting = graph.getProperty(LayeredOptions.EDGE_ROUTING);
for (Layer l : graph.getLayers()) {
for (LNode node : Lists.newArrayList(l.getNodes())) {
if (BPInfo.isEnd(node)) {
BPInfo bpi = node.getProperty(InternalProperties.BREAKING_POINT_INFO);
if (bpi.next == null) {
remove(graph, bpi);
}
}
}
}
progressMonitor.done();
}