public static string RunSequential(List <IPolygon> polygons) { var pool = new TrianglePool(); var predicates = new RobustPredicates(); var config = new Configuration(); config.Predicates = () => predicates; config.TrianglePool = () => pool.Restart(); var mesher = new GenericMesher(config); var result = new MeshResult(); foreach (var poly in polygons) { var mesh = mesher.Triangulate(poly); ProcessMesh(mesh, result); } pool.Clear(); //Console.WriteLine("Total number of triangles processed: {0}", result.NumberOfTriangles); var sequential = $"Total number of triangles processed: {result.NumberOfTriangles}"; if (result.Invalid > 0) { //Console.WriteLine(" Number of invalid triangulations: {0}", result.Invalid); sequential += $"Number of invalid triangulations: {result.Invalid}"; } return(sequential); }
/// <summary> /// Initializes a new instance of the <see cref="SimpleSmoother" /> class. /// </summary> public SimpleSmoother(IVoronoiFactory factory) { this.factory = factory; this.pool = new TrianglePool(); this.config = new Configuration( () => RobustPredicates.Default, () => pool.Restart()); this.options = new ConstraintOptions() { ConformingDelaunay = true }; }
/// <summary> /// Initializes a new instance of the <see cref="SimpleSmoother" /> class. /// </summary> public SimpleSmoother(IVoronoiFactory factory) { this.factory = factory; this.pool = new TrianglePool(); this.config = new Configuration( () => RobustPredicates.Default, () => pool.Restart()); this.options = new ConstraintOptions() { ConformingDelaunay = true }; }
public void TestRestart() { var pool = new TrianglePool(); Assert.AreEqual(0, pool.Count); Assert.AreEqual(0, pool.Capacity); int n = 10; for (int i = 0; i < n; i++) { Assert.AreEqual(i, pool.Get().ID); } Assert.AreEqual(n, pool.Count); pool.Restart(); Assert.AreEqual(0, pool.Count); Assert.AreEqual(10, pool.Capacity); }
/// <summary> /// Reads all .poly files from given directory and processes them in parallel. /// </summary> public static bool Run(string dir) { var files = Directory.EnumerateFiles(dir, "*.poly", SearchOption.AllDirectories); var queue = new ConcurrentQueue <string>(files); int concurrencyLevel = Environment.ProcessorCount / 2; var tasks = new Task <MeshResult> [concurrencyLevel]; for (int i = 0; i < concurrencyLevel; i++) { tasks[i] = Task.Run(() => { // Each task has it's own triangle pool and predicates instance. var pool = new TrianglePool(); var predicates = new RobustPredicates(); // The factory methods return the above instances. var config = new Configuration() { Predicates = () => predicates, TrianglePool = () => pool.Restart(), RandomSource = () => Random.Shared }; var mesher = new GenericMesher(config); var result = new MeshResult(); while (queue.Count > 0) { if (queue.TryDequeue(out var file)) { var poly = FileProcessor.Read(file); var mesh = mesher.Triangulate(poly); ProcessMesh(mesh, result); } } pool.Clear(); return(result); }); } Task.WaitAll(tasks); int numberOfTriangles = tasks.Sum(t => t.Result.NumberOfTriangles); int invalid = tasks.Sum(t => t.Result.Invalid); Console.WriteLine("Total number of triangles processed: {0}", numberOfTriangles); if (invalid > 0) { Console.WriteLine(" Number of invalid triangulations: {0}", invalid); } return(invalid == 0); }
/// <summary> /// Triangulate a given number of random point sets in parallel. /// </summary> public static bool Run(int n = 1000) { // Use thread-safe random source. var random = Random.Shared; // Generate a random set of sizes. var sizes = Enumerable.Range(0, n).Select(_ => random.Next(500, 5000)); var queue = new ConcurrentQueue <int>(sizes); int concurrencyLevel = Environment.ProcessorCount / 2; var tasks = new Task <MeshResult> [concurrencyLevel]; for (int i = 0; i < concurrencyLevel; i++) { tasks[i] = Task.Run(() => { // Each task has it's own triangle pool and predicates instance. var pool = new TrianglePool(); var predicates = new RobustPredicates(); // The factory methods return the above instances. var config = new Configuration() { Predicates = () => predicates, TrianglePool = () => pool.Restart(), RandomSource = () => Random.Shared }; var triangulator = new Dwyer(); var result = new MeshResult(); var bounds = new Rectangle(0d, 0d, 1000d, 1000d); while (queue.Count > 0) { if (queue.TryDequeue(out int size)) { var points = Generate.RandomPoints(size, bounds); var mesh = triangulator.Triangulate(points, config); ProcessMesh(mesh, result); } } pool.Clear(); return(result); }); } Task.WaitAll(tasks); int numberOfTriangles = tasks.Sum(t => t.Result.NumberOfTriangles); int invalid = tasks.Sum(t => t.Result.Invalid); Console.WriteLine("Total number of triangles processed: {0}", numberOfTriangles); if (invalid > 0) { Console.WriteLine(" Number of invalid triangulations: {0}", invalid); } return(invalid == 0); }
public static string RunParallel(List <IPolygon> polygons) { var queue = new ConcurrentQueue <IPolygon>(polygons); int concurrencyLevel = Environment.ProcessorCount; var tasks = new Task <MeshResult> [concurrencyLevel]; for (int i = 0; i < concurrencyLevel; i++) { tasks[i] = Task.Run(() => { // Each task has it's own triangle pool and predicates instance. var pool = new TrianglePool(); var predicates = new RobustPredicates(); var config = new Configuration(); // The factory methods return the above instances. config.Predicates = () => predicates; config.TrianglePool = () => pool.Restart(); IPolygon poly; var mesher = new GenericMesher(config); var result = new MeshResult(); while (queue.Count > 0) { if (queue.TryDequeue(out poly)) { var mesh = mesher.Triangulate(poly); ProcessMesh(mesh, result); } } pool.Clear(); return(result); }); } Task.WaitAll(tasks); int numberOfTriangles = 0; int invalid = 0; for (int i = 0; i < concurrencyLevel; i++) { var result = tasks[i].Result; numberOfTriangles += result.NumberOfTriangles; invalid += result.Invalid; } string parallel = $"Total number of triangles processed: {numberOfTriangles}"; //Console.WriteLine("Total number of triangles processed: {0}", numberOfTriangles); if (invalid > 0) { //Console.WriteLine(" Number of invalid triangulations: {0}", invalid); parallel += $"\tNumber of invalid triangulations: {invalid}"; } return(parallel); }