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);
        }
示例#4
0
        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)
 {
 }
 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);
            }
        }
示例#10
0
        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);
        }