Ejemplo n.º 1
0
        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);
            }
        }