/// <summary> /// Add an additional node, from the current last node along the next TrackNodeVector (given by index) /// The added node will always be a junction node. /// </summary> /// <param name="lastNode">Currently last node of path</param> /// <param name="nextTvnIndex">TrackNodeVector index along which to place the track</param> /// <param name="isMainPath">Are we adding a node on the main path (alternative is passing path)</param> /// <returns>The newly created junction path node</returns> TrainpathJunctionNode AddAdditionalJunctionNode(TrainpathNode lastNode, int nextTvnIndex, bool isMainPath) { // we add a new activeNodeAsJunction TrainpathJunctionNode newNode = new TrainpathJunctionNode(lastNode); if (TrackExtensions.TrackNode(nextTvnIndex) == null) { return(null); // apparently there is some issue in the track. } newNode.JunctionIndex = lastNode.GetNextJunctionIndex(nextTvnIndex); newNode.SetLocationFromTrackNode(); // simple linking newNode.PrevNode = lastNode; if (isMainPath) { lastNode.NextMainTvnIndex = nextTvnIndex; lastNode.NextMainNode = newNode; } else { lastNode.NextSidingTvnIndex = nextTvnIndex; lastNode.NextSidingNode = newNode; } newNode.SetFacingPoint(); newNode.DetermineOrientation(lastNode, nextTvnIndex); NetNodesAdded++; return(newNode); }
/// <summary> /// base constructor that only stores the information of the tracks. /// </summary> /// <param name="routeData">The route information that contains track data base and track section data</param> /// <param name="drawTrackDB">The drawn tracks to know about where the mouse is</param> private PathEditor(RouteData routeData, DrawTrackDB drawTrackDB) { this.drawTrackDB = drawTrackDB; this.trackDB = routeData.TrackDB; this.tsectionDat = routeData.TsectionDat; TrackExtensions.Initialize(trackDB.TrackNodes, tsectionDat); // we might be calling this more than once, but so be it. enableMouseUpdate = true; drawPath = new DrawPath(trackDB, tsectionDat); CreateNonMenuActions(); CreateDirectActions(); CreateContextMenuEntries(); CreateContextMenu(); }
/// <summary> /// Determine the details of junction from which we connect in case this is a vector node. /// In this case it is important to know whether we are in a From node or in a To node. /// </summary> private void DetermineJunctionForVectorNode() { int tvnIndex = OriginalNodeAsVector.TvnIndex; if ((IsFrom && IsConnectingForward) || (!IsFrom && !IsConnectingForward)) { // the first junction node of the reconnect path is after the vector node. this.ConnectingJunctionIndex = OriginalNodeAsVector.GetNextJunctionIndex(tvnIndex); int junctionTrailingTvn = TrackExtensions.TrackNode(this.ConnectingJunctionIndex).TrailingTvn(); this.IsConnectingJunctionFacing = (tvnIndex == junctionTrailingTvn); } else { // the last junction node of the reconnect path is before this vector node. this.ConnectingJunctionIndex = OriginalNodeAsVector.GetPrevJunctionIndex(tvnIndex); int junctionTrailingTvn = TrackExtensions.TrackNode(this.ConnectingJunctionIndex).TrailingTvn(); this.IsConnectingJunctionFacing = (tvnIndex != junctionTrailingTvn); } }
/// <summary> /// Try to find a connection between the current junction and a reconnect junction. /// We do a depth-first search, using the main tracks first. /// The result (the path) is stored in a list of linking tvns. /// In case there are DisAllowedJunctionIndexes we will not allow the connection to go over these junctions /// </summary> /// <param name="currentJunctionIndex">Index of the current junction</param> /// <param name="currentJunctionIsFacing">true if the current junction is a facing junction</param> /// <returns>true if a path was found</returns> private bool TryToFindConnection(int currentJunctionIndex, bool currentJunctionIsFacing) { if (autoConnectToNodeOptions.FoundConnection(currentJunctionIndex, currentJunctionIsFacing)) { return(autoConnectToNodeOptions.ConnectionIsGood); } // Did we go as deep as we want wanted to go? if (linkingTvns.Count == maxNumberNodesToCheckForAutoFix) { return(false); } // Search further along the next Tvns that we can try. TrackNode tn = TrackExtensions.TrackNode(currentJunctionIndex); if (tn is TrackEndNode) { return(false); } if (currentJunctionIsFacing) { //for debugging it is better to have multiple lines bool found; found = TryToFindConnectionVia(currentJunctionIndex, tn.MainTvn()); if (found) { return(true); } found = TryToFindConnectionVia(currentJunctionIndex, tn.SidingTvn()); return(found); } else { return(TryToFindConnectionVia(currentJunctionIndex, tn.TrailingTvn())); } }
/// <summary> /// Try to find a connection between the current junction and a reconnect junction, along the given TVN /// We do a depth-first search, using the main tracks first. /// The result (the path) is stored in a list of linking tvns. /// </summary> /// <param name="nextTvn">The TVN (Track Vector Node index) that we will take.</param> /// <param name="currentJunctionIndex">Index of the current junction</param> /// <returns>true if a path was found</returns> private bool TryToFindConnectionVia(int currentJunctionIndex, int nextTvn) { if (nextTvn <= 0) { return(false); // something wrong in train database. } int nextJunctionIndex = TrackExtensions.GetNextJunctionIndex(currentJunctionIndex, nextTvn); if (DisAllowedJunctionIndexes.Contains(nextJunctionIndex)) { return(false); } bool nextJunctionIsFacing = (nextTvn == TrackExtensions.TrackNode(nextJunctionIndex).TrailingTvn()); linkingTvns.Add(nextTvn); bool succeeded = TryToFindConnection(nextJunctionIndex, nextJunctionIsFacing); if (!succeeded) { //Pop the index that did not work linkingTvns.RemoveAt(linkingTvns.Count - 1); } return(succeeded); }
/// <summary> /// From the current pathnode and the linking tracknode, fin the junctionIndex of the next junction (or possibly end-point) /// </summary> /// <param name="linkingTrackNodeIndex">The index of the tracknode leaving the node</param> /// <returns>The index of the junction index at the end of the track (as seen from the node)</returns> public override int GetNextJunctionIndex(int linkingTrackNodeIndex) { return(TrackExtensions.GetNextJunctionIndex(this.JunctionIndex, linkingTrackNodeIndex)); }