예제 #1
0
        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);
        }
예제 #2
0
        /// <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);
        }
예제 #3
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);
        }
예제 #4
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);
        }
    /* loop through each point to add, brute force search through each triangle, if
     *  the point is contained in the triangle's circumcircle remove it. Create a polygon with
     *  each removed triangle's outer edge, and add the triangles made by linking each edge to
     *  the new point
     */
    private void Triangulate()
    {
        triangulation.Clear();
        trianglePool.Clear();
        // first triangle, containing the whole playground
        superTriangle = trianglePool.Get();
        superTriangle.Populate(new Vector2(-halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(halfWidth * 2.5f * scalePlayground, -halfHeight * 2 * scalePlayground),
                               new Vector2(0.0f, halfHeight * 3 * scalePlayground));
        triangulation.Add(superTriangle);

        List <Triangle> badTriangles = new List <Triangle>();
        List <Edge>     polygon      = new List <Edge>();

        for (int i = 0; i < points.Count; i++)
        {
            Vector2 point = points[i].position;
            badTriangles.Clear();
            polygon.Clear();

            // check if the triangle contains point in its circumcircle
            foreach (Triangle triangle in triangulation)
            {
                if (triangle.isPointInsideCircumcircle(point))
                {
                    badTriangles.Add(triangle);
                }
            }

            // create the outer polygon
            for (int outer = 0; outer < badTriangles.Count; outer++)
            {
                for (int edge = 0; edge < 3; edge++)
                {
                    bool isShared = false;
                    for (int inner = 0; inner < badTriangles.Count; inner++)
                    {
                        if (inner != outer && !isShared)
                        {
                            for (int badEdge = 0; badEdge < 3; badEdge++)
                            {
                                if (badTriangles[outer].edges[edge].Compare(badTriangles[inner].edges[badEdge]))
                                {
                                    isShared = true;
                                }
                            }
                        }
                    }
                    if (!isShared)
                    {
                        polygon.Add(badTriangles[outer].edges[edge]);
                    }
                }
            }

            // remove bad triangles
            for (int j = 0; j < badTriangles.Count; j++)
            {
                trianglePool.Remove(badTriangles[j]);
                triangulation.Remove(badTriangles[j]);
            }

            // create new triangles
            for (int j = 0; j < polygon.Count; j++)
            {
                Triangle thisTriangle = trianglePool.Get();
                thisTriangle.Populate(polygon[j].A, polygon[j].B, point);
                triangulation.Add(thisTriangle);
            }
        }
    }