scripts
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
using System;
|
||||
using TriangleNet.Data;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000012 RID: 18
|
||||
public class AdjacencyMatrix
|
||||
{
|
||||
// Token: 0x1700001E RID: 30
|
||||
// (get) Token: 0x0600009B RID: 155 RVA: 0x0001158A File Offset: 0x0000F78A
|
||||
public int[] AdjacencyRow
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.adj_row;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700001F RID: 31
|
||||
// (get) Token: 0x0600009C RID: 156 RVA: 0x00011592 File Offset: 0x0000F792
|
||||
public int[] Adjacency
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.adj;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x0600009D RID: 157 RVA: 0x0001159C File Offset: 0x0000F79C
|
||||
public AdjacencyMatrix(Mesh mesh)
|
||||
{
|
||||
this.node_num = mesh.vertices.Count;
|
||||
this.adj_row = this.AdjacencyCount(mesh);
|
||||
this.adj_num = this.adj_row[this.node_num] - 1;
|
||||
this.adj = this.AdjacencySet(mesh, this.adj_row);
|
||||
}
|
||||
|
||||
// Token: 0x0600009E RID: 158 RVA: 0x000115F8 File Offset: 0x0000F7F8
|
||||
public int Bandwidth()
|
||||
{
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
for (int j = this.adj_row[i]; j <= this.adj_row[i + 1] - 1; j++)
|
||||
{
|
||||
int num3 = this.adj[j - 1];
|
||||
num = Math.Max(num, i - num3);
|
||||
num2 = Math.Max(num2, num3 - i);
|
||||
}
|
||||
}
|
||||
return num + 1 + num2;
|
||||
}
|
||||
|
||||
// Token: 0x0600009F RID: 159 RVA: 0x00011664 File Offset: 0x0000F864
|
||||
private int[] AdjacencyCount(Mesh mesh)
|
||||
{
|
||||
int[] array = new int[this.node_num + 1];
|
||||
int i;
|
||||
for (i = 0; i < this.node_num; i++)
|
||||
{
|
||||
array[i] = 1;
|
||||
}
|
||||
foreach (Triangle triangle in mesh.triangles.Values)
|
||||
{
|
||||
int id = triangle.id;
|
||||
int id2 = triangle.vertices[0].id;
|
||||
int id3 = triangle.vertices[1].id;
|
||||
int id4 = triangle.vertices[2].id;
|
||||
int num = triangle.neighbors[2].triangle.id;
|
||||
if (num < 0 || id < num)
|
||||
{
|
||||
array[id2]++;
|
||||
array[id3]++;
|
||||
}
|
||||
num = triangle.neighbors[0].triangle.id;
|
||||
if (num < 0 || id < num)
|
||||
{
|
||||
array[id3]++;
|
||||
array[id4]++;
|
||||
}
|
||||
num = triangle.neighbors[1].triangle.id;
|
||||
if (num < 0 || id < num)
|
||||
{
|
||||
array[id4]++;
|
||||
array[id2]++;
|
||||
}
|
||||
}
|
||||
i = this.node_num;
|
||||
while (1 <= i)
|
||||
{
|
||||
array[i] = array[i - 1];
|
||||
i--;
|
||||
}
|
||||
array[0] = 1;
|
||||
for (int j = 1; j <= this.node_num; j++)
|
||||
{
|
||||
array[j] = array[j - 1] + array[j];
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Token: 0x060000A0 RID: 160 RVA: 0x0001181C File Offset: 0x0000FA1C
|
||||
private int[] AdjacencySet(Mesh mesh, int[] rows)
|
||||
{
|
||||
int[] array = new int[this.node_num];
|
||||
Array.Copy(rows, array, this.node_num);
|
||||
int num = rows[this.node_num] - 1;
|
||||
int[] array2 = new int[num];
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
array2[i] = -1;
|
||||
}
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
array2[array[i] - 1] = i;
|
||||
array[i]++;
|
||||
}
|
||||
foreach (Triangle triangle in mesh.triangles.Values)
|
||||
{
|
||||
int id = triangle.id;
|
||||
int id2 = triangle.vertices[0].id;
|
||||
int id3 = triangle.vertices[1].id;
|
||||
int id4 = triangle.vertices[2].id;
|
||||
int num2 = triangle.neighbors[2].triangle.id;
|
||||
if (num2 < 0 || id < num2)
|
||||
{
|
||||
array2[array[id2] - 1] = id3;
|
||||
array[id2]++;
|
||||
array2[array[id3] - 1] = id2;
|
||||
array[id3]++;
|
||||
}
|
||||
num2 = triangle.neighbors[0].triangle.id;
|
||||
if (num2 < 0 || id < num2)
|
||||
{
|
||||
array2[array[id3] - 1] = id4;
|
||||
array[id3]++;
|
||||
array2[array[id4] - 1] = id3;
|
||||
array[id4]++;
|
||||
}
|
||||
num2 = triangle.neighbors[1].triangle.id;
|
||||
if (num2 < 0 || id < num2)
|
||||
{
|
||||
array2[array[id2] - 1] = id4;
|
||||
array[id2]++;
|
||||
array2[array[id4] - 1] = id2;
|
||||
array[id4]++;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
int num3 = rows[i];
|
||||
int num4 = rows[i + 1] - 1;
|
||||
this.HeapSort(array2, num3 - 1, num4 + 1 - num3);
|
||||
}
|
||||
return array2;
|
||||
}
|
||||
|
||||
// Token: 0x060000A1 RID: 161 RVA: 0x00011A38 File Offset: 0x0000FC38
|
||||
private void CreateHeap(int[] a, int offset, int size)
|
||||
{
|
||||
int num = size / 2 - 1;
|
||||
while (0 <= num)
|
||||
{
|
||||
int num2 = a[offset + num];
|
||||
int num3 = num;
|
||||
for (;;)
|
||||
{
|
||||
int num4 = 2 * num3 + 1;
|
||||
if (size <= num4)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (num4 + 1 < size && a[offset + num4] < a[offset + num4 + 1])
|
||||
{
|
||||
num4++;
|
||||
}
|
||||
if (num2 >= a[offset + num4])
|
||||
{
|
||||
break;
|
||||
}
|
||||
a[offset + num3] = a[offset + num4];
|
||||
num3 = num4;
|
||||
}
|
||||
a[offset + num3] = num2;
|
||||
num--;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000A2 RID: 162 RVA: 0x00011A9C File Offset: 0x0000FC9C
|
||||
private void HeapSort(int[] a, int offset, int size)
|
||||
{
|
||||
if (size <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
this.CreateHeap(a, offset, size);
|
||||
int num = a[offset];
|
||||
a[offset] = a[offset + size - 1];
|
||||
a[offset + size - 1] = num;
|
||||
int num2 = size - 1;
|
||||
while (2 <= num2)
|
||||
{
|
||||
this.CreateHeap(a, offset, num2);
|
||||
num = a[offset];
|
||||
a[offset] = a[offset + num2 - 1];
|
||||
a[offset + num2 - 1] = num;
|
||||
num2--;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x04000086 RID: 134
|
||||
private int node_num;
|
||||
|
||||
// Token: 0x04000087 RID: 135
|
||||
private int adj_num;
|
||||
|
||||
// Token: 0x04000088 RID: 136
|
||||
private int[] adj_row;
|
||||
|
||||
// Token: 0x04000089 RID: 137
|
||||
private int[] adj;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,503 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000013 RID: 19
|
||||
public class BoundedVoronoi : IVoronoi
|
||||
{
|
||||
// Token: 0x060000A3 RID: 163 RVA: 0x00011AFA File Offset: 0x0000FCFA
|
||||
public BoundedVoronoi(Mesh mesh)
|
||||
: this(mesh, true)
|
||||
{
|
||||
}
|
||||
|
||||
// Token: 0x060000A4 RID: 164 RVA: 0x00011B04 File Offset: 0x0000FD04
|
||||
public BoundedVoronoi(Mesh mesh, bool includeBoundary)
|
||||
{
|
||||
this.mesh = mesh;
|
||||
this.includeBoundary = includeBoundary;
|
||||
this.Generate();
|
||||
}
|
||||
|
||||
// Token: 0x17000020 RID: 32
|
||||
// (get) Token: 0x060000A5 RID: 165 RVA: 0x00011B27 File Offset: 0x0000FD27
|
||||
public Point[] Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.points;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000021 RID: 33
|
||||
// (get) Token: 0x060000A6 RID: 166 RVA: 0x00011B2F File Offset: 0x0000FD2F
|
||||
public ICollection<VoronoiRegion> Regions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.regions;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000A7 RID: 167 RVA: 0x00011B38 File Offset: 0x0000FD38
|
||||
private void Generate()
|
||||
{
|
||||
this.mesh.Renumber();
|
||||
this.mesh.MakeVertexMap();
|
||||
this.regions = new List<VoronoiRegion>(this.mesh.vertices.Count);
|
||||
this.points = new Point[this.mesh.triangles.Count];
|
||||
this.segPoints = new List<Point>(this.mesh.subsegs.Count * 4);
|
||||
this.ComputeCircumCenters();
|
||||
this.TagBlindTriangles();
|
||||
foreach (Vertex vertex in this.mesh.vertices.Values)
|
||||
{
|
||||
if (vertex.type == VertexType.FreeVertex || vertex.Boundary == 0)
|
||||
{
|
||||
this.ConstructCell(vertex);
|
||||
}
|
||||
else if (this.includeBoundary)
|
||||
{
|
||||
this.ConstructBoundaryCell(vertex);
|
||||
}
|
||||
}
|
||||
int num = this.points.Length;
|
||||
Array.Resize<Point>(ref this.points, num + this.segPoints.Count);
|
||||
for (int i = 0; i < this.segPoints.Count; i++)
|
||||
{
|
||||
this.points[num + i] = this.segPoints[i];
|
||||
}
|
||||
this.segPoints.Clear();
|
||||
this.segPoints = null;
|
||||
}
|
||||
|
||||
// Token: 0x060000A8 RID: 168 RVA: 0x00011C8C File Offset: 0x0000FE8C
|
||||
private void ComputeCircumCenters()
|
||||
{
|
||||
Otri otri = default(Otri);
|
||||
double num = 0.0;
|
||||
double num2 = 0.0;
|
||||
foreach (Triangle triangle in this.mesh.triangles.Values)
|
||||
{
|
||||
otri.triangle = triangle;
|
||||
Point point = Primitives.FindCircumcenter(otri.Org(), otri.Dest(), otri.Apex(), ref num, ref num2);
|
||||
point.id = triangle.id;
|
||||
this.points[triangle.id] = point;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000A9 RID: 169 RVA: 0x00011D44 File Offset: 0x0000FF44
|
||||
private void TagBlindTriangles()
|
||||
{
|
||||
int num = 0;
|
||||
this.subsegMap = new Dictionary<int, Segment>();
|
||||
Otri otri = default(Otri);
|
||||
Otri otri2 = default(Otri);
|
||||
Osub osub = default(Osub);
|
||||
Osub osub2 = default(Osub);
|
||||
foreach (Triangle triangle in this.mesh.triangles.Values)
|
||||
{
|
||||
triangle.infected = false;
|
||||
}
|
||||
foreach (Segment segment in this.mesh.subsegs.Values)
|
||||
{
|
||||
Stack<Triangle> stack = new Stack<Triangle>();
|
||||
osub.seg = segment;
|
||||
osub.orient = 0;
|
||||
osub.TriPivot(ref otri);
|
||||
if (otri.triangle != Mesh.dummytri && !otri.triangle.infected)
|
||||
{
|
||||
stack.Push(otri.triangle);
|
||||
}
|
||||
osub.SymSelf();
|
||||
osub.TriPivot(ref otri);
|
||||
if (otri.triangle != Mesh.dummytri && !otri.triangle.infected)
|
||||
{
|
||||
stack.Push(otri.triangle);
|
||||
}
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
otri.triangle = stack.Pop();
|
||||
otri.orient = 0;
|
||||
if (this.TriangleIsBlinded(ref otri, ref osub))
|
||||
{
|
||||
otri.triangle.infected = true;
|
||||
num++;
|
||||
this.subsegMap.Add(otri.triangle.hash, osub.seg);
|
||||
otri.orient = 0;
|
||||
while (otri.orient < 3)
|
||||
{
|
||||
otri.Sym(ref otri2);
|
||||
otri2.SegPivot(ref osub2);
|
||||
if (otri2.triangle != Mesh.dummytri && !otri2.triangle.infected && osub2.seg == Mesh.dummysub)
|
||||
{
|
||||
stack.Push(otri2.triangle);
|
||||
}
|
||||
otri.orient++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
num = 0;
|
||||
}
|
||||
|
||||
// Token: 0x060000AA RID: 170 RVA: 0x00011F80 File Offset: 0x00010180
|
||||
private bool TriangleIsBlinded(ref Otri tri, ref Osub seg)
|
||||
{
|
||||
Vertex vertex = tri.Org();
|
||||
Vertex vertex2 = tri.Dest();
|
||||
Vertex vertex3 = tri.Apex();
|
||||
Vertex vertex4 = seg.Org();
|
||||
Vertex vertex5 = seg.Dest();
|
||||
Point point = this.points[tri.triangle.id];
|
||||
Point point2;
|
||||
return this.SegmentsIntersect(vertex4, vertex5, point, vertex, out point2, true) || this.SegmentsIntersect(vertex4, vertex5, point, vertex2, out point2, true) || this.SegmentsIntersect(vertex4, vertex5, point, vertex3, out point2, true);
|
||||
}
|
||||
|
||||
// Token: 0x060000AB RID: 171 RVA: 0x00012004 File Offset: 0x00010204
|
||||
private void ConstructCell(Vertex vertex)
|
||||
{
|
||||
VoronoiRegion voronoiRegion = new VoronoiRegion(vertex);
|
||||
this.regions.Add(voronoiRegion);
|
||||
Otri otri = default(Otri);
|
||||
Otri otri2 = default(Otri);
|
||||
Otri otri3 = default(Otri);
|
||||
Osub osub = default(Osub);
|
||||
Osub osub2 = default(Osub);
|
||||
int count = this.mesh.triangles.Count;
|
||||
List<Point> list = new List<Point>();
|
||||
vertex.tri.Copy(ref otri2);
|
||||
if (otri2.Org() != vertex)
|
||||
{
|
||||
throw new Exception("ConstructBvdCell: inconsistent topology.");
|
||||
}
|
||||
otri2.Copy(ref otri);
|
||||
otri2.Onext(ref otri3);
|
||||
do
|
||||
{
|
||||
Point point = this.points[otri.triangle.id];
|
||||
Point point2 = this.points[otri3.triangle.id];
|
||||
if (!otri.triangle.infected)
|
||||
{
|
||||
list.Add(point);
|
||||
if (otri3.triangle.infected)
|
||||
{
|
||||
osub2.seg = this.subsegMap[otri3.triangle.hash];
|
||||
Point point3;
|
||||
if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point, point2, out point3, true))
|
||||
{
|
||||
Point point4 = point3;
|
||||
int num = count;
|
||||
int num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point4.id = num + num2;
|
||||
this.segPoints.Add(point3);
|
||||
list.Add(point3);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osub.seg = this.subsegMap[otri.triangle.hash];
|
||||
if (!otri3.triangle.infected)
|
||||
{
|
||||
Point point3;
|
||||
if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point, point2, out point3, true))
|
||||
{
|
||||
Point point5 = point3;
|
||||
int num3 = count;
|
||||
int num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point5.id = num3 + num2;
|
||||
this.segPoints.Add(point3);
|
||||
list.Add(point3);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osub2.seg = this.subsegMap[otri3.triangle.hash];
|
||||
if (!osub.Equal(osub2))
|
||||
{
|
||||
Point point3;
|
||||
if (this.SegmentsIntersect(osub.SegOrg(), osub.SegDest(), point, point2, out point3, true))
|
||||
{
|
||||
Point point6 = point3;
|
||||
int num4 = count;
|
||||
int num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point6.id = num4 + num2;
|
||||
this.segPoints.Add(point3);
|
||||
list.Add(point3);
|
||||
}
|
||||
if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point, point2, out point3, true))
|
||||
{
|
||||
Point point7 = point3;
|
||||
int num5 = count;
|
||||
int num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point7.id = num5 + num2;
|
||||
this.segPoints.Add(point3);
|
||||
list.Add(point3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
otri3.Copy(ref otri);
|
||||
otri3.OnextSelf();
|
||||
}
|
||||
while (!otri.Equal(otri2));
|
||||
voronoiRegion.Add(list);
|
||||
}
|
||||
|
||||
// Token: 0x060000AC RID: 172 RVA: 0x000122DC File Offset: 0x000104DC
|
||||
private void ConstructBoundaryCell(Vertex vertex)
|
||||
{
|
||||
VoronoiRegion voronoiRegion = new VoronoiRegion(vertex);
|
||||
this.regions.Add(voronoiRegion);
|
||||
Otri otri = default(Otri);
|
||||
Otri otri2 = default(Otri);
|
||||
Otri otri3 = default(Otri);
|
||||
Otri otri4 = default(Otri);
|
||||
Osub osub = default(Osub);
|
||||
Osub osub2 = default(Osub);
|
||||
int count = this.mesh.triangles.Count;
|
||||
List<Point> list = new List<Point>();
|
||||
vertex.tri.Copy(ref otri2);
|
||||
if (otri2.Org() != vertex)
|
||||
{
|
||||
throw new Exception("ConstructBoundaryBvdCell: inconsistent topology.");
|
||||
}
|
||||
otri2.Copy(ref otri);
|
||||
otri2.Onext(ref otri3);
|
||||
otri2.Oprev(ref otri4);
|
||||
if (otri4.triangle != Mesh.dummytri)
|
||||
{
|
||||
while (otri4.triangle != Mesh.dummytri && !otri4.Equal(otri2))
|
||||
{
|
||||
otri4.Copy(ref otri);
|
||||
otri4.OprevSelf();
|
||||
}
|
||||
otri.Copy(ref otri2);
|
||||
otri.Onext(ref otri3);
|
||||
}
|
||||
Point point;
|
||||
int num2;
|
||||
if (otri4.triangle == Mesh.dummytri)
|
||||
{
|
||||
point = new Point(vertex.x, vertex.y);
|
||||
Point point2 = point;
|
||||
int num = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point2.id = num + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
Vertex vertex2 = otri.Org();
|
||||
Vertex vertex3 = otri.Dest();
|
||||
point = new Point((vertex2.X + vertex3.X) / 2.0, (vertex2.Y + vertex3.Y) / 2.0);
|
||||
Point point3 = point;
|
||||
int num3 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point3.id = num3 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
Point point4;
|
||||
Vertex vertex6;
|
||||
for (;;)
|
||||
{
|
||||
point4 = this.points[otri.triangle.id];
|
||||
if (otri3.triangle == Mesh.dummytri)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Point point5 = this.points[otri3.triangle.id];
|
||||
if (!otri.triangle.infected)
|
||||
{
|
||||
list.Add(point4);
|
||||
if (otri3.triangle.infected)
|
||||
{
|
||||
osub2.seg = this.subsegMap[otri3.triangle.hash];
|
||||
if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point4, point5, out point, true))
|
||||
{
|
||||
Point point6 = point;
|
||||
int num4 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point6.id = num4 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osub.seg = this.subsegMap[otri.triangle.hash];
|
||||
Vertex vertex4 = osub.SegOrg();
|
||||
Vertex vertex5 = osub.SegDest();
|
||||
if (!otri3.triangle.infected)
|
||||
{
|
||||
vertex3 = otri.Dest();
|
||||
vertex6 = otri.Apex();
|
||||
Point point7 = new Point((vertex3.X + vertex6.X) / 2.0, (vertex3.Y + vertex6.Y) / 2.0);
|
||||
if (this.SegmentsIntersect(vertex4, vertex5, point7, point4, out point, false))
|
||||
{
|
||||
Point point8 = point;
|
||||
int num5 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point8.id = num5 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
if (this.SegmentsIntersect(vertex4, vertex5, point4, point5, out point, true))
|
||||
{
|
||||
Point point9 = point;
|
||||
int num6 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point9.id = num6 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
osub2.seg = this.subsegMap[otri3.triangle.hash];
|
||||
if (!osub.Equal(osub2))
|
||||
{
|
||||
if (this.SegmentsIntersect(vertex4, vertex5, point4, point5, out point, true))
|
||||
{
|
||||
Point point10 = point;
|
||||
int num7 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point10.id = num7 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
if (this.SegmentsIntersect(osub2.SegOrg(), osub2.SegDest(), point4, point5, out point, true))
|
||||
{
|
||||
Point point11 = point;
|
||||
int num8 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point11.id = num8 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Point point12 = new Point((vertex2.X + vertex3.X) / 2.0, (vertex2.Y + vertex3.Y) / 2.0);
|
||||
if (this.SegmentsIntersect(vertex4, vertex5, point12, point5, out point, false))
|
||||
{
|
||||
Point point13 = point;
|
||||
int num9 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point13.id = num9 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
otri3.Copy(ref otri);
|
||||
otri3.OnextSelf();
|
||||
if (otri.Equal(otri2))
|
||||
{
|
||||
goto IL_5B5;
|
||||
}
|
||||
}
|
||||
if (!otri.triangle.infected)
|
||||
{
|
||||
list.Add(point4);
|
||||
}
|
||||
vertex2 = otri.Org();
|
||||
vertex6 = otri.Apex();
|
||||
point = new Point((vertex2.X + vertex6.X) / 2.0, (vertex2.Y + vertex6.Y) / 2.0);
|
||||
Point point14 = point;
|
||||
int num10 = count;
|
||||
num2 = this.segIndex;
|
||||
this.segIndex = num2 + 1;
|
||||
point14.id = num10 + num2;
|
||||
this.segPoints.Add(point);
|
||||
list.Add(point);
|
||||
IL_5B5:
|
||||
voronoiRegion.Add(list);
|
||||
}
|
||||
|
||||
// Token: 0x060000AD RID: 173 RVA: 0x000128A8 File Offset: 0x00010AA8
|
||||
private bool SegmentsIntersect(Point p1, Point p2, Point p3, Point p4, out Point p, bool strictIntersect)
|
||||
{
|
||||
p = null;
|
||||
double x = p1.X;
|
||||
double y = p1.Y;
|
||||
double num = p2.X;
|
||||
double num2 = p2.Y;
|
||||
double num3 = p3.X;
|
||||
double num4 = p3.Y;
|
||||
double num5 = p4.X;
|
||||
double num6 = p4.Y;
|
||||
if ((x == num && y == num2) || (num3 == num5 && num4 == num6))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ((x == num3 && y == num4) || (num == num3 && num2 == num4) || (x == num5 && y == num6) || (num == num5 && num2 == num6))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
num -= x;
|
||||
num2 -= y;
|
||||
num3 -= x;
|
||||
num4 -= y;
|
||||
num5 -= x;
|
||||
num6 -= y;
|
||||
double num7 = Math.Sqrt(num * num + num2 * num2);
|
||||
double num8 = num / num7;
|
||||
double num9 = num2 / num7;
|
||||
double num10 = num3 * num8 + num4 * num9;
|
||||
num4 = num4 * num8 - num3 * num9;
|
||||
num3 = num10;
|
||||
double num11 = num5 * num8 + num6 * num9;
|
||||
num6 = num6 * num8 - num5 * num9;
|
||||
num5 = num11;
|
||||
if ((num4 < 0.0 && num6 < 0.0) || (num4 >= 0.0 && num6 >= 0.0 && strictIntersect))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
double num12 = num5 + (num3 - num5) * num6 / (num6 - num4);
|
||||
if (num12 < 0.0 || (num12 > num7 && strictIntersect))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
p = new Point(x + num12 * num8, y + num12 * num9);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token: 0x0400008A RID: 138
|
||||
private Mesh mesh;
|
||||
|
||||
// Token: 0x0400008B RID: 139
|
||||
private Point[] points;
|
||||
|
||||
// Token: 0x0400008C RID: 140
|
||||
private List<VoronoiRegion> regions;
|
||||
|
||||
// Token: 0x0400008D RID: 141
|
||||
private List<Point> segPoints;
|
||||
|
||||
// Token: 0x0400008E RID: 142
|
||||
private int segIndex;
|
||||
|
||||
// Token: 0x0400008F RID: 143
|
||||
private Dictionary<int, Segment> subsegMap;
|
||||
|
||||
// Token: 0x04000090 RID: 144
|
||||
private bool includeBoundary = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,299 @@
|
||||
using System;
|
||||
using TriangleNet.Log;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000014 RID: 20
|
||||
public class CuthillMcKee
|
||||
{
|
||||
// Token: 0x060000AE RID: 174 RVA: 0x00012A2C File Offset: 0x00010C2C
|
||||
public int[] Renumber(Mesh mesh)
|
||||
{
|
||||
this.node_num = mesh.vertices.Count;
|
||||
mesh.Renumber(NodeNumbering.Linear);
|
||||
this.matrix = new AdjacencyMatrix(mesh);
|
||||
int num = this.matrix.Bandwidth();
|
||||
int[] array = this.GenerateRcm();
|
||||
int[] array2 = this.PermInverse(this.node_num, array);
|
||||
int num2 = this.PermBandwidth(array, array2);
|
||||
if (Behavior.Verbose)
|
||||
{
|
||||
SimpleLog.Instance.Info(string.Format("Reverse Cuthill-McKee (Bandwidth: {0} > {1})", num, num2));
|
||||
}
|
||||
return array2;
|
||||
}
|
||||
|
||||
// Token: 0x060000AF RID: 175 RVA: 0x00012AB0 File Offset: 0x00010CB0
|
||||
private int PermBandwidth(int[] perm, int[] perm_inv)
|
||||
{
|
||||
int[] adjacencyRow = this.matrix.AdjacencyRow;
|
||||
int[] adjacency = this.matrix.Adjacency;
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
for (int j = adjacencyRow[perm[i]]; j <= adjacencyRow[perm[i] + 1] - 1; j++)
|
||||
{
|
||||
int num3 = perm_inv[adjacency[j - 1]];
|
||||
num = Math.Max(num, i - num3);
|
||||
num2 = Math.Max(num2, num3 - i);
|
||||
}
|
||||
}
|
||||
return num + 1 + num2;
|
||||
}
|
||||
|
||||
// Token: 0x060000B0 RID: 176 RVA: 0x00012B30 File Offset: 0x00010D30
|
||||
private int[] GenerateRcm()
|
||||
{
|
||||
int[] array = new int[this.node_num];
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
int[] array2 = new int[this.node_num + 1];
|
||||
int[] array3 = new int[this.node_num];
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
array3[i] = 1;
|
||||
}
|
||||
int num3 = 1;
|
||||
for (int i = 0; i < this.node_num; i++)
|
||||
{
|
||||
if (array3[i] != 0)
|
||||
{
|
||||
int num4 = i;
|
||||
this.FindRoot(ref num4, array3, ref num2, array2, array, num3 - 1);
|
||||
this.Rcm(num4, array3, array, num3 - 1, ref num);
|
||||
num3 += num;
|
||||
if (this.node_num < num3)
|
||||
{
|
||||
return array;
|
||||
}
|
||||
}
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Token: 0x060000B1 RID: 177 RVA: 0x00012BD0 File Offset: 0x00010DD0
|
||||
private void Rcm(int root, int[] mask, int[] perm, int offset, ref int iccsze)
|
||||
{
|
||||
int[] adjacencyRow = this.matrix.AdjacencyRow;
|
||||
int[] adjacency = this.matrix.Adjacency;
|
||||
int[] array = new int[this.node_num];
|
||||
this.Degree(root, mask, array, ref iccsze, perm, offset);
|
||||
mask[root] = 0;
|
||||
if (iccsze <= 1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
int i = 0;
|
||||
int num = 1;
|
||||
while (i < num)
|
||||
{
|
||||
int num2 = i + 1;
|
||||
i = num;
|
||||
for (int j = num2; j <= i; j++)
|
||||
{
|
||||
int num3 = perm[offset + j - 1];
|
||||
int num4 = adjacencyRow[num3];
|
||||
int num5 = adjacencyRow[num3 + 1] - 1;
|
||||
int k = num + 1;
|
||||
for (int l = num4; l <= num5; l++)
|
||||
{
|
||||
int num6 = adjacency[l - 1];
|
||||
if (mask[num6] != 0)
|
||||
{
|
||||
num++;
|
||||
mask[num6] = 0;
|
||||
perm[offset + num - 1] = num6;
|
||||
}
|
||||
}
|
||||
if (num > k)
|
||||
{
|
||||
int m = k;
|
||||
while (m < num)
|
||||
{
|
||||
int num7 = m;
|
||||
m++;
|
||||
int num6 = perm[offset + m - 1];
|
||||
while (k < num7)
|
||||
{
|
||||
int num8 = perm[offset + num7 - 1];
|
||||
if (array[num8 - 1] <= array[num6 - 1])
|
||||
{
|
||||
break;
|
||||
}
|
||||
perm[offset + num7] = num8;
|
||||
num7--;
|
||||
}
|
||||
perm[offset + num7] = num6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
this.ReverseVector(perm, offset, iccsze);
|
||||
}
|
||||
|
||||
// Token: 0x060000B2 RID: 178 RVA: 0x00012D0C File Offset: 0x00010F0C
|
||||
private void FindRoot(ref int root, int[] mask, ref int level_num, int[] level_row, int[] level, int offset)
|
||||
{
|
||||
int[] adjacencyRow = this.matrix.AdjacencyRow;
|
||||
int[] adjacency = this.matrix.Adjacency;
|
||||
int num = 0;
|
||||
this.GetLevelSet(ref root, mask, ref level_num, level_row, level, offset);
|
||||
int num2 = level_row[level_num] - 1;
|
||||
if (level_num == 1 || level_num == num2)
|
||||
{
|
||||
return;
|
||||
}
|
||||
do
|
||||
{
|
||||
int num3 = num2;
|
||||
int num4 = level_row[level_num - 1];
|
||||
root = level[offset + num4 - 1];
|
||||
if (num4 < num2)
|
||||
{
|
||||
for (int i = num4; i <= num2; i++)
|
||||
{
|
||||
int num5 = level[offset + i - 1];
|
||||
int num6 = 0;
|
||||
int num7 = adjacencyRow[num5 - 1];
|
||||
int num8 = adjacencyRow[num5] - 1;
|
||||
for (int j = num7; j <= num8; j++)
|
||||
{
|
||||
int num9 = adjacency[j - 1];
|
||||
if (mask[num9] > 0)
|
||||
{
|
||||
num6++;
|
||||
}
|
||||
}
|
||||
if (num6 < num3)
|
||||
{
|
||||
root = num5;
|
||||
num3 = num6;
|
||||
}
|
||||
}
|
||||
}
|
||||
this.GetLevelSet(ref root, mask, ref num, level_row, level, offset);
|
||||
if (num <= level_num)
|
||||
{
|
||||
break;
|
||||
}
|
||||
level_num = num;
|
||||
}
|
||||
while (num2 > level_num);
|
||||
}
|
||||
|
||||
// Token: 0x060000B3 RID: 179 RVA: 0x00012DF8 File Offset: 0x00010FF8
|
||||
private void GetLevelSet(ref int root, int[] mask, ref int level_num, int[] level_row, int[] level, int offset)
|
||||
{
|
||||
int[] adjacencyRow = this.matrix.AdjacencyRow;
|
||||
int[] adjacency = this.matrix.Adjacency;
|
||||
mask[root] = 0;
|
||||
level[offset] = root;
|
||||
level_num = 0;
|
||||
int num = 0;
|
||||
int num2 = 1;
|
||||
do
|
||||
{
|
||||
int num3 = num + 1;
|
||||
num = num2;
|
||||
level_num++;
|
||||
level_row[level_num - 1] = num3;
|
||||
for (int i = num3; i <= num; i++)
|
||||
{
|
||||
int num4 = level[offset + i - 1];
|
||||
int num5 = adjacencyRow[num4];
|
||||
int num6 = adjacencyRow[num4 + 1] - 1;
|
||||
for (int j = num5; j <= num6; j++)
|
||||
{
|
||||
int num7 = adjacency[j - 1];
|
||||
if (mask[num7] != 0)
|
||||
{
|
||||
num2++;
|
||||
level[offset + num2 - 1] = num7;
|
||||
mask[num7] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
while (num2 - num > 0);
|
||||
level_row[level_num] = num + 1;
|
||||
for (int i = 0; i < num2; i++)
|
||||
{
|
||||
mask[level[offset + i]] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000B4 RID: 180 RVA: 0x00012ECC File Offset: 0x000110CC
|
||||
private void Degree(int root, int[] mask, int[] deg, ref int iccsze, int[] ls, int offset)
|
||||
{
|
||||
int[] adjacencyRow = this.matrix.AdjacencyRow;
|
||||
int[] adjacency = this.matrix.Adjacency;
|
||||
int i = 1;
|
||||
ls[offset] = root;
|
||||
adjacencyRow[root] = -adjacencyRow[root];
|
||||
int num = 0;
|
||||
iccsze = 1;
|
||||
while (i > 0)
|
||||
{
|
||||
int num2 = num + 1;
|
||||
num = iccsze;
|
||||
for (int j = num2; j <= num; j++)
|
||||
{
|
||||
int num3 = ls[offset + j - 1];
|
||||
int num4 = -adjacencyRow[num3];
|
||||
int num5 = Math.Abs(adjacencyRow[num3 + 1]) - 1;
|
||||
int num6 = 0;
|
||||
for (int k = num4; k <= num5; k++)
|
||||
{
|
||||
int num7 = adjacency[k - 1];
|
||||
if (mask[num7] != 0)
|
||||
{
|
||||
num6++;
|
||||
if (0 <= adjacencyRow[num7])
|
||||
{
|
||||
adjacencyRow[num7] = -adjacencyRow[num7];
|
||||
iccsze++;
|
||||
ls[offset + iccsze - 1] = num7;
|
||||
}
|
||||
}
|
||||
}
|
||||
deg[num3] = num6;
|
||||
}
|
||||
i = iccsze - num;
|
||||
}
|
||||
for (int j = 0; j < iccsze; j++)
|
||||
{
|
||||
int num3 = ls[offset + j];
|
||||
adjacencyRow[num3] = -adjacencyRow[num3];
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000B5 RID: 181 RVA: 0x00012FC0 File Offset: 0x000111C0
|
||||
private int[] PermInverse(int n, int[] perm)
|
||||
{
|
||||
int[] array = new int[this.node_num];
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
array[perm[i]] = i;
|
||||
}
|
||||
return array;
|
||||
}
|
||||
|
||||
// Token: 0x060000B6 RID: 182 RVA: 0x00012FEC File Offset: 0x000111EC
|
||||
private void ReverseVector(int[] a, int offset, int size)
|
||||
{
|
||||
for (int i = 0; i < size / 2; i++)
|
||||
{
|
||||
int num = a[offset + i];
|
||||
a[offset + i] = a[offset + size - 1 - i];
|
||||
a[offset + size - 1 - i] = num;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x04000091 RID: 145
|
||||
private int node_num;
|
||||
|
||||
// Token: 0x04000092 RID: 146
|
||||
private AdjacencyMatrix matrix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000015 RID: 21
|
||||
public interface IVoronoi
|
||||
{
|
||||
// Token: 0x17000022 RID: 34
|
||||
// (get) Token: 0x060000B8 RID: 184
|
||||
Point[] Points { get; }
|
||||
|
||||
// Token: 0x17000023 RID: 35
|
||||
// (get) Token: 0x060000B9 RID: 185
|
||||
ICollection<VoronoiRegion> Regions { get; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,272 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000017 RID: 23
|
||||
internal class QuadNode
|
||||
{
|
||||
// Token: 0x060000BF RID: 191 RVA: 0x0001322D File Offset: 0x0001142D
|
||||
public QuadNode(BoundingBox box, QuadTree tree)
|
||||
: this(box, tree, false)
|
||||
{
|
||||
}
|
||||
|
||||
// Token: 0x060000C0 RID: 192 RVA: 0x00013238 File Offset: 0x00011438
|
||||
public QuadNode(BoundingBox box, QuadTree tree, bool init)
|
||||
{
|
||||
this.tree = tree;
|
||||
this.bounds = new BoundingBox(box.MinX, box.MinY, box.MaxX, box.MaxY);
|
||||
this.pivot = new Point((box.MinX + box.MaxX) / 2.0, (box.MinY + box.MaxY) / 2.0);
|
||||
this.bitRegions = 0;
|
||||
this.regions = new QuadNode[4];
|
||||
this.triangles = new List<int>();
|
||||
if (init)
|
||||
{
|
||||
int num = tree.triangles.Length;
|
||||
this.triangles.Capacity = num;
|
||||
for (int i = 0; i < num; i++)
|
||||
{
|
||||
this.triangles.Add(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C1 RID: 193 RVA: 0x000132FC File Offset: 0x000114FC
|
||||
public List<int> FindTriangles(Point searchPoint)
|
||||
{
|
||||
int num = this.FindRegion(searchPoint);
|
||||
if (this.regions[num] == null)
|
||||
{
|
||||
return this.triangles;
|
||||
}
|
||||
return this.regions[num].FindTriangles(searchPoint);
|
||||
}
|
||||
|
||||
// Token: 0x060000C2 RID: 194 RVA: 0x00013330 File Offset: 0x00011530
|
||||
public void CreateSubRegion(int currentDepth)
|
||||
{
|
||||
BoundingBox boundingBox = new BoundingBox(this.bounds.MinX, this.bounds.MinY, this.pivot.X, this.pivot.Y);
|
||||
this.regions[0] = new QuadNode(boundingBox, this.tree);
|
||||
boundingBox = new BoundingBox(this.pivot.X, this.bounds.MinY, this.bounds.MaxX, this.pivot.Y);
|
||||
this.regions[1] = new QuadNode(boundingBox, this.tree);
|
||||
boundingBox = new BoundingBox(this.bounds.MinX, this.pivot.Y, this.pivot.X, this.bounds.MaxY);
|
||||
this.regions[2] = new QuadNode(boundingBox, this.tree);
|
||||
boundingBox = new BoundingBox(this.pivot.X, this.pivot.Y, this.bounds.MaxX, this.bounds.MaxY);
|
||||
this.regions[3] = new QuadNode(boundingBox, this.tree);
|
||||
Point[] array = new Point[3];
|
||||
foreach (int num in this.triangles)
|
||||
{
|
||||
ITriangle triangle = this.tree.triangles[num];
|
||||
array[0] = triangle.GetVertex(0);
|
||||
array[1] = triangle.GetVertex(1);
|
||||
array[2] = triangle.GetVertex(2);
|
||||
this.AddTriangleToRegion(array, num);
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
if (this.regions[i].triangles.Count > this.tree.sizeBound && currentDepth < this.tree.maxDepth)
|
||||
{
|
||||
this.regions[i].CreateSubRegion(currentDepth + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C3 RID: 195 RVA: 0x00013524 File Offset: 0x00011724
|
||||
private void AddTriangleToRegion(Point[] triangle, int index)
|
||||
{
|
||||
this.bitRegions = 0;
|
||||
if (QuadTree.IsPointInTriangle(this.pivot, triangle[0], triangle[1], triangle[2]))
|
||||
{
|
||||
this.AddToRegion(index, 0);
|
||||
this.AddToRegion(index, 1);
|
||||
this.AddToRegion(index, 2);
|
||||
this.AddToRegion(index, 3);
|
||||
return;
|
||||
}
|
||||
this.FindTriangleIntersections(triangle, index);
|
||||
if (this.bitRegions == 0)
|
||||
{
|
||||
int num = this.FindRegion(triangle[0]);
|
||||
this.regions[num].triangles.Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C4 RID: 196 RVA: 0x0001359C File Offset: 0x0001179C
|
||||
private void FindTriangleIntersections(Point[] triangle, int index)
|
||||
{
|
||||
int num = 2;
|
||||
int i = 0;
|
||||
while (i < 3)
|
||||
{
|
||||
double num2 = triangle[i].X - triangle[num].X;
|
||||
double num3 = triangle[i].Y - triangle[num].Y;
|
||||
if (num2 != 0.0)
|
||||
{
|
||||
this.FindIntersectionsWithX(num2, num3, triangle, index, num);
|
||||
}
|
||||
if (num3 != 0.0)
|
||||
{
|
||||
this.FindIntersectionsWithY(num2, num3, triangle, index, num);
|
||||
}
|
||||
num = i++;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C5 RID: 197 RVA: 0x0001360C File Offset: 0x0001180C
|
||||
private void FindIntersectionsWithX(double dx, double dy, Point[] triangle, int index, int k)
|
||||
{
|
||||
double num = (this.pivot.X - triangle[k].X) / dx;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num2 = triangle[k].Y + num * dy;
|
||||
if (num2 < this.pivot.Y && num2 >= this.bounds.MinY)
|
||||
{
|
||||
this.AddToRegion(index, 0);
|
||||
this.AddToRegion(index, 1);
|
||||
}
|
||||
else if (num2 <= this.bounds.MaxY)
|
||||
{
|
||||
this.AddToRegion(index, 2);
|
||||
this.AddToRegion(index, 3);
|
||||
}
|
||||
}
|
||||
num = (this.bounds.MinX - triangle[k].X) / dx;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num3 = triangle[k].Y + num * dy;
|
||||
if (num3 < this.pivot.Y && num3 >= this.bounds.MinY)
|
||||
{
|
||||
this.AddToRegion(index, 0);
|
||||
}
|
||||
else if (num3 <= this.bounds.MaxY)
|
||||
{
|
||||
this.AddToRegion(index, 2);
|
||||
}
|
||||
}
|
||||
num = (this.bounds.MaxX - triangle[k].X) / dx;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num4 = triangle[k].Y + num * dy;
|
||||
if (num4 < this.pivot.Y && num4 >= this.bounds.MinY)
|
||||
{
|
||||
this.AddToRegion(index, 1);
|
||||
return;
|
||||
}
|
||||
if (num4 <= this.bounds.MaxY)
|
||||
{
|
||||
this.AddToRegion(index, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C6 RID: 198 RVA: 0x000137A0 File Offset: 0x000119A0
|
||||
private void FindIntersectionsWithY(double dx, double dy, Point[] triangle, int index, int k)
|
||||
{
|
||||
double num = (this.pivot.Y - triangle[k].Y) / dy;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num2 = triangle[k].X + num * dx;
|
||||
if (num2 > this.pivot.X && num2 <= this.bounds.MaxX)
|
||||
{
|
||||
this.AddToRegion(index, 1);
|
||||
this.AddToRegion(index, 3);
|
||||
}
|
||||
else if (num2 >= this.bounds.MinX)
|
||||
{
|
||||
this.AddToRegion(index, 0);
|
||||
this.AddToRegion(index, 2);
|
||||
}
|
||||
}
|
||||
num = (this.bounds.MinY - triangle[k].Y) / dy;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num2 = triangle[k].X + num * dx;
|
||||
if (num2 > this.pivot.X && num2 <= this.bounds.MaxX)
|
||||
{
|
||||
this.AddToRegion(index, 1);
|
||||
}
|
||||
else if (num2 >= this.bounds.MinX)
|
||||
{
|
||||
this.AddToRegion(index, 0);
|
||||
}
|
||||
}
|
||||
num = (this.bounds.MaxY - triangle[k].Y) / dy;
|
||||
if (num < 1.000001 && num > -1E-06)
|
||||
{
|
||||
double num2 = triangle[k].X + num * dx;
|
||||
if (num2 > this.pivot.X && num2 <= this.bounds.MaxX)
|
||||
{
|
||||
this.AddToRegion(index, 3);
|
||||
return;
|
||||
}
|
||||
if (num2 >= this.bounds.MinX)
|
||||
{
|
||||
this.AddToRegion(index, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000C7 RID: 199 RVA: 0x00013934 File Offset: 0x00011B34
|
||||
private int FindRegion(Point point)
|
||||
{
|
||||
int num = 2;
|
||||
if (point.Y < this.pivot.Y)
|
||||
{
|
||||
num = 0;
|
||||
}
|
||||
if (point.X > this.pivot.X)
|
||||
{
|
||||
num++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// Token: 0x060000C8 RID: 200 RVA: 0x00013970 File Offset: 0x00011B70
|
||||
private void AddToRegion(int index, int region)
|
||||
{
|
||||
if ((this.bitRegions & QuadNode.BITVECTOR[region]) == 0)
|
||||
{
|
||||
this.regions[region].triangles.Add(index);
|
||||
this.bitRegions |= QuadNode.BITVECTOR[region];
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x04000097 RID: 151
|
||||
private const int SW = 0;
|
||||
|
||||
// Token: 0x04000098 RID: 152
|
||||
private const int SE = 1;
|
||||
|
||||
// Token: 0x04000099 RID: 153
|
||||
private const int NW = 2;
|
||||
|
||||
// Token: 0x0400009A RID: 154
|
||||
private const int NE = 3;
|
||||
|
||||
// Token: 0x0400009B RID: 155
|
||||
private const double EPS = 1E-06;
|
||||
|
||||
// Token: 0x0400009C RID: 156
|
||||
private static readonly byte[] BITVECTOR = new byte[] { 1, 2, 4, 8 };
|
||||
|
||||
// Token: 0x0400009D RID: 157
|
||||
private BoundingBox bounds;
|
||||
|
||||
// Token: 0x0400009E RID: 158
|
||||
private Point pivot;
|
||||
|
||||
// Token: 0x0400009F RID: 159
|
||||
private QuadTree tree;
|
||||
|
||||
// Token: 0x040000A0 RID: 160
|
||||
private QuadNode[] regions;
|
||||
|
||||
// Token: 0x040000A1 RID: 161
|
||||
private List<int> triangles;
|
||||
|
||||
// Token: 0x040000A2 RID: 162
|
||||
private byte bitRegions;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000016 RID: 22
|
||||
public class QuadTree
|
||||
{
|
||||
// Token: 0x060000BA RID: 186 RVA: 0x00013030 File Offset: 0x00011230
|
||||
public QuadTree(Mesh mesh, int maxDepth, int sizeBound)
|
||||
{
|
||||
this.maxDepth = maxDepth;
|
||||
this.sizeBound = sizeBound;
|
||||
this.triangles = mesh.Triangles.ToArray<Triangle>();
|
||||
int num = 0;
|
||||
this.root = new QuadNode(mesh.Bounds, this, true);
|
||||
this.root.CreateSubRegion(num + 1);
|
||||
}
|
||||
|
||||
// Token: 0x060000BB RID: 187 RVA: 0x00013087 File Offset: 0x00011287
|
||||
public QuadTree(Mesh mesh)
|
||||
: this(mesh, 10, 10)
|
||||
{
|
||||
}
|
||||
|
||||
// Token: 0x060000BC RID: 188 RVA: 0x00013094 File Offset: 0x00011294
|
||||
public ITriangle Query(double x, double y)
|
||||
{
|
||||
Point point = new Point(x, y);
|
||||
List<int> list = this.root.FindTriangles(point);
|
||||
List<ITriangle> list2 = new List<ITriangle>();
|
||||
foreach (int num in list)
|
||||
{
|
||||
ITriangle triangle = this.triangles[num];
|
||||
if (QuadTree.IsPointInTriangle(point, triangle.GetVertex(0), triangle.GetVertex(1), triangle.GetVertex(2)))
|
||||
{
|
||||
list2.Add(triangle);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return list2.FirstOrDefault<ITriangle>();
|
||||
}
|
||||
|
||||
// Token: 0x060000BD RID: 189 RVA: 0x00013130 File Offset: 0x00011330
|
||||
internal static bool IsPointInTriangle(Point p, Point t0, Point t1, Point t2)
|
||||
{
|
||||
Point point = new Point(t1.X - t0.X, t1.Y - t0.Y);
|
||||
Point point2 = new Point(t2.X - t0.X, t2.Y - t0.Y);
|
||||
Point point3 = new Point(p.X - t0.X, p.Y - t0.Y);
|
||||
Point point4 = new Point(-point.Y, point.X);
|
||||
Point point5 = new Point(-point2.Y, point2.X);
|
||||
double num = QuadTree.DotProduct(point3, point5) / QuadTree.DotProduct(point, point5);
|
||||
double num2 = QuadTree.DotProduct(point3, point4) / QuadTree.DotProduct(point2, point4);
|
||||
return num >= 0.0 && num2 >= 0.0 && num + num2 <= 1.0;
|
||||
}
|
||||
|
||||
// Token: 0x060000BE RID: 190 RVA: 0x00013210 File Offset: 0x00011410
|
||||
internal static double DotProduct(Point p, Point q)
|
||||
{
|
||||
return p.X * q.X + p.Y * q.Y;
|
||||
}
|
||||
|
||||
// Token: 0x04000093 RID: 147
|
||||
private QuadNode root;
|
||||
|
||||
// Token: 0x04000094 RID: 148
|
||||
internal ITriangle[] triangles;
|
||||
|
||||
// Token: 0x04000095 RID: 149
|
||||
internal int sizeBound;
|
||||
|
||||
// Token: 0x04000096 RID: 150
|
||||
internal int maxDepth;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,408 @@
|
||||
using System;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000018 RID: 24
|
||||
public class QualityMeasure
|
||||
{
|
||||
// Token: 0x060000CA RID: 202 RVA: 0x000139C2 File Offset: 0x00011BC2
|
||||
public QualityMeasure()
|
||||
{
|
||||
this.areaMeasure = new QualityMeasure.AreaMeasure();
|
||||
this.alphaMeasure = new QualityMeasure.AlphaMeasure();
|
||||
this.qMeasure = new QualityMeasure.Q_Measure();
|
||||
}
|
||||
|
||||
// Token: 0x17000024 RID: 36
|
||||
// (get) Token: 0x060000CB RID: 203 RVA: 0x000139EB File Offset: 0x00011BEB
|
||||
public double AreaMinimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.areaMeasure.area_min;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000025 RID: 37
|
||||
// (get) Token: 0x060000CC RID: 204 RVA: 0x000139F8 File Offset: 0x00011BF8
|
||||
public double AreaMaximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.areaMeasure.area_max;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000026 RID: 38
|
||||
// (get) Token: 0x060000CD RID: 205 RVA: 0x00013A05 File Offset: 0x00011C05
|
||||
public double AreaRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.areaMeasure.area_max / this.areaMeasure.area_min;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000027 RID: 39
|
||||
// (get) Token: 0x060000CE RID: 206 RVA: 0x00013A1E File Offset: 0x00011C1E
|
||||
public double AlphaMinimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.alphaMeasure.alpha_min;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000028 RID: 40
|
||||
// (get) Token: 0x060000CF RID: 207 RVA: 0x00013A2B File Offset: 0x00011C2B
|
||||
public double AlphaMaximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.alphaMeasure.alpha_max;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000029 RID: 41
|
||||
// (get) Token: 0x060000D0 RID: 208 RVA: 0x00013A38 File Offset: 0x00011C38
|
||||
public double AlphaAverage
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.alphaMeasure.alpha_ave;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700002A RID: 42
|
||||
// (get) Token: 0x060000D1 RID: 209 RVA: 0x00013A45 File Offset: 0x00011C45
|
||||
public double AlphaArea
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.alphaMeasure.alpha_area;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700002B RID: 43
|
||||
// (get) Token: 0x060000D2 RID: 210 RVA: 0x00013A52 File Offset: 0x00011C52
|
||||
public double Q_Minimum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.qMeasure.q_min;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700002C RID: 44
|
||||
// (get) Token: 0x060000D3 RID: 211 RVA: 0x00013A5F File Offset: 0x00011C5F
|
||||
public double Q_Maximum
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.qMeasure.q_max;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700002D RID: 45
|
||||
// (get) Token: 0x060000D4 RID: 212 RVA: 0x00013A6C File Offset: 0x00011C6C
|
||||
public double Q_Average
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.qMeasure.q_ave;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700002E RID: 46
|
||||
// (get) Token: 0x060000D5 RID: 213 RVA: 0x00013A79 File Offset: 0x00011C79
|
||||
public double Q_Area
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.qMeasure.q_area;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000D6 RID: 214 RVA: 0x00013A86 File Offset: 0x00011C86
|
||||
public void Update(Mesh mesh)
|
||||
{
|
||||
this.mesh = mesh;
|
||||
this.areaMeasure.Reset();
|
||||
this.alphaMeasure.Reset();
|
||||
this.qMeasure.Reset();
|
||||
this.Compute();
|
||||
}
|
||||
|
||||
// Token: 0x060000D7 RID: 215 RVA: 0x00013AB8 File Offset: 0x00011CB8
|
||||
private void Compute()
|
||||
{
|
||||
int num = 0;
|
||||
foreach (Triangle triangle in this.mesh.triangles.Values)
|
||||
{
|
||||
num++;
|
||||
Point point = triangle.vertices[0];
|
||||
Point point2 = triangle.vertices[1];
|
||||
Point point3 = triangle.vertices[2];
|
||||
double num2 = point.x - point2.x;
|
||||
double num3 = point.y - point2.y;
|
||||
double num4 = Math.Sqrt(num2 * num2 + num3 * num3);
|
||||
double num5 = point2.x - point3.x;
|
||||
num3 = point2.y - point3.y;
|
||||
double num6 = Math.Sqrt(num5 * num5 + num3 * num3);
|
||||
double num7 = point3.x - point.x;
|
||||
num3 = point3.y - point.y;
|
||||
double num8 = Math.Sqrt(num7 * num7 + num3 * num3);
|
||||
double num9 = this.areaMeasure.Measure(point, point2, point3);
|
||||
this.alphaMeasure.Measure(num4, num6, num8, num9);
|
||||
this.qMeasure.Measure(num4, num6, num8, num9);
|
||||
}
|
||||
this.alphaMeasure.Normalize(num, this.areaMeasure.area_total);
|
||||
this.qMeasure.Normalize(num, this.areaMeasure.area_total);
|
||||
}
|
||||
|
||||
// Token: 0x060000D8 RID: 216 RVA: 0x00013C20 File Offset: 0x00011E20
|
||||
public int Bandwidth()
|
||||
{
|
||||
if (this.mesh == null)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int num = 0;
|
||||
int num2 = 0;
|
||||
foreach (Triangle triangle in this.mesh.triangles.Values)
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int id = triangle.GetVertex(i).id;
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
int id2 = triangle.GetVertex(j).id;
|
||||
num2 = Math.Max(num2, id2 - id);
|
||||
num = Math.Max(num, id - id2);
|
||||
}
|
||||
}
|
||||
}
|
||||
return num + 1 + num2;
|
||||
}
|
||||
|
||||
// Token: 0x040000A3 RID: 163
|
||||
private QualityMeasure.AreaMeasure areaMeasure;
|
||||
|
||||
// Token: 0x040000A4 RID: 164
|
||||
private QualityMeasure.AlphaMeasure alphaMeasure;
|
||||
|
||||
// Token: 0x040000A5 RID: 165
|
||||
private QualityMeasure.Q_Measure qMeasure;
|
||||
|
||||
// Token: 0x040000A6 RID: 166
|
||||
private Mesh mesh;
|
||||
|
||||
// Token: 0x02000041 RID: 65
|
||||
private class AreaMeasure
|
||||
{
|
||||
// Token: 0x06000246 RID: 582 RVA: 0x0001B9BC File Offset: 0x00019BBC
|
||||
public void Reset()
|
||||
{
|
||||
this.area_min = double.MaxValue;
|
||||
this.area_max = double.MinValue;
|
||||
this.area_total = 0.0;
|
||||
this.area_zero = 0;
|
||||
}
|
||||
|
||||
// Token: 0x06000247 RID: 583 RVA: 0x0001B9F4 File Offset: 0x00019BF4
|
||||
public double Measure(Point a, Point b, Point c)
|
||||
{
|
||||
double num = 0.5 * Math.Abs(a.x * (b.y - c.y) + b.x * (c.y - a.y) + c.x * (a.y - b.y));
|
||||
this.area_min = Math.Min(this.area_min, num);
|
||||
this.area_max = Math.Max(this.area_max, num);
|
||||
this.area_total += num;
|
||||
if (num == 0.0)
|
||||
{
|
||||
this.area_zero++;
|
||||
}
|
||||
return num;
|
||||
}
|
||||
|
||||
// Token: 0x0400013D RID: 317
|
||||
public double area_min = double.MaxValue;
|
||||
|
||||
// Token: 0x0400013E RID: 318
|
||||
public double area_max = double.MinValue;
|
||||
|
||||
// Token: 0x0400013F RID: 319
|
||||
public double area_total;
|
||||
|
||||
// Token: 0x04000140 RID: 320
|
||||
public int area_zero;
|
||||
}
|
||||
|
||||
// Token: 0x02000042 RID: 66
|
||||
private class AlphaMeasure
|
||||
{
|
||||
// Token: 0x06000249 RID: 585 RVA: 0x0001BAC2 File Offset: 0x00019CC2
|
||||
public void Reset()
|
||||
{
|
||||
this.alpha_min = double.MaxValue;
|
||||
this.alpha_max = double.MinValue;
|
||||
this.alpha_ave = 0.0;
|
||||
this.alpha_area = 0.0;
|
||||
}
|
||||
|
||||
// Token: 0x0600024A RID: 586 RVA: 0x0001BB00 File Offset: 0x00019D00
|
||||
private double acos(double c)
|
||||
{
|
||||
if (c <= -1.0)
|
||||
{
|
||||
return 3.141592653589793;
|
||||
}
|
||||
if (1.0 <= c)
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
return Math.Acos(c);
|
||||
}
|
||||
|
||||
// Token: 0x0600024B RID: 587 RVA: 0x0001BB34 File Offset: 0x00019D34
|
||||
public double Measure(double ab, double bc, double ca, double area)
|
||||
{
|
||||
double num = double.MaxValue;
|
||||
double num2 = ab * ab;
|
||||
double num3 = bc * bc;
|
||||
double num4 = ca * ca;
|
||||
double num5;
|
||||
double num6;
|
||||
double num7;
|
||||
if (ab == 0.0 && bc == 0.0 && ca == 0.0)
|
||||
{
|
||||
num5 = 2.0943951023931953;
|
||||
num6 = 2.0943951023931953;
|
||||
num7 = 2.0943951023931953;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ca == 0.0 || ab == 0.0)
|
||||
{
|
||||
num5 = 3.141592653589793;
|
||||
}
|
||||
else
|
||||
{
|
||||
num5 = this.acos((num4 + num2 - num3) / (2.0 * ca * ab));
|
||||
}
|
||||
if (ab == 0.0 || bc == 0.0)
|
||||
{
|
||||
num6 = 3.141592653589793;
|
||||
}
|
||||
else
|
||||
{
|
||||
num6 = this.acos((num2 + num3 - num4) / (2.0 * ab * bc));
|
||||
}
|
||||
if (bc == 0.0 || ca == 0.0)
|
||||
{
|
||||
num7 = 3.141592653589793;
|
||||
}
|
||||
else
|
||||
{
|
||||
num7 = this.acos((num3 + num4 - num2) / (2.0 * bc * ca));
|
||||
}
|
||||
}
|
||||
num = Math.Min(num, num5);
|
||||
num = Math.Min(num, num6);
|
||||
num = Math.Min(num, num7);
|
||||
num = num * 3.0 / 3.141592653589793;
|
||||
this.alpha_ave += num;
|
||||
this.alpha_area += area * num;
|
||||
this.alpha_min = Math.Min(num, this.alpha_min);
|
||||
this.alpha_max = Math.Max(num, this.alpha_max);
|
||||
return num;
|
||||
}
|
||||
|
||||
// Token: 0x0600024C RID: 588 RVA: 0x0001BCD8 File Offset: 0x00019ED8
|
||||
public void Normalize(int n, double area_total)
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
this.alpha_ave /= (double)n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alpha_ave = 0.0;
|
||||
}
|
||||
if (0.0 < area_total)
|
||||
{
|
||||
this.alpha_area /= area_total;
|
||||
return;
|
||||
}
|
||||
this.alpha_area = 0.0;
|
||||
}
|
||||
|
||||
// Token: 0x04000141 RID: 321
|
||||
public double alpha_min;
|
||||
|
||||
// Token: 0x04000142 RID: 322
|
||||
public double alpha_max;
|
||||
|
||||
// Token: 0x04000143 RID: 323
|
||||
public double alpha_ave;
|
||||
|
||||
// Token: 0x04000144 RID: 324
|
||||
public double alpha_area;
|
||||
}
|
||||
|
||||
// Token: 0x02000043 RID: 67
|
||||
private class Q_Measure
|
||||
{
|
||||
// Token: 0x0600024E RID: 590 RVA: 0x0001BD33 File Offset: 0x00019F33
|
||||
public void Reset()
|
||||
{
|
||||
this.q_min = double.MaxValue;
|
||||
this.q_max = double.MinValue;
|
||||
this.q_ave = 0.0;
|
||||
this.q_area = 0.0;
|
||||
}
|
||||
|
||||
// Token: 0x0600024F RID: 591 RVA: 0x0001BD74 File Offset: 0x00019F74
|
||||
public double Measure(double ab, double bc, double ca, double area)
|
||||
{
|
||||
double num = (bc + ca - ab) * (ca + ab - bc) * (ab + bc - ca) / (ab * bc * ca);
|
||||
this.q_min = Math.Min(this.q_min, num);
|
||||
this.q_max = Math.Max(this.q_max, num);
|
||||
this.q_ave += num;
|
||||
this.q_area += num * area;
|
||||
return num;
|
||||
}
|
||||
|
||||
// Token: 0x06000250 RID: 592 RVA: 0x0001BDE0 File Offset: 0x00019FE0
|
||||
public void Normalize(int n, double area_total)
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
this.q_ave /= (double)n;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.q_ave = 0.0;
|
||||
}
|
||||
if (area_total > 0.0)
|
||||
{
|
||||
this.q_area /= area_total;
|
||||
return;
|
||||
}
|
||||
this.q_area = 0.0;
|
||||
}
|
||||
|
||||
// Token: 0x04000145 RID: 325
|
||||
public double q_min;
|
||||
|
||||
// Token: 0x04000146 RID: 326
|
||||
public double q_max;
|
||||
|
||||
// Token: 0x04000147 RID: 327
|
||||
public double q_ave;
|
||||
|
||||
// Token: 0x04000148 RID: 328
|
||||
public double q_area;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Data;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x02000019 RID: 25
|
||||
public class RegionIterator
|
||||
{
|
||||
// Token: 0x060000D9 RID: 217 RVA: 0x00013CE0 File Offset: 0x00011EE0
|
||||
public RegionIterator(Mesh mesh)
|
||||
{
|
||||
this.mesh = mesh;
|
||||
this.viri = new List<Triangle>();
|
||||
}
|
||||
|
||||
// Token: 0x060000DA RID: 218 RVA: 0x00013CFC File Offset: 0x00011EFC
|
||||
private void ProcessRegion(Action<Triangle> func)
|
||||
{
|
||||
Otri otri = default(Otri);
|
||||
Otri otri2 = default(Otri);
|
||||
Osub osub = default(Osub);
|
||||
Behavior behavior = this.mesh.behavior;
|
||||
for (int i = 0; i < this.viri.Count; i++)
|
||||
{
|
||||
otri.triangle = this.viri[i];
|
||||
otri.Uninfect();
|
||||
func(otri.triangle);
|
||||
otri.orient = 0;
|
||||
while (otri.orient < 3)
|
||||
{
|
||||
otri.Sym(ref otri2);
|
||||
otri.SegPivot(ref osub);
|
||||
if (otri2.triangle != Mesh.dummytri && !otri2.IsInfected() && osub.seg == Mesh.dummysub)
|
||||
{
|
||||
otri2.Infect();
|
||||
this.viri.Add(otri2.triangle);
|
||||
}
|
||||
otri.orient++;
|
||||
}
|
||||
otri.Infect();
|
||||
}
|
||||
foreach (Triangle triangle in this.viri)
|
||||
{
|
||||
triangle.infected = false;
|
||||
}
|
||||
this.viri.Clear();
|
||||
}
|
||||
|
||||
// Token: 0x060000DB RID: 219 RVA: 0x00013E34 File Offset: 0x00012034
|
||||
public void Process(Triangle triangle)
|
||||
{
|
||||
this.Process(triangle, delegate(Triangle tri)
|
||||
{
|
||||
tri.region = triangle.region;
|
||||
});
|
||||
}
|
||||
|
||||
// Token: 0x060000DC RID: 220 RVA: 0x00013E66 File Offset: 0x00012066
|
||||
public void Process(Triangle triangle, Action<Triangle> func)
|
||||
{
|
||||
if (triangle != Mesh.dummytri && !Otri.IsDead(triangle))
|
||||
{
|
||||
triangle.infected = true;
|
||||
this.viri.Add(triangle);
|
||||
this.ProcessRegion(func);
|
||||
}
|
||||
this.viri.Clear();
|
||||
}
|
||||
|
||||
// Token: 0x040000A7 RID: 167
|
||||
private Mesh mesh;
|
||||
|
||||
// Token: 0x040000A8 RID: 168
|
||||
private List<Triangle> viri;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,568 @@
|
||||
using System;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x0200001A RID: 26
|
||||
public class Statistic
|
||||
{
|
||||
// Token: 0x1700002F RID: 47
|
||||
// (get) Token: 0x060000DD RID: 221 RVA: 0x00013E9D File Offset: 0x0001209D
|
||||
public double ShortestEdge
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.minEdge;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000030 RID: 48
|
||||
// (get) Token: 0x060000DE RID: 222 RVA: 0x00013EA5 File Offset: 0x000120A5
|
||||
public double LongestEdge
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxEdge;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000031 RID: 49
|
||||
// (get) Token: 0x060000DF RID: 223 RVA: 0x00013EAD File Offset: 0x000120AD
|
||||
public double ShortestAltitude
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.minAspect;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000032 RID: 50
|
||||
// (get) Token: 0x060000E0 RID: 224 RVA: 0x00013EB5 File Offset: 0x000120B5
|
||||
public double LargestAspectRatio
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxAspect;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000033 RID: 51
|
||||
// (get) Token: 0x060000E1 RID: 225 RVA: 0x00013EBD File Offset: 0x000120BD
|
||||
public double SmallestArea
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.minArea;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000034 RID: 52
|
||||
// (get) Token: 0x060000E2 RID: 226 RVA: 0x00013EC5 File Offset: 0x000120C5
|
||||
public double LargestArea
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxArea;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000035 RID: 53
|
||||
// (get) Token: 0x060000E3 RID: 227 RVA: 0x00013ECD File Offset: 0x000120CD
|
||||
public double SmallestAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.minAngle;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000036 RID: 54
|
||||
// (get) Token: 0x060000E4 RID: 228 RVA: 0x00013ED5 File Offset: 0x000120D5
|
||||
public double LargestAngle
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxAngle;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000037 RID: 55
|
||||
// (get) Token: 0x060000E5 RID: 229 RVA: 0x00013EDD File Offset: 0x000120DD
|
||||
public int InputVertices
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.inVetrices;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000038 RID: 56
|
||||
// (get) Token: 0x060000E6 RID: 230 RVA: 0x00013EE5 File Offset: 0x000120E5
|
||||
public int InputTriangles
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.inTriangles;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000039 RID: 57
|
||||
// (get) Token: 0x060000E7 RID: 231 RVA: 0x00013EED File Offset: 0x000120ED
|
||||
public int InputSegments
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.inSegments;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003A RID: 58
|
||||
// (get) Token: 0x060000E8 RID: 232 RVA: 0x00013EF5 File Offset: 0x000120F5
|
||||
public int InputHoles
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.inHoles;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003B RID: 59
|
||||
// (get) Token: 0x060000E9 RID: 233 RVA: 0x00013EFD File Offset: 0x000120FD
|
||||
public int Vertices
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.outVertices;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003C RID: 60
|
||||
// (get) Token: 0x060000EA RID: 234 RVA: 0x00013F05 File Offset: 0x00012105
|
||||
public int Triangles
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.outTriangles;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003D RID: 61
|
||||
// (get) Token: 0x060000EB RID: 235 RVA: 0x00013F0D File Offset: 0x0001210D
|
||||
public int Edges
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.outEdges;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003E RID: 62
|
||||
// (get) Token: 0x060000EC RID: 236 RVA: 0x00013F15 File Offset: 0x00012115
|
||||
public int BoundaryEdges
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.boundaryEdges;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x1700003F RID: 63
|
||||
// (get) Token: 0x060000ED RID: 237 RVA: 0x00013F1D File Offset: 0x0001211D
|
||||
public int InteriorBoundaryEdges
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.intBoundaryEdges;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000040 RID: 64
|
||||
// (get) Token: 0x060000EE RID: 238 RVA: 0x00013F25 File Offset: 0x00012125
|
||||
public int ConstrainedEdges
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.constrainedEdges;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000041 RID: 65
|
||||
// (get) Token: 0x060000EF RID: 239 RVA: 0x00013F2D File Offset: 0x0001212D
|
||||
public int[] AngleHistogram
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.angleTable;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000042 RID: 66
|
||||
// (get) Token: 0x060000F0 RID: 240 RVA: 0x00013F35 File Offset: 0x00012135
|
||||
public int[] MinAngleHistogram
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.minAngles;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000043 RID: 67
|
||||
// (get) Token: 0x060000F1 RID: 241 RVA: 0x00013F3D File Offset: 0x0001213D
|
||||
public int[] MaxAngleHistogram
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.maxAngles;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000F2 RID: 242 RVA: 0x00013F48 File Offset: 0x00012148
|
||||
private void GetAspectHistogram(Mesh mesh)
|
||||
{
|
||||
int[] array = new int[16];
|
||||
double[] array2 = new double[]
|
||||
{
|
||||
1.5, 2.0, 2.5, 3.0, 4.0, 6.0, 10.0, 15.0, 25.0, 50.0,
|
||||
100.0, 300.0, 1000.0, 10000.0, 100000.0, 0.0
|
||||
};
|
||||
Otri otri = default(Otri);
|
||||
Vertex[] array3 = new Vertex[3];
|
||||
double[] array4 = new double[3];
|
||||
double[] array5 = new double[3];
|
||||
double[] array6 = new double[3];
|
||||
otri.orient = 0;
|
||||
foreach (Triangle triangle in mesh.triangles.Values)
|
||||
{
|
||||
otri.triangle = triangle;
|
||||
array3[0] = otri.Org();
|
||||
array3[1] = otri.Dest();
|
||||
array3[2] = otri.Apex();
|
||||
double num = 0.0;
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
int num2 = Statistic.plus1Mod3[i];
|
||||
int num3 = Statistic.minus1Mod3[i];
|
||||
array4[i] = array3[num2].x - array3[num3].x;
|
||||
array5[i] = array3[num2].y - array3[num3].y;
|
||||
array6[i] = array4[i] * array4[i] + array5[i] * array5[i];
|
||||
if (array6[i] > num)
|
||||
{
|
||||
num = array6[i];
|
||||
}
|
||||
}
|
||||
double num4 = Math.Abs((array3[2].x - array3[0].x) * (array3[1].y - array3[0].y) - (array3[1].x - array3[0].x) * (array3[2].y - array3[0].y)) / 2.0;
|
||||
double num5 = num4 * num4 / num;
|
||||
double num6 = num / num5;
|
||||
int num7 = 0;
|
||||
while (num6 > array2[num7] * array2[num7] && num7 < 15)
|
||||
{
|
||||
num7++;
|
||||
}
|
||||
array[num7]++;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000F3 RID: 243 RVA: 0x00014138 File Offset: 0x00012338
|
||||
public void Update(Mesh mesh, int sampleDegrees)
|
||||
{
|
||||
this.inVetrices = mesh.invertices;
|
||||
this.inTriangles = mesh.inelements;
|
||||
this.inSegments = mesh.insegments;
|
||||
this.inHoles = mesh.holes.Count;
|
||||
this.outVertices = mesh.vertices.Count - mesh.undeads;
|
||||
this.outTriangles = mesh.triangles.Count;
|
||||
this.outEdges = mesh.edges;
|
||||
this.boundaryEdges = mesh.hullsize;
|
||||
this.intBoundaryEdges = mesh.subsegs.Count - mesh.hullsize;
|
||||
this.constrainedEdges = mesh.subsegs.Count;
|
||||
Point[] array = new Point[3];
|
||||
sampleDegrees = 60;
|
||||
double[] array2 = new double[sampleDegrees / 2 - 1];
|
||||
double[] array3 = new double[3];
|
||||
double[] array4 = new double[3];
|
||||
double[] array5 = new double[3];
|
||||
double num = 3.141592653589793 / (double)sampleDegrees;
|
||||
double num2 = 57.29577951308232;
|
||||
this.angleTable = new int[sampleDegrees];
|
||||
this.minAngles = new int[sampleDegrees];
|
||||
this.maxAngles = new int[sampleDegrees];
|
||||
for (int i = 0; i < sampleDegrees / 2 - 1; i++)
|
||||
{
|
||||
array2[i] = Math.Cos(num * (double)(i + 1));
|
||||
array2[i] *= array2[i];
|
||||
}
|
||||
for (int j = 0; j < sampleDegrees; j++)
|
||||
{
|
||||
this.angleTable[j] = 0;
|
||||
}
|
||||
this.minAspect = mesh.bounds.Width + mesh.bounds.Height;
|
||||
this.minAspect *= this.minAspect;
|
||||
this.maxAspect = 0.0;
|
||||
this.minEdge = this.minAspect;
|
||||
this.maxEdge = 0.0;
|
||||
this.minArea = this.minAspect;
|
||||
this.maxArea = 0.0;
|
||||
this.minAngle = 0.0;
|
||||
this.maxAngle = 2.0;
|
||||
bool flag = true;
|
||||
bool flag2 = true;
|
||||
foreach (Triangle triangle in mesh.triangles.Values)
|
||||
{
|
||||
double num3 = 0.0;
|
||||
double num4 = 1.0;
|
||||
array[0] = triangle.vertices[0];
|
||||
array[1] = triangle.vertices[1];
|
||||
array[2] = triangle.vertices[2];
|
||||
double num5 = 0.0;
|
||||
for (int k = 0; k < 3; k++)
|
||||
{
|
||||
int num6 = Statistic.plus1Mod3[k];
|
||||
int num7 = Statistic.minus1Mod3[k];
|
||||
array3[k] = array[num6].X - array[num7].X;
|
||||
array4[k] = array[num6].Y - array[num7].Y;
|
||||
array5[k] = array3[k] * array3[k] + array4[k] * array4[k];
|
||||
if (array5[k] > num5)
|
||||
{
|
||||
num5 = array5[k];
|
||||
}
|
||||
if (array5[k] > this.maxEdge)
|
||||
{
|
||||
this.maxEdge = array5[k];
|
||||
}
|
||||
if (array5[k] < this.minEdge)
|
||||
{
|
||||
this.minEdge = array5[k];
|
||||
}
|
||||
}
|
||||
double num8 = Math.Abs((array[2].X - array[0].X) * (array[1].Y - array[0].Y) - (array[1].X - array[0].X) * (array[2].Y - array[0].Y));
|
||||
if (num8 < this.minArea)
|
||||
{
|
||||
this.minArea = num8;
|
||||
}
|
||||
if (num8 > this.maxArea)
|
||||
{
|
||||
this.maxArea = num8;
|
||||
}
|
||||
double num9 = num8 * num8 / num5;
|
||||
if (num9 < this.minAspect)
|
||||
{
|
||||
this.minAspect = num9;
|
||||
}
|
||||
double num10 = num5 / num9;
|
||||
if (num10 > this.maxAspect)
|
||||
{
|
||||
this.maxAspect = num10;
|
||||
}
|
||||
int num13;
|
||||
for (int l = 0; l < 3; l++)
|
||||
{
|
||||
int num6 = Statistic.plus1Mod3[l];
|
||||
int num7 = Statistic.minus1Mod3[l];
|
||||
double num11 = array3[num6] * array3[num7] + array4[num6] * array4[num7];
|
||||
double num12 = num11 * num11 / (array5[num6] * array5[num7]);
|
||||
num13 = sampleDegrees / 2 - 1;
|
||||
for (int m = num13 - 1; m >= 0; m--)
|
||||
{
|
||||
if (num12 > array2[m])
|
||||
{
|
||||
num13 = m;
|
||||
}
|
||||
}
|
||||
if (num11 <= 0.0)
|
||||
{
|
||||
this.angleTable[num13]++;
|
||||
if (num12 > this.minAngle)
|
||||
{
|
||||
this.minAngle = num12;
|
||||
}
|
||||
if (flag && num12 < this.maxAngle)
|
||||
{
|
||||
this.maxAngle = num12;
|
||||
}
|
||||
if (num12 > num3)
|
||||
{
|
||||
num3 = num12;
|
||||
}
|
||||
if (flag2 && num12 < num4)
|
||||
{
|
||||
num4 = num12;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.angleTable[sampleDegrees - num13 - 1]++;
|
||||
if (flag || num12 > this.maxAngle)
|
||||
{
|
||||
this.maxAngle = num12;
|
||||
flag = false;
|
||||
}
|
||||
if (flag2 || num12 > num4)
|
||||
{
|
||||
num4 = num12;
|
||||
flag2 = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
num13 = sampleDegrees / 2 - 1;
|
||||
for (int n = num13 - 1; n >= 0; n--)
|
||||
{
|
||||
if (num3 > array2[n])
|
||||
{
|
||||
num13 = n;
|
||||
}
|
||||
}
|
||||
this.minAngles[num13]++;
|
||||
num13 = sampleDegrees / 2 - 1;
|
||||
for (int num14 = num13 - 1; num14 >= 0; num14--)
|
||||
{
|
||||
if (num4 > array2[num14])
|
||||
{
|
||||
num13 = num14;
|
||||
}
|
||||
}
|
||||
if (flag2)
|
||||
{
|
||||
this.maxAngles[num13]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.maxAngles[sampleDegrees - num13 - 1]++;
|
||||
}
|
||||
flag2 = true;
|
||||
}
|
||||
this.minEdge = Math.Sqrt(this.minEdge);
|
||||
this.maxEdge = Math.Sqrt(this.maxEdge);
|
||||
this.minAspect = Math.Sqrt(this.minAspect);
|
||||
this.maxAspect = Math.Sqrt(this.maxAspect);
|
||||
this.minArea *= 0.5;
|
||||
this.maxArea *= 0.5;
|
||||
if (this.minAngle >= 1.0)
|
||||
{
|
||||
this.minAngle = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.minAngle = num2 * Math.Acos(Math.Sqrt(this.minAngle));
|
||||
}
|
||||
if (this.maxAngle >= 1.0)
|
||||
{
|
||||
this.maxAngle = 180.0;
|
||||
return;
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
this.maxAngle = num2 * Math.Acos(Math.Sqrt(this.maxAngle));
|
||||
return;
|
||||
}
|
||||
this.maxAngle = 180.0 - num2 * Math.Acos(Math.Sqrt(this.maxAngle));
|
||||
}
|
||||
|
||||
// Token: 0x060000F5 RID: 245 RVA: 0x000147E0 File Offset: 0x000129E0
|
||||
// Note: this type is marked as 'beforefieldinit'.
|
||||
static Statistic()
|
||||
{
|
||||
int[] array = new int[3];
|
||||
array[0] = 1;
|
||||
array[1] = 2;
|
||||
Statistic.plus1Mod3 = array;
|
||||
Statistic.minus1Mod3 = new int[] { 2, 0, 1 };
|
||||
}
|
||||
|
||||
// Token: 0x040000A9 RID: 169
|
||||
public static long InCircleCount = 0L;
|
||||
|
||||
// Token: 0x040000AA RID: 170
|
||||
public static long InCircleAdaptCount = 0L;
|
||||
|
||||
// Token: 0x040000AB RID: 171
|
||||
public static long CounterClockwiseCount = 0L;
|
||||
|
||||
// Token: 0x040000AC RID: 172
|
||||
public static long CounterClockwiseAdaptCount = 0L;
|
||||
|
||||
// Token: 0x040000AD RID: 173
|
||||
public static long Orient3dCount = 0L;
|
||||
|
||||
// Token: 0x040000AE RID: 174
|
||||
public static long HyperbolaCount = 0L;
|
||||
|
||||
// Token: 0x040000AF RID: 175
|
||||
public static long CircumcenterCount = 0L;
|
||||
|
||||
// Token: 0x040000B0 RID: 176
|
||||
public static long CircleTopCount = 0L;
|
||||
|
||||
// Token: 0x040000B1 RID: 177
|
||||
public static long RelocationCount = 0L;
|
||||
|
||||
// Token: 0x040000B2 RID: 178
|
||||
private double minEdge;
|
||||
|
||||
// Token: 0x040000B3 RID: 179
|
||||
private double maxEdge;
|
||||
|
||||
// Token: 0x040000B4 RID: 180
|
||||
private double minAspect;
|
||||
|
||||
// Token: 0x040000B5 RID: 181
|
||||
private double maxAspect;
|
||||
|
||||
// Token: 0x040000B6 RID: 182
|
||||
private double minArea;
|
||||
|
||||
// Token: 0x040000B7 RID: 183
|
||||
private double maxArea;
|
||||
|
||||
// Token: 0x040000B8 RID: 184
|
||||
private double minAngle;
|
||||
|
||||
// Token: 0x040000B9 RID: 185
|
||||
private double maxAngle;
|
||||
|
||||
// Token: 0x040000BA RID: 186
|
||||
private int inVetrices;
|
||||
|
||||
// Token: 0x040000BB RID: 187
|
||||
private int inTriangles;
|
||||
|
||||
// Token: 0x040000BC RID: 188
|
||||
private int inSegments;
|
||||
|
||||
// Token: 0x040000BD RID: 189
|
||||
private int inHoles;
|
||||
|
||||
// Token: 0x040000BE RID: 190
|
||||
private int outVertices;
|
||||
|
||||
// Token: 0x040000BF RID: 191
|
||||
private int outTriangles;
|
||||
|
||||
// Token: 0x040000C0 RID: 192
|
||||
private int outEdges;
|
||||
|
||||
// Token: 0x040000C1 RID: 193
|
||||
private int boundaryEdges;
|
||||
|
||||
// Token: 0x040000C2 RID: 194
|
||||
private int intBoundaryEdges;
|
||||
|
||||
// Token: 0x040000C3 RID: 195
|
||||
private int constrainedEdges;
|
||||
|
||||
// Token: 0x040000C4 RID: 196
|
||||
private int[] angleTable;
|
||||
|
||||
// Token: 0x040000C5 RID: 197
|
||||
private int[] minAngles;
|
||||
|
||||
// Token: 0x040000C6 RID: 198
|
||||
private int[] maxAngles;
|
||||
|
||||
// Token: 0x040000C7 RID: 199
|
||||
private static readonly int[] plus1Mod3;
|
||||
|
||||
// Token: 0x040000C8 RID: 200
|
||||
private static readonly int[] minus1Mod3;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x0200001B RID: 27
|
||||
public class Voronoi : IVoronoi
|
||||
{
|
||||
// Token: 0x060000F6 RID: 246 RVA: 0x00014852 File Offset: 0x00012A52
|
||||
public Voronoi(Mesh mesh)
|
||||
{
|
||||
this.mesh = mesh;
|
||||
this.Generate();
|
||||
}
|
||||
|
||||
// Token: 0x17000044 RID: 68
|
||||
// (get) Token: 0x060000F7 RID: 247 RVA: 0x00014867 File Offset: 0x00012A67
|
||||
public Point[] Points
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.points;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000045 RID: 69
|
||||
// (get) Token: 0x060000F8 RID: 248 RVA: 0x0001486F File Offset: 0x00012A6F
|
||||
public ICollection<VoronoiRegion> Regions
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.regions.Values;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000F9 RID: 249 RVA: 0x0001487C File Offset: 0x00012A7C
|
||||
private void Generate()
|
||||
{
|
||||
this.mesh.Renumber();
|
||||
this.mesh.MakeVertexMap();
|
||||
this.points = new Point[this.mesh.triangles.Count + this.mesh.hullsize];
|
||||
this.regions = new Dictionary<int, VoronoiRegion>(this.mesh.vertices.Count);
|
||||
this.rayPoints = new Dictionary<int, Point>();
|
||||
this.rayIndex = 0;
|
||||
this.bounds = new BoundingBox();
|
||||
this.ComputeCircumCenters();
|
||||
foreach (Vertex vertex in this.mesh.vertices.Values)
|
||||
{
|
||||
this.regions.Add(vertex.id, new VoronoiRegion(vertex));
|
||||
}
|
||||
foreach (VoronoiRegion voronoiRegion in this.regions.Values)
|
||||
{
|
||||
this.ConstructVoronoiRegion(voronoiRegion);
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x060000FA RID: 250 RVA: 0x000149AC File Offset: 0x00012BAC
|
||||
private void ComputeCircumCenters()
|
||||
{
|
||||
Otri otri = default(Otri);
|
||||
double num = 0.0;
|
||||
double num2 = 0.0;
|
||||
foreach (Triangle triangle in this.mesh.triangles.Values)
|
||||
{
|
||||
otri.triangle = triangle;
|
||||
Point point = Primitives.FindCircumcenter(otri.Org(), otri.Dest(), otri.Apex(), ref num, ref num2);
|
||||
point.id = triangle.id;
|
||||
this.points[triangle.id] = point;
|
||||
this.bounds.Expand(point.x, point.y);
|
||||
}
|
||||
double num3 = Math.Max(this.bounds.Width, this.bounds.Height);
|
||||
this.bounds.Resize(num3, num3);
|
||||
}
|
||||
|
||||
// Token: 0x060000FB RID: 251 RVA: 0x00014AA8 File Offset: 0x00012CA8
|
||||
private void ConstructVoronoiRegion(VoronoiRegion region)
|
||||
{
|
||||
Vertex vertex = region.Generator as Vertex;
|
||||
List<Point> list = new List<Point>();
|
||||
Otri otri = default(Otri);
|
||||
Otri otri2 = default(Otri);
|
||||
Otri otri3 = default(Otri);
|
||||
Otri otri4 = default(Otri);
|
||||
Osub osub = default(Osub);
|
||||
vertex.tri.Copy(ref otri2);
|
||||
otri2.Copy(ref otri);
|
||||
otri2.Onext(ref otri3);
|
||||
if (otri3.triangle == Mesh.dummytri)
|
||||
{
|
||||
otri2.Oprev(ref otri4);
|
||||
if (otri4.triangle != Mesh.dummytri)
|
||||
{
|
||||
otri2.Copy(ref otri3);
|
||||
otri2.OprevSelf();
|
||||
otri2.Copy(ref otri);
|
||||
}
|
||||
}
|
||||
while (otri3.triangle != Mesh.dummytri)
|
||||
{
|
||||
list.Add(this.points[otri.triangle.id]);
|
||||
region.AddNeighbor(otri.triangle.id, this.regions[otri.Apex().id]);
|
||||
if (otri3.Equal(otri2))
|
||||
{
|
||||
region.Add(list);
|
||||
return;
|
||||
}
|
||||
otri3.Copy(ref otri);
|
||||
otri3.OnextSelf();
|
||||
}
|
||||
region.Bounded = false;
|
||||
int count = this.mesh.triangles.Count;
|
||||
otri.Lprev(ref otri3);
|
||||
otri3.SegPivot(ref osub);
|
||||
int num = osub.seg.hash;
|
||||
list.Add(this.points[otri.triangle.id]);
|
||||
region.AddNeighbor(otri.triangle.id, this.regions[otri.Apex().id]);
|
||||
Point point;
|
||||
if (!this.rayPoints.TryGetValue(num, out point))
|
||||
{
|
||||
Vertex vertex2 = otri.Org();
|
||||
Vertex vertex3 = otri.Apex();
|
||||
this.BoxRayIntersection(this.points[otri.triangle.id], vertex2.y - vertex3.y, vertex3.x - vertex2.x, out point);
|
||||
point.id = count + this.rayIndex;
|
||||
this.points[count + this.rayIndex] = point;
|
||||
this.rayIndex++;
|
||||
this.rayPoints.Add(num, point);
|
||||
}
|
||||
list.Add(point);
|
||||
list.Reverse();
|
||||
otri2.Copy(ref otri);
|
||||
otri.Oprev(ref otri4);
|
||||
while (otri4.triangle != Mesh.dummytri)
|
||||
{
|
||||
list.Add(this.points[otri4.triangle.id]);
|
||||
region.AddNeighbor(otri4.triangle.id, this.regions[otri4.Apex().id]);
|
||||
otri4.Copy(ref otri);
|
||||
otri4.OprevSelf();
|
||||
}
|
||||
otri.SegPivot(ref osub);
|
||||
num = osub.seg.hash;
|
||||
if (!this.rayPoints.TryGetValue(num, out point))
|
||||
{
|
||||
Vertex vertex2 = otri.Org();
|
||||
Vertex vertex4 = otri.Dest();
|
||||
this.BoxRayIntersection(this.points[otri.triangle.id], vertex4.y - vertex2.y, vertex2.x - vertex4.x, out point);
|
||||
point.id = count + this.rayIndex;
|
||||
this.rayPoints.Add(num, point);
|
||||
this.points[count + this.rayIndex] = point;
|
||||
this.rayIndex++;
|
||||
}
|
||||
list.Add(point);
|
||||
region.AddNeighbor(point.id, this.regions[otri.Dest().id]);
|
||||
list.Reverse();
|
||||
region.Add(list);
|
||||
}
|
||||
|
||||
// Token: 0x060000FC RID: 252 RVA: 0x00014E44 File Offset: 0x00013044
|
||||
private bool BoxRayIntersection(Point pt, double dx, double dy, out Point intersect)
|
||||
{
|
||||
double x = pt.X;
|
||||
double y = pt.Y;
|
||||
double minX = this.bounds.MinX;
|
||||
double maxX = this.bounds.MaxX;
|
||||
double minY = this.bounds.MinY;
|
||||
double maxY = this.bounds.MaxY;
|
||||
if (x < minX || x > maxX || y < minY || y > maxY)
|
||||
{
|
||||
intersect = null;
|
||||
return false;
|
||||
}
|
||||
double num;
|
||||
double num2;
|
||||
double num3;
|
||||
if (dx < 0.0)
|
||||
{
|
||||
num = (minX - x) / dx;
|
||||
num2 = minX;
|
||||
num3 = y + num * dy;
|
||||
}
|
||||
else if (dx > 0.0)
|
||||
{
|
||||
num = (maxX - x) / dx;
|
||||
num2 = maxX;
|
||||
num3 = y + num * dy;
|
||||
}
|
||||
else
|
||||
{
|
||||
num = double.MaxValue;
|
||||
num3 = (num2 = 0.0);
|
||||
}
|
||||
double num4;
|
||||
double num5;
|
||||
double num6;
|
||||
if (dy < 0.0)
|
||||
{
|
||||
num4 = (minY - y) / dy;
|
||||
num5 = x + num4 * dx;
|
||||
num6 = minY;
|
||||
}
|
||||
else if (dy > 0.0)
|
||||
{
|
||||
num4 = (maxY - y) / dy;
|
||||
num5 = x + num4 * dx;
|
||||
num6 = maxY;
|
||||
}
|
||||
else
|
||||
{
|
||||
num4 = double.MaxValue;
|
||||
num6 = (num5 = 0.0);
|
||||
}
|
||||
if (num < num4)
|
||||
{
|
||||
intersect = new Point(num2, num3);
|
||||
}
|
||||
else
|
||||
{
|
||||
intersect = new Point(num5, num6);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Token: 0x040000C9 RID: 201
|
||||
private Mesh mesh;
|
||||
|
||||
// Token: 0x040000CA RID: 202
|
||||
private Point[] points;
|
||||
|
||||
// Token: 0x040000CB RID: 203
|
||||
private Dictionary<int, VoronoiRegion> regions;
|
||||
|
||||
// Token: 0x040000CC RID: 204
|
||||
private Dictionary<int, Point> rayPoints;
|
||||
|
||||
// Token: 0x040000CD RID: 205
|
||||
private int rayIndex;
|
||||
|
||||
// Token: 0x040000CE RID: 206
|
||||
private BoundingBox bounds;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using TriangleNet.Data;
|
||||
using TriangleNet.Geometry;
|
||||
|
||||
namespace TriangleNet.Tools
|
||||
{
|
||||
// Token: 0x0200001C RID: 28
|
||||
public class VoronoiRegion
|
||||
{
|
||||
// Token: 0x17000046 RID: 70
|
||||
// (get) Token: 0x060000FD RID: 253 RVA: 0x00014F7E File Offset: 0x0001317E
|
||||
public int ID
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.id;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000047 RID: 71
|
||||
// (get) Token: 0x060000FE RID: 254 RVA: 0x00014F86 File Offset: 0x00013186
|
||||
public Point Generator
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.generator;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000048 RID: 72
|
||||
// (get) Token: 0x060000FF RID: 255 RVA: 0x00014F8E File Offset: 0x0001318E
|
||||
public ICollection<Point> Vertices
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.vertices;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x17000049 RID: 73
|
||||
// (get) Token: 0x06000100 RID: 256 RVA: 0x00014F96 File Offset: 0x00013196
|
||||
// (set) Token: 0x06000101 RID: 257 RVA: 0x00014F9E File Offset: 0x0001319E
|
||||
public bool Bounded
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.bounded;
|
||||
}
|
||||
set
|
||||
{
|
||||
this.bounded = value;
|
||||
}
|
||||
}
|
||||
|
||||
// Token: 0x06000102 RID: 258 RVA: 0x00014FA7 File Offset: 0x000131A7
|
||||
public VoronoiRegion(Vertex generator)
|
||||
{
|
||||
this.id = generator.id;
|
||||
this.generator = generator;
|
||||
this.vertices = new List<Point>();
|
||||
this.bounded = true;
|
||||
this.neighbors = new Dictionary<int, VoronoiRegion>();
|
||||
}
|
||||
|
||||
// Token: 0x06000103 RID: 259 RVA: 0x00014FDF File Offset: 0x000131DF
|
||||
public void Add(Point point)
|
||||
{
|
||||
this.vertices.Add(point);
|
||||
}
|
||||
|
||||
// Token: 0x06000104 RID: 260 RVA: 0x00014FED File Offset: 0x000131ED
|
||||
public void Add(List<Point> points)
|
||||
{
|
||||
this.vertices.AddRange(points);
|
||||
}
|
||||
|
||||
// Token: 0x06000105 RID: 261 RVA: 0x00014FFC File Offset: 0x000131FC
|
||||
public VoronoiRegion GetNeighbor(Point p)
|
||||
{
|
||||
VoronoiRegion voronoiRegion;
|
||||
if (this.neighbors.TryGetValue(p.id, out voronoiRegion))
|
||||
{
|
||||
return voronoiRegion;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Token: 0x06000106 RID: 262 RVA: 0x00015021 File Offset: 0x00013221
|
||||
internal void AddNeighbor(int id, VoronoiRegion neighbor)
|
||||
{
|
||||
this.neighbors.Add(id, neighbor);
|
||||
}
|
||||
|
||||
// Token: 0x06000107 RID: 263 RVA: 0x00015030 File Offset: 0x00013230
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("R-ID {0}", this.id);
|
||||
}
|
||||
|
||||
// Token: 0x040000CF RID: 207
|
||||
private int id;
|
||||
|
||||
// Token: 0x040000D0 RID: 208
|
||||
private Point generator;
|
||||
|
||||
// Token: 0x040000D1 RID: 209
|
||||
private List<Point> vertices;
|
||||
|
||||
// Token: 0x040000D2 RID: 210
|
||||
private bool bounded;
|
||||
|
||||
// Token: 0x040000D3 RID: 211
|
||||
private Dictionary<int, VoronoiRegion> neighbors;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user