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

388 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using ProBuilder2.Common;
using UnityEngine;
namespace ProBuilder2.MeshOperations
{
// Token: 0x02000006 RID: 6
public static class pbVertexOps
{
// Token: 0x06000047 RID: 71 RVA: 0x00007250 File Offset: 0x00005650
public static bool MergeVertices(this pb_Object pb, int[] indices, out int collapsedIndex, bool collapseToFirst = false)
{
pb_Vertex[] vertices = pb_Vertex.GetVertices(pb, null);
pb_Vertex pb_Vertex = ((!collapseToFirst) ? pb_Vertex.Average(vertices, indices) : vertices[indices[0]]);
pb_IntArray[] sharedIndices = pb.sharedIndices;
pb_IntArray[] sharedIndicesUV = pb.sharedIndicesUV;
int num = pb_IntArrayUtility.MergeSharedIndices(ref sharedIndices, indices);
pb_IntArrayUtility.MergeSharedIndices(ref sharedIndicesUV, indices);
pb.SetSharedIndices(sharedIndices);
pb.SetSharedIndicesUV(sharedIndicesUV);
pb.SetSharedVertexValues(num, pb_Vertex);
int[] array = pb.GetSharedIndices()[num].array;
int[] array2;
pb.RemoveDegenerateTriangles(out array2);
int num2 = -1;
for (int i = 0; i < array.Length; i++)
{
if (!array2.Contains(array[i]))
{
num2 = array[i];
}
}
int num3 = num2;
for (int j = 0; j < array2.Length; j++)
{
if (num2 > array2[j])
{
num3--;
}
}
if (num3 > -1)
{
collapsedIndex = num3;
return true;
}
collapsedIndex = -1;
return false;
}
// Token: 0x06000048 RID: 72 RVA: 0x00007344 File Offset: 0x00005744
public static bool SplitCommonVertices(this pb_Object pb, int[] indices)
{
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
pb_IntArray[] sharedIndices = pb.sharedIndices;
List<int> list = new List<int>();
List<int> list2 = new List<int>();
for (int i = 0; i < indices.Length; i++)
{
int num = dictionary[indices[i]];
if (!list.Contains(num))
{
list.Add(num);
list2.AddRange(sharedIndices[num].array);
}
}
pb_IntArrayUtility.RemoveValues(ref sharedIndices, list2.ToArray());
foreach (int num2 in list2)
{
pb_IntArrayUtility.AddValueAtIndex(ref sharedIndices, -1, num2);
}
pb.SetSharedIndices(sharedIndices);
return true;
}
// Token: 0x06000049 RID: 73 RVA: 0x00007420 File Offset: 0x00005820
public static void SplitVertices(this pb_Object pb, pb_Edge edge)
{
pb.SplitVertices(new int[] { edge.x, edge.y });
}
// Token: 0x0600004A RID: 74 RVA: 0x00007440 File Offset: 0x00005840
public static void SplitVertices(this pb_Object pb, IEnumerable<int> indices)
{
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
int num = dictionary.Count<KeyValuePair<int, int>>();
foreach (int num2 in indices)
{
num = (dictionary[num2] = num + 1);
}
pb.SetSharedIndices(dictionary);
}
// Token: 0x0600004B RID: 75 RVA: 0x000074B4 File Offset: 0x000058B4
public static bool AppendVerticesToFace(this pb_Object pb, pb_Face face, Vector3[] points, Color[] addColors, out pb_Face newFace)
{
if (!face.IsValid())
{
newFace = face;
return false;
}
List<pb_Vertex> list = pb_Vertex.GetVertices(pb, null).ToList<pb_Vertex>();
List<pb_Face> list2 = new List<pb_Face>(pb.faces);
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
Dictionary<int, int> dictionary2 = ((pb.sharedIndicesUV != null) ? pb.sharedIndicesUV.ToDictionary() : null);
List<pb_Edge> list3 = pb_WingedEdge.SortEdgesByAdjacency(face);
List<pb_Vertex> list4 = new List<pb_Vertex>();
List<int> list5 = new List<int>();
List<int> list6 = ((dictionary2 == null) ? null : new List<int>());
for (int i = 0; i < list3.Count; i++)
{
list4.Add(list[list3[i].x]);
list5.Add(dictionary[list3[i].x]);
if (dictionary2 != null)
{
int num;
if (dictionary2.TryGetValue(list3[i].x, out num))
{
list6.Add(num);
}
else
{
list6.Add(-1);
}
}
}
for (int j = 0; j < points.Length; j++)
{
int num2 = -1;
float num3 = float.PositiveInfinity;
Vector3 vector = points[j];
int count = list4.Count;
for (int k = 0; k < count; k++)
{
Vector3 position = list4[k].position;
Vector3 position2 = list4[(k + 1) % count].position;
float num4 = pb_Math.DistancePointLineSegment(vector, position, position2);
if (num4 < num3)
{
num3 = num4;
num2 = k;
}
}
pb_Vertex pb_Vertex = list4[num2];
pb_Vertex pb_Vertex2 = list4[(num2 + 1) % count];
float sqrMagnitude = (vector - pb_Vertex.position).sqrMagnitude;
float sqrMagnitude2 = (vector - pb_Vertex2.position).sqrMagnitude;
pb_Vertex pb_Vertex3 = pb_Vertex.Mix(pb_Vertex, pb_Vertex2, sqrMagnitude / (sqrMagnitude + sqrMagnitude2));
list4.Insert((num2 + 1) % count, pb_Vertex3);
list5.Insert((num2 + 1) % count, -1);
if (list6 != null)
{
list6.Insert((num2 + 1) % count, -1);
}
}
List<int> list7;
try
{
pb_Triangulation.TriangulateVertices(list4, out list7, false, false);
}
catch
{
Debug.Log("Failed triangulating face after appending vertices.");
newFace = null;
return false;
}
pb_FaceRebuildData pb_FaceRebuildData = new pb_FaceRebuildData();
pb_FaceRebuildData.face = new pb_Face(list7.ToArray(), face.material, new pb_UV(face.uv), face.smoothingGroup, face.textureGroup, -1, face.manualUV);
pb_FaceRebuildData.vertices = list4;
pb_FaceRebuildData.sharedIndices = list5;
pb_FaceRebuildData.sharedIndicesUV = list6;
pb_FaceRebuildData.Apply(new List<pb_FaceRebuildData> { pb_FaceRebuildData }, list, list2, dictionary, dictionary2);
newFace = pb_FaceRebuildData.face;
pb.SetVertices(list, false);
pb.SetFaces(list2.ToArray());
pb.SetSharedIndices(dictionary);
pb.SetSharedIndicesUV(dictionary2);
Vector3 vector2 = pb_Math.Normal(pb, face);
Vector3 vector3 = pb_Math.Normal(pb, newFace);
if (Vector3.Dot(vector2, vector3) < 0f)
{
newFace.ReverseIndices();
}
pb.DeleteFace(face);
return true;
}
// Token: 0x0600004C RID: 76 RVA: 0x00007804 File Offset: 0x00005C04
public static pb_ActionResult AppendVerticesToEdge(this pb_Object pb, pb_Edge edge, int count, out List<pb_Edge> newEdges)
{
return pb.AppendVerticesToEdge(new pb_Edge[] { edge }, count, out newEdges);
}
// Token: 0x0600004D RID: 77 RVA: 0x00007818 File Offset: 0x00005C18
public static pb_ActionResult AppendVerticesToEdge(this pb_Object pb, IList<pb_Edge> edges, int count, out List<pb_Edge> newEdges)
{
newEdges = new List<pb_Edge>();
if (count < 1 || count > 512)
{
return new pb_ActionResult(Status.Failure, "New edge vertex count is less than 1 or greater than 512.");
}
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
Dictionary<int, int> dictionary2 = pb.sharedIndicesUV.ToDictionary();
List<int> list2 = new List<int>();
pb_Edge[] universalEdges = pb_Edge.GetUniversalEdges(edges.ToArray<pb_Edge>(), dictionary);
List<pb_Edge> list3 = universalEdges.Distinct<pb_Edge>().ToList<pb_Edge>();
Dictionary<pb_Face, pb_FaceRebuildData> dictionary3 = new Dictionary<pb_Face, pb_FaceRebuildData>();
int num = dictionary.Count<KeyValuePair<int, int>>();
int num2 = num;
foreach (pb_Edge pb_Edge in list3)
{
pb_Edge localEdgeFast = pb_Edge.GetLocalEdgeFast(pb_Edge, pb.sharedIndices);
List<pb_Vertex> list4 = new List<pb_Vertex>(count);
for (int i = 0; i < count; i++)
{
list4.Add(pb_Vertex.Mix(list[localEdgeFast.x], list[localEdgeFast.y], (float)(i + 1) / ((float)count + 1f)));
}
List<pb_Tuple<pb_Face, pb_Edge>> neighborFaces = pbMeshUtils.GetNeighborFaces(pb, localEdgeFast, null);
foreach (pb_Tuple<pb_Face, pb_Edge> pb_Tuple in neighborFaces)
{
pb_Face item = pb_Tuple.Item1;
pb_FaceRebuildData pb_FaceRebuildData;
if (!dictionary3.TryGetValue(item, out pb_FaceRebuildData))
{
pb_FaceRebuildData = new pb_FaceRebuildData();
pb_FaceRebuildData.face = new pb_Face(null, item.material, new pb_UV(item.uv), item.smoothingGroup, item.textureGroup, -1, item.manualUV);
pb_FaceRebuildData.vertices = new List<pb_Vertex>(list.ValuesWithIndices(item.distinctIndices));
pb_FaceRebuildData.sharedIndices = new List<int>();
pb_FaceRebuildData.sharedIndicesUV = new List<int>();
foreach (int num3 in item.distinctIndices)
{
int num4;
if (dictionary.TryGetValue(num3, out num4))
{
pb_FaceRebuildData.sharedIndices.Add(num4);
}
if (dictionary2.TryGetValue(num3, out num4))
{
pb_FaceRebuildData.sharedIndicesUV.Add(num4);
}
}
list2.AddRange(item.distinctIndices);
dictionary3.Add(item, pb_FaceRebuildData);
}
pb_FaceRebuildData.vertices.AddRange(list4);
for (int k = 0; k < count; k++)
{
pb_FaceRebuildData.sharedIndices.Add(num2 + k);
pb_FaceRebuildData.sharedIndicesUV.Add(-1);
}
}
num2 += count;
}
List<pb_Face> list5 = dictionary3.Keys.ToList<pb_Face>();
List<pb_FaceRebuildData> list6 = dictionary3.Values.ToList<pb_FaceRebuildData>();
List<pb_EdgeLookup> list7 = new List<pb_EdgeLookup>();
for (int l = 0; l < list5.Count; l++)
{
pb_Face pb_Face = list5[l];
pb_FaceRebuildData pb_FaceRebuildData2 = list6[l];
Vector3 vector = pb_Math.Normal(pb, pb_Face);
Vector2[] array = pb_Projection.PlanarProject(pb_FaceRebuildData2.vertices.Select((pb_Vertex x) => x.position).ToArray<Vector3>(), vector);
int count2 = list.Count;
List<int> list8;
if (pb_Triangulation.SortAndTriangulate(array, out list8, false))
{
pb_FaceRebuildData2.face.SetIndices(list8.ToArray());
pb_FaceRebuildData2.face.ShiftIndices(count2);
pb_Face.CopyFrom(pb_FaceRebuildData2.face);
for (int m = 0; m < pb_FaceRebuildData2.vertices.Count; m++)
{
dictionary.Add(count2 + m, pb_FaceRebuildData2.sharedIndices[m]);
}
if (pb_FaceRebuildData2.sharedIndicesUV.Count == pb_FaceRebuildData2.vertices.Count)
{
for (int n = 0; n < pb_FaceRebuildData2.vertices.Count; n++)
{
dictionary2.Add(count2 + n, pb_FaceRebuildData2.sharedIndicesUV[n]);
}
}
list.AddRange(pb_FaceRebuildData2.vertices);
foreach (pb_Edge pb_Edge2 in pb_Face.edges)
{
pb_EdgeLookup pb_EdgeLookup = new pb_EdgeLookup(new pb_Edge(dictionary[pb_Edge2.x], dictionary[pb_Edge2.y]), pb_Edge2);
if (pb_EdgeLookup.common.x >= num || pb_EdgeLookup.common.y >= num)
{
list7.Add(pb_EdgeLookup);
}
}
}
}
list2 = list2.Distinct<int>().ToList<int>();
int delCount = list2.Count;
newEdges = (from x in list7.Distinct<pb_EdgeLookup>()
select x.local - delCount).ToList<pb_Edge>();
pb.SetVertices(list, false);
pb.SetSharedIndices(dictionary.ToSharedIndices());
pb.SetSharedIndicesUV(dictionary2.ToSharedIndices());
pb.DeleteVerticesWithIndices(list2);
return new pb_ActionResult(Status.Success, "Subdivide Edges");
}
// Token: 0x0600004E RID: 78 RVA: 0x00007D74 File Offset: 0x00006174
public static pb_FaceRebuildData ExplodeVertex(IList<pb_Vertex> vertices, IList<pb_Tuple<pb_WingedEdge, int>> edgeAndCommonIndex, float distance, out Dictionary<int, List<int>> appendedVertices)
{
pb_Face face = edgeAndCommonIndex.FirstOrDefault<pb_Tuple<pb_WingedEdge, int>>().Item1.face;
List<pb_Edge> list = pb_WingedEdge.SortEdgesByAdjacency(face);
appendedVertices = new Dictionary<int, List<int>>();
Vector3 vector = pb_Math.Normal(vertices, face.indices);
Dictionary<int, int> dictionary = new Dictionary<int, int>();
foreach (pb_Tuple<pb_WingedEdge, int> pb_Tuple in edgeAndCommonIndex)
{
if (pb_Tuple.Item2 == pb_Tuple.Item1.edge.common.x)
{
dictionary.Add(pb_Tuple.Item1.edge.local.x, pb_Tuple.Item2);
}
else
{
dictionary.Add(pb_Tuple.Item1.edge.local.y, pb_Tuple.Item2);
}
}
int count = list.Count;
List<pb_Vertex> list2 = new List<pb_Vertex>();
for (int i = 0; i < count; i++)
{
int y = list[i].y;
if (dictionary.ContainsKey(y))
{
pb_Vertex pb_Vertex = vertices[list[i].x];
pb_Vertex pb_Vertex2 = vertices[list[i].y];
pb_Vertex pb_Vertex3 = vertices[list[(i + 1) % count].y];
pb_Vertex pb_Vertex4 = pb_Vertex - pb_Vertex2;
pb_Vertex pb_Vertex5 = pb_Vertex3 - pb_Vertex2;
pb_Vertex4.Normalize();
pb_Vertex5.Normalize();
pb_Vertex pb_Vertex6 = vertices[y] + pb_Vertex4 * distance;
pb_Vertex pb_Vertex7 = vertices[y] + pb_Vertex5 * distance;
appendedVertices.AddOrAppend(dictionary[y], list2.Count);
list2.Add(pb_Vertex6);
appendedVertices.AddOrAppend(dictionary[y], list2.Count);
list2.Add(pb_Vertex7);
}
else
{
list2.Add(vertices[y]);
}
}
List<int> list3;
if (pb_Triangulation.TriangulateVertices(list2, out list3, false, false))
{
pb_FaceRebuildData pb_FaceRebuildData = new pb_FaceRebuildData();
pb_FaceRebuildData.vertices = list2;
pb_FaceRebuildData.face = new pb_Face(face);
Vector3 vector2 = pb_Math.Normal(list2, list3);
if (Vector3.Dot(vector, vector2) < 0f)
{
list3.Reverse();
}
pb_FaceRebuildData.face.SetIndices(list3.ToArray());
return pb_FaceRebuildData;
}
return null;
}
// Token: 0x0600004F RID: 79 RVA: 0x00007FF8 File Offset: 0x000063F8
private static pb_Edge AlignEdgeWithDirection(pb_EdgeLookup edge, int commonIndex)
{
if (edge.common.x == commonIndex)
{
return new pb_Edge(edge.local.x, edge.local.y);
}
return new pb_Edge(edge.local.y, edge.local.x);
}
// Token: 0x06000050 RID: 80 RVA: 0x00008050 File Offset: 0x00006450
public static void Quantize(pb_Object pb, IList<int> indices, Vector3 snap)
{
Vector3[] vertices = pb.vertices;
for (int i = 0; i < indices.Count; i++)
{
vertices[indices[i]] = pb.transform.InverseTransformPoint(pb_Snap.SnapValue(pb.transform.TransformPoint(vertices[indices[i]]), snap));
}
}
}
}