/// <summary>
        /// Based upon the info of the nearest vertex (of each vertex), the triangles are created
        /// </summary>
        /// <param name="myModel"></param>
        //private static List<Triangle> CreateTrianglesByNearestVertices(PointCloud pointCloud)
        //{

        //    List<Triangle> listTriangles = new List<Triangle>();

        //    //create triangles
        //    //for (int i = pointCloud.Count - 1; i >= 0; i--)
        //    for (int i = 0; i < pointCloud.Count; i++)
        //    {
        //        Vertex v = pointCloud[i];

        //        if (v.KDTreeSearch.Count >= 2)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[1].Key, listTriangles, v);


        //        }
        //        if (v.KDTreeSearch.Count >= 3)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[2].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[2].Key, listTriangles, v);


        //        }
        //        if (v.KDTreeSearch.Count >= 4)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[3].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[3].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[2].Key, v.KDTreeSearch[3].Key, listTriangles, v);

        //        }
        //        if (v.KDTreeSearch.Count >= 5)
        //        {
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[0].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[1].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[2].Key, v.KDTreeSearch[4].Key, listTriangles, v);
        //            Triangle.AddTriangleToList(v.Index, v.KDTreeSearch[3].Key, v.KDTreeSearch[4].Key, listTriangles, v);

        //        }



        //    }
        //    //RemoveDuplicateTriangles(listTriangles);
        //    listTriangles.Sort(new TriangleComparer());

        //    return listTriangles;
        //}

        public void Triangulate_KDTree(int numberNeighbours)
        {
            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(this);

            List <Triangle> listTriangles = new List <Triangle>();

            for (int i = 0; i < this.Vectors.Length; i++)
            {
                VertexKDTree vSource = new VertexKDTree(this.Vectors[i], this.Colors[i], i);
                uint         indexI  = Convert.ToUInt32(i);

                ListKDTreeResultVectors listResult = kdTree.Find_N_Nearest(vSource.Vector, numberNeighbours);
                for (int j = 1; j < listResult.Count; j++)
                {
                    for (int k = j + 1; k < listResult.Count; k++)
                    {
                        Triangle t = new Triangle(indexI, listResult[j].IndexNeighbour, listResult[k].IndexNeighbour);
                        listTriangles.Add(t);
                    }
                }
            }
            this.Triangles = listTriangles;


            CreateIndicesFromTriangles();
        }
Beispiel #2
0
        /// <summary>
        /// Algorithm based on ignoring points with less neighbours    int thresholdNeighboursCount = 10; float thresholdDistance = 15e-5f;
        /// at given distance.
        /// </summary>
        /// <param name="source"></param>
        /// <param name="threshold"></param>
        /// <returns></returns>
        public static PointCloud ByLessNeighbours(PointCloud source, float thresholdDistance, int thresholdNeighboursCount)
        {
            PointCloud pcResult = new PointCloud();

            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(source);


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();
                System.Threading.Tasks.Parallel.For(0, source.Count, i =>
                {
                    VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i);
                    int neighboursCount  = 0;

                    kdTree.FindClosestPoints_Radius(vSource, thresholdDistance, ref neighboursCount);

                    if (neighboursCount >= thresholdNeighboursCount)
                    {
                        resultArray[i] = vSource;
                    }
                });

                for (int i = 0; i < source.Count; i++)
                {
                    if (resultArray[i] != null)
                    {
                        listV.Add(resultArray[i].Vector);
                        listC.Add(resultArray[i].Color);
                    }
                }

                pcResult.Vectors = listV.ToArray();
                pcResult.Colors  = listC.ToArray();
                pcResult.SetDefaultIndices();
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }

            return(pcResult);
        }
        /// <summary>
        /// mergedPoints
        /// </summary>
        /// <param name="pointsTransformed"></param>
        /// <param name="pointsTarget"></param>
        /// <param name="kdTree"></param>
        /// <param name="meanDistance"></param>
        /// <returns></returns>
        public static PointCloud CalculateMergedPoints(PointCloud pointsTransformed, PointCloud pointsTarget, IKDTree kdTree, float threshold, out int pointsAdded, bool changeColorsOfMergedPoints)
        {
            if (pointsTransformed.Colors == null || pointsTransformed.Colors.Length != pointsTransformed.Vectors.Length)
            {
                pointsTransformed.Colors = new Vector3[pointsTransformed.Vectors.Length];
            }

            if (pointsTarget.Colors == null || pointsTarget.Colors.Length != pointsTarget.Vectors.Length)
            {
                pointsTarget.Colors = new Vector3[pointsTarget.Vectors.Length];
            }


            //search in tree


            // PointCloud resultKDTree = kdTree.FindClosestPointCloud_Parallel(result);
            KDTreeKennell kdTreeKennell = kdTree as KDTreeKennell;
            PointCloud    pcToAdd       = kdTreeKennell.RemoveDuplicates(pointsTransformed, threshold);

            pointsAdded = pcToAdd.Vectors.Length;
            //System.Diagnostics.Debug.WriteLine("target points added : " + pcToAdd.Vectors.Length.ToString() + " - outof " + result.Vectors.Length.ToString());


            if (changeColorsOfMergedPoints)
            {
                pcToAdd.SetColor(new Vector3(0, 1, 1));
            }

            List <Vector3> listV = pointsTarget.ListVectors;
            List <Vector3> listC = pointsTarget.ListColors;

            listV.AddRange(pcToAdd.ListVectors);
            listC.AddRange(pcToAdd.ListColors);



            PointCloud pMerged = new PointCloud(listV, listC, null, null, null, null);

            return(pMerged);
        }
Beispiel #4
0
 public KDTreeNodeKennell(KDTreeKennell parent)
 {
     Parent = parent;
 }
Beispiel #5
0
        public static void StandardDeviation(PointCloud source, int numberOfNeighbours, out float meanDistance, out float standardDeviation, out float[] distances)
        {
            meanDistance      = 0;
            standardDeviation = 0f;
            distances         = new float[source.Count];

            KDTreeKennell kdTree = new KDTreeKennell();

            kdTree.Build(source);


            PointCloud pcResult = new PointCloud();


            VertexKDTree[] resultArray = new VertexKDTree[source.Count];
            VertexKDTree[] outliers    = new VertexKDTree[source.Count];

            try
            {
                List <Vector3> listV = new List <Vector3>();
                List <Vector3> listC = new List <Vector3>();



                //1. mean distance of one point to his next "numberOfNeighbours" neighbours - stored in the "distances" array
                for (int i = 0; i < source.Count; i++)
                {
                    VertexKDTree vSource = new VertexKDTree(source.Vectors[i], source.Colors[i], i);

                    ListKDTreeResultVectors listResult = kdTree.Find_N_Nearest(vSource.Vector, numberOfNeighbours);

                    float distSum = 0f;
                    for (int k = 1; k < listResult.Count; ++k)  // k = 0 is the query point
                    {
                        distSum += listResult[k].Distance;
                    }

                    distances[i] = (distSum / (listResult.Count - 1));
                }
                //2. calculate the mean distance of ALL points



                for (int i = 0; i < distances.Length; ++i)
                {
                    meanDistance += distances[i];
                }
                meanDistance /= distances.Length;

                //3. calculate the deviation of each data point from the mean, and square the result of each

                for (int i = 0; i < distances.Length; i++)
                {
                    float dev = distances[i] - meanDistance;
                    dev *= dev;
                    standardDeviation += dev;
                }
                standardDeviation /= distances.Length;
                standardDeviation  = Convert.ToSingle(Math.Sqrt(standardDeviation));
            }
            catch (Exception err)
            {
                System.Windows.Forms.MessageBox.Show("Error in KDTreeKennnellRemoveDuplicates: " + err.Message);
            }
        }