/// <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(); }
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); }
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(); }
/// <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(); }
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(); }
/// <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(); }
/// <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(); }
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(); }
/// <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(); }
/// <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(); }