Пример #1
1
 /// <summary>
 /// Identifies the points on the surface of hull.
 /// </summary>
 /// <param name="points">List of points in the set.</param>
 /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
 public static void GetConvexHull(IList<Vector3> points, IList<Vector3> outputSurfacePoints)
 {
     var rawPoints = new QuickList<Vector3>(BufferPools<Vector3>.Locking, BufferPool.GetPoolIndex(points.Count));
     rawPoints.AddRange(points);
     GetConvexHull(ref rawPoints, outputSurfacePoints);
     rawPoints.Dispose();
 }
Пример #2
0
        public static IEnumerable <string> GetAllFiles(string path, string[] extensions = null, string[] excludedExtensions = null)
        {
            QuickList <string> files = new QuickList <string>();

            files.AddRange(Directory.EnumerateFiles(path, "*.*", SearchOption.AllDirectories));

            if (extensions != null && extensions.Length > 0)
            {
                for (int i = files.Count; i >= 0; --i)
                {
                    string file = files.Array[i];
                    if (!extensions.Contains(Path.GetExtension(file)))
                    {
                        files.Remove(file);
                    }
                }
            }

            if (excludedExtensions != null && excludedExtensions.Length > 0)
            {
                for (int i = files.Count; i >= 0; --i)
                {
                    string file = files.Array[i];
                    if (excludedExtensions.Contains(Path.GetExtension(file)))
                    {
                        files.Remove(file);
                    }
                }
            }
            return(files);
        }
Пример #3
0
        private static void RemoveInsidePoints(ref QuickList <Vector3> points, ref QuickList <int> triangleIndices, ref QuickList <int> outsidePoints)
        {
            var insidePoints = new QuickList <int>(BufferPools <int> .Locking);

            //We're going to remove points from this list as we go to prune it down to the truly inner points.
            insidePoints.AddRange(outsidePoints);
            outsidePoints.Clear();

            for (int i = 0; i < triangleIndices.Count && insidePoints.Count > 0; i += 3)
            {
                //Compute the triangle's plane in point-normal representation to test other points against.
                Vector3 normal;
                FindNormal(ref triangleIndices, ref points, i, out normal);
                Vector3 p = points.Elements[triangleIndices.Elements[i]];

                for (int j = insidePoints.Count - 1; j >= 0; --j)
                {
                    //Offset from the triangle to the current point, tested against the normal, determines if the current point is visible
                    //from the triangle face.
                    Vector3 offset = points.Elements[insidePoints.Elements[j]] - p;
                    float   dot    = Vector3.Dot(offset, normal);
                    //If it's visible, then it's outside!
                    if (dot > 0)
                    {
                        //This point is known to be on the outside; put it on the outside!
                        outsidePoints.Add(insidePoints.Elements[j]);
                        insidePoints.FastRemoveAt(j);
                    }
                }
            }
            insidePoints.Dispose();
        }
Пример #4
0
        /// <summary>
        /// Identifies the points on the surface of hull.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
        public static void GetConvexHull(IList <Vector3> points, IList <Vector3> outputSurfacePoints)
        {
            var rawPoints = new QuickList <Vector3>(BufferPools <Vector3> .Locking, BufferPool.GetPoolIndex(points.Count));

            rawPoints.AddRange(points);
            GetConvexHull(ref rawPoints, outputSurfacePoints);
            rawPoints.Dispose();
        }
Пример #5
0
        public void GetRaw <T>(QuickList <IPartitionObject> existingList) where T : IPartitionObject
        {
            lock (tileLock) {
                if (!PartitionObjects.TryGetValue(typeof(T), out QuickList <IPartitionObject> objects))
                {
                    return;
                }

                existingList.AddRange(objects);
            }
        }
 /// <summary>
 /// Removes redundant points.  Two points are redundant if they occupy the same hash grid cell.
 /// </summary>
 /// <param name="points">List of points to prune.</param>
 /// <param name="cellSize">Size of cells to determine redundancy.</param>
 public static void RemoveRedundantPoints(IList<Vector3> points, double cellSize)
 {
     var rawPoints = new QuickList<Vector3>(BufferPools<Vector3>.Locking, BufferPool.GetPoolIndex(points.Count));
     rawPoints.AddRange(points);
     RemoveRedundantPoints(ref rawPoints, cellSize);
     points.Clear();
     for (int i = 0; i < rawPoints.Count; ++i)
     {
         points.Add(rawPoints.Elements[i]);
     }
     rawPoints.Dispose();
 }
        /// <summary>
        /// Removes redundant points.  Two points are redundant if they occupy the same hash grid cell.
        /// </summary>
        /// <param name="points">List of points to prune.</param>
        /// <param name="cellSize">Size of cells to determine redundancy.</param>
        public static void RemoveRedundantPoints(IList <Vector3> points, double cellSize)
        {
            var rawPoints = new QuickList <Vector3>(BufferPools <Vector3> .Locking, BufferPool.GetPoolIndex(points.Count));

            rawPoints.AddRange(points);
            RemoveRedundantPoints(ref rawPoints, cellSize);
            points.Clear();
            for (int i = 0; i < rawPoints.Count; ++i)
            {
                points.Add(rawPoints.Elements[i]);
            }
            rawPoints.Dispose();
        }
Пример #8
0
 /// <summary>
 /// Identifies the points on the surface of hull.
 /// </summary>
 /// <param name="points">List of points in the set.</param>
 /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
 /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
 /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
 public static void GetConvexHull(IList<Vector3> points, IList<int> outputTriangleIndices, IList<Vector3> outputSurfacePoints)
 {
     var rawPoints = new QuickList<Vector3>(BufferPools<Vector3>.Locking, BufferPool.GetPoolIndex(points.Count));
     var rawIndices = new QuickList<int>(BufferPools<int>.Locking, BufferPool.GetPoolIndex(points.Count * 3));
     rawPoints.AddRange(points);
     GetConvexHull(ref rawPoints, ref rawIndices, outputSurfacePoints);
     rawPoints.Dispose();
     for (int i = 0; i < rawIndices.Count; i++)
     {
         outputTriangleIndices.Add(rawIndices[i]);
     }
     rawIndices.Dispose();
 }
Пример #9
0
        /// <summary>
        /// Identifies the points on the surface of hull.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        /// <param name="outputSurfacePoints">Unique points on the surface of the convex hull.</param>
        public static void GetConvexHull(IList <Vector3> points, IList <int> outputTriangleIndices, IList <Vector3> outputSurfacePoints)
        {
            var rawPoints  = new QuickList <Vector3>(BufferPools <Vector3> .Locking, BufferPool.GetPoolIndex(points.Count));
            var rawIndices = new QuickList <int>(BufferPools <int> .Locking, BufferPool.GetPoolIndex(points.Count * 3));

            rawPoints.AddRange(points);
            GetConvexHull(ref rawPoints, ref rawIndices, outputSurfacePoints);
            rawPoints.Dispose();
            for (int i = 0; i < rawIndices.Count; i++)
            {
                outputTriangleIndices.Add(rawIndices[i]);
            }
            rawIndices.Dispose();
        }
Пример #10
0
        private static void RemoveInsidePoints(ref QuickList<Vector3> points, ref QuickList<int> triangleIndices, ref QuickList<int> outsidePoints)
        {
            var insidePoints = new QuickList<int>(BufferPools<int>.Locking);
            //We're going to remove points from this list as we go to prune it down to the truly inner points.
            insidePoints.AddRange(outsidePoints);
            outsidePoints.Clear();

            for (int i = 0; i < triangleIndices.Count && insidePoints.Count > 0; i += 3)
            {
                //Compute the triangle's plane in point-normal representation to test other points against.
                Vector3 normal;
                FindNormal(ref triangleIndices, ref points, i, out normal);
                Vector3 p = points.Elements[triangleIndices.Elements[i]];

                for (int j = insidePoints.Count - 1; j >= 0; --j)
                {
                    //Offset from the triangle to the current point, tested against the normal, determines if the current point is visible
                    //from the triangle face.
                    Vector3 offset = points.Elements[insidePoints.Elements[j]] - p;
                    float dot = Vector3.Dot(offset, normal);
                    //If it's visible, then it's outside!
                    if (dot > 0)
                    {
                        //This point is known to be on the outside; put it on the outside!
                        outsidePoints.Add(insidePoints.Elements[j]);
                        insidePoints.FastRemoveAt(j);
                    }
                }
            }
            insidePoints.Dispose();
        }
Пример #11
0
        /// <summary>
        /// Identifies the indices of points in a set which are on the outer convex hull of the set.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        public static void GetConvexHull(ref QuickList<Vector3> points, ref QuickList<int> outputTriangleIndices)
        {
            if (points.Count == 0)
            {
                throw new ArgumentException("Point set must have volume.");
            }
            var outsidePoints = new QuickList<int>(BufferPools<int>.Locking, BufferPool.GetPoolIndex(points.Count - 4));

            //Build the initial tetrahedron.
            //It will also give us the location of a point which is guaranteed to be within the
            //final convex hull.  We can use this point to calibrate the winding of triangles.
            //A set of outside point candidates (all points other than those composing the tetrahedron) will be returned in the outsidePoints list.
            //That list will then be further pruned by the RemoveInsidePoints call.
            Vector3 insidePoint;
            ComputeInitialTetrahedron(ref points, ref outsidePoints, ref outputTriangleIndices, out insidePoint);

            //Compute outside points.
            RemoveInsidePoints(ref points, ref outputTriangleIndices, ref outsidePoints);

            var edges = new QuickList<int>(BufferPools<int>.Locking);
            var toRemove = new QuickList<int>(BufferPools<int>.Locking);
            var newTriangles = new QuickList<int>(BufferPools<int>.Locking);

            //We're now ready to begin the main loop.
            while (outsidePoints.Count > 0)
            {
                //While the convex hull is incomplete...
                for (int k = 0; k < outputTriangleIndices.Count; k += 3)
                {
                    //Find the normal of the triangle
                    Vector3 normal;
                    FindNormal(ref outputTriangleIndices, ref points, k, out normal);

                    //Get the furthest point in the direction of the normal.
                    int maxIndexInOutsideList = GetExtremePoint(ref normal, ref points, ref outsidePoints);
                    int maxIndex = outsidePoints.Elements[maxIndexInOutsideList];
                    Vector3 maximum = points.Elements[maxIndex];

                    //If the point is beyond the current triangle, continue.
                    Vector3 offset = maximum - points.Elements[outputTriangleIndices.Elements[k]];
                    float dot = Vector3.Dot(normal, offset);
                    if (dot > 0)
                    {
                        //It's been picked! Remove the maximum point from the outside.
                        outsidePoints.FastRemoveAt(maxIndexInOutsideList);
                        //Remove any triangles that can see the point, including itself!
                        edges.Clear();
                        toRemove.Clear();
                        for (int n = outputTriangleIndices.Count - 3; n >= 0; n -= 3)
                        {
                            //Go through each triangle, if it can be seen, delete it and use maintainEdge on its edges.
                            if (IsTriangleVisibleFromPoint(ref outputTriangleIndices, ref points, n, ref maximum))
                            {
                                //This triangle can see it!
                                //TODO: CONSIDER CONSISTENT WINDING HAPPYTIMES
                                MaintainEdge(outputTriangleIndices[n], outputTriangleIndices[n + 1], ref edges);
                                MaintainEdge(outputTriangleIndices[n], outputTriangleIndices[n + 2], ref edges);
                                MaintainEdge(outputTriangleIndices[n + 1], outputTriangleIndices[n + 2], ref edges);
                                //Because fast removals are being used, the order is very important.
                                //It's pulling indices in from the end of the list in order, and also ensuring
                                //that we never issue a removal order beyond the end of the list.
                                outputTriangleIndices.FastRemoveAt(n + 2);
                                outputTriangleIndices.FastRemoveAt(n + 1);
                                outputTriangleIndices.FastRemoveAt(n);

                            }
                        }
                        //Create new triangles.
                        for (int n = 0; n < edges.Count; n += 2)
                        {
                            //For each edge, create a triangle with the extreme point.
                            newTriangles.Add(edges[n]);
                            newTriangles.Add(edges[n + 1]);
                            newTriangles.Add(maxIndex);
                        }
                        //Only verify the windings of the new triangles.
                        VerifyWindings(ref newTriangles, ref points, ref insidePoint);
                        outputTriangleIndices.AddRange(ref newTriangles);
                        newTriangles.Count = 0;

                        //Remove all points from the outsidePoints if they are inside the polyhedron
                        RemoveInsidePoints(ref points, ref outputTriangleIndices, ref outsidePoints);

                        //The list has been significantly messed with, so restart the loop.
                        break;
                    }
                }
            }

            outsidePoints.Dispose();
            edges.Dispose();
            toRemove.Dispose();
            newTriangles.Dispose();
        }
Пример #12
0
        /// <summary>
        /// Identifies the indices of points in a set which are on the outer convex hull of the set.
        /// </summary>
        /// <param name="points">List of points in the set.</param>
        /// <param name="outputTriangleIndices">List of indices into the input point set composing the triangulated surface of the convex hull.
        /// Each group of 3 indices represents a triangle on the surface of the hull.</param>
        public static void GetConvexHull(ref QuickList <Vector3> points, ref QuickList <int> outputTriangleIndices)
        {
            if (points.Count == 0)
            {
                throw new ArgumentException("Point set must have volume.");
            }
            var outsidePoints = new QuickList <int>(BufferPools <int> .Locking, BufferPool.GetPoolIndex(points.Count - 4));

            //Build the initial tetrahedron.
            //It will also give us the location of a point which is guaranteed to be within the
            //final convex hull.  We can use this point to calibrate the winding of triangles.
            //A set of outside point candidates (all points other than those composing the tetrahedron) will be returned in the outsidePoints list.
            //That list will then be further pruned by the RemoveInsidePoints call.
            Vector3 insidePoint;

            ComputeInitialTetrahedron(ref points, ref outsidePoints, ref outputTriangleIndices, out insidePoint);

            //Compute outside points.
            RemoveInsidePoints(ref points, ref outputTriangleIndices, ref outsidePoints);

            var edges        = new QuickList <int>(BufferPools <int> .Locking);
            var toRemove     = new QuickList <int>(BufferPools <int> .Locking);
            var newTriangles = new QuickList <int>(BufferPools <int> .Locking);

            //We're now ready to begin the main loop.
            while (outsidePoints.Count > 0)
            {
                //While the convex hull is incomplete...
                for (int k = 0; k < outputTriangleIndices.Count; k += 3)
                {
                    //Find the normal of the triangle
                    Vector3 normal;
                    FindNormal(ref outputTriangleIndices, ref points, k, out normal);

                    //Get the furthest point in the direction of the normal.
                    int     maxIndexInOutsideList = GetExtremePoint(ref normal, ref points, ref outsidePoints);
                    int     maxIndex = outsidePoints.Elements[maxIndexInOutsideList];
                    Vector3 maximum  = points.Elements[maxIndex];

                    //If the point is beyond the current triangle, continue.
                    Vector3 offset = maximum - points.Elements[outputTriangleIndices.Elements[k]];
                    float   dot    = Vector3.Dot(normal, offset);
                    if (dot > 0)
                    {
                        //It's been picked! Remove the maximum point from the outside.
                        outsidePoints.FastRemoveAt(maxIndexInOutsideList);
                        //Remove any triangles that can see the point, including itself!
                        edges.Clear();
                        toRemove.Clear();
                        for (int n = outputTriangleIndices.Count - 3; n >= 0; n -= 3)
                        {
                            //Go through each triangle, if it can be seen, delete it and use maintainEdge on its edges.
                            if (IsTriangleVisibleFromPoint(ref outputTriangleIndices, ref points, n, ref maximum))
                            {
                                //This triangle can see it!
                                //TODO: CONSIDER CONSISTENT WINDING HAPPYTIMES
                                MaintainEdge(outputTriangleIndices[n], outputTriangleIndices[n + 1], ref edges);
                                MaintainEdge(outputTriangleIndices[n], outputTriangleIndices[n + 2], ref edges);
                                MaintainEdge(outputTriangleIndices[n + 1], outputTriangleIndices[n + 2], ref edges);
                                //Because fast removals are being used, the order is very important.
                                //It's pulling indices in from the end of the list in order, and also ensuring
                                //that we never issue a removal order beyond the end of the list.
                                outputTriangleIndices.FastRemoveAt(n + 2);
                                outputTriangleIndices.FastRemoveAt(n + 1);
                                outputTriangleIndices.FastRemoveAt(n);
                            }
                        }
                        //Create new triangles.
                        for (int n = 0; n < edges.Count; n += 2)
                        {
                            //For each edge, create a triangle with the extreme point.
                            newTriangles.Add(edges[n]);
                            newTriangles.Add(edges[n + 1]);
                            newTriangles.Add(maxIndex);
                        }
                        //Only verify the windings of the new triangles.
                        VerifyWindings(ref newTriangles, ref points, ref insidePoint);
                        outputTriangleIndices.AddRange(ref newTriangles);
                        newTriangles.Count = 0;

                        //Remove all points from the outsidePoints if they are inside the polyhedron
                        RemoveInsidePoints(ref points, ref outputTriangleIndices, ref outsidePoints);

                        //The list has been significantly messed with, so restart the loop.
                        break;
                    }
                }
            }

            outsidePoints.Dispose();
            edges.Dispose();
            toRemove.Dispose();
            newTriangles.Dispose();
        }