700 lines
18 KiB
C#
700 lines
18 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using TriangleNet.Data;
|
|
using TriangleNet.Geometry;
|
|
using TriangleNet.Log;
|
|
using TriangleNet.Tools;
|
|
|
|
namespace TriangleNet
|
|
{
|
|
// Token: 0x02000004 RID: 4
|
|
internal class ConstraintMesher
|
|
{
|
|
// Token: 0x0600002C RID: 44 RVA: 0x00002603 File Offset: 0x00000803
|
|
public ConstraintMesher(Mesh mesh)
|
|
{
|
|
this.mesh = mesh;
|
|
this.behavior = mesh.behavior;
|
|
this.locator = mesh.locator;
|
|
this.viri = new List<Triangle>();
|
|
this.logger = SimpleLog.Instance;
|
|
}
|
|
|
|
// Token: 0x0600002D RID: 45 RVA: 0x00002640 File Offset: 0x00000840
|
|
public void CarveHoles()
|
|
{
|
|
Otri otri = default(Otri);
|
|
Triangle[] array = null;
|
|
if (!this.mesh.behavior.Convex)
|
|
{
|
|
this.InfectHull();
|
|
}
|
|
if (!this.mesh.behavior.NoHoles)
|
|
{
|
|
foreach (Point point in this.mesh.holes)
|
|
{
|
|
if (this.mesh.bounds.Contains(point))
|
|
{
|
|
otri.triangle = Mesh.dummytri;
|
|
otri.orient = 0;
|
|
otri.SymSelf();
|
|
Point point2 = otri.Org();
|
|
Vertex vertex = otri.Dest();
|
|
if (Primitives.CounterClockwise(point2, vertex, point) > 0.0 && this.mesh.locator.Locate(point, ref otri) != LocateResult.Outside && !otri.IsInfected())
|
|
{
|
|
otri.Infect();
|
|
this.viri.Add(otri.triangle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.mesh.regions.Count > 0)
|
|
{
|
|
int num = 0;
|
|
array = new Triangle[this.mesh.regions.Count];
|
|
foreach (RegionPointer regionPointer in this.mesh.regions)
|
|
{
|
|
array[num] = Mesh.dummytri;
|
|
if (this.mesh.bounds.Contains(regionPointer.point))
|
|
{
|
|
otri.triangle = Mesh.dummytri;
|
|
otri.orient = 0;
|
|
otri.SymSelf();
|
|
Point point3 = otri.Org();
|
|
Vertex vertex = otri.Dest();
|
|
if (Primitives.CounterClockwise(point3, vertex, regionPointer.point) > 0.0 && this.mesh.locator.Locate(regionPointer.point, ref otri) != LocateResult.Outside && !otri.IsInfected())
|
|
{
|
|
array[num] = otri.triangle;
|
|
array[num].region = regionPointer.id;
|
|
}
|
|
}
|
|
num++;
|
|
}
|
|
}
|
|
if (this.viri.Count > 0)
|
|
{
|
|
this.Plague();
|
|
}
|
|
if (array != null)
|
|
{
|
|
RegionIterator regionIterator = new RegionIterator(this.mesh);
|
|
for (int i = 0; i < array.Length; i++)
|
|
{
|
|
if (array[i] != Mesh.dummytri && !Otri.IsDead(array[i]))
|
|
{
|
|
regionIterator.Process(array[i]);
|
|
}
|
|
}
|
|
}
|
|
this.viri.Clear();
|
|
}
|
|
|
|
// Token: 0x0600002E RID: 46 RVA: 0x000028E0 File Offset: 0x00000AE0
|
|
public void FormSkeleton(InputGeometry input)
|
|
{
|
|
this.mesh.insegments = 0;
|
|
if (this.behavior.Poly)
|
|
{
|
|
if (this.mesh.triangles.Count == 0)
|
|
{
|
|
return;
|
|
}
|
|
if (input.HasSegments)
|
|
{
|
|
this.mesh.MakeVertexMap();
|
|
}
|
|
foreach (Edge edge in input.segments)
|
|
{
|
|
this.mesh.insegments++;
|
|
int p = edge.P0;
|
|
int p2 = edge.P1;
|
|
int boundary = edge.Boundary;
|
|
if (p < 0 || p >= this.mesh.invertices)
|
|
{
|
|
if (Behavior.Verbose)
|
|
{
|
|
this.logger.Warning("Invalid first endpoint of segment.", "Mesh.FormSkeleton().1");
|
|
}
|
|
}
|
|
else if (p2 < 0 || p2 >= this.mesh.invertices)
|
|
{
|
|
if (Behavior.Verbose)
|
|
{
|
|
this.logger.Warning("Invalid second endpoint of segment.", "Mesh.FormSkeleton().2");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Vertex vertex = this.mesh.vertices[p];
|
|
Vertex vertex2 = this.mesh.vertices[p2];
|
|
if (vertex.x == vertex2.x && vertex.y == vertex2.y)
|
|
{
|
|
if (Behavior.Verbose)
|
|
{
|
|
this.logger.Warning(string.Concat(new object[] { "Endpoints of segment (IDs ", p, "/", p2, ") are coincident." }), "Mesh.FormSkeleton()");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.InsertSegment(vertex, vertex2, boundary);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (this.behavior.Convex || !this.behavior.Poly)
|
|
{
|
|
this.MarkHull();
|
|
}
|
|
}
|
|
|
|
// Token: 0x0600002F RID: 47 RVA: 0x00002AD0 File Offset: 0x00000CD0
|
|
private void InfectHull()
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Otri otri3 = default(Otri);
|
|
Osub osub = default(Osub);
|
|
otri.triangle = Mesh.dummytri;
|
|
otri.orient = 0;
|
|
otri.SymSelf();
|
|
otri.Copy(ref otri3);
|
|
do
|
|
{
|
|
if (!otri.IsInfected())
|
|
{
|
|
otri.SegPivot(ref osub);
|
|
if (osub.seg == Mesh.dummysub)
|
|
{
|
|
if (!otri.IsInfected())
|
|
{
|
|
otri.Infect();
|
|
this.viri.Add(otri.triangle);
|
|
}
|
|
}
|
|
else if (osub.seg.boundary == 0)
|
|
{
|
|
osub.seg.boundary = 1;
|
|
Vertex vertex = otri.Org();
|
|
Vertex vertex2 = otri.Dest();
|
|
if (vertex.mark == 0)
|
|
{
|
|
vertex.mark = 1;
|
|
}
|
|
if (vertex2.mark == 0)
|
|
{
|
|
vertex2.mark = 1;
|
|
}
|
|
}
|
|
}
|
|
otri.LnextSelf();
|
|
otri.Oprev(ref otri2);
|
|
while (otri2.triangle != Mesh.dummytri)
|
|
{
|
|
otri2.Copy(ref otri);
|
|
otri.Oprev(ref otri2);
|
|
}
|
|
}
|
|
while (!otri.Equal(otri3));
|
|
}
|
|
|
|
// Token: 0x06000030 RID: 48 RVA: 0x00002BF4 File Offset: 0x00000DF4
|
|
private void Plague()
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Osub osub = default(Osub);
|
|
for (int i = 0; i < this.viri.Count; i++)
|
|
{
|
|
otri.triangle = this.viri[i];
|
|
otri.Uninfect();
|
|
otri.orient = 0;
|
|
while (otri.orient < 3)
|
|
{
|
|
otri.Sym(ref otri2);
|
|
otri.SegPivot(ref osub);
|
|
if (otri2.triangle == Mesh.dummytri || otri2.IsInfected())
|
|
{
|
|
if (osub.seg != Mesh.dummysub)
|
|
{
|
|
this.mesh.SubsegDealloc(osub.seg);
|
|
if (otri2.triangle != Mesh.dummytri)
|
|
{
|
|
otri2.Uninfect();
|
|
otri2.SegDissolve();
|
|
otri2.Infect();
|
|
}
|
|
}
|
|
}
|
|
else if (osub.seg == Mesh.dummysub)
|
|
{
|
|
otri2.Infect();
|
|
this.viri.Add(otri2.triangle);
|
|
}
|
|
else
|
|
{
|
|
osub.TriDissolve();
|
|
if (osub.seg.boundary == 0)
|
|
{
|
|
osub.seg.boundary = 1;
|
|
}
|
|
Vertex vertex = otri2.Org();
|
|
Vertex vertex2 = otri2.Dest();
|
|
if (vertex.mark == 0)
|
|
{
|
|
vertex.mark = 1;
|
|
}
|
|
if (vertex2.mark == 0)
|
|
{
|
|
vertex2.mark = 1;
|
|
}
|
|
}
|
|
otri.orient++;
|
|
}
|
|
otri.Infect();
|
|
}
|
|
foreach (Triangle triangle in this.viri)
|
|
{
|
|
otri.triangle = triangle;
|
|
otri.orient = 0;
|
|
while (otri.orient < 3)
|
|
{
|
|
Vertex vertex3 = otri.Org();
|
|
if (vertex3 != null)
|
|
{
|
|
bool flag = true;
|
|
otri.SetOrg(null);
|
|
otri.Onext(ref otri2);
|
|
while (otri2.triangle != Mesh.dummytri && !otri2.Equal(otri))
|
|
{
|
|
if (otri2.IsInfected())
|
|
{
|
|
otri2.SetOrg(null);
|
|
}
|
|
else
|
|
{
|
|
flag = false;
|
|
}
|
|
otri2.OnextSelf();
|
|
}
|
|
if (otri2.triangle == Mesh.dummytri)
|
|
{
|
|
otri.Oprev(ref otri2);
|
|
while (otri2.triangle != Mesh.dummytri)
|
|
{
|
|
if (otri2.IsInfected())
|
|
{
|
|
otri2.SetOrg(null);
|
|
}
|
|
else
|
|
{
|
|
flag = false;
|
|
}
|
|
otri2.OprevSelf();
|
|
}
|
|
}
|
|
if (flag)
|
|
{
|
|
vertex3.type = VertexType.UndeadVertex;
|
|
this.mesh.undeads++;
|
|
}
|
|
}
|
|
otri.orient++;
|
|
}
|
|
otri.orient = 0;
|
|
while (otri.orient < 3)
|
|
{
|
|
otri.Sym(ref otri2);
|
|
if (otri2.triangle == Mesh.dummytri)
|
|
{
|
|
this.mesh.hullsize--;
|
|
}
|
|
else
|
|
{
|
|
otri2.Dissolve();
|
|
this.mesh.hullsize++;
|
|
}
|
|
otri.orient++;
|
|
}
|
|
this.mesh.TriangleDealloc(otri.triangle);
|
|
}
|
|
this.viri.Clear();
|
|
}
|
|
|
|
// Token: 0x06000031 RID: 49 RVA: 0x00002F2C File Offset: 0x0000112C
|
|
private FindDirectionResult FindDirection(ref Otri searchtri, Vertex searchpoint)
|
|
{
|
|
Otri otri = default(Otri);
|
|
Vertex vertex = searchtri.Org();
|
|
Vertex vertex2 = searchtri.Dest();
|
|
Vertex vertex3 = searchtri.Apex();
|
|
double num = Primitives.CounterClockwise(searchpoint, vertex, vertex3);
|
|
bool flag = num > 0.0;
|
|
double num2 = Primitives.CounterClockwise(vertex, searchpoint, vertex2);
|
|
bool flag2 = num2 > 0.0;
|
|
if (flag && flag2)
|
|
{
|
|
searchtri.Onext(ref otri);
|
|
if (otri.triangle == Mesh.dummytri)
|
|
{
|
|
flag = false;
|
|
}
|
|
else
|
|
{
|
|
flag2 = false;
|
|
}
|
|
}
|
|
while (flag)
|
|
{
|
|
searchtri.OnextSelf();
|
|
if (searchtri.triangle == Mesh.dummytri)
|
|
{
|
|
this.logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().1");
|
|
throw new Exception("Unable to find a triangle on path.");
|
|
}
|
|
vertex3 = searchtri.Apex();
|
|
num2 = num;
|
|
num = Primitives.CounterClockwise(searchpoint, vertex, vertex3);
|
|
flag = num > 0.0;
|
|
}
|
|
while (flag2)
|
|
{
|
|
searchtri.OprevSelf();
|
|
if (searchtri.triangle == Mesh.dummytri)
|
|
{
|
|
this.logger.Error("Unable to find a triangle on path.", "Mesh.FindDirection().2");
|
|
throw new Exception("Unable to find a triangle on path.");
|
|
}
|
|
vertex2 = searchtri.Dest();
|
|
num = num2;
|
|
num2 = Primitives.CounterClockwise(vertex, searchpoint, vertex2);
|
|
flag2 = num2 > 0.0;
|
|
}
|
|
if (num == 0.0)
|
|
{
|
|
return FindDirectionResult.Leftcollinear;
|
|
}
|
|
if (num2 == 0.0)
|
|
{
|
|
return FindDirectionResult.Rightcollinear;
|
|
}
|
|
return FindDirectionResult.Within;
|
|
}
|
|
|
|
// Token: 0x06000032 RID: 50 RVA: 0x00003088 File Offset: 0x00001288
|
|
private void SegmentIntersection(ref Otri splittri, ref Osub splitsubseg, Vertex endpoint2)
|
|
{
|
|
Osub osub = default(Osub);
|
|
Vertex vertex = splittri.Apex();
|
|
Vertex vertex2 = splittri.Org();
|
|
Vertex vertex3 = splittri.Dest();
|
|
double num = vertex3.x - vertex2.x;
|
|
double num2 = vertex3.y - vertex2.y;
|
|
double num3 = endpoint2.x - vertex.x;
|
|
double num4 = endpoint2.y - vertex.y;
|
|
double num5 = vertex2.x - endpoint2.x;
|
|
double num6 = vertex2.y - endpoint2.y;
|
|
double num7 = num2 * num3 - num * num4;
|
|
if (num7 == 0.0)
|
|
{
|
|
this.logger.Error("Attempt to find intersection of parallel segments.", "Mesh.SegmentIntersection()");
|
|
throw new Exception("Attempt to find intersection of parallel segments.");
|
|
}
|
|
double num8 = (num4 * num5 - num3 * num6) / num7;
|
|
Vertex vertex4 = new Vertex(vertex2.x + num8 * (vertex3.x - vertex2.x), vertex2.y + num8 * (vertex3.y - vertex2.y), splitsubseg.seg.boundary, this.mesh.nextras);
|
|
Vertex vertex5 = vertex4;
|
|
Mesh mesh = this.mesh;
|
|
int hash_vtx = mesh.hash_vtx;
|
|
mesh.hash_vtx = hash_vtx + 1;
|
|
vertex5.hash = hash_vtx;
|
|
vertex4.id = vertex4.hash;
|
|
for (int i = 0; i < this.mesh.nextras; i++)
|
|
{
|
|
vertex4.attributes[i] = vertex2.attributes[i] + num8 * (vertex3.attributes[i] - vertex2.attributes[i]);
|
|
}
|
|
this.mesh.vertices.Add(vertex4.hash, vertex4);
|
|
if (this.mesh.InsertVertex(vertex4, ref splittri, ref splitsubseg, false, false) != InsertVertexResult.Successful)
|
|
{
|
|
this.logger.Error("Failure to split a segment.", "Mesh.SegmentIntersection()");
|
|
throw new Exception("Failure to split a segment.");
|
|
}
|
|
vertex4.tri = splittri;
|
|
if (this.mesh.steinerleft > 0)
|
|
{
|
|
this.mesh.steinerleft--;
|
|
}
|
|
splitsubseg.SymSelf();
|
|
splitsubseg.Pivot(ref osub);
|
|
splitsubseg.Dissolve();
|
|
osub.Dissolve();
|
|
do
|
|
{
|
|
splitsubseg.SetSegOrg(vertex4);
|
|
splitsubseg.NextSelf();
|
|
}
|
|
while (splitsubseg.seg != Mesh.dummysub);
|
|
do
|
|
{
|
|
osub.SetSegOrg(vertex4);
|
|
osub.NextSelf();
|
|
}
|
|
while (osub.seg != Mesh.dummysub);
|
|
this.FindDirection(ref splittri, vertex);
|
|
Vertex vertex6 = splittri.Dest();
|
|
Vertex vertex7 = splittri.Apex();
|
|
if (vertex7.x == vertex.x && vertex7.y == vertex.y)
|
|
{
|
|
splittri.OnextSelf();
|
|
return;
|
|
}
|
|
if (vertex6.x != vertex.x || vertex6.y != vertex.y)
|
|
{
|
|
this.logger.Error("Topological inconsistency after splitting a segment.", "Mesh.SegmentIntersection()");
|
|
throw new Exception("Topological inconsistency after splitting a segment.");
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000033 RID: 51 RVA: 0x00003358 File Offset: 0x00001558
|
|
private bool ScoutSegment(ref Otri searchtri, Vertex endpoint2, int newmark)
|
|
{
|
|
Otri otri = default(Otri);
|
|
Osub osub = default(Osub);
|
|
FindDirectionResult findDirectionResult = this.FindDirection(ref searchtri, endpoint2);
|
|
Vertex vertex = searchtri.Dest();
|
|
Vertex vertex2 = searchtri.Apex();
|
|
if ((vertex2.x == endpoint2.x && vertex2.y == endpoint2.y) || (vertex.x == endpoint2.x && vertex.y == endpoint2.y))
|
|
{
|
|
if (vertex2.x == endpoint2.x && vertex2.y == endpoint2.y)
|
|
{
|
|
searchtri.LprevSelf();
|
|
}
|
|
this.mesh.InsertSubseg(ref searchtri, newmark);
|
|
return true;
|
|
}
|
|
if (findDirectionResult == FindDirectionResult.Leftcollinear)
|
|
{
|
|
searchtri.LprevSelf();
|
|
this.mesh.InsertSubseg(ref searchtri, newmark);
|
|
return this.ScoutSegment(ref searchtri, endpoint2, newmark);
|
|
}
|
|
if (findDirectionResult == FindDirectionResult.Rightcollinear)
|
|
{
|
|
this.mesh.InsertSubseg(ref searchtri, newmark);
|
|
searchtri.LnextSelf();
|
|
return this.ScoutSegment(ref searchtri, endpoint2, newmark);
|
|
}
|
|
searchtri.Lnext(ref otri);
|
|
otri.SegPivot(ref osub);
|
|
if (osub.seg == Mesh.dummysub)
|
|
{
|
|
return false;
|
|
}
|
|
this.SegmentIntersection(ref otri, ref osub, endpoint2);
|
|
otri.Copy(ref searchtri);
|
|
this.mesh.InsertSubseg(ref searchtri, newmark);
|
|
return this.ScoutSegment(ref searchtri, endpoint2, newmark);
|
|
}
|
|
|
|
// Token: 0x06000034 RID: 52 RVA: 0x00003484 File Offset: 0x00001684
|
|
private void DelaunayFixup(ref Otri fixuptri, bool leftside)
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Osub osub = default(Osub);
|
|
fixuptri.Lnext(ref otri);
|
|
otri.Sym(ref otri2);
|
|
if (otri2.triangle == Mesh.dummytri)
|
|
{
|
|
return;
|
|
}
|
|
otri.SegPivot(ref osub);
|
|
if (osub.seg != Mesh.dummysub)
|
|
{
|
|
return;
|
|
}
|
|
Vertex vertex = otri.Apex();
|
|
Vertex vertex2 = otri.Org();
|
|
Vertex vertex3 = otri.Dest();
|
|
Vertex vertex4 = otri2.Apex();
|
|
if (leftside)
|
|
{
|
|
if (Primitives.CounterClockwise(vertex, vertex2, vertex4) <= 0.0)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
else if (Primitives.CounterClockwise(vertex4, vertex3, vertex) <= 0.0)
|
|
{
|
|
return;
|
|
}
|
|
if (Primitives.CounterClockwise(vertex3, vertex2, vertex4) > 0.0 && Primitives.InCircle(vertex2, vertex4, vertex3, vertex) <= 0.0)
|
|
{
|
|
return;
|
|
}
|
|
this.mesh.Flip(ref otri);
|
|
fixuptri.LprevSelf();
|
|
this.DelaunayFixup(ref fixuptri, leftside);
|
|
this.DelaunayFixup(ref otri2, leftside);
|
|
}
|
|
|
|
// Token: 0x06000035 RID: 53 RVA: 0x00003584 File Offset: 0x00001784
|
|
private void ConstrainedEdge(ref Otri starttri, Vertex endpoint2, int newmark)
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Osub osub = default(Osub);
|
|
Vertex vertex = starttri.Org();
|
|
starttri.Lnext(ref otri);
|
|
this.mesh.Flip(ref otri);
|
|
bool flag = false;
|
|
bool flag2 = false;
|
|
do
|
|
{
|
|
Vertex vertex2 = otri.Org();
|
|
if (vertex2.x == endpoint2.x && vertex2.y == endpoint2.y)
|
|
{
|
|
otri.Oprev(ref otri2);
|
|
this.DelaunayFixup(ref otri, false);
|
|
this.DelaunayFixup(ref otri2, true);
|
|
flag2 = true;
|
|
}
|
|
else
|
|
{
|
|
double num = Primitives.CounterClockwise(vertex, endpoint2, vertex2);
|
|
if (num == 0.0)
|
|
{
|
|
flag = true;
|
|
otri.Oprev(ref otri2);
|
|
this.DelaunayFixup(ref otri, false);
|
|
this.DelaunayFixup(ref otri2, true);
|
|
flag2 = true;
|
|
}
|
|
else
|
|
{
|
|
if (num > 0.0)
|
|
{
|
|
otri.Oprev(ref otri2);
|
|
this.DelaunayFixup(ref otri2, true);
|
|
otri.LprevSelf();
|
|
}
|
|
else
|
|
{
|
|
this.DelaunayFixup(ref otri, false);
|
|
otri.OprevSelf();
|
|
}
|
|
otri.SegPivot(ref osub);
|
|
if (osub.seg == Mesh.dummysub)
|
|
{
|
|
this.mesh.Flip(ref otri);
|
|
}
|
|
else
|
|
{
|
|
flag = true;
|
|
this.SegmentIntersection(ref otri, ref osub, endpoint2);
|
|
flag2 = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
while (!flag2);
|
|
this.mesh.InsertSubseg(ref otri, newmark);
|
|
if (flag && !this.ScoutSegment(ref otri, endpoint2, newmark))
|
|
{
|
|
this.ConstrainedEdge(ref otri, endpoint2, newmark);
|
|
}
|
|
}
|
|
|
|
// Token: 0x06000036 RID: 54 RVA: 0x000036F0 File Offset: 0x000018F0
|
|
private void InsertSegment(Vertex endpoint1, Vertex endpoint2, int newmark)
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Vertex vertex = null;
|
|
otri = endpoint1.tri;
|
|
if (otri.triangle != null)
|
|
{
|
|
vertex = otri.Org();
|
|
}
|
|
if (vertex != endpoint1)
|
|
{
|
|
otri.triangle = Mesh.dummytri;
|
|
otri.orient = 0;
|
|
otri.SymSelf();
|
|
if (this.locator.Locate(endpoint1, ref otri) != LocateResult.OnVertex)
|
|
{
|
|
this.logger.Error("Unable to locate PSLG vertex in triangulation.", "Mesh.InsertSegment().1");
|
|
throw new Exception("Unable to locate PSLG vertex in triangulation.");
|
|
}
|
|
}
|
|
this.locator.Update(ref otri);
|
|
if (this.ScoutSegment(ref otri, endpoint2, newmark))
|
|
{
|
|
return;
|
|
}
|
|
endpoint1 = otri.Org();
|
|
vertex = null;
|
|
otri2 = endpoint2.tri;
|
|
if (otri2.triangle != null)
|
|
{
|
|
vertex = otri2.Org();
|
|
}
|
|
if (vertex != endpoint2)
|
|
{
|
|
otri2.triangle = Mesh.dummytri;
|
|
otri2.orient = 0;
|
|
otri2.SymSelf();
|
|
if (this.locator.Locate(endpoint2, ref otri2) != LocateResult.OnVertex)
|
|
{
|
|
this.logger.Error("Unable to locate PSLG vertex in triangulation.", "Mesh.InsertSegment().2");
|
|
throw new Exception("Unable to locate PSLG vertex in triangulation.");
|
|
}
|
|
}
|
|
this.locator.Update(ref otri2);
|
|
if (this.ScoutSegment(ref otri2, endpoint1, newmark))
|
|
{
|
|
return;
|
|
}
|
|
endpoint2 = otri2.Org();
|
|
this.ConstrainedEdge(ref otri, endpoint2, newmark);
|
|
}
|
|
|
|
// Token: 0x06000037 RID: 55 RVA: 0x0000383C File Offset: 0x00001A3C
|
|
private void MarkHull()
|
|
{
|
|
Otri otri = default(Otri);
|
|
Otri otri2 = default(Otri);
|
|
Otri otri3 = default(Otri);
|
|
otri.triangle = Mesh.dummytri;
|
|
otri.orient = 0;
|
|
otri.SymSelf();
|
|
otri.Copy(ref otri3);
|
|
do
|
|
{
|
|
this.mesh.InsertSubseg(ref otri, 1);
|
|
otri.LnextSelf();
|
|
otri.Oprev(ref otri2);
|
|
while (otri2.triangle != Mesh.dummytri)
|
|
{
|
|
otri2.Copy(ref otri);
|
|
otri.Oprev(ref otri2);
|
|
}
|
|
}
|
|
while (!otri.Equal(otri3));
|
|
}
|
|
|
|
// Token: 0x0400001E RID: 30
|
|
private Mesh mesh;
|
|
|
|
// Token: 0x0400001F RID: 31
|
|
private Behavior behavior;
|
|
|
|
// Token: 0x04000020 RID: 32
|
|
private TriangleLocator locator;
|
|
|
|
// Token: 0x04000021 RID: 33
|
|
private List<Triangle> viri;
|
|
|
|
// Token: 0x04000022 RID: 34
|
|
private ILog<SimpleLogItem> logger;
|
|
}
|
|
}
|