// ----------------------------------------------------------------------- // // Original Triangle code by Jonathan Richard Shewchuk, http://www.cs.cmu.edu/~quake/triangle.html // Triangle.NET code by Christian Woltering, http://triangle.codeplex.com/ // // ----------------------------------------------------------------------- namespace UnityEngine.U2D.Animation.TriangleNet .Topology { using System; using Animation.TriangleNet.Geometry; /// /// An oriented subsegment. /// /// /// Includes a pointer to a subsegment and an orientation. The orientation denotes a /// side of the edge. Hence, there are two possible orientations. By convention, the /// edge is always directed so that the "side" denoted is the right side of the edge. /// internal struct Osub { internal SubSegment seg; internal int orient; // Ranges from 0 to 1. public SubSegment Segment { get { return seg; } } public override string ToString() { if (seg == null) { return "O-TID [null]"; } return String.Format("O-SID {0}", seg.hash); } #region Osub primitives /// /// Reverse the orientation of a subsegment. [sym(ab) -> ba] /// public void Sym(ref Osub os) { os.seg = seg; os.orient = 1 - orient; } /// /// Reverse the orientation of a subsegment. [sym(ab) -> ba] /// public void Sym() { orient = 1 - orient; } /// /// Find adjoining subsegment with the same origin. [pivot(ab) -> a*] /// /// spivot() finds the other subsegment (from the same segment) /// that shares the same origin. /// public void Pivot(ref Osub os) { os = seg.subsegs[orient]; } /// /// Finds a triangle abutting a subsegment. /// internal void Pivot(ref Otri ot) { ot = seg.triangles[orient]; } /// /// Find next subsegment in sequence. [next(ab) -> b*] /// public void Next(ref Osub ot) { ot = seg.subsegs[1 - orient]; } /// /// Find next subsegment in sequence. [next(ab) -> b*] /// public void Next() { this = seg.subsegs[1 - orient]; } /// /// Get the origin of a subsegment /// public Vertex Org() { return seg.vertices[orient]; } /// /// Get the destination of a subsegment /// public Vertex Dest() { return seg.vertices[1 - orient]; } #endregion #region Osub primitives (internal) /// /// Set the origin or destination of a subsegment. /// internal void SetOrg(Vertex vertex) { seg.vertices[orient] = vertex; } /// /// Set destination of a subsegment. /// internal void SetDest(Vertex vertex) { seg.vertices[1 - orient] = vertex; } /// /// Get the origin of the segment that includes the subsegment. /// internal Vertex SegOrg() { return seg.vertices[2 + orient]; } /// /// Get the destination of the segment that includes the subsegment. /// internal Vertex SegDest() { return seg.vertices[3 - orient]; } /// /// Set the origin of the segment that includes the subsegment. /// internal void SetSegOrg(Vertex vertex) { seg.vertices[2 + orient] = vertex; } /// /// Set the destination of the segment that includes the subsegment. /// internal void SetSegDest(Vertex vertex) { seg.vertices[3 - orient] = vertex; } /* Unused primitives. /// /// Find adjoining subsegment with the same origin. [pivot(ab) -> a*] /// public void PivotSelf() { this = seg.subsegs[orient]; } /// /// Read a boundary marker. /// /// Boundary markers are used to hold user-defined tags for /// setting boundary conditions in finite element solvers. public int Mark() { return seg.boundary; } /// /// Set a boundary marker. /// public void SetMark(int value) { seg.boundary = value; } /// /// Copy a subsegment. /// public void Copy(ref Osub o2) { o2.seg = seg; o2.orient = orient; } //*/ /// /// Bond two subsegments together. [bond(abc, ba)] /// internal void Bond(ref Osub os) { seg.subsegs[orient] = os; os.seg.subsegs[os.orient] = this; } /// /// Dissolve a subsegment bond (from one side). /// /// Note that the other subsegment will still think it's /// connected to this subsegment. internal void Dissolve(SubSegment dummy) { seg.subsegs[orient].seg = dummy; } /// /// Test for equality of subsegments. /// internal bool Equal(Osub os) { return ((seg == os.seg) && (orient == os.orient)); } /// /// Dissolve a bond (from the subsegment side). /// internal void TriDissolve(Triangle dummy) { seg.triangles[orient].tri = dummy; } /// /// Check a subsegment's deallocation. /// internal static bool IsDead(SubSegment sub) { return sub.subsegs[0].seg == null; } /// /// Set a subsegment's deallocation. /// internal static void Kill(SubSegment sub) { sub.subsegs[0].seg = null; sub.subsegs[1].seg = null; } #endregion } }