public GraphLayout getLayoutFromEmbeddedGraph()

in graphLayout/jetbrains.mps.graphLayout.orthogonalLayout/source_gen/jetbrains/mps/graphLayout/flowOrthogonalLayout/OrthogonalFlowLayouter.java [38:312]


  public GraphLayout getLayoutFromEmbeddedGraph(EmbeddedGraph embeddedGraph, LayoutInfo layoutInfo) {
    if (SHOW_INFO > 0) {
      System.out.println("initial graph: " + embeddedGraph);
    }
    Map<Node, Dimension> nodeSizes = MapSequence.fromMap(new LinkedHashMap<Node, Dimension>(16, (float) 0.75, false));
    for (Node node : SetSequence.fromSet(layoutInfo.getNodesWithSize())) {
      MapSequence.fromMap(nodeSizes).put(node, layoutInfo.getNodeSize(node));
    }
    Map<Edge, Dimension> edgeSizes = MapSequence.fromMap(new LinkedHashMap<Edge, Dimension>(16, (float) 0.75, false));
    for (Edge edge : SetSequence.fromSet(layoutInfo.getLabeledEdges())) {
      MapSequence.fromMap(edgeSizes).put(edge, layoutInfo.getLabelSize(edge));
    }
    Graph graph = embeddedGraph.getGraph();
    EdgesHistoryManager historyManager = new EdgesHistoryManager(graph);
    List<Edge> initialEdges = ListSequence.fromList(new ArrayList<Edge>());
    ListSequence.fromList(initialEdges).addSequence(ListSequence.fromList(graph.getEdges()));
    List<Node> initialNodes = ListSequence.fromList(new ArrayList<Node>());
    ListSequence.fromList(initialNodes).addSequence(SetSequence.fromSet(MapSequence.fromMap(nodeSizes).keySet()));
    Map<Dart, Integer> bends = MapSequence.fromMap(new HashMap<Dart, Integer>());
    Map<Dart, Integer> angles = MapSequence.fromMap(new HashMap<Dart, Integer>());
    for (Edge edge : ListSequence.fromList(graph.getEdges())) {
      if (ListSequence.fromList(embeddedGraph.getDarts(edge)).count() != 2) {

        throw new RuntimeException("botva!!!");
      }
    }
    QuasiOrthogonalRepresentation orthogonalRepresentation = new QuasiOrthogonalRepresentation();
    if (getUseRepresentationOptimizations()) {
      orthogonalRepresentation.setRealEdges(myRealEdges);
      orthogonalRepresentation.setRealNodes(myRealNodes);
      orthogonalRepresentation.setStraightEdges(myStraightEdges);
    }
    Tuples._2<Map<Dart, Integer>, Map<Dart, Integer>> pair = orthogonalRepresentation.getRepresentation(embeddedGraph);
    bends = pair._0();
    angles = pair._1();
    /*
      for (Face face : ListSequence.fromList(embeddedGraph.getFaces())) {
        System.out.println("face:");
        for (Dart dart : ListSequence.fromList(face.getDarts())) {
          System.out.println(dart + " b = " + MapSequence.fromMap(bends).get(dart));
        }
        for (Node node : ListSequence.fromList(graph.getNodes())) {
          for (Dart dart : ListSequence.fromList(embeddedGraph.getDartWithSource(node))) {
            System.out.println(dart + " = " + MapSequence.fromMap(angles).get(dart));
          }
        }
      }
    */
    for (Edge edge : ListSequence.fromList(graph.getEdges())) {
      for (Dart dart : ListSequence.fromList(embeddedGraph.getDarts(edge))) {
        /*
          if (MapSequence.fromMap(bends).get(dart) < 0 || MapSequence.fromMap(bends).get(dart) > 4) {
            throw new RuntimeException("botva!!!");
          }
        */
        if (MapSequence.fromMap(angles).get(dart) < 0 || MapSequence.fromMap(angles).get(dart) > 3) {
          throw new RuntimeException("botva!!!");
        }
      }
    }

    QuasiRepresentationModifier quasiModifier = new QuasiRepresentationModifier(embeddedGraph, bends, angles);
    quasiModifier.reduceToOrthogonalRepresentation();
    List<QuasiRepresentationModifier.Modification> modifications = quasiModifier.getModifications();
    Set<Edge> modifiedEdges = SetSequence.fromSet(new HashSet<Edge>());
    Set<Edge> newEdges = SetSequence.fromSet(new HashSet<Edge>());
    for (QuasiRepresentationModifier.Modification modification : ListSequence.fromList(modifications)) {
      SetSequence.fromSet(modifiedEdges).addSequence(ListSequence.fromList(modification.getModifiedEdges()));
      SetSequence.fromSet(newEdges).addSequence(ListSequence.fromList(modification.getNewEdges()));
    }
    Map<Edge, Edge> labeledEdges = MapSequence.fromMap(new HashMap<Edge, Edge>());
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      List<Edge> history = historyManager.getHistory(edge);
      if (SetSequence.fromSet(modifiedEdges).contains(edge)) {
        for (Edge historyEdge : ListSequence.fromList(history)) {
          if (SetSequence.fromSet(newEdges).contains(historyEdge)) {
            MapSequence.fromMap(labeledEdges).put(edge, historyEdge);
          }
        }
      } else {
        MapSequence.fromMap(labeledEdges).put(edge, edge);
      }
    }
    if (SHOW_INFO > 0) {
      System.out.println("modifications: ");
      for (QuasiRepresentationModifier.Modification modification : ListSequence.fromList(modifications)) {
        System.out.println(modification);
      }
    }
    OrthogonalRepresentation.replaceBendsByNodes(embeddedGraph, bends, angles);
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      Edge labeledEdge = getLabeledEdge(historyManager.getHistory(MapSequence.fromMap(labeledEdges).get(edge)));
      MapSequence.fromMap(labeledEdges).put(edge, labeledEdge);
    }
    Map<Dart, Direction2D> directions = OrthogonalRepresentation.getDirections(embeddedGraph, angles);
    if (SHOW_INFO > 0) {
      System.out.println("modified graph: " + embeddedGraph);
    }

    Map<Node, Map<Direction2D, Integer>> nodeDirectionSizes = this.getNodeDirectionSizes(initialNodes, nodeSizes);
    Map<Edge, Integer> edgeShifts = getEdgesShifts(modifications, directions, nodeSizes);

    NodeBoxesMaker boxesMaker = new NodeBoxesMaker(embeddedGraph, directions);
    boxesMaker.makeBoxes(nodeSizes);
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      Edge labeledEdge = MapSequence.fromMap(labeledEdges).get(edge);
      List<Edge> history = historyManager.getHistory(labeledEdge);
      int pos = 0;
      if (ListSequence.fromList(initialNodes).contains(labeledEdge.getSource())) {
        pos = 1;
      }
      MapSequence.fromMap(labeledEdges).put(edge, ListSequence.fromList(history).getElement(pos));
    }
    Map<Edge, Direction2D> labelDir = MapSequence.fromMap(new HashMap<Edge, Direction2D>());
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      Edge labeledEdge = MapSequence.fromMap(labeledEdges).get(edge);
      if (MapSequence.fromMap(directions).get(ListSequence.fromList(embeddedGraph.getDarts(labeledEdge)).first()).isHorizontal()) {
        MapSequence.fromMap(labelDir).put(edge, Direction2D.UP);
      } else {
        MapSequence.fromMap(labelDir).put(edge, Direction2D.RIGHT);
      }
    }
    Map<Edge, Node> labelCenters = MapSequence.fromMap(new HashMap<Edge, Node>());
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      MapSequence.fromMap(labelCenters).put(edge, splitEdge(MapSequence.fromMap(labeledEdges).get(edge), embeddedGraph, directions));
    }
    Set<Face> boxFaces = boxesMaker.getBoxFaces();
    Map<Edge, Integer> edgeLengths = boxesMaker.getBoxEdgeLengths();
    for (Node node : ListSequence.fromList(initialNodes)) {
      for (Edge edge : ListSequence.fromList(node.getEdges())) {
        Dart dart = embeddedGraph.getSourceDart(edge, node);
        MapSequence.fromMap(edgeLengths).put(edge, MapSequence.fromMap(MapSequence.fromMap(nodeDirectionSizes).get(node)).get(MapSequence.fromMap(directions).get(dart)));
      }
    }
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      Dimension size = MapSequence.fromMap(edgeSizes).get(edge);
      int length;
      if (MapSequence.fromMap(labelDir).get(edge).isHorizontal()) {
        length = size.height;
      } else {
        length = size.width;
      }
      for (Edge nodeEdge : ListSequence.fromList(MapSequence.fromMap(labelCenters).get(edge).getEdges())) {
        MapSequence.fromMap(edgeLengths).put(nodeEdge, length / 2 + getUnitLength());
      }
    }
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeShifts).keySet())) {
      Edge firstEdge = ListSequence.fromList(historyManager.getHistory(edge)).first();
      if (MapSequence.fromMap(edgeLengths).containsKey(firstEdge)) {
        MapSequence.fromMap(edgeLengths).put(firstEdge, MapSequence.fromMap(edgeLengths).get(firstEdge) + MapSequence.fromMap(edgeShifts).get(edge));
      } else {
        MapSequence.fromMap(edgeLengths).put(firstEdge, MapSequence.fromMap(edgeShifts).get(edge) + 2 * getUnitLength());
      }
    }
    ConstraintsGraph constraintsGraph = new ConstraintsGraph(embeddedGraph, directions);
    constraintsGraph.constructGraph(boxFaces);
    constraintsGraph.setUnitLength(getUnitLength());
    Map<Node, Point> coordinates = constraintsGraph.getCoordinates(edgeLengths, null);

    Map<Edge, Rectangle> labelRects = MapSequence.fromMap(new HashMap<Edge, Rectangle>());
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      MapSequence.fromMap(labelRects).put(edge, getLabelLayout(labelCenters, edge, coordinates, embeddedGraph, edgeSizes, directions));
    }
    Map<Edge, Integer> constraintEdgeLengths = MapSequence.fromMap(new HashMap<Edge, Integer>());
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(labelRects).keySet())) {
      Node center = MapSequence.fromMap(labelCenters).get(edge);
      boolean isHorizontal = MapSequence.fromMap(labelDir).get(edge).isVertical();
      Rectangle labelRect = MapSequence.fromMap(labelRects).get(edge);
      Rectangle rect;
      int width = labelRect.width + getUnitLength();
      int height = labelRect.height + getUnitLength();
      if (isHorizontal) {
        rect = new Rectangle(labelRect.x - getUnitLength() / 2, labelRect.y, width, height);
      } else {
        rect = new Rectangle(labelRect.x, labelRect.y - getUnitLength() / 2, width, height);
      }
      for (Node node : ListSequence.fromList(graph.getNodes())) {
        if (node == center) {
          continue;
        }
        Point point = MapSequence.fromMap(coordinates).get(node);
        if (rect.contains(point)) {
          if (isHorizontal) {
            Edge constraintEdge = constraintsGraph.addConstraintEdge(center, node, Direction2D.UP);
            MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, rect.height);

          } else {
            Edge constraintEdge = constraintsGraph.addConstraintEdge(center, node, Direction2D.RIGHT);
            MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, rect.width);

          }
        }
      }
      if (getAvoidLabelCrossings()) {
        for (Edge graphEdge : ListSequence.fromList(graph.getEdges())) {
          if (ListSequence.fromList(center.getEdges()).contains(graphEdge)) {
            continue;
          }
          if (MapSequence.fromMap(directions).get(ListSequence.fromList(embeddedGraph.getDarts(graphEdge)).first()).isHorizontal() != isHorizontal) {
            continue;
          }
          Point sourcePoint = MapSequence.fromMap(coordinates).get(graphEdge.getSource());
          Point targetPoint = MapSequence.fromMap(coordinates).get(graphEdge.getTarget());
          if (isHorizontal) {
            boolean isIntersecting = Util1D.insideClosedSegment(sourcePoint.x, targetPoint.x, rect.x) && Util1D.insideClosedSegment(sourcePoint.x, targetPoint.x, rect.x + rect.width);
            int dist = rect.y + rect.height - sourcePoint.y;
            if (isIntersecting && dist < rect.height) {
              Edge constraintEdge = constraintsGraph.addConstraintEdge(center, graphEdge.getSource(), Direction2D.UP);
              MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, rect.height);

            }
          } else {
            boolean isIntersecting = Util1D.insideClosedSegment(sourcePoint.y, targetPoint.y, rect.y) && Util1D.insideClosedSegment(sourcePoint.y, targetPoint.y, rect.y + rect.height);
            int dist = rect.x + rect.width - sourcePoint.x;
            if (isIntersecting && dist < rect.width) {
              Edge constraintEdge = constraintsGraph.addConstraintEdge(center, graphEdge.getSource(), Direction2D.RIGHT);
              MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, rect.width);
            }
          }
        }
      }
    }

    coordinates = constraintsGraph.getCoordinates(edgeLengths, constraintEdgeLengths);
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      MapSequence.fromMap(labelRects).put(edge, getLabelLayout(labelCenters, edge, coordinates, embeddedGraph, edgeSizes, directions));
    }
    List<Edge> edgeList = ListSequence.fromList(new ArrayList<Edge>());
    ListSequence.fromList(edgeList).addSequence(SetSequence.fromSet(MapSequence.fromMap(labelRects).keySet()));
    for (int i = 0; i < ListSequence.fromList(edgeList).count(); i++) {
      Edge edgeI = ListSequence.fromList(edgeList).getElement(i);
      Direction2D dirI = MapSequence.fromMap(labelDir).get(edgeI);
      Rectangle rectI = MapSequence.fromMap(labelRects).get(edgeI);
      for (int j = i + 1; j < ListSequence.fromList(edgeList).count(); j++) {
        Edge edgeJ = ListSequence.fromList(edgeList).getElement(j);
        Direction2D dirJ = MapSequence.fromMap(labelDir).get(edgeJ);
        Rectangle rectJ = MapSequence.fromMap(labelRects).get(edgeJ);
        if (rectI.intersects(rectJ)) {
          int shiftByDirI = rectJ.size(dirI) + rectI.size(dirI);
          int shiftByDirJ = rectJ.size(dirJ) + rectI.size(dirJ);
          if (shiftByDirJ < shiftByDirI) {
            Edge constraintEdge = constraintsGraph.addConstraintEdge(MapSequence.fromMap(labelCenters).get(edgeJ), MapSequence.fromMap(labelCenters).get(edgeI), dirJ);
            MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, shiftByDirJ - rectI.size(dirJ) / 2 + LABEL_DIST);
          } else {
            Edge constraintEdge = constraintsGraph.addConstraintEdge(MapSequence.fromMap(labelCenters).get(edgeI), MapSequence.fromMap(labelCenters).get(edgeJ), dirI);
            MapSequence.fromMap(constraintEdgeLengths).put(constraintEdge, shiftByDirI - rectJ.size(dirI) / 2 + LABEL_DIST);
          }
        }
      }
    }
    for (Edge edge : ListSequence.fromList(graph.getEdges())) {
      Point sourcePoint = MapSequence.fromMap(coordinates).get(edge.getSource());
      Point targetPoint = MapSequence.fromMap(coordinates).get(edge.getTarget());
      MapSequence.fromMap(edgeLengths).put(edge, Math.abs(sourcePoint.x - targetPoint.x) + Math.abs(sourcePoint.y - targetPoint.y));
    }
    coordinates = constraintsGraph.getCoordinates(edgeLengths, constraintEdgeLengths);

    GraphLayout graphLayout = GraphLayoutFactory.createGraphLayout(graph);
    for (Node node : ListSequence.fromList(initialNodes)) {
      Rectangle rect = this.getNodeLayout(coordinates, node, nodeDirectionSizes, nodeSizes);
      graphLayout.setLayoutFor(node, rect);
    }
    for (Edge edge : ListSequence.fromList(initialEdges)) {
      List<Point> edgeLayout = this.getEdgeLayout(edge, embeddedGraph, historyManager, coordinates, initialNodes, directions, nodeDirectionSizes);
      graphLayout.setLayoutFor(edge, edgeLayout);
    }
    for (Edge edge : SetSequence.fromSet(MapSequence.fromMap(edgeSizes).keySet())) {
      Rectangle rect = this.getLabelLayout(labelCenters, edge, coordinates, embeddedGraph, edgeSizes, directions);
      graphLayout.setLabelLayout(edge, rect);
    }
    for (QuasiRepresentationModifier.Modification modification : ListSequence.fromList(modifications)) {
      splitEdges(graphLayout, modification, edgeShifts);
    }
    return graphLayout;
  }