Files
2026-06-04 11:42:34 +02:00

232 lines
8.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using ProBuilder2.Common;
using UnityEngine;
namespace ProBuilder2.MeshOperations
{
// Token: 0x02000008 RID: 8
public static class pb_AppendPolygon
{
// Token: 0x0600005A RID: 90 RVA: 0x0000873C File Offset: 0x00006B3C
public static pb_ActionResult CreatePolygon(this pb_Object pb, IList<int> indices, bool unordered, out pb_Face face)
{
pb_IntArray[] sharedIndices = pb.sharedIndices;
Dictionary<int, int> dictionary = sharedIndices.ToDictionary();
HashSet<int> commonIndices = pb_IntArrayUtility.GetCommonIndices(dictionary, indices);
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
List<pb_Vertex> list2 = new List<pb_Vertex>();
foreach (int num in commonIndices)
{
int num2 = sharedIndices[num][0];
list2.Add(new pb_Vertex(list[num2]));
}
pb_FaceRebuildData pb_FaceRebuildData = pb_AppendPolygon.FaceWithVertices(list2, unordered);
if (pb_FaceRebuildData != null)
{
pb_FaceRebuildData.sharedIndices = commonIndices.ToList<int>();
List<pb_Face> list3 = new List<pb_Face>(pb.faces);
pb_FaceRebuildData.Apply(new pb_FaceRebuildData[] { pb_FaceRebuildData }, list, list3, dictionary, null);
pb.SetVertices(list, false);
pb.SetFaces(list3.ToArray());
pb.SetSharedIndices(dictionary);
face = pb_FaceRebuildData.face;
return new pb_ActionResult(Status.Success, "Create Polygon");
}
face = null;
return new pb_ActionResult(Status.Failure, (!unordered) ? "Points not ordered correctly" : "Too Few Unique Points Selected");
}
// Token: 0x0600005B RID: 91 RVA: 0x00008868 File Offset: 0x00006C68
public static pb_ActionResult CreateShapeFromPolygon(this pb_PolyShape poly)
{
return poly.mesh.CreateShapeFromPolygon(poly.points, poly.extrude, poly.flipNormals);
}
// Token: 0x0600005C RID: 92 RVA: 0x00008888 File Offset: 0x00006C88
public static pb_ActionResult CreateShapeFromPolygon(this pb_Object pb, IList<Vector3> points, float extrude, bool flipNormals)
{
if (points.Count < 3)
{
pb.SetVertices(new Vector3[0]);
pb.SetFaces(new pb_Face[0]);
pb.SetSharedIndices(new pb_IntArray[0]);
return new pb_ActionResult(Status.NoChange, "Too Few Points");
}
Vector3[] array = points.ToArray<Vector3>();
pb_Log.PushLogLevel(pb_LogLevel.Error);
List<int> list;
if (!pb_Triangulation.TriangulateVertices(array, out list, false, false))
{
pb_Log.PopLogLevel();
return new pb_ActionResult(Status.Failure, "Failed Triangulating Points");
}
int[] array2 = list.ToArray();
if (pb_Math.PolygonArea(array, array2) < Mathf.Epsilon)
{
pb.SetVertices(new Vector3[0]);
pb.SetFaces(new pb_Face[0]);
pb.SetSharedIndices(new pb_IntArray[0]);
pb_Log.PopLogLevel();
return new pb_ActionResult(Status.Failure, "Polygon Area < Epsilon");
}
pb.GeometryWithVerticesFaces(array, new pb_Face[]
{
new pb_Face(array2)
});
Vector3 vector = pb_Math.Normal(pb, pb.faces[0]);
if (Vector3.Dot(Vector3.up, vector) > 0f)
{
pb.faces[0].ReverseIndices();
}
pb.DuplicateAndFlip(pb.faces);
pb.Extrude(new pb_Face[] { pb.faces[1] }, ExtrudeMethod.IndividualFaces, extrude);
if ((extrude < 0f && !flipNormals) || (extrude > 0f && flipNormals))
{
pb.ReverseWindingOrder(pb.faces);
}
pb_Log.PopLogLevel();
pb.ToMesh();
pb.Refresh(RefreshMask.All);
return new pb_ActionResult(Status.Success, "Create Polygon Shape");
}
// Token: 0x0600005D RID: 93 RVA: 0x00008A0C File Offset: 0x00006E0C
public static pb_FaceRebuildData FaceWithVertices(List<pb_Vertex> vertices, bool unordered = true)
{
List<int> list;
if (pb_Triangulation.TriangulateVertices(vertices, out list, unordered, false))
{
return new pb_FaceRebuildData
{
vertices = vertices,
face = new pb_Face(list.ToArray())
};
}
return null;
}
// Token: 0x0600005E RID: 94 RVA: 0x00008A4C File Offset: 0x00006E4C
public static List<pb_FaceRebuildData> TentCapWithVertices(List<pb_Vertex> path)
{
int count = path.Count;
pb_Vertex pb_Vertex = pb_Vertex.Average(path, null);
List<pb_FaceRebuildData> list = new List<pb_FaceRebuildData>();
for (int i = 0; i < count; i++)
{
List<pb_Vertex> list2 = new List<pb_Vertex>
{
path[i],
pb_Vertex,
path[(i + 1) % count]
};
list.Add(new pb_FaceRebuildData
{
vertices = list2,
face = new pb_Face(new int[] { 0, 1, 2 })
});
}
return list;
}
// Token: 0x0600005F RID: 95 RVA: 0x00008AE8 File Offset: 0x00006EE8
public static List<List<pb_Edge>> FindHoles(pb_Object pb, IList<int> indices)
{
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
HashSet<int> commonIndices = pb_IntArrayUtility.GetCommonIndices(dictionary, indices);
List<List<pb_Edge>> list = new List<List<pb_Edge>>();
List<pb_WingedEdge> wingedEdges = pb_WingedEdge.GetWingedEdges(pb, false);
foreach (List<pb_WingedEdge> list2 in pb_AppendPolygon.FindHoles(wingedEdges, commonIndices))
{
list.Add(list2.Select((pb_WingedEdge x) => x.edge.local).ToList<pb_Edge>());
}
return list;
}
// Token: 0x06000060 RID: 96 RVA: 0x00008B94 File Offset: 0x00006F94
public static List<List<pb_WingedEdge>> FindHoles(List<pb_WingedEdge> wings, HashSet<int> common)
{
HashSet<pb_WingedEdge> hashSet = new HashSet<pb_WingedEdge>();
List<List<pb_WingedEdge>> list = new List<List<pb_WingedEdge>>();
for (int i = 0; i < wings.Count; i++)
{
pb_WingedEdge pb_WingedEdge = wings[i];
if (pb_WingedEdge.opposite == null && !hashSet.Contains(pb_WingedEdge) && (common.Contains(pb_WingedEdge.edge.common.x) || common.Contains(pb_WingedEdge.edge.common.y)))
{
List<pb_WingedEdge> list2 = new List<pb_WingedEdge>();
pb_WingedEdge pb_WingedEdge2 = pb_WingedEdge;
int num = pb_WingedEdge2.edge.common.x;
int num2 = 0;
while (pb_WingedEdge2 != null && num2++ < 2048)
{
hashSet.Add(pb_WingedEdge2);
list2.Add(pb_WingedEdge2);
num = ((pb_WingedEdge2.edge.common.x != num) ? pb_WingedEdge2.edge.common.x : pb_WingedEdge2.edge.common.y);
pb_WingedEdge2 = pb_AppendPolygon.FindNextEdgeInHole(pb_WingedEdge2, num);
if (pb_WingedEdge2 == pb_WingedEdge)
{
break;
}
}
List<pb_Tuple<int, int>> list3 = new List<pb_Tuple<int, int>>();
for (int j = 0; j < list2.Count; j++)
{
pb_WingedEdge pb_WingedEdge3 = list2[j];
for (int k = j - 1; k > -1; k--)
{
if (pb_WingedEdge3.edge.common.y == list2[k].edge.common.x)
{
list3.Add(new pb_Tuple<int, int>(k, j));
break;
}
}
}
int count = list3.Count;
list3.Sort((pb_Tuple<int, int> x, pb_Tuple<int, int> y) => x.Item1.CompareTo(y.Item1));
int[] array = new int[count];
for (int l = count - 1; l > -1; l--)
{
int item = list3[l].Item1;
int num3 = list3[l].Item2 - array[l];
int num4 = num3 - item + 1;
List<pb_WingedEdge> range = list2.GetRange(item, num4);
list2.RemoveRange(item, num4);
for (int m = l - 1; m > -1; m--)
{
if (list3[m].Item2 > list3[l].Item2)
{
array[m] += num4;
}
}
if (count < 2 || range.Any((pb_WingedEdge w) => common.Contains(w.edge.common.x)) || range.Any((pb_WingedEdge w) => common.Contains(w.edge.common.y)))
{
list.Add(range);
}
}
}
}
return list;
}
// Token: 0x06000061 RID: 97 RVA: 0x00008E90 File Offset: 0x00007290
private static pb_WingedEdge FindNextEdgeInHole(pb_WingedEdge wing, int common)
{
pb_WingedEdge pb_WingedEdge = wing.GetAdjacentEdgeWithCommonIndex(common);
int num = 0;
while (pb_WingedEdge != null && pb_WingedEdge != wing && num++ < 2048)
{
if (pb_WingedEdge.opposite == null)
{
return pb_WingedEdge;
}
pb_WingedEdge = pb_WingedEdge.opposite.GetAdjacentEdgeWithCommonIndex(common);
}
return null;
}
// Token: 0x04000014 RID: 20
private const int MAX_HOLE_ITERATIONS = 2048;
}
}