275 lines
11 KiB
C#
275 lines
11 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using ProBuilder2.Common;
|
|
using UnityEngine;
|
|
|
|
namespace ProBuilder2.MeshOperations
|
|
{
|
|
// Token: 0x02000009 RID: 9
|
|
public static class pb_Bevel
|
|
{
|
|
// Token: 0x06000064 RID: 100 RVA: 0x00008F48 File Offset: 0x00007348
|
|
public static pb_ActionResult BevelEdges(pb_Object pb, IList<pb_Edge> edges, float amount, out List<pb_Face> createdFaces)
|
|
{
|
|
createdFaces = null;
|
|
Dictionary<int, int> dictionary = pb.sharedIndices.ToDictionary();
|
|
List<pb_Vertex> list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
|
|
List<pb_EdgeLookup> list2 = pb_EdgeLookup.GetEdgeLookup(edges, dictionary).Distinct<pb_EdgeLookup>().ToList<pb_EdgeLookup>();
|
|
List<pb_WingedEdge> wingedEdges = pb_WingedEdge.GetWingedEdges(pb, false);
|
|
List<pb_FaceRebuildData> list3 = new List<pb_FaceRebuildData>();
|
|
Dictionary<pb_Face, List<int>> ignore = new Dictionary<pb_Face, List<int>>();
|
|
HashSet<int> hashSet = new HashSet<int>();
|
|
int num = 0;
|
|
Dictionary<int, List<pb_Tuple<pb_FaceRebuildData, List<int>>>> dictionary2 = new Dictionary<int, List<pb_Tuple<pb_FaceRebuildData, List<int>>>>();
|
|
Dictionary<int, List<pb_WingedEdge>> spokes = pb_WingedEdge.GetSpokes(wingedEdges);
|
|
HashSet<int> hashSet2 = new HashSet<int>();
|
|
foreach (pb_EdgeLookup pb_EdgeLookup in list2)
|
|
{
|
|
if (hashSet2.Add(pb_EdgeLookup.common.x))
|
|
{
|
|
foreach (pb_WingedEdge pb_WingedEdge in spokes[pb_EdgeLookup.common.x])
|
|
{
|
|
pb_Edge local = pb_WingedEdge.edge.local;
|
|
amount = Mathf.Min(Vector3.Distance(list[local.x].position, list[local.y].position) - 0.001f, amount);
|
|
}
|
|
}
|
|
if (hashSet2.Add(pb_EdgeLookup.common.y))
|
|
{
|
|
foreach (pb_WingedEdge pb_WingedEdge2 in spokes[pb_EdgeLookup.common.y])
|
|
{
|
|
pb_Edge local2 = pb_WingedEdge2.edge.local;
|
|
amount = Mathf.Min(Vector3.Distance(list[local2.x].position, list[local2.y].position) - 0.001f, amount);
|
|
}
|
|
}
|
|
}
|
|
if (amount < 0.001f)
|
|
{
|
|
return new pb_ActionResult(Status.Canceled, "Bevel Distance > Available Surface");
|
|
}
|
|
using (List<pb_EdgeLookup>.Enumerator enumerator4 = list2.GetEnumerator())
|
|
{
|
|
while (enumerator4.MoveNext())
|
|
{
|
|
pb_EdgeLookup lup = enumerator4.Current;
|
|
pb_WingedEdge pb_WingedEdge3 = wingedEdges.FirstOrDefault((pb_WingedEdge x) => x.edge.Equals(lup));
|
|
if (pb_WingedEdge3 != null && pb_WingedEdge3.opposite != null)
|
|
{
|
|
num++;
|
|
ignore.AddOrAppend(pb_WingedEdge3.face, pb_WingedEdge3.edge.common.x);
|
|
ignore.AddOrAppend(pb_WingedEdge3.face, pb_WingedEdge3.edge.common.y);
|
|
ignore.AddOrAppend(pb_WingedEdge3.opposite.face, pb_WingedEdge3.edge.common.x);
|
|
ignore.AddOrAppend(pb_WingedEdge3.opposite.face, pb_WingedEdge3.edge.common.y);
|
|
hashSet.Add(pb_WingedEdge3.edge.common.x);
|
|
hashSet.Add(pb_WingedEdge3.edge.common.y);
|
|
pb_Bevel.SlideEdge(list, pb_WingedEdge3, amount);
|
|
pb_Bevel.SlideEdge(list, pb_WingedEdge3.opposite, amount);
|
|
list3.AddRange(pb_Bevel.GetBridgeFaces(list, pb_WingedEdge3, pb_WingedEdge3.opposite, dictionary2));
|
|
}
|
|
}
|
|
}
|
|
if (num < 1)
|
|
{
|
|
createdFaces = null;
|
|
return new pb_ActionResult(Status.Canceled, "Cannot Bevel Open Edges");
|
|
}
|
|
createdFaces = new List<pb_Face>(list3.Select((pb_FaceRebuildData x) => x.face));
|
|
Dictionary<pb_Face, List<pb_Tuple<pb_WingedEdge, int>>> dictionary3 = new Dictionary<pb_Face, List<pb_Tuple<pb_WingedEdge, int>>>();
|
|
using (HashSet<int>.Enumerator enumerator5 = hashSet.GetEnumerator())
|
|
{
|
|
while (enumerator5.MoveNext())
|
|
{
|
|
int c = enumerator5.Current;
|
|
IEnumerable<pb_WingedEdge> enumerable = wingedEdges.Where((pb_WingedEdge x) => x.edge.common.Contains(c) && (!ignore.ContainsKey(x.face) || !ignore[x.face].Contains(c)));
|
|
HashSet<pb_Face> hashSet3 = new HashSet<pb_Face>();
|
|
foreach (pb_WingedEdge pb_WingedEdge4 in enumerable)
|
|
{
|
|
if (hashSet3.Add(pb_WingedEdge4.face))
|
|
{
|
|
dictionary3.AddOrAppend(pb_WingedEdge4.face, new pb_Tuple<pb_WingedEdge, int>(pb_WingedEdge4, c));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
foreach (KeyValuePair<pb_Face, List<pb_Tuple<pb_WingedEdge, int>>> keyValuePair in dictionary3)
|
|
{
|
|
Dictionary<int, List<int>> dictionary4;
|
|
pb_FaceRebuildData pb_FaceRebuildData = pbVertexOps.ExplodeVertex(list, keyValuePair.Value, amount, out dictionary4);
|
|
if (pb_FaceRebuildData != null)
|
|
{
|
|
list3.Add(pb_FaceRebuildData);
|
|
foreach (KeyValuePair<int, List<int>> keyValuePair2 in dictionary4)
|
|
{
|
|
dictionary2.AddOrAppend(keyValuePair2.Key, new pb_Tuple<pb_FaceRebuildData, List<int>>(pb_FaceRebuildData, keyValuePair2.Value));
|
|
}
|
|
}
|
|
}
|
|
pb_FaceRebuildData.Apply(list3, pb, list, null, null, null);
|
|
int num2 = pb.DeleteFaces(dictionary3.Keys).Length;
|
|
pb.SetSharedIndicesUV(new pb_IntArray[0]);
|
|
pb.SetSharedIndices(pb_IntArrayUtility.ExtractSharedIndices(pb.vertices));
|
|
pb_IntArray[] sharedIndices = pb.sharedIndices;
|
|
dictionary = sharedIndices.ToDictionary();
|
|
List<HashSet<int>> list4 = new List<HashSet<int>>();
|
|
foreach (KeyValuePair<int, List<pb_Tuple<pb_FaceRebuildData, List<int>>>> keyValuePair3 in dictionary2)
|
|
{
|
|
if (keyValuePair3.Value.Sum((pb_Tuple<pb_FaceRebuildData, List<int>> x) => x.Item2.Count) >= 3)
|
|
{
|
|
HashSet<int> hashSet4 = new HashSet<int>();
|
|
foreach (pb_Tuple<pb_FaceRebuildData, List<int>> pb_Tuple in keyValuePair3.Value)
|
|
{
|
|
int num3 = pb_Tuple.Item1.Offset() - num2;
|
|
for (int i = 0; i < pb_Tuple.Item2.Count; i++)
|
|
{
|
|
hashSet4.Add(dictionary[pb_Tuple.Item2[i] + num3]);
|
|
}
|
|
}
|
|
list4.Add(hashSet4);
|
|
}
|
|
}
|
|
List<pb_WingedEdge> wingedEdges2 = pb_WingedEdge.GetWingedEdges(pb, list3.Select((pb_FaceRebuildData x) => x.face), false, null);
|
|
list = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, null));
|
|
List<pb_FaceRebuildData> list5 = new List<pb_FaceRebuildData>();
|
|
foreach (HashSet<int> hashSet5 in list4)
|
|
{
|
|
if (hashSet5.Count >= 3)
|
|
{
|
|
if (hashSet5.Count < 4)
|
|
{
|
|
List<pb_Vertex> list6 = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, hashSet5.Select((int x) => sharedIndices[x][0]).ToList<int>()));
|
|
list5.Add(pb_AppendPolygon.FaceWithVertices(list6, true));
|
|
}
|
|
else
|
|
{
|
|
List<int> list7 = pb_WingedEdge.SortCommonIndicesByAdjacency(wingedEdges2, hashSet5);
|
|
List<pb_Vertex> list8 = new List<pb_Vertex>(pb_Vertex.GetVertices(pb, list7.Select((int x) => sharedIndices[x][0]).ToList<int>()));
|
|
list5.AddRange(pb_AppendPolygon.TentCapWithVertices(list8));
|
|
}
|
|
}
|
|
}
|
|
pb_FaceRebuildData.Apply(list5, pb, list, null, null, null);
|
|
pb.SetSharedIndices(pb_IntArrayUtility.ExtractSharedIndices(pb.vertices));
|
|
HashSet<pb_Face> hashSet6 = new HashSet<pb_Face>(list5.Select((pb_FaceRebuildData x) => x.face));
|
|
list3.AddRange(list5);
|
|
List<pb_WingedEdge> wingedEdges3 = pb_WingedEdge.GetWingedEdges(pb, list3.Select((pb_FaceRebuildData x) => x.face), false, null);
|
|
int num4 = 0;
|
|
while (num4 < wingedEdges3.Count && hashSet6.Count > 0)
|
|
{
|
|
pb_WingedEdge pb_WingedEdge5 = wingedEdges3[num4];
|
|
if (hashSet6.Contains(pb_WingedEdge5.face))
|
|
{
|
|
hashSet6.Remove(pb_WingedEdge5.face);
|
|
pb_WingedEdgeEnumerator enumerator12 = pb_WingedEdge5.GetEnumerator();
|
|
try
|
|
{
|
|
while (enumerator12.MoveNext())
|
|
{
|
|
pb_WingedEdge pb_WingedEdge6 = enumerator12.Current;
|
|
if (!hashSet6.Contains(pb_WingedEdge6.opposite.face))
|
|
{
|
|
pb_WingedEdge6.face.material = pb_WingedEdge6.opposite.face.material;
|
|
pb_WingedEdge6.face.uv = new pb_UV(pb_WingedEdge6.opposite.face.uv);
|
|
pb_ConformNormals.ConformOppositeNormal(pb_WingedEdge6.opposite);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
IDisposable disposable;
|
|
if ((disposable = enumerator12 as IDisposable) != null)
|
|
{
|
|
disposable.Dispose();
|
|
}
|
|
}
|
|
}
|
|
num4++;
|
|
}
|
|
pb.ToMesh();
|
|
return new pb_ActionResult(Status.Success, "Bevel Edges");
|
|
}
|
|
|
|
// Token: 0x06000065 RID: 101 RVA: 0x000099B0 File Offset: 0x00007DB0
|
|
private static List<pb_FaceRebuildData> GetBridgeFaces(IList<pb_Vertex> vertices, pb_WingedEdge left, pb_WingedEdge right, Dictionary<int, List<pb_Tuple<pb_FaceRebuildData, List<int>>>> holes)
|
|
{
|
|
List<pb_FaceRebuildData> list = new List<pb_FaceRebuildData>();
|
|
pb_FaceRebuildData pb_FaceRebuildData = new pb_FaceRebuildData();
|
|
pb_EdgeLookup edge = left.edge;
|
|
pb_EdgeLookup edge2 = right.edge;
|
|
pb_FaceRebuildData.vertices = new List<pb_Vertex>
|
|
{
|
|
vertices[edge.local.x],
|
|
vertices[edge.local.y],
|
|
vertices[(edge.common.x != edge2.common.x) ? edge2.local.y : edge2.local.x],
|
|
vertices[(edge.common.x != edge2.common.x) ? edge2.local.x : edge2.local.y]
|
|
};
|
|
Vector3 vector = pb_Math.Normal(vertices, left.face.indices);
|
|
Vector3 vector2 = pb_Math.Normal(pb_FaceRebuildData.vertices, pb_Bevel.BRIDGE_INDICES_NRM);
|
|
int[] array = new int[] { 2, 1, 0, 2, 3, 1 };
|
|
if (Vector3.Dot(vector, vector2) < 0f)
|
|
{
|
|
Array.Reverse(array);
|
|
}
|
|
pb_FaceRebuildData.face = new pb_Face(array, left.face.material, new pb_UV(), -1, -1, -1, false);
|
|
list.Add(pb_FaceRebuildData);
|
|
holes.AddOrAppend(edge.common.x, new pb_Tuple<pb_FaceRebuildData, List<int>>(pb_FaceRebuildData, new List<int> { 0, 2 }));
|
|
holes.AddOrAppend(edge.common.y, new pb_Tuple<pb_FaceRebuildData, List<int>>(pb_FaceRebuildData, new List<int> { 1, 3 }));
|
|
return list;
|
|
}
|
|
|
|
// Token: 0x06000066 RID: 102 RVA: 0x00009B78 File Offset: 0x00007F78
|
|
private static void SlideEdge(IList<pb_Vertex> vertices, pb_WingedEdge we, float amount)
|
|
{
|
|
we.face.manualUV = true;
|
|
we.face.textureGroup = -1;
|
|
pb_Edge leadingEdge = pb_Bevel.GetLeadingEdge(we, we.edge.common.x);
|
|
pb_Edge leadingEdge2 = pb_Bevel.GetLeadingEdge(we, we.edge.common.y);
|
|
if (leadingEdge == null || leadingEdge2 == null)
|
|
{
|
|
return;
|
|
}
|
|
pb_Vertex pb_Vertex = vertices[leadingEdge.x] - vertices[leadingEdge.y];
|
|
pb_Vertex.Normalize();
|
|
pb_Vertex pb_Vertex2 = vertices[leadingEdge2.x] - vertices[leadingEdge2.y];
|
|
pb_Vertex2.Normalize();
|
|
vertices[we.edge.local.x].Add(pb_Vertex * amount);
|
|
vertices[we.edge.local.y].Add(pb_Vertex2 * amount);
|
|
}
|
|
|
|
// Token: 0x06000067 RID: 103 RVA: 0x00009C64 File Offset: 0x00008064
|
|
private static pb_Edge GetLeadingEdge(pb_WingedEdge wing, int common)
|
|
{
|
|
if (wing.previous.edge.common.x == common)
|
|
{
|
|
return new pb_Edge(wing.previous.edge.local.y, wing.previous.edge.local.x);
|
|
}
|
|
if (wing.previous.edge.common.y == common)
|
|
{
|
|
return new pb_Edge(wing.previous.edge.local.x, wing.previous.edge.local.y);
|
|
}
|
|
if (wing.next.edge.common.x == common)
|
|
{
|
|
return new pb_Edge(wing.next.edge.local.y, wing.next.edge.local.x);
|
|
}
|
|
if (wing.next.edge.common.y == common)
|
|
{
|
|
return new pb_Edge(wing.next.edge.local.x, wing.next.edge.local.y);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
// Token: 0x06000068 RID: 104 RVA: 0x00009D9E File Offset: 0x0000819E
|
|
// Note: this type is marked as 'beforefieldinit'.
|
|
static pb_Bevel()
|
|
{
|
|
int[] array = new int[3];
|
|
array[0] = 2;
|
|
array[1] = 1;
|
|
pb_Bevel.BRIDGE_INDICES_NRM = array;
|
|
}
|
|
|
|
// Token: 0x04000017 RID: 23
|
|
private static readonly int[] BRIDGE_INDICES_NRM;
|
|
}
|
|
}
|