/// <summary> /// Given a set of points ordered counter-clockwise along a contour and a set of holes, return triangle indexes. /// </summary> /// <param name="points"></param> /// <param name="holes"></param> /// <param name="indexes">Indices outside of the points list index into holes when layed out linearly. /// {vertices 0,1,2...vertices.length-1, holes 0 values, hole 1 values etc.} </param> /// <returns></returns> public static bool Triangulate(IList <Vector2> points, IList <IList <Vector2> > holes, out List <int> indexes) { indexes = new List <int>(); int index = 0; var allPoints = new List <Vector2>(points); Polygon polygon = new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++))); if (holes != null) { for (int i = 0; i < holes.Count; i++) { allPoints.AddRange(holes[i]); var holePolgyon = new Polygon(holes[i].Select(x => new PolygonPoint(x.x, x.y, index++))); polygon.AddHole(holePolgyon); } } try { P2T.Triangulate(TriangulationAlgorithm.DTSweep, polygon); } catch (System.Exception e) { Log.Info("Triangulation failed: " + e.ToString()); return(false); } foreach (DelaunayTriangle d in polygon.Triangles) { if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0) { Log.Info("Triangulation failed: Additional vertices were inserted."); return(false); } indexes.Add(d.Points[0].Index); indexes.Add(d.Points[1].Index); indexes.Add(d.Points[2].Index); } WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points); // if the re-triangulated first tri doesn't match the winding order of the original // vertices, flip 'em if (SurfaceTopology.GetWindingOrder(new Vector2[3] { allPoints[indexes[0]], allPoints[indexes[1]], allPoints[indexes[2]], }) != originalWinding) { indexes.Reverse(); } return(true); }
/// <summary> /// Given a set of points ordered counter-clockwise along a contour, return triangle indexes. /// </summary> /// <param name="points"></param> /// <param name="indexes"></param> /// <param name="convex">Triangulation may optionally be set to convex, which will result in some a convex shape.</param> /// <returns></returns> public static bool Triangulate(IList <Vector2> points, out List <int> indexes, bool convex = false) { indexes = new List <int>(); int index = 0; Triangulatable soup = convex ? new PointSet(points.Select(x => new TriangulationPoint(x.x, x.y, index++)).ToList()) : (Triangulatable) new Polygon(points.Select(x => new PolygonPoint(x.x, x.y, index++))); try { triangulationContext.Clear(); triangulationContext.PrepareTriangulation(soup); DTSweep.Triangulate((DTSweepContext)triangulationContext); } catch (System.Exception e) { Log.Info("Triangulation failed: " + e.ToString()); return(false); } foreach (DelaunayTriangle d in soup.Triangles) { if (d.Points[0].Index < 0 || d.Points[1].Index < 0 || d.Points[2].Index < 0) { Log.Info("Triangulation failed: Additional vertices were inserted."); return(false); } indexes.Add(d.Points[0].Index); indexes.Add(d.Points[1].Index); indexes.Add(d.Points[2].Index); } WindingOrder originalWinding = SurfaceTopology.GetWindingOrder(points); // if the re-triangulated first tri doesn't match the winding order of the original // vertices, flip 'em if (SurfaceTopology.GetWindingOrder(new Vector2[3] { points[indexes[0]], points[indexes[1]], points[indexes[2]], }) != originalWinding) { indexes.Reverse(); } return(true); }