using System; using System.Collections.Generic; using TriangleNet.Algorithm; using TriangleNet.Data; using TriangleNet.Geometry; using TriangleNet.IO; using TriangleNet.Log; using TriangleNet.Smoothing; using TriangleNet.Tools; namespace TriangleNet { // Token: 0x0200000E RID: 14 public class Mesh { // Token: 0x17000013 RID: 19 // (get) Token: 0x0600005C RID: 92 RVA: 0x0000B456 File Offset: 0x00009656 public Behavior Behavior { get { return this.behavior; } } // Token: 0x17000014 RID: 20 // (get) Token: 0x0600005D RID: 93 RVA: 0x0000B45E File Offset: 0x0000965E public BoundingBox Bounds { get { return this.bounds; } } // Token: 0x17000015 RID: 21 // (get) Token: 0x0600005E RID: 94 RVA: 0x0000B466 File Offset: 0x00009666 public ICollection Vertices { get { return this.vertices.Values; } } // Token: 0x17000016 RID: 22 // (get) Token: 0x0600005F RID: 95 RVA: 0x0000B473 File Offset: 0x00009673 public IList Holes { get { return this.holes; } } // Token: 0x17000017 RID: 23 // (get) Token: 0x06000060 RID: 96 RVA: 0x0000B47B File Offset: 0x0000967B public ICollection Triangles { get { return this.triangles.Values; } } // Token: 0x17000018 RID: 24 // (get) Token: 0x06000061 RID: 97 RVA: 0x0000B488 File Offset: 0x00009688 public ICollection Segments { get { return this.subsegs.Values; } } // Token: 0x17000019 RID: 25 // (get) Token: 0x06000062 RID: 98 RVA: 0x0000B495 File Offset: 0x00009695 public IEnumerable Edges { get { EdgeEnumerator e = new EdgeEnumerator(this); while (e.MoveNext()) { Edge edge = e.Current; yield return edge; } yield break; } } // Token: 0x1700001A RID: 26 // (get) Token: 0x06000063 RID: 99 RVA: 0x0000B4A5 File Offset: 0x000096A5 public int NumberOfInputPoints { get { return this.invertices; } } // Token: 0x1700001B RID: 27 // (get) Token: 0x06000064 RID: 100 RVA: 0x0000B4AD File Offset: 0x000096AD public int NumberOfEdges { get { return this.edges; } } // Token: 0x1700001C RID: 28 // (get) Token: 0x06000065 RID: 101 RVA: 0x0000B4B5 File Offset: 0x000096B5 public bool IsPolygon { get { return this.insegments > 0; } } // Token: 0x1700001D RID: 29 // (get) Token: 0x06000066 RID: 102 RVA: 0x0000B4C0 File Offset: 0x000096C0 public NodeNumbering CurrentNumbering { get { return this.numbering; } } // Token: 0x06000067 RID: 103 RVA: 0x0000B4C8 File Offset: 0x000096C8 public Mesh() : this(new Behavior()) { } // Token: 0x06000068 RID: 104 RVA: 0x0000B4D8 File Offset: 0x000096D8 public Mesh(Behavior behavior) { this.behavior = behavior; this.logger = SimpleLog.Instance; this.vertices = new Dictionary(); this.triangles = new Dictionary(); this.subsegs = new Dictionary(); this.flipstack = new Stack(); this.holes = new List(); this.regions = new List(); this.quality = new QualityMesher(this); this.locator = new TriangleLocator(this); Primitives.ExactInit(); if (Mesh.dummytri == null) { this.DummyInit(); } } // Token: 0x06000069 RID: 105 RVA: 0x0000B56C File Offset: 0x0000976C public void Load(string filename) { InputGeometry inputGeometry; List list; FileReader.Read(filename, out inputGeometry, out list); if (inputGeometry != null && list != null) { this.Load(inputGeometry, list); } } // Token: 0x0600006A RID: 106 RVA: 0x0000B594 File Offset: 0x00009794 public void Load(InputGeometry input, List triangles) { if (input == null || triangles == null) { throw new ArgumentException("Invalid input (argument is null)."); } this.ResetData(); if (input.HasSegments) { this.behavior.Poly = true; this.holes.AddRange(input.Holes); } if (!this.behavior.Poly) { this.behavior.VarArea = false; this.behavior.useRegions = false; } this.behavior.useRegions = input.Regions.Count > 0; this.TransferNodes(input); this.hullsize = DataReader.Reconstruct(this, input, triangles.ToArray()); this.edges = (3 * triangles.Count + this.hullsize) / 2; } // Token: 0x0600006B RID: 107 RVA: 0x0000B64C File Offset: 0x0000984C public void Triangulate(string inputFile) { InputGeometry inputGeometry = FileReader.Read(inputFile); this.Triangulate(inputGeometry); } // Token: 0x0600006C RID: 108 RVA: 0x0000B668 File Offset: 0x00009868 public void Triangulate(InputGeometry input) { this.ResetData(); this.behavior.Poly = input.HasSegments; if (!this.behavior.Poly) { this.behavior.VarArea = false; this.behavior.useRegions = false; } this.behavior.useRegions = input.Regions.Count > 0; this.steinerleft = this.behavior.SteinerPoints; this.TransferNodes(input); this.hullsize = this.Delaunay(); this.infvertex1 = null; this.infvertex2 = null; this.infvertex3 = null; ConstraintMesher constraintMesher = new ConstraintMesher(this); if (this.behavior.useSegments) { this.checksegments = true; constraintMesher.FormSkeleton(input); } if (this.behavior.Poly && this.triangles.Count > 0) { foreach (Point point in input.holes) { this.holes.Add(point); } foreach (RegionPointer regionPointer in input.regions) { this.regions.Add(regionPointer); } constraintMesher.CarveHoles(); } else { this.holes.Clear(); this.regions.Clear(); } if ((this.behavior.Quality || this.behavior.ConformingDelaunay) && this.triangles.Count > 0) { this.quality.EnforceQuality(); } this.edges = (3 * this.triangles.Count + this.hullsize) / 2; } // Token: 0x0600006D RID: 109 RVA: 0x0000B848 File Offset: 0x00009A48 public void Refine(bool halfArea) { if (halfArea) { double num = 0.0; foreach (Triangle triangle in this.triangles.Values) { double num2 = (triangle.vertices[2].x - triangle.vertices[0].x) * (triangle.vertices[1].y - triangle.vertices[0].y) - (triangle.vertices[1].x - triangle.vertices[0].x) * (triangle.vertices[2].y - triangle.vertices[0].y); num2 = Math.Abs(num2) / 2.0; if (num2 > num) { num = num2; } } this.Refine(num / 2.0); return; } this.Refine(); } // Token: 0x0600006E RID: 110 RVA: 0x0000B950 File Offset: 0x00009B50 public void Refine(double areaConstraint) { this.behavior.fixedArea = true; this.behavior.MaxArea = areaConstraint; this.Refine(); this.behavior.fixedArea = false; this.behavior.MaxArea = -1.0; } // Token: 0x0600006F RID: 111 RVA: 0x0000B990 File Offset: 0x00009B90 public void Refine() { this.inelements = this.triangles.Count; this.invertices = this.vertices.Count; if (this.behavior.Poly) { if (this.behavior.useSegments) { this.insegments = this.subsegs.Count; } else { this.insegments = this.hullsize; } } this.Reset(); this.steinerleft = this.behavior.SteinerPoints; this.infvertex1 = null; this.infvertex2 = null; this.infvertex3 = null; if (this.behavior.useSegments) { this.checksegments = true; } if (this.triangles.Count > 0) { this.quality.EnforceQuality(); } this.edges = (3 * this.triangles.Count + this.hullsize) / 2; } // Token: 0x06000070 RID: 112 RVA: 0x0000BA6D File Offset: 0x00009C6D public void Smooth() { this.numbering = NodeNumbering.None; ((ISmoother)new SimpleSmoother(this)).Smooth(); } // Token: 0x06000071 RID: 113 RVA: 0x0000BA81 File Offset: 0x00009C81 public void Renumber() { this.Renumber(NodeNumbering.Linear); } // Token: 0x06000072 RID: 114 RVA: 0x0000BA8C File Offset: 0x00009C8C public void Renumber(NodeNumbering num) { if (num == this.numbering) { return; } int num2; if (num == NodeNumbering.Linear) { num2 = 0; using (Dictionary.ValueCollection.Enumerator enumerator = this.vertices.Values.GetEnumerator()) { while (enumerator.MoveNext()) { Vertex vertex = enumerator.Current; vertex.id = num2++; } goto IL_9F; } } if (num == NodeNumbering.CuthillMcKee) { int[] array = new CuthillMcKee().Renumber(this); foreach (Vertex vertex2 in this.vertices.Values) { vertex2.id = array[vertex2.id]; } } IL_9F: this.numbering = num; num2 = 0; foreach (Triangle triangle in this.triangles.Values) { triangle.id = num2++; } } // Token: 0x06000073 RID: 115 RVA: 0x0000BBA8 File Offset: 0x00009DA8 private int Delaunay() { int num; if (this.behavior.Algorithm == TriangulationAlgorithm.Dwyer) { num = new Dwyer().Triangulate(this); } else if (this.behavior.Algorithm == TriangulationAlgorithm.SweepLine) { num = new SweepLine().Triangulate(this); } else { num = new Incremental().Triangulate(this); } if (this.triangles.Count != 0) { return num; } return 0; } // Token: 0x06000074 RID: 116 RVA: 0x0000BC0C File Offset: 0x00009E0C private void ResetData() { this.vertices.Clear(); this.triangles.Clear(); this.subsegs.Clear(); this.holes.Clear(); this.regions.Clear(); this.hash_vtx = 0; this.hash_seg = 0; this.hash_tri = 0; this.flipstack.Clear(); this.hullsize = 0; this.edges = 0; this.Reset(); this.locator.Reset(); } // Token: 0x06000075 RID: 117 RVA: 0x0000BC90 File Offset: 0x00009E90 private void Reset() { this.numbering = NodeNumbering.None; this.undeads = 0; this.checksegments = false; this.checkquality = false; Statistic.InCircleCount = 0L; Statistic.CounterClockwiseCount = 0L; Statistic.InCircleAdaptCount = 0L; Statistic.CounterClockwiseAdaptCount = 0L; Statistic.Orient3dCount = 0L; Statistic.HyperbolaCount = 0L; Statistic.CircleTopCount = 0L; Statistic.CircumcenterCount = 0L; } // Token: 0x06000076 RID: 118 RVA: 0x0000BCF4 File Offset: 0x00009EF4 private void DummyInit() { Mesh.dummytri = new Triangle(); Mesh.dummytri.hash = -1; Mesh.dummytri.id = -1; Mesh.dummytri.neighbors[0].triangle = Mesh.dummytri; Mesh.dummytri.neighbors[1].triangle = Mesh.dummytri; Mesh.dummytri.neighbors[2].triangle = Mesh.dummytri; if (this.behavior.useSegments) { Mesh.dummysub = new Segment(); Mesh.dummysub.hash = -1; Mesh.dummysub.subsegs[0].seg = Mesh.dummysub; Mesh.dummysub.subsegs[1].seg = Mesh.dummysub; Mesh.dummytri.subsegs[0].seg = Mesh.dummysub; Mesh.dummytri.subsegs[1].seg = Mesh.dummysub; Mesh.dummytri.subsegs[2].seg = Mesh.dummysub; } } // Token: 0x06000077 RID: 119 RVA: 0x0000BE18 File Offset: 0x0000A018 private void TransferNodes(InputGeometry data) { List points = data.points; this.invertices = points.Count; this.mesh_dim = 2; if (this.invertices < 3) { this.logger.Error("Input must have at least three input vertices.", "MeshReader.TransferNodes()"); throw new Exception("Input must have at least three input vertices."); } this.nextras = ((points[0].attributes == null) ? 0 : points[0].attributes.Length); foreach (Vertex vertex in points) { Vertex vertex2 = vertex; int num = this.hash_vtx; this.hash_vtx = num + 1; vertex2.hash = num; vertex.id = vertex.hash; this.vertices.Add(vertex.hash, vertex); } this.bounds = data.Bounds; } // Token: 0x06000078 RID: 120 RVA: 0x0000BF08 File Offset: 0x0000A108 internal void MakeVertexMap() { Otri otri = default(Otri); foreach (Triangle triangle in this.triangles.Values) { otri.triangle = triangle; otri.orient = 0; while (otri.orient < 3) { otri.Org().tri = otri; otri.orient++; } } } // Token: 0x06000079 RID: 121 RVA: 0x0000BF98 File Offset: 0x0000A198 internal void MakeTriangle(ref Otri newotri) { Triangle triangle = new Triangle(); Triangle triangle2 = triangle; int num = this.hash_tri; this.hash_tri = num + 1; triangle2.hash = num; triangle.id = triangle.hash; newotri.triangle = triangle; newotri.orient = 0; this.triangles.Add(triangle.hash, triangle); } // Token: 0x0600007A RID: 122 RVA: 0x0000BFF0 File Offset: 0x0000A1F0 internal void MakeSegment(ref Osub newsubseg) { Segment segment = new Segment(); Segment segment2 = segment; int num = this.hash_seg; this.hash_seg = num + 1; segment2.hash = num; newsubseg.seg = segment; newsubseg.orient = 0; this.subsegs.Add(segment.hash, segment); } // Token: 0x0600007B RID: 123 RVA: 0x0000C03C File Offset: 0x0000A23C internal InsertVertexResult InsertVertex(Vertex newvertex, ref Otri searchtri, ref Osub splitseg, bool segmentflaws, bool triflaws) { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Otri otri5 = default(Otri); Otri otri6 = default(Otri); Otri otri7 = default(Otri); Otri otri8 = default(Otri); Otri otri9 = default(Otri); Otri otri10 = default(Otri); Otri otri11 = default(Otri); Otri otri12 = default(Otri); Otri otri13 = default(Otri); Otri otri14 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); Osub osub3 = default(Osub); Osub osub4 = default(Osub); Osub osub5 = default(Osub); Osub osub6 = default(Osub); Osub osub7 = default(Osub); Osub osub8 = default(Osub); LocateResult locateResult; if (splitseg.seg == null) { if (searchtri.triangle == Mesh.dummytri) { otri.triangle = Mesh.dummytri; otri.orient = 0; otri.SymSelf(); locateResult = this.locator.Locate(newvertex, ref otri); } else { searchtri.Copy(ref otri); locateResult = this.locator.PreciseLocate(newvertex, ref otri, true); } } else { searchtri.Copy(ref otri); locateResult = LocateResult.OnEdge; } if (locateResult == LocateResult.OnVertex) { otri.Copy(ref searchtri); this.locator.Update(ref otri); return InsertVertexResult.Duplicate; } Vertex vertex; Vertex vertex2; if (locateResult == LocateResult.OnEdge || locateResult == LocateResult.Outside) { if (this.checksegments && splitseg.seg == null) { otri.SegPivot(ref osub5); if (osub5.seg != Mesh.dummysub) { if (segmentflaws) { bool flag = this.behavior.NoBisect != 2; if (flag && this.behavior.NoBisect == 1) { otri.Sym(ref otri14); flag = otri14.triangle != Mesh.dummytri; } if (flag) { BadSubseg badSubseg = new BadSubseg(); badSubseg.encsubseg = osub5; badSubseg.subsegorg = osub5.Org(); badSubseg.subsegdest = osub5.Dest(); this.quality.AddBadSubseg(badSubseg); } } otri.Copy(ref searchtri); this.locator.Update(ref otri); return InsertVertexResult.Violating; } } otri.Lprev(ref otri4); otri4.Sym(ref otri11); otri.Sym(ref otri6); bool flag2 = otri6.triangle != Mesh.dummytri; if (flag2) { otri6.LnextSelf(); otri6.Sym(ref otri13); this.MakeTriangle(ref otri9); } else { this.hullsize++; } this.MakeTriangle(ref otri8); vertex = otri.Org(); vertex2 = otri.Dest(); Vertex vertex3 = otri.Apex(); otri8.SetOrg(vertex3); otri8.SetDest(vertex); otri8.SetApex(newvertex); otri.SetOrg(newvertex); otri8.triangle.region = otri4.triangle.region; if (this.behavior.VarArea) { otri8.triangle.area = otri4.triangle.area; } if (flag2) { Vertex vertex4 = otri6.Dest(); otri9.SetOrg(vertex); otri9.SetDest(vertex4); otri9.SetApex(newvertex); otri6.SetOrg(newvertex); otri9.triangle.region = otri6.triangle.region; if (this.behavior.VarArea) { otri9.triangle.area = otri6.triangle.area; } } if (this.checksegments) { otri4.SegPivot(ref osub2); if (osub2.seg != Mesh.dummysub) { otri4.SegDissolve(); otri8.SegBond(ref osub2); } if (flag2) { otri6.SegPivot(ref osub4); if (osub4.seg != Mesh.dummysub) { otri6.SegDissolve(); otri9.SegBond(ref osub4); } } } otri8.Bond(ref otri11); otri8.LprevSelf(); otri8.Bond(ref otri4); otri8.LprevSelf(); if (flag2) { otri9.Bond(ref otri13); otri9.LnextSelf(); otri9.Bond(ref otri6); otri9.LnextSelf(); otri9.Bond(ref otri8); } if (splitseg.seg != null) { splitseg.SetDest(newvertex); Vertex vertex5 = splitseg.SegOrg(); Vertex vertex6 = splitseg.SegDest(); splitseg.SymSelf(); splitseg.Pivot(ref osub7); this.InsertSubseg(ref otri8, splitseg.seg.boundary); otri8.SegPivot(ref osub8); osub8.SetSegOrg(vertex5); osub8.SetSegDest(vertex6); splitseg.Bond(ref osub8); osub8.SymSelf(); osub8.Bond(ref osub7); splitseg.SymSelf(); if (newvertex.mark == 0) { newvertex.mark = splitseg.seg.boundary; } } if (this.checkquality) { this.flipstack.Clear(); this.flipstack.Push(default(Otri)); this.flipstack.Push(otri); } otri.LnextSelf(); } else { otri.Lnext(ref otri3); otri.Lprev(ref otri4); otri3.Sym(ref otri10); otri4.Sym(ref otri11); this.MakeTriangle(ref otri7); this.MakeTriangle(ref otri8); vertex = otri.Org(); vertex2 = otri.Dest(); Vertex vertex3 = otri.Apex(); otri7.SetOrg(vertex2); otri7.SetDest(vertex3); otri7.SetApex(newvertex); otri8.SetOrg(vertex3); otri8.SetDest(vertex); otri8.SetApex(newvertex); otri.SetApex(newvertex); otri7.triangle.region = otri.triangle.region; otri8.triangle.region = otri.triangle.region; if (this.behavior.VarArea) { double num = otri.triangle.area; otri7.triangle.area = num; otri8.triangle.area = num; } if (this.checksegments) { otri3.SegPivot(ref osub); if (osub.seg != Mesh.dummysub) { otri3.SegDissolve(); otri7.SegBond(ref osub); } otri4.SegPivot(ref osub2); if (osub2.seg != Mesh.dummysub) { otri4.SegDissolve(); otri8.SegBond(ref osub2); } } otri7.Bond(ref otri10); otri8.Bond(ref otri11); otri7.LnextSelf(); otri8.LprevSelf(); otri7.Bond(ref otri8); otri7.LnextSelf(); otri3.Bond(ref otri7); otri8.LprevSelf(); otri4.Bond(ref otri8); if (this.checkquality) { this.flipstack.Clear(); this.flipstack.Push(otri); } } InsertVertexResult insertVertexResult = InsertVertexResult.Successful; Vertex vertex7 = otri.Org(); vertex = vertex7; vertex2 = otri.Dest(); for (;;) { bool flag3 = true; if (this.checksegments) { otri.SegPivot(ref osub6); if (osub6.seg != Mesh.dummysub) { flag3 = false; if (segmentflaws && this.quality.CheckSeg4Encroach(ref osub6) > 0) { insertVertexResult = InsertVertexResult.Encroaching; } } } if (flag3) { otri.Sym(ref otri2); if (otri2.triangle == Mesh.dummytri) { flag3 = false; } else { Vertex vertex8 = otri2.Apex(); if (vertex2 == this.infvertex1 || vertex2 == this.infvertex2 || vertex2 == this.infvertex3) { flag3 = Primitives.CounterClockwise(newvertex, vertex, vertex8) > 0.0; } else if (vertex == this.infvertex1 || vertex == this.infvertex2 || vertex == this.infvertex3) { flag3 = Primitives.CounterClockwise(vertex8, vertex2, newvertex) > 0.0; } else { flag3 = !(vertex8 == this.infvertex1) && !(vertex8 == this.infvertex2) && !(vertex8 == this.infvertex3) && Primitives.InCircle(vertex2, newvertex, vertex, vertex8) > 0.0; } if (flag3) { otri2.Lprev(ref otri5); otri5.Sym(ref otri12); otri2.Lnext(ref otri6); otri6.Sym(ref otri13); otri.Lnext(ref otri3); otri3.Sym(ref otri10); otri.Lprev(ref otri4); otri4.Sym(ref otri11); otri5.Bond(ref otri10); otri3.Bond(ref otri11); otri4.Bond(ref otri13); otri6.Bond(ref otri12); if (this.checksegments) { otri5.SegPivot(ref osub3); otri3.SegPivot(ref osub); otri4.SegPivot(ref osub2); otri6.SegPivot(ref osub4); if (osub3.seg == Mesh.dummysub) { otri6.SegDissolve(); } else { otri6.SegBond(ref osub3); } if (osub.seg == Mesh.dummysub) { otri5.SegDissolve(); } else { otri5.SegBond(ref osub); } if (osub2.seg == Mesh.dummysub) { otri3.SegDissolve(); } else { otri3.SegBond(ref osub2); } if (osub4.seg == Mesh.dummysub) { otri4.SegDissolve(); } else { otri4.SegBond(ref osub4); } } otri.SetOrg(vertex8); otri.SetDest(newvertex); otri.SetApex(vertex); otri2.SetOrg(newvertex); otri2.SetDest(vertex8); otri2.SetApex(vertex2); int num2 = Math.Min(otri2.triangle.region, otri.triangle.region); otri2.triangle.region = num2; otri.triangle.region = num2; if (this.behavior.VarArea) { double num; if (otri2.triangle.area <= 0.0 || otri.triangle.area <= 0.0) { num = -1.0; } else { num = 0.5 * (otri2.triangle.area + otri.triangle.area); } otri2.triangle.area = num; otri.triangle.area = num; } if (this.checkquality) { this.flipstack.Push(otri); } otri.LprevSelf(); vertex2 = vertex8; } } } if (!flag3) { if (triflaws) { this.quality.TestTriangle(ref otri); } otri.LnextSelf(); otri.Sym(ref otri14); if (vertex2 == vertex7 || otri14.triangle == Mesh.dummytri) { break; } otri14.Lnext(ref otri); vertex = vertex2; vertex2 = otri.Dest(); } } otri.Lnext(ref searchtri); Otri otri15 = default(Otri); otri.Lnext(ref otri15); this.locator.Update(ref otri15); return insertVertexResult; } // Token: 0x0600007C RID: 124 RVA: 0x0000CAD4 File Offset: 0x0000ACD4 internal void InsertSubseg(ref Otri tri, int subsegmark) { Otri otri = default(Otri); Osub osub = default(Osub); Vertex vertex = tri.Org(); Vertex vertex2 = tri.Dest(); if (vertex.mark == 0) { vertex.mark = subsegmark; } if (vertex2.mark == 0) { vertex2.mark = subsegmark; } tri.SegPivot(ref osub); if (osub.seg == Mesh.dummysub) { this.MakeSegment(ref osub); osub.SetOrg(vertex2); osub.SetDest(vertex); osub.SetSegOrg(vertex2); osub.SetSegDest(vertex); tri.SegBond(ref osub); tri.Sym(ref otri); osub.SymSelf(); otri.SegBond(ref osub); osub.seg.boundary = subsegmark; return; } if (osub.seg.boundary == 0) { osub.seg.boundary = subsegmark; } } // Token: 0x0600007D RID: 125 RVA: 0x0000CBA0 File Offset: 0x0000ADA0 internal void Flip(ref Otri flipedge) { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Otri otri5 = default(Otri); Otri otri6 = default(Otri); Otri otri7 = default(Otri); Otri otri8 = default(Otri); Otri otri9 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); Osub osub3 = default(Osub); Osub osub4 = default(Osub); Vertex vertex = flipedge.Org(); Vertex vertex2 = flipedge.Dest(); Vertex vertex3 = flipedge.Apex(); flipedge.Sym(ref otri5); Vertex vertex4 = otri5.Apex(); otri5.Lprev(ref otri3); otri3.Sym(ref otri8); otri5.Lnext(ref otri4); otri4.Sym(ref otri9); flipedge.Lnext(ref otri); otri.Sym(ref otri6); flipedge.Lprev(ref otri2); otri2.Sym(ref otri7); otri3.Bond(ref otri6); otri.Bond(ref otri7); otri2.Bond(ref otri9); otri4.Bond(ref otri8); if (this.checksegments) { otri3.SegPivot(ref osub3); otri.SegPivot(ref osub); otri2.SegPivot(ref osub2); otri4.SegPivot(ref osub4); if (osub3.seg == Mesh.dummysub) { otri4.SegDissolve(); } else { otri4.SegBond(ref osub3); } if (osub.seg == Mesh.dummysub) { otri3.SegDissolve(); } else { otri3.SegBond(ref osub); } if (osub2.seg == Mesh.dummysub) { otri.SegDissolve(); } else { otri.SegBond(ref osub2); } if (osub4.seg == Mesh.dummysub) { otri2.SegDissolve(); } else { otri2.SegBond(ref osub4); } } flipedge.SetOrg(vertex4); flipedge.SetDest(vertex3); flipedge.SetApex(vertex); otri5.SetOrg(vertex3); otri5.SetDest(vertex4); otri5.SetApex(vertex2); } // Token: 0x0600007E RID: 126 RVA: 0x0000CD8C File Offset: 0x0000AF8C internal void Unflip(ref Otri flipedge) { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Otri otri5 = default(Otri); Otri otri6 = default(Otri); Otri otri7 = default(Otri); Otri otri8 = default(Otri); Otri otri9 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); Osub osub3 = default(Osub); Osub osub4 = default(Osub); Vertex vertex = flipedge.Org(); Vertex vertex2 = flipedge.Dest(); Vertex vertex3 = flipedge.Apex(); flipedge.Sym(ref otri5); Vertex vertex4 = otri5.Apex(); otri5.Lprev(ref otri3); otri3.Sym(ref otri8); otri5.Lnext(ref otri4); otri4.Sym(ref otri9); flipedge.Lnext(ref otri); otri.Sym(ref otri6); flipedge.Lprev(ref otri2); otri2.Sym(ref otri7); otri3.Bond(ref otri9); otri.Bond(ref otri8); otri2.Bond(ref otri6); otri4.Bond(ref otri7); if (this.checksegments) { otri3.SegPivot(ref osub3); otri.SegPivot(ref osub); otri2.SegPivot(ref osub2); otri4.SegPivot(ref osub4); if (osub3.seg == Mesh.dummysub) { otri.SegDissolve(); } else { otri.SegBond(ref osub3); } if (osub.seg == Mesh.dummysub) { otri2.SegDissolve(); } else { otri2.SegBond(ref osub); } if (osub2.seg == Mesh.dummysub) { otri4.SegDissolve(); } else { otri4.SegBond(ref osub2); } if (osub4.seg == Mesh.dummysub) { otri3.SegDissolve(); } else { otri3.SegBond(ref osub4); } } flipedge.SetOrg(vertex3); flipedge.SetDest(vertex4); flipedge.SetApex(vertex2); otri5.SetOrg(vertex4); otri5.SetDest(vertex3); otri5.SetApex(vertex); } // Token: 0x0600007F RID: 127 RVA: 0x0000CF78 File Offset: 0x0000B178 private void TriangulatePolygon(Otri firstedge, Otri lastedge, int edgecount, bool doflip, bool triflaws) { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); int num = 1; Vertex vertex = lastedge.Apex(); Vertex vertex2 = firstedge.Dest(); firstedge.Onext(ref otri2); Vertex vertex3 = otri2.Dest(); otri2.Copy(ref otri); for (int i = 2; i <= edgecount - 2; i++) { otri.OnextSelf(); Vertex vertex4 = otri.Dest(); if (Primitives.InCircle(vertex, vertex2, vertex3, vertex4) > 0.0) { otri.Copy(ref otri2); vertex3 = vertex4; num = i; } } if (num > 1) { otri2.Oprev(ref otri3); this.TriangulatePolygon(firstedge, otri3, num + 1, true, triflaws); } if (num < edgecount - 2) { otri2.Sym(ref otri3); this.TriangulatePolygon(otri2, lastedge, edgecount - num, true, triflaws); otri3.Sym(ref otri2); } if (doflip) { this.Flip(ref otri2); if (triflaws) { otri2.Sym(ref otri); this.quality.TestTriangle(ref otri); } } otri2.Copy(ref lastedge); } // Token: 0x06000080 RID: 128 RVA: 0x0000D08C File Offset: 0x0000B28C internal void DeleteVertex(ref Otri deltri) { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Otri otri5 = default(Otri); Otri otri6 = default(Otri); Otri otri7 = default(Otri); Otri otri8 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); Vertex vertex = deltri.Org(); this.VertexDealloc(vertex); deltri.Onext(ref otri); int num = 1; while (!deltri.Equal(otri)) { num++; otri.OnextSelf(); } if (num > 3) { deltri.Onext(ref otri2); deltri.Oprev(ref otri3); this.TriangulatePolygon(otri2, otri3, num, false, this.behavior.NoBisect == 0); } deltri.Lprev(ref otri4); deltri.Dnext(ref otri5); otri5.Sym(ref otri7); otri4.Oprev(ref otri6); otri6.Sym(ref otri8); deltri.Bond(ref otri7); otri4.Bond(ref otri8); otri5.SegPivot(ref osub); if (osub.seg != Mesh.dummysub) { deltri.SegBond(ref osub); } otri6.SegPivot(ref osub2); if (osub2.seg != Mesh.dummysub) { otri4.SegBond(ref osub2); } Vertex vertex2 = otri5.Org(); deltri.SetOrg(vertex2); if (this.behavior.NoBisect == 0) { this.quality.TestTriangle(ref deltri); } this.TriangleDealloc(otri5.triangle); this.TriangleDealloc(otri6.triangle); } // Token: 0x06000081 RID: 129 RVA: 0x0000D20C File Offset: 0x0000B40C internal void UndoVertex() { Otri otri = default(Otri); Otri otri2 = default(Otri); Otri otri3 = default(Otri); Otri otri4 = default(Otri); Otri otri5 = default(Otri); Otri otri6 = default(Otri); Otri otri7 = default(Otri); Osub osub = default(Osub); Osub osub2 = default(Osub); Osub osub3 = default(Osub); while (this.flipstack.Count > 0) { Otri otri8 = this.flipstack.Pop(); if (this.flipstack.Count == 0) { otri8.Dprev(ref otri); otri.LnextSelf(); otri8.Onext(ref otri2); otri2.LprevSelf(); otri.Sym(ref otri4); otri2.Sym(ref otri5); Vertex vertex = otri.Dest(); otri8.SetApex(vertex); otri8.LnextSelf(); otri8.Bond(ref otri4); otri.SegPivot(ref osub); otri8.SegBond(ref osub); otri8.LnextSelf(); otri8.Bond(ref otri5); otri2.SegPivot(ref osub2); otri8.SegBond(ref osub2); this.TriangleDealloc(otri.triangle); this.TriangleDealloc(otri2.triangle); } else if (this.flipstack.Peek().triangle == null) { otri8.Lprev(ref otri7); otri7.Sym(ref otri2); otri2.LnextSelf(); otri2.Sym(ref otri5); Vertex vertex2 = otri2.Dest(); otri8.SetOrg(vertex2); otri7.Bond(ref otri5); otri2.SegPivot(ref osub2); otri7.SegBond(ref osub2); this.TriangleDealloc(otri2.triangle); otri8.Sym(ref otri7); if (otri7.triangle != Mesh.dummytri) { otri7.LnextSelf(); otri7.Dnext(ref otri3); otri3.Sym(ref otri6); otri7.SetOrg(vertex2); otri7.Bond(ref otri6); otri3.SegPivot(ref osub3); otri7.SegBond(ref osub3); this.TriangleDealloc(otri3.triangle); } this.flipstack.Clear(); } else { this.Unflip(ref otri8); } } } // Token: 0x06000082 RID: 130 RVA: 0x0000D425 File Offset: 0x0000B625 internal void TriangleDealloc(Triangle dyingtriangle) { Otri.Kill(dyingtriangle); this.triangles.Remove(dyingtriangle.hash); } // Token: 0x06000083 RID: 131 RVA: 0x0000D43F File Offset: 0x0000B63F internal void VertexDealloc(Vertex dyingvertex) { dyingvertex.type = VertexType.DeadVertex; this.vertices.Remove(dyingvertex.hash); } // Token: 0x06000084 RID: 132 RVA: 0x0000D45A File Offset: 0x0000B65A internal void SubsegDealloc(Segment dyingsubseg) { Osub.Kill(dyingsubseg); this.subsegs.Remove(dyingsubseg.hash); } // Token: 0x04000053 RID: 83 private ILog logger; // Token: 0x04000054 RID: 84 private QualityMesher quality; // Token: 0x04000055 RID: 85 private Stack flipstack; // Token: 0x04000056 RID: 86 internal Dictionary triangles; // Token: 0x04000057 RID: 87 internal Dictionary subsegs; // Token: 0x04000058 RID: 88 internal Dictionary vertices; // Token: 0x04000059 RID: 89 internal int hash_vtx; // Token: 0x0400005A RID: 90 internal int hash_seg; // Token: 0x0400005B RID: 91 internal int hash_tri; // Token: 0x0400005C RID: 92 internal List holes; // Token: 0x0400005D RID: 93 internal List regions; // Token: 0x0400005E RID: 94 internal BoundingBox bounds; // Token: 0x0400005F RID: 95 internal int invertices; // Token: 0x04000060 RID: 96 internal int inelements; // Token: 0x04000061 RID: 97 internal int insegments; // Token: 0x04000062 RID: 98 internal int undeads; // Token: 0x04000063 RID: 99 internal int edges; // Token: 0x04000064 RID: 100 internal int mesh_dim; // Token: 0x04000065 RID: 101 internal int nextras; // Token: 0x04000066 RID: 102 internal int hullsize; // Token: 0x04000067 RID: 103 internal int steinerleft; // Token: 0x04000068 RID: 104 internal bool checksegments; // Token: 0x04000069 RID: 105 internal bool checkquality; // Token: 0x0400006A RID: 106 internal Vertex infvertex1; // Token: 0x0400006B RID: 107 internal Vertex infvertex2; // Token: 0x0400006C RID: 108 internal Vertex infvertex3; // Token: 0x0400006D RID: 109 internal static Triangle dummytri; // Token: 0x0400006E RID: 110 internal static Segment dummysub; // Token: 0x0400006F RID: 111 internal TriangleLocator locator; // Token: 0x04000070 RID: 112 internal Behavior behavior; // Token: 0x04000071 RID: 113 internal NodeNumbering numbering; } }