internal MultiEdgeRouter(List<Edge[]> multiEdgeGeoms, InteractiveEdgeRouter interactiveEdgeRouter, IEnumerable<ICurve> nodeBoundaryCurves, BundlingSettings bundlingSettings, Func<EdgeGeometry, List<Shape>> transparentShapeSetter) { multiEdgeGeometries = multiEdgeGeoms.Select(l => l.Select(e => e.EdgeGeometry).ToArray()).ToList(); this.interactiveEdgeRouter = interactiveEdgeRouter; this.bundlingSettings = bundlingSettings; this.transparentShapeSetter = transparentShapeSetter; nodeTree = RectangleNode<ICurve>.CreateRectangleNodeOnData(nodeBoundaryCurves, c => c.BoundingBox); }
static void DrawEdgeWithPort(Edge edge, InteractiveEdgeRouter portRouter, double par0, double par1) { var port0 = new CurvePort(edge.Source.BoundaryCurve, par0); var port1 = new CurvePort(edge.Target.BoundaryCurve,par1); SmoothedPolyline sp; var spline = portRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(port0, port1, true, out sp); Arrowheads.TrimSplineAndCalculateArrowheads(edge.EdgeGeometry, edge.Source.BoundaryCurve, edge.Target.BoundaryCurve, spline, true, false); }
static void DemoRoutingFromPortToPort(GeometryGraph graph) { var edges = graph.Edges.ToArray(); SetCurvesToNull(edges); var portRouter = new InteractiveEdgeRouter(graph.Nodes.Select(n => n.BoundaryCurve), 3, 0.65*3, 0); portRouter.Run(); //calculates the whole visibility graph, takes a long time DrawEdgeWithPort(edges[0], portRouter, 0.3, 0.4); DrawEdgeWithPort(edges[1], portRouter, 0.7, 1.5*Math.PI); //I know here that my node boundary curves are ellipses so the parameters run from 0 to 2Pi //otherwise the curve parameter runs from curve.ParStart, to curve.ParEnd #if TEST LayoutAlgorithmSettings.ShowGraph(graph); #endif }
private void Route() { //foreach (var edge in graph.Edges) { // edge.EdgeGeometry.Curve = new LineSegment(edge.Source.Center, edge.Target.Center); //} //return; var edgeRouter = new InteractiveEdgeRouter(from v in AllLabels() select v.BoundaryCurve, this.locationRadius / 3, this.locationRadius/9, Math.PI/6); edgeRouter.Run();//it will calculate the visibility graph edgeRouter.GetVisibilityGraph(); foreach (var edge in Edges()) { SmoothedPolyline sp; edge.EdgeGeometry.Curve = edgeRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady(new FloatingPort(edge.Source.BoundaryCurve, edge.Source.Center), new FloatingPort(null, edge.Target.Center), true, out sp); TrimAtSource(edge); } }
/// <summary> /// prepares for edge dragging /// </summary> public void PrepareForEdgeDragging() { if(viewer.Graph == null) return; if(DraggingStraightLine()) return; var settings = viewer.Graph.LayoutAlgorithmSettings; if(!RectRouting(settings.EdgeRoutingSettings.EdgeRoutingMode)) { if(InteractiveEdgeRouter == null) { var padding = settings.NodeSeparation / 3; var loosePadding = 0.65 * padding; InteractiveEdgeRouter = new InteractiveEdgeRouter(EnumerateNodeBoundaryCurves(),padding, loosePadding,0); } } }
void RouteEdgeGeometry(Edge edge, InteractiveEdgeRouter iRouter) { var edgeGeometry = edge.EdgeGeometry; var addedEdges = new List<VisibilityEdge>(); if (!(edgeGeometry.SourcePort is HookUpAnywhereFromInsidePort)) addedEdges.AddRange(AddVisibilityEdgesFromPort(edgeGeometry.SourcePort)); if (!(edgeGeometry.TargetPort is HookUpAnywhereFromInsidePort)) addedEdges.AddRange(AddVisibilityEdgesFromPort(edgeGeometry.TargetPort)); SmoothedPolyline smoothedPolyline; if (!ApproximateComparer.Close(edgeGeometry.SourcePort.Location, edgeGeometry.TargetPort.Location)) edgeGeometry.Curve = iRouter.RouteSplineFromPortToPortWhenTheWholeGraphIsReady( edgeGeometry.SourcePort, edgeGeometry.TargetPort, true, out smoothedPolyline); else { edgeGeometry.Curve = Edge.RouteSelfEdge(edgeGeometry.SourcePort.Curve, Math.Max(LoosePadding * 2, edgeGeometry.GetMaxArrowheadLength()), out smoothedPolyline); } edgeGeometry.SmoothedPolyline = smoothedPolyline; if (edgeGeometry.Curve == null) throw new NotImplementedException(); foreach (var visibilityEdge in addedEdges) VisibilityGraph.RemoveEdge(visibilityEdge); Arrowheads.TrimSplineAndCalculateArrowheads(edgeGeometry, edgeGeometry.SourcePort.Curve, edgeGeometry.TargetPort.Curve, edgeGeometry.Curve, false, KeepOriginalSpline); if (ReplaceEdgeByRails != null) ReplaceEdgeByRails(edge); // SetTransparency(transparentShapes, false); }
InteractiveEdgeRouter CreateInteractiveEdgeRouter(IEnumerable<Shape> obstacleShapes) { //we need to create a set here because one loose polyline can hold several original shapes var loosePolys = new Set<Polyline>(obstacleShapes.Select(sh => shapesToTightLooseCouples[sh].LooseShape.BoundaryCurve as Polyline)); var router = new InteractiveEdgeRouter { VisibilityGraph = visGraph, TightHierarchy = CreateTightObstacleHierarachy(obstacleShapes), LooseHierarchy = CreateLooseObstacleHierarachy(loosePolys), UseSpanner = true, LookForRoundedVertices = true, TightPadding = tightPadding, LoosePadding = LoosePadding, UseEdgeLengthMultiplier = UseEdgeLengthMultiplier, UsePolylineEndShortcutting = UsePolylineEndShortcutting, UseInnerPolylingShortcutting = UseInnerPolylingShortcutting, AllowedShootingStraightLines = AllowedShootingStraightLines, CacheCorners = CacheCornersForSmoothing, }; router.AddActivePolygons(loosePolys.Select(polyline => new Polygon(polyline))); return router; }
void RouteMultiEdges(List<Edge[]> multiEdges, InteractiveEdgeRouter interactiveEdgeRouter, Set<Shape> parents) { var mer = new MultiEdgeRouter(multiEdges, interactiveEdgeRouter, parents.SelectMany(p => p.Children).Select(s => s.BoundaryCurve), new BundlingSettings { InkImportance = 0.00001, EdgeSeparation = MultiEdgesSeparation}, MakeTransparentShapesOfEdgeGeometryAndGetTheShapes); //giving more importance to ink might produce weird routings with huge detours, maybe 0 is the best value here mer.Run(); }
void ScaleDownLooseHierarchy(InteractiveEdgeRouter interactiveEdgeRouter, Set<Shape> obstacleShapes) { var loosePolys = new List<Polyline>(); foreach (var obstacleShape in obstacleShapes) { var tl = shapesToTightLooseCouples[obstacleShape]; loosePolys.Add( InteractiveObstacleCalculator.LoosePolylineWithFewCorners(tl.TightPolyline, tl.Distance / BundleRouter.SuperLoosePaddingCoefficient)); } interactiveEdgeRouter.LooseHierarchy=CreateLooseObstacleHierarachy(loosePolys); interactiveEdgeRouter.ClearActivePolygons(); interactiveEdgeRouter.AddActivePolygons(loosePolys.Select(polyline => new Polygon(polyline))); }
void RouteEdge(InteractiveEdgeRouter interactiveEdgeRouter, Edge edge) { var transparentShapes = MakeTransparentShapesOfEdgeGeometryAndGetTheShapes(edge.EdgeGeometry); ProgressStep(); RouteEdgeGeometry(edge, interactiveEdgeRouter); SetTransparency(transparentShapes, false); }
void RouteEdgesWithTheSamePassport(IGrouping<Set<Shape>, Edge> edgeGeometryGroup, InteractiveEdgeRouter interactiveEdgeRouter, Set<Shape> obstacleShapes) { List<Edge> regularEdges; List<Edge[]> multiEdges; if (RouteMultiEdgesAsBundles) { SplitOnRegularAndMultiedges(edgeGeometryGroup, out regularEdges, out multiEdges); foreach (var edge in regularEdges) RouteEdge(interactiveEdgeRouter, edge); if (multiEdges != null) { ScaleDownLooseHierarchy(interactiveEdgeRouter, obstacleShapes); RouteMultiEdges(multiEdges, interactiveEdgeRouter, edgeGeometryGroup.Key); } } else foreach (var eg in edgeGeometryGroup) RouteEdge(interactiveEdgeRouter, eg); }
/// <summary> /// Executes the algorithm. /// </summary> protected override void RunInternal() { if (pairArray.Length > 0) { PositionLabelsOfFlatEdges(); interactiveEdgeRouter = new InteractiveEdgeRouter(GetObstacles(), PaddingForEdges, PaddingForEdges/3, Math.PI/6); interactiveEdgeRouter.CalculateWholeTangentVisibilityGraph(); foreach (IntEdge intEdge in IntEdges()) { this.ProgressStep(); RouteEdge(intEdge); } } }