Files
Dec2017-Script-Dump/Triangle/Tools/BoundedVoronoi.cs
T
2026-06-04 11:42:34 +02:00

504 lines
14 KiB
C#

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;
}
}