private Map constructSubclusterGraphEmbedding()

in graphLayout/jetbrains.mps.graphLayout.planarization/source_gen/jetbrains/mps/graphLayout/planarization/ClusterEmbeddingConstructor.java [198:320]


  private Map<Edge, Edge> constructSubclusterGraphEmbedding() {
    // Creating a subcluster graph, where each subcluster is represented by a single node, 
    // and finding embedding for it. 
    mySubclustersGraph = new Graph();
    Map<Node, Node> nodeMap = MapSequence.fromMap(new HashMap<Node, Node>());
    myNodeMap = nodeMap;
    mySubclustersMap = MapSequence.fromMap(new HashMap<INode, Node>());
    List<Node> subclusters = myGraph.getSubclusters(myCluster);
    for (Node subcluster : ListSequence.fromList(subclusters)) {
      Node clusterNode = mySubclustersGraph.createNode();
      for (Node node : myGraph.getNodesInCluster(subcluster)) {
        MapSequence.fromMap(nodeMap).put(node, clusterNode);
      }
      MapSequence.fromMap(mySubclustersMap).put(subcluster, clusterNode);
    }
    Map<Edge, Edge> invEdgeMap = MapSequence.fromMap(new HashMap<Edge, Edge>());
    for (Node source : SetSequence.fromSet(myClusterNodes)) {
      for (Edge edge : source.getOutEdges()) {
        Node target = edge.getTarget();
        if (SetSequence.fromSet(myClusterNodes).contains(target) && MapSequence.fromMap(nodeMap).get(source) != MapSequence.fromMap(nodeMap).get(target)) {
          Edge newEdge = mySubclustersGraph.connect(MapSequence.fromMap(nodeMap).get(source), MapSequence.fromMap(nodeMap).get(target));
          MapSequence.fromMap(invEdgeMap).put(newEdge, edge);
        }
      }
    }
    if (showInfo > 0) {
      System.out.println("i subgraph " + myCluster + ": " + mySubclustersGraph.getEdges());
    }
    Set<Edge> connectingEdges = ConnectivityComponents.makeConnected(mySubclustersGraph);
    if (showInfo > 0) {
      System.out.println("c subgraph " + myCluster + ": " + mySubclustersGraph.getEdges());
    }
    for (Edge edge : SetSequence.fromSet(connectingEdges)) {
      Node source = this.getRealNode(edge.getSource(), nodeMap);
      Node target = getRealNode(edge.getTarget(), nodeMap);
      Edge realEdge = myGraph.connect(source, target);
      MapSequence.fromMap(invEdgeMap).put(edge, realEdge);
    }
    GroupedGraphModificationSynchronizer synchronizer = new GroupedGraphModificationSynchronizer(mySubclustersGraph, myGraph, invEdgeMap);
    mySubEmbeddedGraph = EmbeddingFinderFactory.getFinder().find(mySubclustersGraph);
    if (showInfo > 0) {
      System.out.println("e subgraph " + myCluster + ": " + mySubclustersGraph.getEdges());
    }
    synchronizer.disconnect();

    if (ListSequence.fromList(myOuterEdgesOrder).count() > 0) {
      // Creating a special structure for processing outer edges. Syncronizer should be turned off 
      // due to this structure has no corresponding in initial graph. 
      int numShifts = 0;
      while (getSubcluster(ListSequence.fromList(myOuterEdgesOrder).first()) == getSubcluster(ListSequence.fromList(myOuterEdgesOrder).last()) && numShifts < ListSequence.fromList(myOuterEdgesOrder).count()) {
        ListSequence.fromList(myOuterEdgesOrder).insertElement(0, ListSequence.fromList(myOuterEdgesOrder).removeLastElement());
        numShifts++;
      }
      List<Edge> subClusterBorder = ListSequence.fromList(new ArrayList<Edge>(ListSequence.fromList(myOuterEdgesOrder).count()));
      myClusterBorder = ListSequence.fromList(new ArrayList<Edge>(ListSequence.fromList(myOuterEdgesOrder).count()));
      List<Edge> subOuterEdges = ListSequence.fromList(new ArrayList<Edge>(ListSequence.fromList(myOuterEdgesOrder).count()));
      List<Node> realBorderNodes = ListSequence.fromList(new ArrayList<Node>(ListSequence.fromList(myOuterEdgesOrder).count()));
      List<Node> subBorderNodes = ListSequence.fromList(new ArrayList<Node>(ListSequence.fromList(myOuterEdgesOrder).count()));
      for (Edge outerEdge : ListSequence.fromList(myOuterEdgesOrder)) {
        final Node realClusterNode = getClusterNode(outerEdge);
        boolean isSource = realClusterNode == outerEdge.getSource();
        List<Edge> realSplit = myGraph.splitEdge(outerEdge);
        ListSequence.fromList(realBorderNodes).addElement(ListSequence.fromList(realSplit).getElement(0).getTarget());
        Node subBorderNode = mySubclustersGraph.createNode();
        ListSequence.fromList(subBorderNodes).addElement(subBorderNode);
        Edge subOuterEdge;
        if (isSource) {
          subOuterEdge = mySubclustersGraph.connect(MapSequence.fromMap(nodeMap).get(realClusterNode), subBorderNode);
        } else {
          subOuterEdge = mySubclustersGraph.connect(subBorderNode, MapSequence.fromMap(nodeMap).get(realClusterNode));
        }
        Edge realOuterEdge = ListSequence.fromList(realSplit).findFirst(new IWhereFilter<Edge>() {
          public boolean accept(Edge it) {
            return ListSequence.fromList(it.getAdjacentNodes()).contains(realClusterNode);
          }
        });
        MapSequence.fromMap(invEdgeMap).put(subOuterEdge, realOuterEdge);
        ListSequence.fromList(subOuterEdges).addElement(subOuterEdge);
      }
      Face outerFace = new Face(mySubclustersGraph);
      for (int i = 0; i < ListSequence.fromList(myOuterEdgesOrder).count(); i++) {
        int next = i + 1;
        if (next == ListSequence.fromList(myOuterEdgesOrder).count()) {
          next = 0;
        }
        Edge realBorderEdge = myGraph.connect(ListSequence.fromList(realBorderNodes).getElement(i), ListSequence.fromList(realBorderNodes).getElement(next));
        ListSequence.fromList(myClusterBorder).addElement(realBorderEdge);
        Edge subBorderEdge = mySubclustersGraph.connect(ListSequence.fromList(subBorderNodes).getElement(i), ListSequence.fromList(subBorderNodes).getElement(next));
        ListSequence.fromList(subClusterBorder).addElement(subBorderEdge);
        MapSequence.fromMap(invEdgeMap).put(subBorderEdge, realBorderEdge);
        outerFace.addFirst(new Dart(subBorderEdge, ListSequence.fromList(subBorderNodes).getElement(next)));
      }
      // make myClusterBorder in correspondence with initial outer edges 
      for (int i = 0; i < numShifts; i++) {
        ListSequence.fromList(myClusterBorder).addElement(ListSequence.fromList(myClusterBorder).removeElementAt(0));
      }

      // Including this construction into subclusters graph embedding as an outer face. 
      Set<Edge> addedEdges = SetSequence.fromSet(new HashSet<Edge>());
      if (useSlowFaceFinder) {
        addedEdges = createOuterFaceWithFaceSelection(subBorderNodes, subOuterEdges, subClusterBorder);
      } else {
        Edge bridge = this.createOuterFace(subBorderNodes, subOuterEdges, subClusterBorder);
        SetSequence.fromSet(addedEdges).addElement(bridge);
      }
      mySubEmbeddedGraph.addFace(outerFace);
      mySubEmbeddedGraph.setOuterFace(outerFace);
      if (debugMode > 0) {
        CheckEmbeddedGraph.checkEmbeddedGraph(mySubEmbeddedGraph, false);
      }
      // Processing outer edges. 
      synchronizer = new GroupedGraphModificationSynchronizer(mySubclustersGraph, myGraph, invEdgeMap);
      for (Edge edge : ListSequence.fromList(subOuterEdges)) {
        if (SetSequence.fromSet(addedEdges).contains(edge)) {
          continue;
        }
        mySubclustersGraph.removeEdge(edge);
        ShortestPathEmbeddingFinder.restoreEdge(mySubEmbeddedGraph, edge, true);
      }
      synchronizer.disconnect();
    }
    return invEdgeMap;
  }