/// <summary>
        /// apply a number of heuristics to improve current routing
        /// </summary>
        internal static void FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings)
        {
// #if DEBUG && TEST_MSAGL
//             Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK());
// #endif
            //TimeMeasurer.DebugOutput("Initial cost = " + CostCalculator.Cost(metroGraphData, bundlingSettings));
            //TimeMeasurer.DebugOutput("Initial cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings));

            var adjuster = new NodePositionsAdjuster(metroGraphData, bundlingSettings);

            adjuster.GlueConflictingNodes();
            adjuster.UnglueEdgesFromBundleToSaveInk(true);

            var step     = 0;
            int MaxSteps = 10;

            while (++step < MaxSteps)
            {
/*#if DEBUG && TEST_MSAGL
 *              Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK());
 #endif*/
                //heuristics to improve routing

                bool progress = adjuster.GlueConflictingNodes();

                progress |= adjuster.RelaxConstrainedEdges();

                progress |= (step <= 3 && adjuster.UnglueEdgesFromBundleToSaveInk(false));


                progress |= adjuster.GlueCollinearNeighbors(step);

                progress |= (step == 3 && adjuster.RemoveDoublePathCrossings());

                if (!progress)
                {
                    break;
                }
            }

            //one SA has to be executed with bundle forces
            metroGraphData.cdtIntersections.ComputeForcesForBundles = true;
            adjuster.RemoveDoublePathCrossings();
            adjuster.UnglueEdgesFromBundleToSaveInk(true);
            while (adjuster.GlueConflictingNodes())
            {
            }
            metroGraphData.Initialize(true); //this time initialize the tight enterables also

//            HubDebugger.ShowHubs(metroGraphData, bundlingSettings);
            //TimeMeasurer.DebugOutput("NodePositionsAdjuster stopped after " + step + " steps");
            //HubDebugger.ShowHubs(metroGraphData, bundlingSettings, true);

            //TimeMeasurer.DebugOutput("Final cost: " + CostCalculator.Cost(metroGraphData, bundlingSettings));
            //TimeMeasurer.DebugOutput("Final cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings));
        }
        /// <summary>
        /// apply a number of heuristics to improve current routing
        /// </summary>
        internal static void FixRouting(MetroGraphData metroGraphData, BundlingSettings bundlingSettings) {
#if DEBUG && TEST_MSAGL
            Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK());
#endif
            //TimeMeasurer.DebugOutput("Initial cost = " + CostCalculator.Cost(metroGraphData, bundlingSettings));
            //TimeMeasurer.DebugOutput("Initial cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings));

            var adjuster = new NodePositionsAdjuster(metroGraphData, bundlingSettings);
            adjuster.GlueConflictingNodes();
            adjuster.UnglueEdgesFromBundleToSaveInk(true);

            var step = 0;
            int MaxSteps = 10;
            while (++step < MaxSteps) {
/*#if DEBUG && TEST_MSAGL
                Debug.Assert(metroGraphData.looseIntersections.HubPositionsAreOK());
#endif*/
                //heuristics to improve routing
                
                bool progress = adjuster.GlueConflictingNodes();

                progress |= adjuster.RelaxConstrainedEdges();

                progress |= (step <= 3 && adjuster.UnglueEdgesFromBundleToSaveInk(false));


                progress |= adjuster.GlueCollinearNeighbors(step);

                progress |= (step == 3 && adjuster.RemoveDoublePathCrossings());

                if (!progress) break;
            }

            //one SA has to be executed with bundle forces
            metroGraphData.cdtIntersections.ComputeForcesForBundles = true;
            adjuster.RemoveDoublePathCrossings();
            adjuster.UnglueEdgesFromBundleToSaveInk(true);
            while (adjuster.GlueConflictingNodes()) { }
            metroGraphData.Initialize(true); //this time initialize the tight enterables also

//            HubDebugger.ShowHubs(metroGraphData, bundlingSettings);
            //TimeMeasurer.DebugOutput("NodePositionsAdjuster stopped after " + step + " steps");
            //HubDebugger.ShowHubs(metroGraphData, bundlingSettings, true);

            //TimeMeasurer.DebugOutput("Final cost: " + CostCalculator.Cost(metroGraphData, bundlingSettings));
            //TimeMeasurer.DebugOutput("Final cost of forces: " + CostCalculator.CostOfForces(metroGraphData, bundlingSettings));
        }
Пример #3
0
        /// <summary>
        /// edge routing with Ordered Bundles:
        /// 1. route edges with bundling
        /// 2. nudge bundles and hubs
        /// 3. order paths
        /// </summary>
        protected override void RunInternal()
        {
            //TimeMeasurer.DebugOutput("edge bundling started");
            if (ThereAreOverlaps(TightHierarchy))
            {
                /*
                 * LayoutAlgorithmSettings.ShowDebugCurves(
                 *  TightHierarchy.GetAllLeaves().Select(p => new DebugCurve(100, 1, "black", p)).ToArray());*/
                Status = BundlingStatus.Overlaps;
                TimeMeasurer.DebugOutput("overlaps in edge bundling");
                return;
            }

            FixLocationsForHookAnywherePorts(geometryGraph.Edges);
            if (!RoutePathsWithSteinerDijkstra())
            {
                Status = BundlingStatus.EdgeSeparationIsTooLarge;
                return;
            }
            FixChildParentEdges();
            if (!bundlingSettings.StopAfterShortestPaths)
            {
                var metroGraphData = new MetroGraphData(regularEdges.Select(e => e.EdgeGeometry).ToArray(),
                                                        LooseHierarchy,
                                                        TightHierarchy,
                                                        bundlingSettings,
                                                        shortestPathRouter.Cdt,
                                                        EdgeLooseEnterable,
                                                        EdgeTightEnterable,
                                                        loosePolylineOfPort);
                NodePositionsAdjuster.FixRouting(metroGraphData, bundlingSettings);
                new EdgeNudger(metroGraphData, bundlingSettings).Run();
                //TimeMeasurer.DebugOutput("edge bundling ended");
            }
            RouteSelfEdges();
            FixArrowheads();
        }