Beispiel #1
0
        private ProximityOverlapRemoval RunOverlapRemoval(GeometryGraph graphCopy, GeometryGraph graphOriginal, HashSet <Tuple <int, int> > proximityEdges,
                                                          HashSet <Tuple <int, int, int> > proximityTriangles, List <Tuple <string, double> > statistics, OverlapRemovalSettings settings)
        {
            ProximityOverlapRemoval prism = new ProximityOverlapRemoval(graphCopy);

            prism.Settings = settings;
            Timer timer = new Timer();

            timer.Start();
            prism.RemoveOverlaps();
            timer.Stop();
            var cpuTimeSpan    = TimeSpan.FromSeconds(timer.Duration);
            var statCpuTime    = Tuple.Create("CPUTime", cpuTimeSpan.TotalSeconds);
            var statIterations = Tuple.Create("Iterations", (double)prism.LastRunIterations);

            var statEdgeLength = Statistics.Statistics.EdgeLengthDeviation(graphOriginal, graphCopy, proximityEdges);
            var statProcrustes =
                Statistics.Statistics.ProcrustesStatistics(graphOriginal.Nodes.Select(v => v.Center).ToList(),
                                                           graphCopy.Nodes.Select(v => v.Center).ToList());
            var statTriangleOrient = Statistics.Statistics.TriangleOrientation(graphOriginal, graphCopy, proximityTriangles);
            var statArea           = Statistics.Statistics.Area(graphCopy);


            statistics.Add(statCpuTime);
            statistics.Add(statIterations);
            statistics.Add(statEdgeLength);
            statistics.Add(statProcrustes);
            statistics.Add(statArea);
            statistics.Add(statTriangleOrient);
            return(prism);
        }
        internal static void Run(String description, Task task) {
#if DEBUG && TEST_MSAGL
            Timer t = new Timer();
            t.Start();
            task();
            t.Stop();

            Console.Write(description);
            Console.WriteLine(" executed in {0} sec.", String.Format("{0:0.00}", t.Duration));
#else
			//task();
#endif
        }
        //        private void CheckLayer(int[]l) {
        //      ///debug 
        //      
        // for (int i = 0; i < l.Length - 1; i++)
        //               if (NodesAreTooClose(l[i], l[i + 1]))
        //                    Console.WriteLine("nodes are too close");
        //        }
        //
        //        private bool NodesAreTooClose (int u, int v) {
        //            Anchor a = dataBase.Anchors[u], side1 = dataBase.Anchors[v];
        //           return a.Right + originalGraph.NodeSeparation > side1.Left;
        //       }

        LayerArrays CalculateLayers() {
            CreateGluedDagSkeletonForLayering();

            #region reporting

#if REPORTING
            Timer t = null;
            if (sugiyamaSettings.Reporting) {
                Report("calculating layers ... ");
                t = new Timer();
                t.Start();
            }
#endif

            #endregion

            LayerArrays layerArrays = CalculateLayerArrays();

            UpdateNodePositionData();

            #region reporting

#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.CurrentCulture, "done with layers for {0}\n", t.Duration));
            }
#endif

            #endregion

            return layerArrays;
        }
        void RunPostLayering() {
#if REPORTING
            Timer t = null;
            if (sugiyamaSettings.Reporting) {
                Report("Calculating edge splines... ");
                t = new Timer();
                t.Start();
            }
#endif
            EdgeRoutingSettings routingSettings = sugiyamaSettings.EdgeRoutingSettings;
            var mode = routingSettings.EdgeRoutingMode;
            if (constrainedOrdering != null) //we switch to splines when there are constraints, since the ordering of virtual nodes sometimes does not do a good job
                mode = EdgeRoutingMode.Spline;
            switch (mode) {
                case EdgeRoutingMode.SugiyamaSplines:
                    CalculateEdgeSplines();
                    break;
                case EdgeRoutingMode.StraightLine:
                    StraightLineEdges.SetStraightLineEdgesWithUnderlyingPolylines(originalGraph);
                    SetLabels();
                    break;
                case EdgeRoutingMode.Spline:
                    double padding = sugiyamaSettings.NodeSeparation/4;
                    double loosePadding = SplineRouter.ComputeLooseSplinePadding(sugiyamaSettings.NodeSeparation,
                                                                                 padding);
                    var router = new SplineRouter(originalGraph, padding, loosePadding, (Math.PI / 6), null);
                    router.Run();
                    SetLabels();
                    break;
                case EdgeRoutingMode.SplineBundling:
                    double coneAngle = routingSettings.ConeAngle;
                    padding = sugiyamaSettings.NodeSeparation/20;
                    loosePadding = SplineRouter.ComputeLooseSplinePadding(sugiyamaSettings.NodeSeparation, padding)*2;
                    if (sugiyamaSettings.EdgeRoutingSettings.BundlingSettings == null)
                        sugiyamaSettings.EdgeRoutingSettings.BundlingSettings = new BundlingSettings();
                    var br = new SplineRouter(originalGraph, padding, loosePadding, coneAngle,
                                              sugiyamaSettings.EdgeRoutingSettings.BundlingSettings);
                    br.Run();
                    SetLabels();
                    break;
                case EdgeRoutingMode.Rectilinear:
                case EdgeRoutingMode.RectilinearToCenter:
                    //todo: are these good values?
                    var rer = new RectilinearEdgeRouter(originalGraph, sugiyamaSettings.NodeSeparation/3,
                                                        sugiyamaSettings.NodeSeparation/4,
                                                        true,
                                                        sugiyamaSettings.EdgeRoutingSettings.UseObstacleRectangles);
                    rer.RouteToCenterOfObstacles = routingSettings.EdgeRoutingMode ==
                                                   EdgeRoutingMode.RectilinearToCenter;
                    rer.BendPenaltyAsAPercentageOfDistance = routingSettings.BendPenalty;
                    rer.Run();
                    SetLabels();
                    break;
            }
            originalGraph.BoundingBox = originalGraph.PumpTheBoxToTheGraphWithMargins();

#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.InvariantCulture, "splines done for {0}", t.Duration));
            }
#endif
        }
        override protected void RunInternal() {
#if REPORTING
            Timer t = null;
            if (sugiyamaSettings.Reporting) {
                Report("removing cycles ... ");
                t = new Timer();
                t.Start();
            }
#endif
            if (originalGraph.Nodes.Count > 0) {
                engineLayerArrays = CalculateLayers();
  
                if (!sugiyamaSettings.LayeringOnly)
                    RunPostLayering();
            } else
                originalGraph.boundingBox.SetToEmpty();

#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.InvariantCulture, "done for {0}, nodes {1} edges {2}", t.Duration,
                                     IntGraph.NodeCount, IntGraph.Edges.Count));
            }

            //SugiyamaLayoutSettings.ShowDatabase(database);
#endif
        }
        void CalculateEdgeSplines() {
#if REPORTING
            if (sugiyamaSettings.Reporting)
                Report("calculating splines ... ");
#endif
            var routing = new Routing(sugiyamaSettings, originalGraph, database, engineLayerArrays, properLayeredGraph,
                                      IntGraph);
#if REPORTING
            Timer t = null;
            if (sugiyamaSettings.Reporting) {
                t = new Timer();
                t.Start();
            }
#endif
            routing.Run();
#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.CurrentCulture, " {0}\n", t.Duration));
            }
#endif
        }
        LayerArrays YLayeringAndOrdering(LayerCalculator layering) {
            #region reporting

#if REPORTING
            Timer t = null;
            if (sugiyamaSettings.Reporting) {
                t = new Timer();
                Report("ylayering ... ");
                t.Start();
            }
#endif

            #endregion

            int[] yLayers = layering.GetLayers();
            Balancing.Balance(GluedDagSkeletonForLayering, yLayers, GetNodeCountsOfGluedDag(), null);
            yLayers = ExtendLayeringToUngluedSameLayerVertices(yLayers);

            #region reporting

#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration));
                Report("ordering ... ");
                t.Start();
            }
#endif

            #endregion

            var layerArrays = new LayerArrays(yLayers);
            //if (!SugiyamaSettings.UseEdgeBundling && (HorizontalConstraints == null || HorizontalConstraints.IsEmpty)) {
            if (HorizontalConstraints == null || HorizontalConstraints.IsEmpty) {
                layerArrays = YLayeringAndOrderingWithoutHorizontalConstraints(layerArrays);

                #region reporting

#if REPORTING
                if (sugiyamaSettings.Reporting) {
                    t.Stop();
                    Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration));
                }
#endif

                #endregion

                return layerArrays;
            }
            constrainedOrdering = new ConstrainedOrdering(originalGraph, IntGraph, layerArrays.Y, nodeIdToIndex,
                                                          database, sugiyamaSettings);
            constrainedOrdering.Calculate();
            properLayeredGraph = constrainedOrdering.ProperLayeredGraph;

            #region reporting

#if REPORTING
            if (sugiyamaSettings.Reporting) {
                t.Stop();
                Report(String.Format(CultureInfo.CurrentCulture, "{0}\n", t.Duration));
            }
#endif

            #endregion

            // SugiyamaLayoutSettings.ShowDatabase(this.database);
            return constrainedOrdering.LayerArrays;
        }
 static TimeMeasurer() {
     timer = new Timer();
     timer.Start();
 }