Exemple #1
0
        //Duplication
        public Type_KDTree DuplicateKDTree()
        {
            GH_Cloud     newCloud = (GH_Cloud)this.Value.Item2.Duplicate();
            KDTree <int> newTree  = KDTreeLib.DubplicateTree(this.Value.Item1);

            return(new Type_KDTree(newTree, newCloud));
        }
Exemple #2
0
        public override IGH_Goo Duplicate()
        {
            PointCloud   newCloud = (PointCloud)this.Value.Item2.Duplicate();
            KDTree <int> newTree  = KDTreeLib.DubplicateTree(this.Value.Item1);

            return(new KDTree(newTree, newCloud));
        }
        private void calcNormal(List <int>[] idc, ref PointCloud MyCloud, ref int count, int i)
        {
            List <Point3d> normalPts = new List <Point3d>();

            normalPts.Add(GlobalCloud[i].Location);
            List <int> ids = idc[i];

            if (ids.Count >= 3)
            {
                for (int j = 0; j < ids.Count; j++)
                {
                    Point3d nPt = GlobalCloud[ids[j]].Location;
                    normalPts.Add(nPt);
                }
                //Get not-oriented normal from Z-Axis of best fit plane to NormalPoints.
                Plane normalPln = new Plane();
                Plane.FitPlaneToPoints(normalPts, out normalPln);

                Vector3d notOriNormal = normalPln.ZAxis;

                //Orient not-oriented NormalVector according to the guiding vector.
                Vector3d guideVector = new Vector3d();
                if (insV_GuideStyle == true)
                {
                    guideVector = insV_GuideVector;
                }
                else if (insV_GuideStyle == false)
                {
                    guideVector = Point3d.Subtract(GlobalCloud[i].Location, new Point3d(insV_GuideVector));
                }
                guideVector.Unitize();

                Vector3d normalVector = new Vector3d();
                double   vecAngle     = Vector3d.VectorAngle(notOriNormal, guideVector);
                if (vecAngle < Math.PI / 2)
                {
                    normalVector = notOriNormal;
                }
                else
                {
                    normalVector = notOriNormal;
                    normalVector.Reverse();
                }

                //Add normal to Cloud.
                Cloud_Utils.AddItem_FromOtherCloud(ref MyCloud, GlobalCloud, i);
                MyCloud[count].Normal = normalVector;

                if (insV_Colorize)
                {
                    MyCloud[count].Color = KDTreeLib.normalColors(1, normalVector, GlobalCloud[i].Color);
                }

                count += 1;
            }
        }
Exemple #4
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            KDTreeType treeT          = null;
            double     NeighborRange  = new double();
            int        NeighborAmount = 5;
            Vector3d   GuideVector    = Vector3d.ZAxis;
            int        GuideStyle     = 0;
            int        Color          = 1;
            bool       Unify          = false;


            if (!DA.GetData(0, ref treeT))
            {
                return;
            }
            if (!DA.GetData(1, ref NeighborRange))
            {
                return;
            }
            if (!DA.GetData(2, ref NeighborAmount))
            {
                return;
            }
            if (!DA.GetData(3, ref GuideVector))
            {
                return;
            }
            if (!DA.GetData(4, ref GuideStyle))
            {
                return;
            }
            if (!DA.GetData(5, ref Color))
            {
                return;
            }

            Tuple <KDTree <int>, PointCloud> KDTreeCloud = treeT.Value;


            if (NeighborAmount < 3)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Minimum Amount of Neighboring Points to calculate Normal is 3.");
                return;
            }

            Tuple <KDTree <int>, PointCloud> newKDTreeCloud = KDTreeLib.CalcNormals(KDTreeCloud, NeighborRange, NeighborAmount, GuideVector, GuideStyle, Color);


            DA.SetData(0, new KDTreeType(newKDTreeCloud.Item1, newKDTreeCloud.Item2));
        }
Exemple #5
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            PointCloud cloud = null;


            if (!DA.GetData(0, ref cloud))
            {
                return;
            }

            KDTree <int> tree = KDTreeLib.ConstructKDTree(cloud);


            DA.SetData(0, new KDTreeType(tree, cloud));
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            GH_Cloud GHcloud = null;


            if (!DA.GetData(0, ref GHcloud))
            {
                return;
            }

            PointCloud   cloud = (PointCloud)GHcloud.Value;
            KDTree <int> tree  = KDTreeLib.ConstructKDTree(cloud);


            DA.SetData(0, new Type_KDTree(tree, GHcloud));
        }
Exemple #7
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // PointCloud to meassure Distance From.
            PointCloud cloudFrom = null;
            // PointCloud/KDTree to meassure Distance From.
            Type_KDTree treeT = null;
            // Amount
            int amount = 1;
            //UserData Key String.
            string key = "CloCloD";

            if (!DA.GetData(0, ref cloudFrom))
            {
                return;
            }
            if (!DA.GetData(1, ref treeT))
            {
                return;
            }
            if (!DA.GetData(2, ref amount))
            {
                return;
            }
            if (!DA.GetData(3, ref key))
            {
                return;
            }

            Tuple <KDTree <int>, GH_Cloud> KDTreeCloud = treeT.Value;

            //Make Duplicate to make sure I dont change UserData in input Cloud.
            cloudFrom = (PointCloud)cloudFrom.Duplicate();

            //Calculate closestPoint distances between the two Clouds.
            double[] dist = KDTreeLib.CloudCloudDist(cloudFrom, KDTreeCloud, amount);

            //Add Distances to UserDictionary
            cloudFrom.UserDictionary.Set(key, dist);

            //Output
            DA.SetData(0, cloudFrom);
        }
        /// <summary>
        /// Parallel Computing Setup for Code to Execute.
        /// </summary>
        /// <param name="pointCloud">ByRef PointCloud to Execute Code on.</param>
        /// <returns></returns>
        public override bool Execute(ref PointCloud pointCloud)
        {
            //Set Global Variables
            LastPercentReported = 0;
            PointCounter        = 0;

            if (insV_KDTree == null)
            {
                tree = KDTreeLib.ConstructKDTree(pointCloud);
            }
            else
            {
                tree = insV_KDTree;
            }

            Dict_Utils.CastDictionary_ToArrayDouble(ref pointCloud);
            GlobalCloud = pointCloud;

            NewCloud    = new PointCloud();
            CloudPieces = null;
            CloudPieces = new PointCloud[ProcCount];
            DictPieces  = new object[ProcCount];

            pts = pointCloud.GetPoints().ToList();

            // Setup the cancellation mechanism.
            po.CancellationToken = cts.Token;

            //Create Partitions for multithreading.
            var rangePartitioner = System.Collections.Concurrent.Partitioner.Create(0, GlobalCloud.Count, (int)Math.Ceiling((double)GlobalCloud.Count / ProcCount));

            Dict_Utils.CastDictionary_ToArrayDouble(ref GlobalCloud);

            //Search for NearestNeighbors per point in PointCloud. Gets the indices in the Cloud for the neighbors to each Point.
            List <double> NRange = new List <double> {
                double.MaxValue
            };

            List <int>[] idc = KDTreeLib.NearestNeighborSearch(tree, pts, NRange, insV_NumN);

            //Run MultiThreaded Loop.
            Parallel.ForEach(rangePartitioner, po, (rng, loopState) =>
            {
                //Initialize Local Variables.
                /// Get Index for Processor to be able to merge clouds in ProcesserIndex order in the end.
                int MyIndex = (int)(rng.Item1 / Math.Ceiling(((double)GlobalCloud.Count / ProcCount)));
                /// Initialize Partial PointCloud
                PointCloud MyCloud = new PointCloud();



                /// Get Total Count Fraction to calculate Operation Percentage.
                double totc = (double)1 / GlobalCloud.Count;
                int count   = 0;
                if (GlobalCloud.UserDictionary.Count > 0)
                {
                    /// Initialize Partial Dictionary Lists
                    List <double>[] MyDict = new List <double> [GlobalCloud.UserDictionary.Count];

                    //Get Dictionary Values from PointCloud
                    List <double[]> GlobalDict = new List <double[]>();
                    GlobalDict.Clear();

                    Dict_Utils.Initialize_Dictionary(ref GlobalDict, ref MyDict, GlobalCloud);

                    //Loop over individual RangePartitions per processor.
                    for (int i = rng.Item1; i < rng.Item2; i++)
                    {
                        //Operation Percentage Report
                        ///Safe Counter Increment.
                        Interlocked.Increment(ref PointCounter);
                        ///Calculate and Report Percentage.
                        if (LastPercentReported < ((PointCounter * totc) * 100))
                        {
                            LastPercentReported = (int)(5 * Math.Ceiling((double)(PointCounter * totc) * 20));
                            this.ReportPercent  = LastPercentReported;
                        }

                        calcNormal(idc, ref MyCloud, ref count, i);
                        Dict_Utils.AddItem_FromGlobalDict(ref MyDict, GlobalDict, i);
                    }

                    //Add MyCloud to CloudPieces at ProcesserIndex.
                    CloudPieces[(int)MyIndex] = MyCloud;
                    //Set DictPieces.
                    DictPieces[(int)MyIndex] = MyDict;
                }
                else
                {
                    //Loop over individual RangePartitions per processor.
                    for (int i = rng.Item1; i < rng.Item2; i++)
                    {
                        //Operation Percentage Report
                        ///Safe Counter Increment.
                        Interlocked.Increment(ref PointCounter);
                        ///Calculate and Report Percentage.
                        if (LastPercentReported < ((PointCounter * totc) * 100))
                        {
                            LastPercentReported = (int)(5 * Math.Ceiling((double)(PointCounter * totc) * 20));
                            this.ReportPercent  = LastPercentReported;
                        }

                        calcNormal(idc, ref MyCloud, ref count, i);
                    }
                    //Add MyCloud to CloudPieces at ProcesserIndex.
                    CloudPieces[(int)MyIndex] = MyCloud;
                }
                //Enable Parrallel Computing Cancellation
                po.CancellationToken.ThrowIfCancellationRequested();
            }
                             );



            //Merge PointCloud Pieces into One PointCloud.
            Cloud_Utils.MergeClouds(ref NewCloud, CloudPieces);
            if (GlobalCloud.UserDictionary.Count > 0)
            {
                List <double>[] NewDict = new List <double> [GlobalCloud.UserDictionary.Count];
                Dict_Utils.Merge_DictPieces(ref NewDict, DictPieces);
                Dict_Utils.SetUserDict_FromDictLists(ref NewCloud, NewDict, GlobalCloud.UserDictionary.Keys);
            }


            //Dispose of Global Clouds.
            GlobalCloud.Dispose();
            pointCloud.Dispose();

            /*
             * //Colorize
             * if (insV_Colorize)
             * {
             *  List<double> colorValues = Color_Utils.ColorValues_Std_pos(NewCloud, insV_Key);
             *  List<Color> Colors = Color_Utils.ColorGradient_Std_GtoR();
             *
             *  Instruction.Instr_Dict_Color col = new Instruction.Instr_Dict_Color(insV_Key, colorValues, Colors, -1, 0.00);
             *  Boolean ColResult = col.Execute(ref NewCloud);
             *
             *  //Set ColorGradient UserData
             *  Color_Utils.Set_ColorGradient_Dict(ref NewCloud, Colors, colorValues);
             * }
             */

            pointCloud = (PointCloud)NewCloud.Duplicate();

            //Dispose of PointCloud Pieces and NewCloud.
            GlobalCloud.Dispose();
            NewCloud.Dispose();

            //Return True on Finish
            return(true);
        }
Exemple #9
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Type_KDTree    treeT       = null;
            List <Point3d> pts         = new List <Point3d>();
            List <double>  range       = new List <double>();
            int            maxReturned = 100;

            if (!DA.GetData("KDTree", ref treeT))
            {
                return;
            }
            if (!DA.GetDataList("Points", pts))
            {
                return;
            }
            if (!DA.GetDataList("Range", range))
            {
                return;
            }
            DA.GetData("Number of Neighbors", ref maxReturned);

            Tuple <KDTree <int>, GH_Cloud> KDTreeCloud = treeT.Value;
            KDTree <int> tree  = KDTreeCloud.Item1;
            PointCloud   cloud = KDTreeCloud.Item2.Value;


            if (range.Count > 1 && range.Count < pts.Count)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Amount of Range values should be a single value, or match the amount of search points.");
                return;
            }

            List <int>[] idc = KDTreeLib.NearestNeighborSearch(tree, pts, range, maxReturned);


            var path1 = DA.ParameterTargetPath(0);
            DataTree <Point3d>        pointT    = new DataTree <Point3d>();
            DataTree <Vector3d>       normalT   = new DataTree <Vector3d>();
            DataTree <Color>          colorT    = new DataTree <Color>();
            DataTree <double>         distanceT = new DataTree <double>();
            GH_Structure <GH_Integer> idxT      = new GH_Structure <GH_Integer>();

            for (int i = 0; i < pts.Count; i++)
            {
                List <int> ids = idc[i];
                for (int j = 0; j < ids.Count; j++)
                {
                    pointT.Add(cloud[ids[j]].Location, path1.AppendElement(i));
                    if (cloud.ContainsNormals)
                    {
                        normalT.Add(cloud[ids[j]].Normal, path1.AppendElement(i));
                    }
                    if (cloud.ContainsColors)
                    {
                        colorT.Add(cloud[ids[j]].Color, path1.AppendElement(i));
                    }
                    //Distance betwen Points
                    double D = pts[i].DistanceTo(cloud[ids[j]].Location);
                    distanceT.Add(D, path1.AppendElement(i));
                }
                idxT.AppendRange(ids.Select(x => new GH_Integer(x)), path1.AppendElement(i));
            }


            DA.SetDataTree(0, pointT);
            DA.SetDataTree(1, normalT);
            DA.SetDataTree(2, colorT);
            DA.SetDataTree(3, distanceT);
            DA.SetDataTree(4, idxT);
        }