private Node GetOrCreateNode(Port port, Dictionary<ICurve, Node> nodeDictionary) {
     var curve = GetPortCurve(port);
     Node node;
     if (!nodeDictionary.TryGetValue(curve, out node))
         nodeDictionary[curve] = node = new Node(curve);
     return node;
 }
        private ObstaclePort CreateObstaclePort(Obstacle obstacle, Port port) {
            // This will replace any previous specification for the port (last one wins).
            Debug.Assert(!obstaclePortMap.ContainsKey(port), "Port is used by more than one obstacle");

            if (null == port.Curve) {
                return null;
            }

            var roundedLocation = ApproximateComparer.Round(port.Location);
            if (PointLocation.Outside == Curve.PointRelativeToCurveLocation(roundedLocation, obstacle.InputShape.BoundaryCurve)) {
                // Obstacle.Port is outside Obstacle.Shape; handle it as a FreePoint.
                return null;
            }

            if ((obstacle.InputShape.BoundaryCurve != port.Curve) 
                && (PointLocation.Outside == Curve.PointRelativeToCurveLocation(roundedLocation, port.Curve))) {
                // Obstacle.Port is outside port.Curve; handle it as a FreePoint.
                return null;
            }

            var oport = new ObstaclePort(port, obstacle);
            obstaclePortMap[port] = oport;
            return oport;
        }
        private void ConnectOobWaypointToEndpointVisibilityAtGraphBoundary(FreePoint oobWaypoint, Port port) {
            if ((oobWaypoint == null) || !oobWaypoint.IsOutOfBounds) {
                return;
            }

            // Connect to the graphbox side at points collinear with the vertices.  The waypoint may be
            // OOB in two directions so call once for each axis.
            var endpointVertices = this.FindVertices(port);
            var dirFromGraph = oobWaypoint.OutOfBoundsDirectionFromGraph & (Directions.North | Directions.South);
            ConnectToGraphAtPointsCollinearWithVertices(oobWaypoint, dirFromGraph, endpointVertices);
            dirFromGraph = oobWaypoint.OutOfBoundsDirectionFromGraph & (Directions.East | Directions.West);
            ConnectToGraphAtPointsCollinearWithVertices(oobWaypoint, dirFromGraph, endpointVertices);
        }
 private Point FigureOutHookLocationForSimpleOtherPort(Polyline poly, Port otherEdgeEndPort, EdgeGeometry edgeGeom) {
     Point otherEdgeEnd = otherEdgeEndPort.Location;
     var shapes = shortestPathRouter.MakeTransparentShapesOfEdgeGeometry(edgeGeom);
     //SplineRouter.ShowVisGraph(this.VisibilityGraph, this.LooseHierarchy.GetAllLeaves(),
     //    shapes.Select(sh => sh.BoundaryCurve), new[] { new LineSegment(edgeGeom.SourcePort.Location, edgeGeom.TargetPort.Location) });
     var s = new SingleSourceMultipleTargetsShortestPathOnVisibilityGraph(
         VisibilityGraph.FindVertex(otherEdgeEnd),
         poly.PolylinePoints.Select(p => VisibilityGraph.FindVertex(p.Point)), VisibilityGraph);
     var path = s.GetPath();
     foreach (var sh in shapes)
         sh.IsTransparent = false;
     return path.Last().Point;
 }
 void RemoveObstaclePort(Port port) {
     obstaclePortMap.Remove(port);
 }
        private void WriteRelativePort(Port port, int shapeId)
        {
            var relativePort = port as RelativeFloatingPort;
            var multiPort = port as MultiLocationFloatingPort;
            Validate.IsNotNull(relativePort, "Unsupported port type for file persistence");
            // ReSharper disable PossibleNullReferenceException

            // The location in the main WritePort line is relevant only for non-multiPort; for multiPorts
            // the caller sets location via ActiveOffsetIndex.
            var portTypeString = (null != multiPort) ? RectFileStrings.Multi : RectFileStrings.Relative;
            this.outputFileWriter.WriteLine(RectFileStrings.WritePort, portTypeString,
                    relativePort.LocationOffset.X, relativePort.LocationOffset.Y,
                    this.portToIdMap[port], shapeId);
            // ReSharper restore PossibleNullReferenceException

            if (null != multiPort)
            {
                this.outputFileWriter.WriteLine(RectFileStrings.WriteMultiPortOffsets, multiPort.ActiveOffsetIndex);
                foreach (var offset in multiPort.LocationOffsets)
                {
                    this.outputFileWriter.WriteLine(RectFileStrings.WritePoint, offset.X, offset.Y);
                }
            }
        }
 static void FixPortAtSource(Shape shape, Port port, Edge e) {
     if (e.SourcePort == null)
         e.SourcePort = port;
     else
         shape.Ports.Insert(e.SourcePort);
 }
        private void AddPortToGraph(Port port, ObstaclePort oport) {
            if (null != oport) {
                AddObstaclePortToGraph(oport);
                return;
            }

            // This is a FreePoint, either a Waypoint or a Port not in an Obstacle.Ports list.
            AddFreePointToGraph(port.Location);
        }
예제 #9
0
 void DrawEdgeInteractivelyToPort(Port targetPortParameter,Polyline portLoosePolyline) {
     viewer.DrawRubberEdge(EdgeGeometry = CalculateEdgeInteractively(targetPortParameter,portLoosePolyline));
 }
예제 #10
0
 void SetPortForMousePositionInsideOfNode(Point mousePosition,
                                          IViewerNode node, ref Port port) {
     GeometryNode geomNode = GeometryNode(node);
     double t;
     if (NeedToCreateBoundaryPort(mousePosition, node, out t))
         port = CreateOrUpdateCurvePort(t, geomNode, port);
     else
         port = CreateFloatingPort(geomNode, ref mousePosition);
 }
        Set<Shape> AncestorsForPort(Port port) {
            Shape shape;
            if (PortToShapes.TryGetValue(port, out shape)) {
                return AncestorsSets[shape];
            }

            // This is a FreePort or Waypoint; return all spatial parents.
            return new Set<Shape>(HierarchyOfGroups.AllHitItems(new Rectangle(port.Location, port.Location), null));
        }
예제 #12
0
 Port CreateOrUpdateCurvePort(double t, GeometryNode geomNode, Port port) {
     var cp = port as CurvePort;
     if (cp == null)
         return new CurvePort(geomNode.BoundaryCurve, t);
     cp.Parameter = t;
     cp.Curve = geomNode.BoundaryCurve;
     return port;
 }
예제 #13
0
 void SetPortUnderLoosePolyline(Point mousePosition, Polyline loosePoly, ref IViewerNode node, ref Port port) {
     double dist = double.PositiveInfinity;
     double par = 0;
     foreach (var viewerNode in GetViewerNodesInsideOfLooseObstacle(loosePoly)) {
         var curve = ((Node)viewerNode.DrawingObject).GeometryNode.BoundaryCurve;
         if (PointIsInside(mousePosition, curve)) {
             node = viewerNode;
             SetPortForMousePositionInsideOfNode(mousePosition, node, ref port);
             return;
         }
         double p = curve.ClosestParameter(mousePosition);
         double d = (curve[p] - mousePosition).Length;
         if (d < dist) {
             par = p;
             dist = d;
             node = viewerNode;
         }
     }
     
     port = CreateOrUpdateCurvePort(par, ((Node)node.DrawingObject).GeometryNode, port);
 }
예제 #14
0
 IViewerNode SetPortWhenDraggingStraightLine(ref Port port, ref Point mousePosition) {
    var viewerNode = viewer.ObjectUnderMouseCursor as IViewerNode;
     if (viewerNode != null){
         double t;
         GeometryNode geomNode = ((Node) viewerNode.DrawingObject).GeometryNode;
         if (NeedToCreateBoundaryPort(mousePosition, viewerNode, out t))
             port = CreateOrUpdateCurvePort(t, geomNode, port);
         else
             port = PointIsInside(mousePosition, ((Node) viewerNode.DrawingObject).GeometryNode.BoundaryCurve)
                        ? CreateFloatingPort(geomNode, ref mousePosition)
                        : null;
     }
     else 
         port = null;
     return viewerNode;
 }
예제 #15
0
        bool TrySetNodePort(MsaglMouseEventArgs e, ref IViewerNode node, ref Port port, out Polyline loosePolyline) {
            Debug.Assert(InsertingEdge);

            Point mousePosition = viewer.ScreenToSource(e);
            loosePolyline = null;
            if (Graph != null) {
                if (DraggingStraightLine()) {
                    node= SetPortWhenDraggingStraightLine(ref port, ref mousePosition);
                } else {
                    if (InteractiveEdgeRouter == null)
                        PrepareForEdgeDragging();
                    loosePolyline = InteractiveEdgeRouter.GetHitLoosePolyline(viewer.ScreenToSource(e));
                    if (loosePolyline != null)
                        SetPortUnderLoosePolyline(mousePosition, loosePolyline, ref node, ref port);
                    else {
                        node = null;
                        port = null;
                    }
                }
            }
            return port != null;
        }
예제 #16
0
 EdgeGeometry CalculateEdgeInteractively(Port targetPortParameter,Polyline portLoosePolyline) {
     if(InteractiveEdgeRouter.SourcePort == null)
         InteractiveEdgeRouter.SetSourcePortAndSourceLoosePolyline(SourcePort,sourceLoosePolyline);
     ICurve curve;
     SmoothedPolyline smoothedPolyline = null;
     if(SourceOfInsertedEdge == TargetOfInsertedEdge) {
         curve = new LineSegment(SourcePort.Location,TargetPort.Location);
     } else {
         curve = InteractiveEdgeRouter.RouteEdgeToPort(targetPortParameter,portLoosePolyline,false,
                                                       out smoothedPolyline);
     }
     return new EdgeGeometry { Curve = curve,SmoothedPolyline = smoothedPolyline };
 }
        internal Set<Shape> FindAncestorsAndObstaclePort(Port port, out ObstaclePort oport) {
            oport = FindObstaclePort(port);
            if (0 == AncestorSets.Count) {
                return null;
            }
            if (null != oport) {
                return AncestorSets[oport.Obstacle.InputShape];
            }

            // This is a free Port (not associated with an obstacle) or a Waypoint; return all spatial parents.
            return new Set<Shape>(ObstacleTree.Root.AllHitItems(new Rectangle(port.Location, port.Location), shape => shape.IsGroup)
                                        .Select(obs => obs.InputShape));
        }
        Rectangle GetPortRectangle(Port port)
        {
            ObstaclePort oport;
            obstaclePortMap.TryGetValue(port, out oport);
            if (null != oport) {
                return (oport.Obstacle.VisibilityBoundingBox);
            }

            // FreePoint.
            return new Rectangle(ApproximateComparer.Round(port.Location));
        }
        internal ObstaclePort FindObstaclePort(Port port) {
            ObstaclePort oport;
            if (obstaclePortMap.TryGetValue(port, out oport)) {
                // First see if the obstacle's port list has changed without UpdateObstacles() being called.
                // Unfortunately we don't have a way to update the obstacle's ports until we enter
                // this block; there is no direct Port->Shape/Obstacle mapping.  So UpdateObstacle must still
                // be called, but at least this check here will remove obsolete ObstaclePorts.
                Set<Port> addedPorts, removedPorts;
                if (oport.Obstacle.GetPortChanges(out addedPorts, out removedPorts)) {
                    foreach (var newPort in addedPorts) {
                        CreateObstaclePort(oport.Obstacle, newPort);
                    }
                    foreach (var oldPort in removedPorts) {
                        RemoveObstaclePort(oldPort);
                    }

                    // If it's not still there, it was moved outside the obstacle so we'll just add it as a FreePoint.
                    if (!obstaclePortMap.TryGetValue(port, out oport)) {
                        oport = null;
                    }
                }
            }
            return oport;
        }
        private void WriteIfFreePort(Port port)
        {
            // Skip this port if we've already processed it.
            if (portToIdMap.ContainsKey(port))
            {
                return;
            }

            int shapeId = FreePortShapeId;
            if (port is RelativeFloatingPort)
            {
                Shape shape;
                if ((null == this.freeRelativePortToShapeMap) || !this.freeRelativePortToShapeMap.TryGetValue(port, out shape))
                {
                    Validate.Fail("Relative FreePorts must be in FreeRelativePortToShapeMap");
                    return;
                }
                shapeId = shapeToIdMap[shape];
            }

            portToIdMap.Add(port, NextPortId);
            WritePort(port, shapeId);
        }
 void BoundAxisEdgeAdjacentToObstaclePort(Port port, AxisEdge axisEdge) {
     if (port is WaypointPort || (port.Curve == null && port.PortEntry == null))
         BoundAxisByPoint(port.Location, axisEdge);
     else if (port.PortEntry == null) {
         if (port.Curve.BoundingBox.Contains(port.Location))
             BoundAxisEdgeByRect(port.Curve.BoundingBox, axisEdge);
     } else {
         var portEntry = port.PortEntry as PortEntryOnCurve;
         if (portEntry != null) {
             Rectangle rect;
             if (FindPortEntryRectCrossingAxisEdge(portEntry, axisEdge, out rect))
                 BoundAxisEdgeByRect(rect, axisEdge);
         }
     }
 }
 static void CheckPortOfNode(Node node, Port nodePort) {
     if (node is Cluster)
         Debug.Assert(nodePort is ClusterBoundaryPort || nodePort is HookUpAnywhereFromInsidePort || nodePort is CurvePort);
 }
 private void WriteObstaclePort(Shape shape, Port port)
 {
     Validate.IsFalse(portToIdMap.ContainsKey(port), "Duplicate entries for port in the same or different shape.Ports list(s)");
     var relativePort = port as RelativeFloatingPort;
     if (null != relativePort)
     {
         Validate.IsTrue(PointComparer.Equal(shape.BoundingBox.Center, relativePort.CenterDelegate()),
                         "Port CenterDelegate must be Shape.Center for file persistence");
         Validate.AreEqual(shape.BoundaryCurve, port.Curve, "Port curve is not the same as that of the Shape in which it is a member");
     }
     portToIdMap.Add(port, NextPortId);
     WritePort(port, shapeToIdMap[shape]);
 }
 private ICurve GetPortCurve(Port port) {
     var curve = nodeTree.FirstHitNode(port.Location,
         (point, c) => Curve.PointRelativeToCurveLocation(point, c) != PointLocation.Outside ? HitTestBehavior.Stop : HitTestBehavior.Continue).UserData;
     return curve;
 }
        private void WritePort(Port port, int shapeId)
        {
            if (typeof(FloatingPort) == port.GetType())
            {
                this.outputFileWriter.WriteLine(RectFileStrings.WritePort, RectFileStrings.Floating,
                            port.Location.X, port.Location.Y, portToIdMap[port], shapeId);
            }
            else
            {
                WriteRelativePort(port, shapeId);
            }

            WritePortEntries(port);
        }
 internal EdgeGeometry(Port sourcePort, Port targetPort) {
     SourcePort = sourcePort;
     TargetPort = targetPort;
 }
        private void WritePortEntries(Port port)
        {
            if (null == port.PortEntry)
            {
                return;
            }
            var portEntryOnCurve = port.PortEntry as PortEntryOnCurve;
            Validate.IsNotNull(portEntryOnCurve, "Unknown IPortEntry implementation");
            // ReSharper disable PossibleNullReferenceException

            this.outputFileWriter.WriteLine(RectFileStrings.PortEntryOnCurve);
            foreach (var span in portEntryOnCurve.Spans)
            {
                this.outputFileWriter.WriteLine(RectFileStrings.WritePoint, span.Item1, span.Item2);
            }
            // ReSharper restore PossibleNullReferenceException
        }
        internal List<VisibilityVertex> FindVertices(Port port) {
            var vertices = new List<VisibilityVertex>();
            ObstaclePort oport;
            if (obstaclePortMap.TryGetValue(port, out oport)) {
                if (RouteToCenterOfObstacles) {
                    vertices.Add(oport.CenterVertex);
                    return vertices;
                }

                // Add all vertices on the obstacle borders.  Avoid LINQ for performance.
                foreach (var entrance in oport.PortEntrances) {
                    VisibilityVertex vertex = this.VisGraph.FindVertex(entrance.UnpaddedBorderIntersect);
                    if (null != vertex) {
                        vertices.Add(vertex);
                    }
                }
                return vertices;
            }
            vertices.Add(VisGraph.FindVertex(ApproximateComparer.Round(port.Location)));
            return vertices;
        }
 static void FixPortAtTarget(Shape shape, Port port, Edge e) {
     if (e.TargetPort == null)
         e.TargetPort = port;
     else 
         shape.Ports.Insert(e.TargetPort);
 }
 Point FigureOutHookLocation(Polyline poly, Port otherEdgeEndPort, EdgeGeometry edgeGeom) {
     var clusterPort = otherEdgeEndPort as ClusterBoundaryPort;
     if (clusterPort == null) {
         return FigureOutHookLocationForSimpleOtherPort(poly, otherEdgeEndPort, edgeGeom);
     }
     return FigureOutHookLocationForClusterOtherPort(poly, clusterPort, edgeGeom);
 }