static void RouteSimplHooksAndFillTheLists(Cluster rootCluster, List<Edge> inParentEdges,
     List<Edge> outParentEdges, EdgeRoutingSettings edgeRoutingSettings) {
     var padding = edgeRoutingSettings.Padding + edgeRoutingSettings.PolylinePadding;
     foreach (var cluster in rootCluster.AllClustersWidthFirstExcludingSelfAvoidingChildrenOfCollapsed().Where(c=>!c.IsCollapsed)) {
         RouteClusterParentInEdges(inParentEdges, edgeRoutingSettings, cluster, padding);
         RouteClusterParentOutEdges(outParentEdges, edgeRoutingSettings, cluster, padding);
     }
 }
        static void LabelParentEdgesAndMaybeRerouteThemNicely(GeometryGraph graph, List<Edge> inParentEdges,
            List<Edge> outParentEdges, EdgeRoutingSettings edgeRoutingSettings) {
            if (AllowedToRoute(inParentEdges, outParentEdges, edgeRoutingSettings)) {
                var shapeGroupRouter = new SplineRouter(graph, edgeRoutingSettings.Padding,
                    edgeRoutingSettings.PolylinePadding,
                    edgeRoutingSettings.RoutingToParentConeAngle, inParentEdges, outParentEdges);
                shapeGroupRouter.Run();
            }

            var labeledEdges = outParentEdges.Concat(inParentEdges).Where(e => e.Labels.Any());
            if (labeledEdges.Any()) {
                var elb = new EdgeLabelPlacement(graph.Nodes, labeledEdges);
                    //consider adding more nodes here: some sibling clusters maybe
                elb.Run();
            }

            /*//*************debug code start
            var parentEdges = inParentEdges.Concat(outParentEdges);
            var ll = new List<DebugCurve>();
            var marked = new Microsoft.Msagl.Core.DataStructures.Set<Node>();
            foreach (var e in parentEdges) {
                marked.Insert(e.Source);
                marked.Insert(e.Target);
                ll.Add(new DebugCurve(100, 1, "blue", e.Curve));
            }
            foreach (var c in graph.RootCluster.AllClustersDepthFirst()) {
                var color = marked.Contains(c) ? "red" : "green";
                ll.Add(new DebugCurve(100, 1, color, c.BoundaryCurve));
            }
            foreach (var c in graph.Nodes) {
                var color = marked.Contains(c) ? "red" : "green";
                ll.Add(new DebugCurve(100, 1, color, c.BoundaryCurve));
            }

            LayoutAlgorithmSettings.ShowDebugCurvesEnumeration(ll);
            */
            //*************debug code end
        }
 static bool AllowedToRoute(List<Edge> inParentEdges, List<Edge> outParentEdges,
     EdgeRoutingSettings edgeRoutingSettings) {
     return ShapeCreatorForRoutingToParents.NumberOfActiveNodesIsUnderThreshold(inParentEdges, outParentEdges,
         edgeRoutingSettings.
             SimpleSelfLoopsForParentEdgesThreshold);
 }
        void EndDragging(WinPoint p, MsaglPoint gp)
        {
            PanningStartOffset = null;
            if (MouseMode == DraggingMode.WindowZoom && DragWindowStart != null)
                DoWindowZoom(DragWindowStart.Value, gp);
            DragWindowStart = null;
            DrawDragWindow(gp);

            if (RouteEdgesAfterDragging && DrawingLayoutEditor.CurrentUndoAction is ObjectDragUndoRedoAction)
            {
                //RouteSelectedEdges((int)Graph.LayoutAlgorithmSettings.NodeSeparation);
                var settings = new EdgeRoutingSettings() { EdgeRoutingMode = Core.Routing.EdgeRoutingMode.Spline };
                DoEdgeRouting(Graph.GeometryGraph, settings, Graph.LayoutAlgorithmSettings.NodeSeparation);
            }
        }
        internal static void RouteParentEdges(GeometryGraph graph, EdgeRoutingSettings edgeRoutingSettings) {
            var inParentEdges = new List<Edge>();
            var outParentEdges = new List<Edge>();
            RouteSimplHooksAndFillTheLists(graph.RootCluster, inParentEdges, outParentEdges, edgeRoutingSettings);

            if (inParentEdges.Count > 0 || outParentEdges.Count > 0)
                LabelParentEdgesAndMaybeRerouteThemNicely(graph, inParentEdges, outParentEdges, edgeRoutingSettings);
        }
 private void OverrideGaphRoutingSettingsToolStripMenuItemClick(object sender, EventArgs e) {
     if (overrideGraphRoutingSettingsToolStripMenuItem.Checked)
         if (EdgeRoutingSettings == null)
             EdgeRoutingSettings = new EdgeRoutingSettings();
 }
        private void DoEdgeRouting(GeometryGraph gg, EdgeRoutingSettings settings, double nodeSeparation)
        {
            var mode = settings.EdgeRoutingMode;
            if (mode == EdgeRoutingMode.SugiyamaSplines)
            {
            }
            else
            {
                if (mode == EdgeRoutingMode.Rectilinear || mode == EdgeRoutingMode.RectilinearToCenter)
                {
                    RectilinearInteractiveEditor.CreatePortsAndRouteEdges(
                        nodeSeparation / 3,
                        nodeSeparation / 3,
                        gg.Nodes,
                        gg.Edges,
                        mode,
                        true);
                }
                else if (mode == EdgeRoutingMode.Spline || mode == EdgeRoutingMode.SplineBundling)
                {
                    /*var coneAngle = Math.PI / 6.0;
                    var nodePadding = nodeSeparation / 3;
                    var loosePadding = SplineRouter.ComputeLooseSplinePadding(nodeSeparation, nodePadding);*/
                    //if (mode == EdgeRoutingMode.Spline)
                    if (mode == EdgeRoutingMode.Spline)
                        settings.BundlingSettings = null;
                    new SplineRouter(gg, settings).Run(CancelToken);
                    //else
                    //BundledEdgeRouter.RouteEdgesInMetroMapStyle(gg, coneAngle, nodePadding, loosePadding, settings.BundlingSettings);
                }
                else if (mode == EdgeRoutingMode.StraightLine)
                {
                    new StraightLineEdges(gg.Edges, settings.Padding).Run(CancelToken);
                }

                // Place labels
                new EdgeLabelPlacement(gg).Run(CancelToken);

                if (CancelToken == null || !CancelToken.Canceled)
                {
                    //                    foreach (GeometryEdge e in gg.Edges)
                    //                      TransformUnderlyingPolyline(gg, e, (dg.LayoutAlgorithmSettings as SugiyamaLayoutSettings).Transformation);
                    gg.UpdateBoundingBox();
                    Dispatcher.BeginInvoke(Invalidate);
                }
            }
        }
        static void LoadDrawingGraph(string fileName, EdgeRoutingSettings edgeRoutingSettings, double bendPenalty) {
            var graph = Graph.Read(fileName);
            if (edgeRoutingSettings.EdgeRoutingMode == EdgeRoutingMode.Rectilinear || edgeRoutingSettings.EdgeRoutingMode == EdgeRoutingMode.RectilinearToCenter) {
                var sugiyamaSettings=new SugiyamaLayoutSettings();
                RouteRectEdgesOfGeomGraph(edgeRoutingSettings.EdgeRoutingMode, true ,
                                        edgeRoutingSettings.UseObstacleRectangles, bendPenalty, graph.GeometryGraph, sugiyamaSettings);
            } else {
                const double angle = 30 * Math.PI / 180;
                var router = new SplineRouter(graph.GeometryGraph, edgeRoutingSettings.Padding, edgeRoutingSettings.PolylinePadding, angle, edgeRoutingSettings.BundlingSettings);
                router.Run();

                TestPadding(graph.GeometryGraph);
#if DEBUG
                var gv = new GViewer();
                var f = new Form {
                    StartPosition = FormStartPosition.CenterScreen,
                    //     f.layerSeparationMult.Value = (decimal)(gwgraph.GraphAttr.LayerSep / gwgraph.GraphAttr.MinLayerSep);

                    Size = new Size(Screen.PrimaryScreen.WorkingArea.Width,
                                      Screen.PrimaryScreen.WorkingArea.Height)
                };
                f.SuspendLayout();
                f.Controls.Add(gv);
                gv.Dock = DockStyle.Fill;
                gv.NeedToCalculateLayout = false;
                gv.Graph = graph;
                f.ResumeLayout();

                f.ShowDialog();
#endif
            }
        }
        static void Main(string[] args) {
            var listFileNames = new List<string>();
            var geomFileNames = new List<string>();
            var dotFileSpecs = new List<string>();
            bool show = true;
            EdgeRoutingMode edgeRoutingMode = EdgeRoutingMode.SugiyamaSplines;
            bool useSparseVisibilityGraph = false;
            bool useObstacleRectangles = false;
#if DEBUG
            DisplayGeometryGraph.SetShowFunctions();
#endif
            const string badEdgeOption = "-edge";
            const string mdsOption = "-mds";
            const string initialLayoutOption = "-initl";

            const string phyloOption = "-phylo";
            bool phylo = false;

            const string multiedges = "-multi";
            bool multiedgesTest = false;

            const string testSaveOption = "-save";
            bool testSave = false;


            const string testConvexHullString = "-convexHull";
            bool testConvexHull = false;
            bool bundling = false;

            double bendPenalty = SsstRectilinearPath.DefaultBendPenaltyAsAPercentageOfDistance;

            int fileReps = 1;
            int randomShifts = 0;
            bool showForm = true;
            try {
                for (int iarg = 0; iarg < args.Length; ++iarg) {
                    string s = args[iarg].ToLower();

                    if ("converttogeom" == s) {
                        if (iarg > (args.Length - 3))
                            throw new ApplicationException(
                                "{0} option requires input .dot filename and output .geom filename");
                        ConvertDotToGeom(args[iarg + 1], args[iarg + 2]);
                        return;
                    }

                    if (s == "-devTrace") {
#if DEVTRACE
                        ++iarg;
                        if (iarg >= args.Length) {      // require one value
                            throw new ApplicationException("Missing filename for -" + s);
                        }

#if MSAGL_INTERNALS_NOT_VISIBLE
                        // Copied the one line from this method here because of access issues, signing, etc.
                        // with InternalsVisibleTo.
                        //DevTrace.AddListenerToFile(args[iarg]);
#else
                        // Use File.Create to overwrite any existing file.
                        Trace.Listeners.Add(new TextWriterTraceListener(File.Create(args[iarg])));
#endif

#else
                        Console.WriteLine("-devtrace requires the DEVTRACE build configuration");
                        return;
#endif
                    }

                    // Start with some specific tests that we'll just pass arguments to.
                    // These are not "-" prefixed.
                    if ("testbinaryqueue" == s) {
                        GenericBinaryHeapPriorityQueue<int>.Test();
                        showForm = false;
                    } else {
                        switch (s) {
                            case "deb11":
                                TestDeb11();
                                return;
                            case "treewithconstraints":
                                TreeWithConstraints();
                                return;
                            
                            case "testgrouprouting":
                                TestGroupRouting();
                                return;
                            case "-vdc":
                                if (iarg == args.Length - 1) {
                                    Console.WriteLine("argument is missing after -vdc");
                                    return;
                                }
#if DEBUG
                                ShowDebugCurves(args[iarg + 1]);
#endif
                                return;
                            case "-testportentry":
                                TestPortEntry();
                                return;
                            case "-geom": // must be before case "g":
                                geomFileNames.Add(args[iarg + 1]);
                                ++iarg;
                                showForm = false;
                                break;
                            case "-g": {
                                var edgeRoutingSettings = new EdgeRoutingSettings {
                                                                                      EdgeRoutingMode = edgeRoutingMode,
                                                                                      BundlingSettings =
                                                                                          bundling
                                                                                              ? new BundlingSettings()
                                                                                              : null,
                                                                                      UseObstacleRectangles =
                                                                                          useObstacleRectangles,
                                                                                      BendPenalty = bendPenalty
                                                                                  };

                                LoadGeomFiles(args.Skip(iarg + 1), edgeRoutingSettings, show);
                                return;
                            }
                            case "-drawinggraphs": {
                                var edgeRoutingSettings = new EdgeRoutingSettings {
                                                                                      EdgeRoutingMode = edgeRoutingMode,
                                                                                      BundlingSettings =
                                                                                          bundling
                                                                                              ? new BundlingSettings()
                                                                                              : null
                                                                                  };

                                LoadDrawingGraphs(args.Skip(iarg + 1), edgeRoutingSettings, bendPenalty);
                                return;
                            }
                            case "-gtest":
                                LoadGeomFilesTest(args.Skip(iarg + 1), edgeRoutingMode, useSparseVisibilityGraph,
                                                  useObstacleRectangles,
                                                  bendPenalty, 0.52359877559829882);
                                return;
                            case "-grouptest":
                                GroupRoutingTest();
                                return;
                            case "-groupbundling":
                                return;
                            case "-wbundling":
                                BundleWithWidths();
                                return;

                            case "-grouptestrect":
                                GroupRoutingTestRect();
                                return;
                            case "-grouptestspline":
                                GroupRoutingTestSpline();
                                return;
                            case "-geomtestcone":
                                LoadGeomFilesTest(args.Skip(iarg + 1), edgeRoutingMode, useSparseVisibilityGraph,
                                                  useObstacleRectangles,
                                                  bendPenalty, Math.PI/6);
                                return;
                            case "layerseparationwithtransform":
                                LayerSeparationWithTransform();
                                return;
                            case "testwaypoints":
                                TestWayPoints();
                                break;
                            case "-bundling":
                                bundling = true;
                                edgeRoutingMode = EdgeRoutingMode.SplineBundling;
                                break;
                            case "testsolver":
                                TestSolver();
                                showForm = false;
                                break;
                            case "testrouting":
                                TestRouting();
                                showForm = false;
                                break;
                            case "-rectsp":
                                edgeRoutingMode = EdgeRoutingMode.Rectilinear;
                                Console.WriteLine("setting rectsp");
                                break;
                            case "-sparsevg":
                                useSparseVisibilityGraph = true;
                                Console.WriteLine("setting sparseVg");
                                break;
                            case "-userect":
                                useObstacleRectangles = true;
                                Console.WriteLine("setting useRect");
                                break;
                            case "-bendpenalty":
                                bendPenalty = double.Parse(args[iarg + 1]);
                                Console.WriteLine("setting bendPenalty");
                                ++iarg;
                                break;
                            case "freespline":
                                edgeRoutingMode = EdgeRoutingMode.Spline;
                                Console.WriteLine("setting EdgeRoutingMode.Spline");
                                break;
                            case "-rectcenter":
                                edgeRoutingMode = EdgeRoutingMode.RectilinearToCenter;
                                Console.WriteLine("setting rectToCenter");
                                break;
                                //                            case "testspanner":
                                //#if TEST_MSAGL
                                //                                ConeSpannerTest.TestSpanner();
                                //#else
                                //                                Console.WriteLine("ConeSpannerTest is only available in TEST mode");
                                //#endif
                            default:
                                if (s.StartsWith(badEdgeOption)) {} else if (s.StartsWith(mdsOption)) {
                                    mds = true;
                                } else if (s.StartsWith(initialLayoutOption)) {
                                    FormStuff.initialLayout = true;
                                } else if (s.StartsWith("-bundling")) {
                                    bundling = true;
                                } else if (s.StartsWith(testConvexHullString)) {
                                    testConvexHull = true;
                                } else if (s == "-filereps")
                                    // This is probably used with -quiet.  Must come before StartsWith("-f") option.
                                    fileReps = Int32.Parse(args[++iarg]);
                                else if (s == "-randomshifts")
                                    randomShifts = Int32.Parse(args[++iarg]);
                                else if (s.StartsWith("-f")) {
                                    listFileNames.Add(GetFileSpec(args, ref iarg));
                                    showForm = false;
                                } else if (s.StartsWith("-p")) {
                                    dotFileSpecs.Add(GetFileSpec(args, ref iarg));
                                    showForm = false;
                                } else if ((s == "-noshow") || (s == "-quiet")) {
                                    show = false;
                                } else if (s == "-verbose") {
                                    Verbose = true;
                                } else if (s.StartsWith("-log:")) {
                                    // Microsoft.Msagl.Layout.LogFileName = s.Substring(5);
                                    Verbose = true;
                                } else if (s == multiedges) {
                                    multiedgesTest = true;
                                } else if (s == phyloOption) {
                                    phylo = true;
                                } else if (s == testSaveOption)
                                    testSave = true;
                                else Console.WriteLine("unknown option " + s);
                                break;
                        }
                    }
                }

                var sw = new Stopwatch();
                sw.Start();

                if (testConvexHull)
                    TestConvexHull();

                if (testSave)
                    TestSave();


                if (phylo)
                    TestPhylo();

                // if (useBrandes)
                // Layout.BrandesThreshold = 0;

                // if (verbose)
                // Microsoft.Msagl.Layout.Reporting = true;

                if (multiedgesTest)
                    TestMultiedges();

                // If both were specified, do listfiles first, then filespecs.
                foreach (string listFileName in listFileNames) {
                    ProcessFileList(listFileName, fileReps, show, mds, edgeRoutingMode, bendPenalty, bundling,
                                    randomShifts,
                                    useSparseVisibilityGraph, useObstacleRectangles);
                }
                foreach (string fileSpec in dotFileSpecs) {
                    ProcessFileSpec(fileSpec, fileReps, show, mds, edgeRoutingMode, bendPenalty, bundling, randomShifts,
                                    useSparseVisibilityGraph, useObstacleRectangles);
                }
                foreach (string geomFileName in geomFileNames) {
                    var edgeRoutingSettings = new EdgeRoutingSettings {
                                                                          EdgeRoutingMode = edgeRoutingMode,
                                                                          BundlingSettings =
                                                                              bundling ? new BundlingSettings() : null,
                                                                          UseObstacleRectangles = useObstacleRectangles,
                                                                          BendPenalty = bendPenalty
                                                                      };
                    LoadGeomFile(geomFileName, edgeRoutingSettings, show);
                }

                sw.Stop();
                var ts = sw.Elapsed;
                Console.WriteLine("  Elapsed time: {0:00}:{1:00}:{2:00}.{3:000}", ts.Hours, ts.Minutes, ts.Seconds,
                                  ts.Milliseconds);

                if (showForm) {
                    gViewer = new GViewer();
                    gViewer.MouseMove += Draw.GviewerMouseMove;
                    var form = FormStuff.CreateForm(gViewer);
                    Application.Run(form);
                }
            }
            catch (Exception e) {
                Console.WriteLine(e);
            }
            return;
        }
        static void LoadGeomFile(string s, EdgeRoutingSettings edgeRoutingSettings, bool show) {
            LayoutAlgorithmSettings settings;
            GeometryGraph geomGraph = GeometryGraphReader.CreateFromFile(s, out settings);
            if (geomGraph == null) {
                //Opens file "data.xml" and deserializes the object from it.
                var stream = File.Open(s, FileMode.Open);
                var formatter = new BinaryFormatter();
                geomGraph = (GeometryGraph) formatter.Deserialize(stream);
                geomGraph.RootCluster = new Cluster();
                stream.Close();
            }
            geomGraph.UpdateBoundingBox();
            if (FormStuff.initialLayout) {
                var l = new List<Cluster>();
                l.Add(geomGraph.RootCluster);
                var il = new InitialLayoutByCluster(geomGraph, new FastIncrementalLayoutSettings());
                il.Run();
            }
            else if (mds) {
                var mdsSettings = new MdsLayoutSettings
                { IterationsWithMajorization = 21,ScaleX = 1, ScaleY=1, RemoveOverlaps = true
                };
                var mdslayout = new MdsGraphLayout(mdsSettings, geomGraph);
                mdslayout.Run();
                var router = new SplineRouter(geomGraph, 1, 20, Math.PI / 6, edgeRoutingSettings.BundlingSettings);
                router.Run();
            }
            else {
                var sugiyamaSettings = (SugiyamaLayoutSettings) settings;
                if (edgeRoutingSettings.EdgeRoutingMode == EdgeRoutingMode.Rectilinear ||
                    edgeRoutingSettings.EdgeRoutingMode == EdgeRoutingMode.RectilinearToCenter) {
                    RouteRectEdgesOfGeomGraph(edgeRoutingSettings.EdgeRoutingMode, true, 
                                            edgeRoutingSettings.UseObstacleRectangles, edgeRoutingSettings.BendPenalty, geomGraph, sugiyamaSettings);
                } else {
                    const double angle = 30*Math.PI/180;
                    var router = new SplineRouter(geomGraph, 1, 20, angle, edgeRoutingSettings.BundlingSettings);
                    router.Run();

                    TestPadding(geomGraph);
                }
            }

#if DEBUG
            if (show) {
                geomGraph.UpdateBoundingBox();
                var b = geomGraph.BoundingBox;
                b.Pad(40);
                geomGraph.BoundingBox = b;
                DisplayGeometryGraph.ShowGraph(geomGraph);
            }
#endif
        }
 static void LoadDrawingGraphs(IEnumerable<string> fileNames, EdgeRoutingSettings edgeRoutingSettings, double bendPenalty) {
     foreach (var fileName in fileNames) {
         LoadDrawingGraph(fileName, edgeRoutingSettings, bendPenalty);
     }
 }
 static void LoadGeomFiles(IEnumerable<string> fileList, EdgeRoutingSettings edgeRoutingSettings, bool show) {
     foreach (string s in fileList)
         LoadGeomFile(s, edgeRoutingSettings, show);
 }
 /// <summary>
 /// Creates a spline group router for the given graph.
 /// </summary>
 public SplineRouter(GeometryGraph graph, EdgeRoutingSettings edgeRoutingSettings) :
     this(
     graph, edgeRoutingSettings.Padding, edgeRoutingSettings.PolylinePadding, edgeRoutingSettings.ConeAngle,
     edgeRoutingSettings.BundlingSettings) {}
        private void DoEdgeRouting(DrawingGraph dg, EdgeRoutingSettings settings, double nodeSeparation)
        {
            var gg = dg.GeometryGraph;
            var mode = settings.EdgeRoutingMode;
            if (mode == EdgeRoutingMode.Rectilinear || mode == EdgeRoutingMode.RectilinearToCenter) {
                RectilinearInteractiveEditor.CreatePortsAndRouteEdges(
                    nodeSeparation/3,
                    nodeSeparation/3,
                    gg.Nodes,
                    gg.Edges,
                    mode,
                    true);
            } else if (mode == EdgeRoutingMode.Spline || mode == EdgeRoutingMode.SplineBundling) {
                var coneAngle = Math.PI/6.0;
                var nodePadding = nodeSeparation/3;
                var loosePadding = SplineRouter.ComputeLooseSplinePadding(nodeSeparation, nodePadding);
                //if (mode == EdgeRoutingMode.Spline)
                new SplineRouter(gg, coneAngle, nodePadding, loosePadding, null).Run(CancelToken);
                //else
                //BundledEdgeRouter.RouteEdgesInMetroMapStyle(gg, coneAngle, nodePadding, loosePadding, settings.BundlingSettings);
            }

            // Place labels
            new EdgeLabelPlacement(gg).Run(CancelToken);

            if (!CancelToken.Canceled) {
                foreach (GeometryEdge e in gg.Edges)
                    TransformUnderlyingPolyline(gg, e,
                                                (dg.LayoutAlgorithmSettings as SugiyamaLayoutSettings).Transformation);
                gg.UpdateBoundingBox();
            }
        }
 static void RouteClusterParentInEdges(List<Edge> inParentEdges, EdgeRoutingSettings edgeRoutingSettings, Cluster cluster,
     double padding) {
     foreach (var e in cluster.InEdges.Where(e => IsDescendant(e.Source, cluster))) {
         double ePadding = Math.Max(padding, 1.5*ArrowlengthAtTarget(e));
         var hookPort = e.TargetPort as HookUpAnywhereFromInsidePort;
         if (hookPort == null)
             e.TargetPort = hookPort = new HookUpAnywhereFromInsidePort(() => cluster.BoundaryCurve);
         hookPort.HookSize = ePadding;
         e.Curve = StraightLineEdges.CreateLoop(e.Source.BoundingBox, cluster.BoundingBox, ePadding, false);
         Arrowheads.TrimSplineAndCalculateArrowheads(e, e.Curve, false,
             edgeRoutingSettings.KeepOriginalSpline);
         inParentEdges.Add(e);
     }
 }
        public void RouteSelectedEdges(int separation)
        {
            double nodeSeparation = Graph.LayoutAlgorithmSettings.NodeSeparation;
            double nodePadding = nodeSeparation / 3;
            double loosePadding = SplineRouter.ComputeLooseSplinePadding(nodeSeparation, nodePadding);
            BundlingSettings bundlingSettings = new BundlingSettings() { EdgeSeparation = separation, CreateUnderlyingPolyline = true };
            EdgeRoutingSettings settings = new EdgeRoutingSettings() { BundlingSettings = bundlingSettings, EdgeRoutingMode = EdgeRoutingMode };
            if (settings.EdgeRoutingMode == EdgeRoutingMode.SugiyamaSplines)
                settings.EdgeRoutingMode = EdgeRoutingMode.Spline;

            if (Nodes().Any(n => n.MarkedForDragging))
            {
                Dictionary<DNode, GeometryNode> nodesThisToAux = new Dictionary<DNode, GeometryNode>();
                Dictionary<DEdge, GeometryEdge> edgesThisToAux = new Dictionary<DEdge, GeometryEdge>();
                GeometryGraph ggAux = new GeometryGraph();
                foreach (DNode node in Nodes())
                {
                    var n = new GeometryNode()
                    {
                        BoundaryCurve = node.GeometryNode.BoundaryCurve,
                        GeometryParent = ggAux,
                        Padding = node.GeometryNode.Padding,
                    };
                    ggAux.Nodes.Add(n);
                    nodesThisToAux[node] = n;
                }

                foreach (DNode node in Nodes().Where(n => n.MarkedForDragging))
                {
                    foreach (DEdge edge in node.Edges)
                    {
                        if (!edgesThisToAux.ContainsKey(edge))
                        {
                            var e = new GeometryEdge(nodesThisToAux[edge.Source], nodesThisToAux[edge.Target]);
                            if (edge.Source == edge.Target)
                                nodesThisToAux[edge.Source].AddSelfEdge(e);
                            else
                            {
                                nodesThisToAux[edge.Source].AddOutEdge(e);
                                nodesThisToAux[edge.Target].AddInEdge(e);
                            }
                            ggAux.Edges.Add(e);
                            edgesThisToAux[edge] = e;
                        }
                    }

                    /*ggAux.Nodes.Add(node.GeometryNode);
                    if (node.MarkedForDragging)
                    {
                        foreach (DEdge edge in node.Edges)
                        {
                            if (!ggAux.Nodes.Contains(edge.Source.GeometryNode))
                                ggAux.Nodes.Add(edge.Source.GeometryNode);
                            if (!ggAux.Nodes.Contains(edge.Target.GeometryNode))
                                ggAux.Nodes.Add(edge.Target.GeometryNode);
                            if (!ggAux.Edges.Contains(edge.GeometryEdge))
                                ggAux.Edges.Add(edge.GeometryEdge);
                        }
                    }*/
                }

                DoEdgeRouting(ggAux, settings, nodeSeparation);

                //BundledEdgeRouter.RouteEdgesInMetroMapStyle(ggAux, Math.PI / 6.0, nodePadding, loosePadding, settings);
                /*var router = new SplineRouter(ggAux, settings);
                router.Run(CancelToken);
                VerifyPolylines();*/
                foreach (var kv in edgesThisToAux)
                    kv.Key.GeometryEdge.EdgeGeometry = kv.Value.EdgeGeometry;
            }
            else
            {
                DoEdgeRouting(Graph.GeometryGraph, settings, nodeSeparation);
                //BundledEdgeRouter.RouteEdgesInMetroMapStyle(Graph.GeometryGraph, Math.PI / 6.0, nodePadding, loosePadding, settings);
                /*var router = new SplineRouter(Graph.GeometryGraph, settings);
                router.Run(CancelToken);
                VerifyPolylines();*/
            }

            //Invalidate();
        }
 public static void RouteBundledEdges(GeometryGraph geometryGraph, bool measureTime, EdgeRoutingSettings edgeRoutingSettings) {
     Stopwatch sw=null;
     if (measureTime) {
         sw=new Stopwatch();
         sw.Start();
     }
     BundleRouter br = new BundleRouter(geometryGraph, edgeRoutingSettings.ConeAngle,
                                        edgeRoutingSettings.Padding, edgeRoutingSettings.PolylinePadding, edgeRoutingSettings.BundlingSettings);
     br.Run();
     if (sw != null) {
         sw.Stop();
         Console.WriteLine("bundling takes " + sw.Elapsed);
     }
 }
        void RoutingSettingsToolStripMenuItemClick(object sender, EventArgs e) {
            if (EdgeRoutingSettings == null)
                EdgeRoutingSettings = new EdgeRoutingSettings();

            if(overrideGraphRoutingSettingsToolStripMenuItem.Checked)
                EdgeRoutingSettings.EdgeRoutingMode = EdgeRoutingMode;

            Form f = CreateFormForEdgeRoutingSettings();

            var dr = f.ShowDialog();
            if (dr == DialogResult.OK) {
                overrideGraphRoutingSettingsToolStripMenuItem.Checked = true;
                EdgeRoutingMode = EdgeRoutingSettings.EdgeRoutingMode;
                RouteEdges();
            }
        }