public TrackingPointGetter(string prompt, CurvesTopology crvTopology, int fromIndex, SearchMode mode) { _crvTopology = crvTopology; _fromIndex = fromIndex; if(!Enum.IsDefined(typeof(SearchMode), mode)) throw new ArgumentException("Enum is undefined.", "mode"); _sm = mode; if (!string.IsNullOrEmpty(prompt)) _getPoint.SetCommandPrompt(prompt); if (fromIndex != -1) { switch(mode) { case SearchMode.CurveLength: _distances = crvTopology.MeasureAllEdgeLengths(); break; case SearchMode.LinearDistance: _distances = crvTopology.MeasureAllEdgeLinearDistances(); break; case SearchMode.Links: _distances = null; break; default: throw new ApplicationException("Behaviour for this enum value is undefined."); } } _getPoint.DynamicDraw += DynamicDraw; _pathSearchMethod = PathMethod.FromMode(_sm, _crvTopology, _distances); }
/// <summary> /// Retrieves the Topology edge of the Edge at position i at this Node /// </summary> /// <param name="i">An edge index smaller than EdgeCount and larger than 0</param> /// <param name="top">The reference topology</param> /// <returns>The Topology edge</returns> public EdgeAddress EdgeAt(int i, CurvesTopology top) { if (i < 0 || i >= EdgeCount) throw new ArgumentOutOfRangeException("i", "index must be smaller than EdgeCount and larger than 0"); return top.EdgeAt(EdgeIndexAt(i, top)); }
public TrackingPointGetter(string prompt, CurvesTopology crvTopology, int fromIndex, SearchMode mode) { _crvTopology = crvTopology; _fromIndex = fromIndex; if (!Enum.IsDefined(typeof(SearchMode), mode)) { throw new ArgumentException("Enum is undefined.", "mode"); } _sm = mode; if (!string.IsNullOrEmpty(prompt)) { _getPoint.SetCommandPrompt(prompt); } if (fromIndex != -1) { switch (mode) { case SearchMode.CurveLength: _distances = crvTopology.MeasureAllEdgeLengths(); break; case SearchMode.LinearDistance: _distances = crvTopology.MeasureAllEdgeLinearDistances(); break; case SearchMode.Links: _distances = null; break; default: throw new ApplicationException("Behaviour for this enum value is undefined."); } } _getPoint.DynamicDraw += DynamicDraw; _pathSearchMethod = PathMethod.FromMode(_sm, _crvTopology, _distances); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { toggle = !toggle; if (toggle) { string layername = "Heating Network"; // Get all of the objects on the layer. If layername is bogus, you will // just get an empty list back Rhino.DocObjects.RhinoObject[] rhobjs = doc.Objects.FindByLayer(layername); if (rhobjs == null || rhobjs.Length < 1) { return(Result.Cancel); } var curves = new Curve[rhobjs.Length]; for (int i = 0; i < rhobjs.Length; i++) { GeometryBase geom = rhobjs[i].Geometry; Curve x = geom as Curve; if (x != null && x.IsValid) { curves[i] = x; } } OptionDouble tol = new OptionDouble(RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true, 0.0); CurvesTopology crvTopology = new CurvesTopology(curves, tol.CurrentValue); ids = CurvesTopologyPreview.Mark(crvTopology, Color.LightBlue, Color.LightCoral, Color.GreenYellow); return(Result.Success); } else { EndOperations(ids); return(Result.Success); } }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { SearchMode sm = SearchMode.CurveLength; Curve[] curves; OptionToggle tog = new OptionToggle(false, "Hide", "Show"); OptionDouble tol = new OptionDouble(RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true, 0.0); using (CurvesGetter getLines = new CurvesGetter("Select curves meeting at endpoints. Press Enter when done")) { for ( ; ;) { getLines.ClearCommandOptions(); getLines.EnableClearObjectsOnEntry(false); int showInt = getLines.AddOptionToggle("Topology", ref tog); int tolInt = getLines.AddOptionDouble("Tolerance", ref tol); int modeInt = GetterExtension.AddEnumOptionList(getLines, sm); if (getLines.Curves(1, 0, out curves)) { break; } else { if (getLines.Result() == GetResult.Option) { if (getLines.Option().Index == modeInt) { sm = GetterExtension.RetrieveEnumOptionValue <SearchMode> (getLines.Option().CurrentListOptionIndex); } continue; } else { RhinoApp.WriteLine("Less than three lines were selected"); return(Result.Cancel); } } } } CurvesTopology crvTopology = new CurvesTopology(curves, tol.CurrentValue); Guid[] ids = null; if (tog.CurrentValue) { ids = CurvesTopologyPreview.Mark(crvTopology, Color.LightBlue, Color.LightCoral); } int walkFromIndex; using (var getStart = new TrackingPointGetter("Select the start point of the walk on the curves", crvTopology)) { if (getStart.GetPointOnTopology(out walkFromIndex) != Result.Success) { EndOperations(ids); return(Result.Cancel); } } Result wasSuccessful = Result.Cancel; for (; ;) { int walkToIndex; double[] distances; using (var getEnd = new TrackingPointGetter("Select the end point", crvTopology, walkFromIndex, sm)) { if (getEnd.GetPointOnTopology(out walkToIndex) != Result.Success) { break; } distances = getEnd.DistanceCache; } if (walkFromIndex == walkToIndex) { RhinoApp.WriteLine("Start and end points are equal"); EndOperations(ids); return(Result.Nothing); } PathMethod pathSearch = PathMethod.FromMode(sm, crvTopology, distances); int[] nIndices, eIndices; bool[] eDirs; double totLength; Curve c = pathSearch.Cross(walkFromIndex, walkToIndex, out nIndices, out eIndices, out eDirs, out totLength); if (c != null && c.IsValid) { if (tog.CurrentValue) { RhinoApp.WriteLine("Vertices: {0}", FormatNumbers(nIndices)); RhinoApp.WriteLine("Edges: {0}", FormatNumbers(eIndices)); } var a = RhinoDoc.ActiveDoc.CreateDefaultAttributes(); Guid g = RhinoDoc.ActiveDoc.Objects.AddCurve(c, a); var obj = RhinoDoc.ActiveDoc.Objects.Find(g); if (obj != null) { obj.Select(true); wasSuccessful = Result.Success; walkFromIndex = walkToIndex; } else { RhinoApp.WriteLine("An error occurred while adding the new polycurve."); wasSuccessful = Result.Failure; break; } } else { RhinoApp.WriteLine("No path was found. Nodes are isolated."); wasSuccessful = Result.Nothing; } } EndOperations(ids); return(wasSuccessful); }
public PointGetter(CurvesTopology crvTopology) : this(crvTopology, -1, SearchMode.Links) { }
public TrackingPointGetter(string prompt, CurvesTopology crvTopology) : this(prompt, crvTopology, -1, SearchMode.Links) { }
protected override void SolveInstance(IGH_DataAccess DA) { var curves = new List<Curve>(); var lines = new List<Line>(); if (DA.GetDataList(0, curves) && DA.GetDataList(1, lines)) { curves.RemoveAll(_removeNullAndInvalidDelegate); lines.RemoveAll(_removeInvalidDelegate); if (curves.Count < 1) return; CurvesTopology top = new CurvesTopology(curves, GH_Component.DocumentTolerance()); var distances = top.MeasureAllEdgeLengths(); List<Curve> result = new List<Curve>(); for (int i = 0; i < lines.Count; i++) { var line = lines[i]; int fromIndex = top.GetClosestNode(line.From); int toIndex = top.GetClosestNode(line.To); if (fromIndex == toIndex) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The start and end positions are equal"); result.Add(null); continue; } var pathSearch = new AStar(top, distances); var current = pathSearch.Cross(fromIndex, toIndex); if (current == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, string.Format("No walk found for line at position {0}. Are end points isolated?", i.ToString())); } result.Add(current); } DA.SetDataList(0, result); } }
protected override void GroundHogSolveInstance(IGH_DataAccess DA) { var CURVES = new List <Curve>(); var STARTS = new List <Point3d>(); var ENDS = new List <Point3d>(); var LENGTHS = new List <double>(); // Access and extract data from the input parameters individually if (!DA.GetDataList(0, CURVES)) { return; } if (!DA.GetDataList(1, STARTS)) { return; } if (!DA.GetDataList(2, ENDS)) { return; } DA.GetDataList(3, LENGTHS); // Input validation int negativeIndex = LENGTHS.FindIndex(_isNegative); if (negativeIndex != -1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, string.Format("Distances cannot be negative. At least one negative value found at index {0}.", negativeIndex)); return; } CURVES.RemoveAll(_removeNullAndInvalidDelegate); if (CURVES.Count < 1) { return; } STARTS.RemoveAll(_removeInvalidDelegate); ENDS.RemoveAll(_removeInvalidDelegate); if (STARTS.Count != ENDS.Count) { if (ENDS.Count == 1 && STARTS.Count > 1) { // Assume multiple starts going to single end; populate ends to match for (int i = 1; i < STARTS.Count; i++) { ENDS.Add(ENDS[0]); } } else if (STARTS.Count == 1 && ENDS.Count > 1) { // Assume single start going to multiple ends; populate starts to match for (int i = 1; i < ENDS.Count; i++) { STARTS.Add(STARTS[0]); } } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The quantity of start points does not match the quantity of end points"); return; } } if (LENGTHS.Count > 0 && LENGTHS.Count != CURVES.Count) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "If lengths are provided they must match the number of curves"); return; } // Construct topology CurvesTopology top = new CurvesTopology(CURVES, GH_Component.DocumentTolerance()); //CurvesTopologyPreview.Mark(top, Color.BurlyWood, Color.Bisque); PathMethod pathSearch; if (LENGTHS.Count == 0) { IList <double> distances = top.MeasureAllEdgeLengths(); pathSearch = new AStar(top, distances); } else if (LENGTHS.Count == 1) { pathSearch = new Dijkstra(top, LENGTHS[0]); } else { IList <double> interfLengths = LENGTHS; if (interfLengths.Count < top.EdgeLength) { interfLengths = new ListByPattern <double>(interfLengths, top.EdgeLength); } bool isAlwaysShorterOrEqual = true; for (int i = 0; i < top.EdgeLength; i++) { if (top.LinearDistanceAt(i) > interfLengths[i]) { isAlwaysShorterOrEqual = false; break; } } if (isAlwaysShorterOrEqual) { pathSearch = new AStar(top, interfLengths); } else { pathSearch = new Dijkstra(top, interfLengths); } } var resultCurves = new List <Curve>(); var resultLinks = new GH_Structure <GH_Integer>(); var resultDirs = new GH_Structure <GH_Boolean>(); var resultLengths = new List <double>(); for (int i = 0; i < STARTS.Count; i++) { int fromIndex = top.GetClosestNode(STARTS[i]); int toIndex = top.GetClosestNode(ENDS[i]); if (fromIndex == toIndex) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The start and end positions are equal; perhaps because they are not close enough to one of the curves in the network."); resultCurves.Add(null); continue; } var current = pathSearch.Cross(fromIndex, toIndex, out int[] nodes, out int[] edges, out bool[] dir, out double tot); if (current == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, string.Format("No walk found for start point at position {0}. Are end points isolated?", i.ToString())); } else { var pathLinks = DA.ParameterTargetPath(1).AppendElement(i); resultLinks.AppendRange(GhWrapTypeArray <int, GH_Integer>(edges), pathLinks); resultDirs.AppendRange(GhWrapTypeArray <bool, GH_Boolean>(dir), pathLinks); resultLengths.Add(tot); } resultCurves.Add(current); } DA.SetDataList(0, resultCurves); DA.SetDataTree(1, resultLinks); DA.SetDataTree(2, resultDirs); DA.SetDataList(3, resultLengths); }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { SearchMode sm = SearchMode.CurveLength; Curve[] curves; OptionToggle tog = new OptionToggle(false, "Hide", "Show"); OptionDouble tol = new OptionDouble(RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, true, 0.0); using (CurvesGetter getLines = new CurvesGetter("Select curves meeting at endpoints. Press Enter when done")) { for( ; ;) { getLines.ClearCommandOptions(); getLines.EnableClearObjectsOnEntry(false); int showInt = getLines.AddOptionToggle("Topology", ref tog); int tolInt = getLines.AddOptionDouble("Tolerance", ref tol); int modeInt = GetterExtension.AddEnumOptionList(getLines, sm); if (getLines.Curves(1, 0, out curves)) break; else { if (getLines.Result() == GetResult.Option) { if (getLines.Option().Index == modeInt) { sm = GetterExtension.RetrieveEnumOptionValue<SearchMode> (getLines.Option().CurrentListOptionIndex); } continue; } else { RhinoApp.WriteLine("Less than three lines were selected"); return Result.Cancel; } } } } CurvesTopology crvTopology = new CurvesTopology(curves, tol.CurrentValue); Guid[] ids = null; if (tog.CurrentValue) ids = CurvesTopologyPreview.Mark(crvTopology, Color.LightBlue, Color.LightCoral); int walkFromIndex; using (var getStart = new TrackingPointGetter("Select the start point of the walk on the curves", crvTopology)) { if (getStart.GetPointOnTopology(out walkFromIndex) != Result.Success) { EndOperations(ids); return Result.Cancel; } } Result wasSuccessful = Result.Cancel; for (; ; ) { int walkToIndex; double[] distances; using (var getEnd = new TrackingPointGetter("Select the end point", crvTopology, walkFromIndex, sm)) { if (getEnd.GetPointOnTopology(out walkToIndex) != Result.Success) { break; } distances = getEnd.DistanceCache; } if (walkFromIndex == walkToIndex) { RhinoApp.WriteLine("Start and end points are equal"); EndOperations(ids); return Result.Nothing; } PathMethod pathSearch = PathMethod.FromMode(sm, crvTopology, distances); int[] nIndices, eIndices; bool[] eDirs; double totLength; Curve c = pathSearch.Cross(walkFromIndex, walkToIndex, out nIndices, out eIndices, out eDirs, out totLength); if (c != null && c.IsValid) { if (tog.CurrentValue) { RhinoApp.WriteLine("Vertices: {0}", FormatNumbers(nIndices)); RhinoApp.WriteLine("Edges: {0}", FormatNumbers(eIndices)); } var a = RhinoDoc.ActiveDoc.CreateDefaultAttributes(); Guid g = RhinoDoc.ActiveDoc.Objects.AddCurve(c, a); var obj = RhinoDoc.ActiveDoc.Objects.Find(g); if (obj != null) { obj.Select(true); wasSuccessful = Result.Success; walkFromIndex = walkToIndex; } else { RhinoApp.WriteLine("An error occurred while adding the new polycurve."); wasSuccessful = Result.Failure; break; } } else { RhinoApp.WriteLine("No path was found. Nodes are isolated."); wasSuccessful = Result.Nothing; } } EndOperations(ids); return wasSuccessful; }
protected override void SolveInstance(IGH_DataAccess DA) { var curves = new List <Curve>(); var lengths = new List <double>(); var lines = new List <Line>(); if (DA.GetDataList(0, curves) && DA.GetDataList(2, lines)) { DA.GetDataList(1, lengths); int negativeIndex = lengths.FindIndex(_isNegative); if (negativeIndex != -1) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, string.Format("Distances cannot be negative. At least one negative value encounter at index {0}.", negativeIndex)); return; } curves.RemoveAll(_removeNullAndInvalidDelegate); lines.RemoveAll(_removeInvalidDelegate); if (curves.Count < 1) { return; } CurvesTopology top = new CurvesTopology(curves, GH_Component.DocumentTolerance()); //CurvesTopologyPreview.Mark(top, Color.BurlyWood, Color.Bisque); PathMethod pathSearch; if (lengths.Count == 0) { IList <double> distances = top.MeasureAllEdgeLengths(); pathSearch = new AStar(top, distances); } else if (lengths.Count == 1) { pathSearch = new Dijkstra(top, lengths[0]); } else { IList <double> interfLengths = lengths; if (interfLengths.Count < top.EdgeLength) { interfLengths = new ListByPattern <double>(interfLengths, top.EdgeLength); } bool isAlwaysShorterOrEqual = true; for (int i = 0; i < top.EdgeLength; i++) { if (top.LinearDistanceAt(i) > interfLengths[i]) { isAlwaysShorterOrEqual = false; break; } } if (isAlwaysShorterOrEqual) { pathSearch = new AStar(top, interfLengths); } else { pathSearch = new Dijkstra(top, interfLengths); } } var resultCurves = new List <Curve>(); var resultLinks = new GH_Structure <GH_Integer>(); var resultDirs = new GH_Structure <GH_Boolean>(); var resultLengths = new List <double>(); for (int i = 0; i < lines.Count; i++) { var line = lines[i]; int fromIndex = top.GetClosestNode(line.From); int toIndex = top.GetClosestNode(line.To); if (fromIndex == toIndex) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The start and end positions are equal"); resultCurves.Add(null); continue; } int[] nodes, edges; bool[] dir; double tot; var current = pathSearch.Cross(fromIndex, toIndex, out nodes, out edges, out dir, out tot); if (current == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, string.Format("No walk found for line at position {0}. Are end points isolated?", i.ToString())); } else { var pathLinks = DA.get_ParameterTargetPath(1).AppendElement(i); resultLinks.AppendRange(GhWrapTypeArray <int, GH_Integer>(edges), pathLinks); resultDirs.AppendRange(GhWrapTypeArray <bool, GH_Boolean>(dir), pathLinks); resultLengths.Add(tot); } resultCurves.Add(current); } DA.SetDataList(0, resultCurves); DA.SetDataTree(1, resultLinks); DA.SetDataTree(2, resultDirs); DA.SetDataList(3, resultLengths); } }
/// <summary> /// Retrieves the Topology edge index of the Edge at position i at this Node /// </summary> /// <param name="i">An index smaller than EdgeCount and larger than 0</param> /// <param name="top">The reference topology</param> /// <returns>The Topology edge index</returns> public int EdgeIndexAt(int i, CurvesTopology top) { if (i < 0 || i >= EdgeCount) throw new ArgumentOutOfRangeException("i", "index must be smaller than EdgeCount and larger than 0"); return top.GetVertexToEdgeIndexFromArrayAt(_edgeStart + i); }
/// <summary> /// Retrieves the direction of the Edge at position i at this Node /// </summary> /// <param name="i">An edge index smaller than EdgeCount and larger than 0</param> /// <param name="top">The reference topology</param> /// <returns>A boolean indicating if the edge is oriented frontal or backwards</returns> public bool RevAt(int i, CurvesTopology top) { if (i < 0 || i >= EdgeCount) throw new ArgumentOutOfRangeException("i", "index must be smaller than EdgeCount and larger than 0"); return top.GetIsVertexEdgeRevOrientedFromArray(_edgeStart + i); }