123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- // -----------------------------------------------------------------------
- // <copyright file="GenericMesher.cs">
- // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
- // </copyright>
- // -----------------------------------------------------------------------
- namespace UnityEngine.U2D.Animation.TriangleNet
- .Meshing
- {
- using System;
- using System.Collections.Generic;
- using Animation.TriangleNet.Geometry;
- using Animation.TriangleNet.IO;
- using Animation.TriangleNet.Meshing.Algorithm;
- /// <summary>
- /// Create meshes of point sets or polygons.
- /// </summary>
- internal class GenericMesher
- {
- Configuration config;
- ITriangulator triangulator;
- public GenericMesher()
- : this(new Dwyer(), new Configuration())
- {
- }
- public GenericMesher(ITriangulator triangulator)
- : this(triangulator, new Configuration())
- {
- }
- public GenericMesher(Configuration config)
- : this(new Dwyer(), config)
- {
- }
- public GenericMesher(ITriangulator triangulator, Configuration config)
- {
- this.config = config;
- this.triangulator = triangulator;
- }
- /// <inheritdoc />
- public IMesh Triangulate(IList<Vertex> points)
- {
- return triangulator.Triangulate(points, config);
- }
- /// <inheritdoc />
- public IMesh Triangulate(IPolygon polygon)
- {
- return Triangulate(polygon, null, null);
- }
- /// <inheritdoc />
- public IMesh Triangulate(IPolygon polygon, ConstraintOptions options)
- {
- return Triangulate(polygon, options, null);
- }
- /// <inheritdoc />
- public IMesh Triangulate(IPolygon polygon, QualityOptions quality)
- {
- return Triangulate(polygon, null, quality);
- }
- /// <inheritdoc />
- public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality)
- {
- var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config);
- var cmesher = new ConstraintMesher(mesh, config);
- var qmesher = new QualityMesher(mesh, config);
- mesh.SetQualityMesher(qmesher);
- // Insert segments.
- cmesher.Apply(polygon, options);
- // Refine mesh.
- qmesher.Apply(quality);
- return mesh;
- }
- /// <summary>
- /// Generates a structured mesh with bounds [0, 0, width, height].
- /// </summary>
- /// <param name="width">Width of the mesh (must be > 0).</param>
- /// <param name="height">Height of the mesh (must be > 0).</param>
- /// <param name="nx">Number of segments in x direction.</param>
- /// <param name="ny">Number of segments in y direction.</param>
- /// <returns>Mesh</returns>
- internal static IMesh StructuredMesh(double width, double height, int nx, int ny)
- {
- if (width <= 0.0)
- {
- throw new ArgumentException("width");
- }
- if (height <= 0.0)
- {
- throw new ArgumentException("height");
- }
- return StructuredMesh(new Rectangle(0.0, 0.0, width, height), nx, ny);
- }
- /// <summary>
- /// Generates a structured mesh.
- /// </summary>
- /// <param name="bounds">Bounds of the mesh.</param>
- /// <param name="nx">Number of segments in x direction.</param>
- /// <param name="ny">Number of segments in y direction.</param>
- /// <returns>Mesh</returns>
- internal static IMesh StructuredMesh(Rectangle bounds, int nx, int ny)
- {
- var polygon = new Polygon((nx + 1) * (ny + 1));
- double x, y, dx, dy, left, bottom;
- dx = bounds.Width / nx;
- dy = bounds.Height / ny;
- left = bounds.Left;
- bottom = bounds.Bottom;
- int i, j, k, l, n = 0;
- // Add vertices.
- var points = new Vertex[(nx + 1) * (ny + 1)];
- for (i = 0; i <= nx; i++)
- {
- x = left + i * dx;
- for (j = 0; j <= ny; j++)
- {
- y = bottom + j * dy;
- points[n++] = new Vertex(x, y);
- }
- }
- polygon.Points.AddRange(points);
- n = 0;
- // Set vertex hash and id.
- foreach (var v in points)
- {
- v.hash = v.id = n++;
- }
- // Add boundary segments.
- var segments = polygon.Segments;
- segments.Capacity = 2 * (nx + ny);
- Vertex a, b;
- for (j = 0; j < ny; j++)
- {
- // Left
- a = points[j];
- b = points[j + 1];
- segments.Add(new Segment(a, b, 1));
- a.Label = b.Label = 1;
- // Right
- a = points[nx * (ny + 1) + j];
- b = points[nx * (ny + 1) + (j + 1)];
- segments.Add(new Segment(a, b, 1));
- a.Label = b.Label = 1;
- }
- for (i = 0; i < nx; i++)
- {
- // Bottom
- a = points[(ny + 1) * i];
- b = points[(ny + 1) * (i + 1)];
- segments.Add(new Segment(a, b, 1));
- a.Label = b.Label = 1;
- // Top
- a = points[ny + (ny + 1) * i];
- b = points[ny + (ny + 1) * (i + 1)];
- segments.Add(new Segment(a, b, 1));
- a.Label = b.Label = 1;
- }
- // Add triangles.
- var triangles = new InputTriangle[2 * nx * ny];
- n = 0;
- for (i = 0; i < nx; i++)
- {
- for (j = 0; j < ny; j++)
- {
- k = j + (ny + 1) * i;
- l = j + (ny + 1) * (i + 1);
- // Create 2 triangles in rectangle [k, l, l + 1, k + 1].
- if ((i + j) % 2 == 0)
- {
- // Diagonal from bottom left to top right.
- triangles[n++] = new InputTriangle(k, l, l + 1);
- triangles[n++] = new InputTriangle(k, l + 1, k + 1);
- }
- else
- {
- // Diagonal from top left to bottom right.
- triangles[n++] = new InputTriangle(k, l, k + 1);
- triangles[n++] = new InputTriangle(l, l + 1, k + 1);
- }
- }
- }
- return Converter.ToMesh(polygon, triangles);
- }
- }
- }
|