예제 #1
0
    public static Tuple <Grasshopper.DataTree <object>, List <Polyline> > MakeOutputs(List <Point3d>[] flowPathPoints)
    {
        var allFlowPathPointsTree = new Grasshopper.DataTree <object>();
        var allFlowPathCurvesList = new List <Polyline>();

        for (var i = 0; i < flowPathPoints.Length; i++)
        {
            var path = new GH_Path(i);
            // For each flow path make the polyline
            if (flowPathPoints[i].Count > 1)
            {
                var flowPath = new Polyline(flowPathPoints[i]);
                allFlowPathCurvesList.Add(flowPath);
            }

            // And make a branch for the list of points
            for (var j = 0; j < flowPathPoints[i].Count; j++)
            {
                allFlowPathPointsTree.Add(flowPathPoints[i][j], path); // For each flow path point
            }
        }

        return(Tuple.Create(allFlowPathPointsTree, allFlowPathCurvesList));
    }
예제 #2
0
        public static List <Polyline> GetCurves(Mesh M, List <Point3d> P, out Grasshopper.DataTree <Line> threeValence, out Grasshopper.DataTree <Point3d> naked)
        {
            threeValence = new Grasshopper.DataTree <Line>();
            naked        = new Grasshopper.DataTree <Point3d>();
            HashSet <long> hash  = new HashSet <long>();
            List <Line>    lines = new List <Line>();
            //List<Tuple<int,int>> edges = new List<Tuple<int,int>>();
            Dictionary <int, Point3d> corners         = new Dictionary <int, Point3d>();
            HashSet <int>             visited3valence = new HashSet <int>();

            List <Point3d> innerValence = new List <Point3d>();


            List <Point3d> endValence = new List <Point3d>();

            HashSet <int> nv = new HashSet <int>();


            List <Point3d> P_ = P;

            if (P.Count != M.Faces.Count)
            {
                P_ = new List <Point3d>(M.MeshFaceCenters());
            }



            for (int i = 0; i < M.Faces.Count; i++)
            {
                int[] ff = M.Faces.AdjacentFaces(i);



                //1. for three valence output
                if (ff.Length > 2)
                {
                    if (visited3valence.Add(M.Faces[i].A))
                    {
                        threeValence.Add(new Line(P_[i], M.Vertices[M.Faces[i].A]), new Grasshopper.Kernel.Data.GH_Path(i));
                    }

                    if (visited3valence.Add(M.Faces[i].B))
                    {
                        threeValence.Add(new Line(P_[i], M.Vertices[M.Faces[i].B]), new Grasshopper.Kernel.Data.GH_Path(i));
                    }

                    if (visited3valence.Add(M.Faces[i].C))
                    {
                        threeValence.Add(new Line(P_[i], M.Vertices[M.Faces[i].C]), new Grasshopper.Kernel.Data.GH_Path(i));
                    }
                    nv.Add(i);
                }//if



                //2. for naked
                if (ff.Length == 1)
                {
                    Point3d corner = M.Vertices[M.Faces[i].A];
                    int     id     = M.Faces[i].A;

                    if (M.Vertices.GetConnectedVertices(M.Faces[i].B).Length == 2)
                    {
                        corner = M.Vertices[M.Faces[i].B];
                        id     = M.Faces[i].B;
                    }
                    else if (M.Vertices.GetConnectedVertices(M.Faces[i].C).Length == 2)
                    {
                        corner = M.Vertices[M.Faces[i].C];
                        id     = M.Faces[i].C;
                    }
                    naked.Add(corner, new Grasshopper.Kernel.Data.GH_Path(i));

                    corners.Add(i, corner);



                    lines.Add(new Line(P_[i], corner));


                    nv.Add(i);
                }//if



                //3. The skeleton
                for (int j = 0; j < ff.Length; j++)
                {
                    //Create a pair key
                    long key0 = GetKey(i, ff[j]);
                    long key1 = GetKey(ff[j], i);

                    //if one of them does not exist add line segment both keys
                    if (!hash.Contains(key0))
                    {
                        lines.Add(new Line(P_[i], P_[ff[j]]));
                        hash.Add(key0);
                        hash.Add(key1);
                    } //if
                }     //for j connected faces
            }         //for i faces



            //get connected paths

            int[]         nvArray   = nv.ToArray();
            HashSet <int> visited   = new HashSet <int>();
            HashSet <int> leftovers = new HashSet <int>();

            bool[] flag = new bool[M.Faces.Count];

            List <Polyline> polylines = new List <Polyline>();

            //loop through starting faces and search the end
            List <int> nv_ = new List <int>();

            foreach (int id in nv)
            {
                int[] ff = M.Faces.AdjacentFaces(id);
                //Rhino.RhinoApp.WriteLine(ff.Length.ToString());
                for (int i = 0; i < ff.Length; i++)
                {
                    nv_.Add(id);
                }
            }


            // Rhino.RhinoApp.WriteLine("LoopStarts");
            HashSet <long> hashPairs = new HashSet <long>();


            foreach (int id in nv_)
            {
                //Rhino.RhinoApp.WriteLine("");
                // Rhino.RhinoApp.WriteLine("start " + id.ToString());



                //List<int> path = new List<int>() { id };
                Polyline      polyline   = new Polyline();
                HashSet <int> localVisit = new HashSet <int>();
                polyline.Add(P_[id]);
                localVisit.Add(id);

                int  start        = id;
                int  current      = id;
                bool run          = true;
                int  counter      = 0;
                bool multivalence = false;


                while (run && counter < 100)
                {
                    //first get neighbour faces
                    int[] ff  = M.Faces.AdjacentFaces(current);
                    int   nei = -1;


                    for (int i = 0; i < ff.Length; i++)
                    {
                        if (!visited.Contains(ff[i]) &&
                            ff[i] != start &&
                            !nv.Contains(ff[i]))
                        {
                            nei = ff[i];
                            break;
                        }
                    }

                    //Rhino.RhinoApp.WriteLine(nei.ToString());

                    if (nei != -1)
                    {
                        //if one of end faces top
                        if (nv.Contains(nei))
                        {
                            //polyline.Add(P_[nei]);
                            run = false;
                        }
                        //visited.Add(nei);
                        polyline.Add(P_[nei]);
                        if (!nv.Contains(nei))
                        {
                            visited.Add(nei);
                            localVisit.Add(nei);
                            flag[nei] = true;
                        }
                        current = nei;
                    }



                    //if only one line segment between two starting points
                    //either multi valece or naked
                    else if (current == id && nei == -1 && counter == 0)
                    {
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(P_[id]);

                        //if (M.Faces.AdjacentFaces(id).Length == 1) {
                        //polyline.Insert(0,corners[id]);
                        //}

                        for (int i = 0; i < ff.Length; i++)
                        {
                            var key0 = GetKey(id, ff[i]);
                            var key1 = GetKey(ff[i], id);



                            if (ff[i] != start && !visited.Contains(ff[i]))
                            {
                                if (hashPairs.Add(key0) && hashPairs.Add(key1))
                                {
                                    polyline.Add(P_[ff[i]]);
                                    Polyline temp = new Polyline(polyline);

                                    //if corner
                                    if (M.Faces.AdjacentFaces(ff[i]).Length == 1)
                                    {
                                        temp.Add(corners[ff[i]]);
                                    }

                                    if (M.Faces.AdjacentFaces(id).Length == 1)
                                    {
                                        temp.Insert(0, corners[id]);
                                    }

                                    polylines.Add(temp);
                                    break;
                                }


                                //nei = ff[i];
                            }
                        }


                        break;
                    }
                    else    //if it has no neighbours check again



                    {
                        ff = M.Faces.AdjacentFaces(current);
                        for (int i = 0; i < ff.Length; i++)
                        {
                            if (nv.Contains(ff[i]) && !localVisit.Contains(ff[i]))
                            {
                                //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(M.Faces.GetFaceCenter(ff[i]));
                                //nei = ff[i];
                                polyline.Add(P_[ff[i]]);
                                localVisit.Add(ff[i]);
                                break;
                            }
                        }
                        break;
                    }

                    counter++;
                }

                if (polyline.Count > 2)
                {
                    int last  = localVisit.Last();
                    int first = localVisit.First();

                    int[] f0 = M.Faces.AdjacentFaces(last);
                    int[] f1 = M.Faces.AdjacentFaces(first);



                    if (f0.Contains(first) || f1.Contains(last))
                    {
                        polyline.Close();
                    }



                    if (M.Faces.AdjacentFaces(last).Length == 1)
                    {
                        polyline.Add(corners[last]);
                    }

                    if (M.Faces.AdjacentFaces(first).Length == 1)
                    {
                        polyline.Insert(0, corners[first]);
                    }

                    polylines.Add(polyline);



                    //} else if (polyline.Count== 1) {
                    //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(polyline[0]);
                }
            }



            //Output
            List <Polyline> outPolylines = new List <Polyline>();

            foreach (var ln in lines)
            {
                outPolylines.Add(new Polyline(new Point3d[] { ln.From, ln.To }));
            }//foreach



            //return outPolylines;
            return(polylines);
        }