GenericMesher.cs 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. // -----------------------------------------------------------------------
  2. // <copyright file="GenericMesher.cs">
  3. // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/
  4. // </copyright>
  5. // -----------------------------------------------------------------------
  6. namespace UnityEngine.U2D.Animation.TriangleNet
  7. .Meshing
  8. {
  9. using System;
  10. using System.Collections.Generic;
  11. using Animation.TriangleNet.Geometry;
  12. using Animation.TriangleNet.IO;
  13. using Animation.TriangleNet.Meshing.Algorithm;
  14. /// <summary>
  15. /// Create meshes of point sets or polygons.
  16. /// </summary>
  17. internal class GenericMesher
  18. {
  19. Configuration config;
  20. ITriangulator triangulator;
  21. public GenericMesher()
  22. : this(new Dwyer(), new Configuration())
  23. {
  24. }
  25. public GenericMesher(ITriangulator triangulator)
  26. : this(triangulator, new Configuration())
  27. {
  28. }
  29. public GenericMesher(Configuration config)
  30. : this(new Dwyer(), config)
  31. {
  32. }
  33. public GenericMesher(ITriangulator triangulator, Configuration config)
  34. {
  35. this.config = config;
  36. this.triangulator = triangulator;
  37. }
  38. /// <inheritdoc />
  39. public IMesh Triangulate(IList<Vertex> points)
  40. {
  41. return triangulator.Triangulate(points, config);
  42. }
  43. /// <inheritdoc />
  44. public IMesh Triangulate(IPolygon polygon)
  45. {
  46. return Triangulate(polygon, null, null);
  47. }
  48. /// <inheritdoc />
  49. public IMesh Triangulate(IPolygon polygon, ConstraintOptions options)
  50. {
  51. return Triangulate(polygon, options, null);
  52. }
  53. /// <inheritdoc />
  54. public IMesh Triangulate(IPolygon polygon, QualityOptions quality)
  55. {
  56. return Triangulate(polygon, null, quality);
  57. }
  58. /// <inheritdoc />
  59. public IMesh Triangulate(IPolygon polygon, ConstraintOptions options, QualityOptions quality)
  60. {
  61. var mesh = (Mesh)triangulator.Triangulate(polygon.Points, config);
  62. var cmesher = new ConstraintMesher(mesh, config);
  63. var qmesher = new QualityMesher(mesh, config);
  64. mesh.SetQualityMesher(qmesher);
  65. // Insert segments.
  66. cmesher.Apply(polygon, options);
  67. // Refine mesh.
  68. qmesher.Apply(quality);
  69. return mesh;
  70. }
  71. /// <summary>
  72. /// Generates a structured mesh with bounds [0, 0, width, height].
  73. /// </summary>
  74. /// <param name="width">Width of the mesh (must be > 0).</param>
  75. /// <param name="height">Height of the mesh (must be > 0).</param>
  76. /// <param name="nx">Number of segments in x direction.</param>
  77. /// <param name="ny">Number of segments in y direction.</param>
  78. /// <returns>Mesh</returns>
  79. internal static IMesh StructuredMesh(double width, double height, int nx, int ny)
  80. {
  81. if (width <= 0.0)
  82. {
  83. throw new ArgumentException("width");
  84. }
  85. if (height <= 0.0)
  86. {
  87. throw new ArgumentException("height");
  88. }
  89. return StructuredMesh(new Rectangle(0.0, 0.0, width, height), nx, ny);
  90. }
  91. /// <summary>
  92. /// Generates a structured mesh.
  93. /// </summary>
  94. /// <param name="bounds">Bounds of the mesh.</param>
  95. /// <param name="nx">Number of segments in x direction.</param>
  96. /// <param name="ny">Number of segments in y direction.</param>
  97. /// <returns>Mesh</returns>
  98. internal static IMesh StructuredMesh(Rectangle bounds, int nx, int ny)
  99. {
  100. var polygon = new Polygon((nx + 1) * (ny + 1));
  101. double x, y, dx, dy, left, bottom;
  102. dx = bounds.Width / nx;
  103. dy = bounds.Height / ny;
  104. left = bounds.Left;
  105. bottom = bounds.Bottom;
  106. int i, j, k, l, n = 0;
  107. // Add vertices.
  108. var points = new Vertex[(nx + 1) * (ny + 1)];
  109. for (i = 0; i <= nx; i++)
  110. {
  111. x = left + i * dx;
  112. for (j = 0; j <= ny; j++)
  113. {
  114. y = bottom + j * dy;
  115. points[n++] = new Vertex(x, y);
  116. }
  117. }
  118. polygon.Points.AddRange(points);
  119. n = 0;
  120. // Set vertex hash and id.
  121. foreach (var v in points)
  122. {
  123. v.hash = v.id = n++;
  124. }
  125. // Add boundary segments.
  126. var segments = polygon.Segments;
  127. segments.Capacity = 2 * (nx + ny);
  128. Vertex a, b;
  129. for (j = 0; j < ny; j++)
  130. {
  131. // Left
  132. a = points[j];
  133. b = points[j + 1];
  134. segments.Add(new Segment(a, b, 1));
  135. a.Label = b.Label = 1;
  136. // Right
  137. a = points[nx * (ny + 1) + j];
  138. b = points[nx * (ny + 1) + (j + 1)];
  139. segments.Add(new Segment(a, b, 1));
  140. a.Label = b.Label = 1;
  141. }
  142. for (i = 0; i < nx; i++)
  143. {
  144. // Bottom
  145. a = points[(ny + 1) * i];
  146. b = points[(ny + 1) * (i + 1)];
  147. segments.Add(new Segment(a, b, 1));
  148. a.Label = b.Label = 1;
  149. // Top
  150. a = points[ny + (ny + 1) * i];
  151. b = points[ny + (ny + 1) * (i + 1)];
  152. segments.Add(new Segment(a, b, 1));
  153. a.Label = b.Label = 1;
  154. }
  155. // Add triangles.
  156. var triangles = new InputTriangle[2 * nx * ny];
  157. n = 0;
  158. for (i = 0; i < nx; i++)
  159. {
  160. for (j = 0; j < ny; j++)
  161. {
  162. k = j + (ny + 1) * i;
  163. l = j + (ny + 1) * (i + 1);
  164. // Create 2 triangles in rectangle [k, l, l + 1, k + 1].
  165. if ((i + j) % 2 == 0)
  166. {
  167. // Diagonal from bottom left to top right.
  168. triangles[n++] = new InputTriangle(k, l, l + 1);
  169. triangles[n++] = new InputTriangle(k, l + 1, k + 1);
  170. }
  171. else
  172. {
  173. // Diagonal from top left to bottom right.
  174. triangles[n++] = new InputTriangle(k, l, k + 1);
  175. triangles[n++] = new InputTriangle(l, l + 1, k + 1);
  176. }
  177. }
  178. }
  179. return Converter.ToMesh(polygon, triangles);
  180. }
  181. }
  182. }