public void Reuse() { this.Id = 0u; V0 = null; V1 = null; Faces.Clear(); }
private EdgeEntry FindEdgeEntry(VertexEntry ve0, VertexEntry ve1) { foreach (var existing in ve0.Edges) { if (existing.V1 == ve1) { return(existing); } } return(null); }
private void RemoveVertexInternal(VertexEntry vertexEntry, bool cascade) { if (!cascade) { if (vertexEntry.Edges.Count > 0) { throw new InvalidOperationException("The vertex is still part of some edges."); } if (vertexEntry.Faces.Count > 0) { throw new InvalidOperationException("The vertex is still part of some faces."); } } else { foreach (var edgeEntry in vertexEntry.Edges) { edges.Remove(edgeEntry); if (edgeEntry.V0 == vertexEntry) { edgeEntry.V1.Edges.Remove(edgeEntry); } else { edgeEntry.V0.Edges.Remove(edgeEntry); } EdgePool.Put(edgeEntry); } foreach (var faceEntry in vertexEntry.Faces) { faces.Remove(faceEntry); foreach (var fve in faceEntry.Vertices) { fve.Faces.Remove(faceEntry); } foreach (var fee in faceEntry.Edges) { fee.Faces.Remove(faceEntry); } FacePool.Put(faceEntry); } } }
private EdgeEntry AddEdgeInternal(VertexEntry ve0, VertexEntry ve1) { var existing = FindEdgeEntry(ve0, ve1); if (existing != null) { return(existing); } var newEdge = EdgePool.Get(); newEdge.Id = edges.Count > 0 ? edges[edges.Count - 1].Id + 1u : 1u; newEdge.V0 = ve0; newEdge.V1 = ve1; edges.Add(newEdge); return(newEdge); }
/// <summary> /// Recalculate the normals of a mesh based on an angle threshold. This takes /// into account distinct vertices that have the same position. /// </summary> /// <param name="mesh"></param> /// <param name="angle"> /// The smoothing angle. Note that triangles that already share /// the same vertex will be smooth regardless of the angle! /// </param> /// <param name="ignoreFactor"> /// A fraction between 0 and 1. /// Weights smaller than this fraction relative to the largest weight are ignored. /// </param> public static void RecalculateNormals(this Mesh mesh, float angle, float ignoreFactor) { var triangles = mesh.triangles; var vertices = mesh.vertices; var triNormals = new Vector3[triangles.Length / 3]; //Normal of each triangle var triNormalsWeighted = new Vector3[triangles.Length / 3]; //Weighted normal of each triangle var normals = new Vector3[vertices.Length]; angle = angle * Mathf.Deg2Rad; var dictionary = new Dictionary <VertexKey, VertexEntry>(vertices.Length); //Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; // By not normalizing the cross product, // the face area is pre-multiplied onto the normal for free. Vector3 normal = Vector3.Cross(p1, p2); int triIndex = i / 3; triNormalsWeighted[triIndex] = normal; triNormals[triIndex] = normal.normalized; VertexEntry entry; VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(key = new VertexKey(vertices[i1]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i2]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i3]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i3, triIndex); } //Foreach point in space (not necessarily the same vertex index!) //{ // Foreach triangle T1 that point belongs to // { // Foreach other triangle T2 (including self) that point belongs to and that // meets any of the following: // 1) The corresponding vertex is actually the same vertex // 2) The angle between the two triangles is less than the smoothing angle // { // > Add to the set of contributing normals // } // > Add the normals in the set together, excluding those smaller than the threshold. // > Normalize the resulting vector to find the average // > Assign the normal to corresponding vertex of T1 // } //} List <Vector3> normalSet = new List <Vector3>(); foreach (var value in dictionary.Values) { for (var i = 0; i < value.Count; ++i) { normalSet.Clear(); float longest = 0; for (var j = 0; j < value.Count; ++j) { bool use = false; if (value.VertexIndex[i] == value.VertexIndex[j]) { use = true; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { use = true; } } if (use) { Vector3 normal = triNormalsWeighted[value.TriangleIndex[j]]; normalSet.Add(normal); float length = normal.magnitude; if (length > longest) { longest = length; } } } var sum = new Vector3(); var threshold = longest * ignoreFactor; for (int j = 0; j < normalSet.Count; j++) { if (normalSet[j].magnitude >= threshold) { sum += normalSet[j]; } } normals[value.VertexIndex[i]] = sum.normalized; } } mesh.normals = normals; }
public static void RecalculateNormals(this Mesh mesh, float angle) { var triangles = mesh.GetTriangles(0); var vertices = mesh.vertices; var triNormals = new Vector3[triangles.Length / 3]; //Holds the normal of each triangle var normals = new Vector3[vertices.Length]; angle = angle * Mathf.Deg2Rad; var dictionary = new Dictionary<VertexKey, VertexEntry>(vertices.Length); //Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(key = new VertexKey(vertices[i1]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i2]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i3]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i3, triIndex); } //Foreach point in space (not necessarily the same vertex index!) //{ // Foreach triangle T1 that point belongs to // { // Foreach other triangle T2 (including self) that point belongs to and that // meets any of the following: // 1) The corresponding vertex is actually the same vertex // 2) The angle between the two triangles is less than the smoothing angle // { // > Add to temporary Vector3 // } // > Normalize temporary Vector3 to find the average // > Assign the normal to corresponding vertex of T1 // } //} foreach (var value in dictionary.Values) { for (var i = 0; i < value.Count; ++i) { var sum = new Vector3(); for (var j = 0; j < value.Count; ++j) { if (value.VertexIndex[i] == value.VertexIndex[j]) { sum += triNormals[value.TriangleIndex[j]]; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.999999f, 0.999999f); float acos = Mathf.Acos(dot); if (acos <= angle) { sum += triNormals[value.TriangleIndex[j]]; } } } normals[value.VertexIndex[i]] = sum.normalized; } } mesh.normals = normals; }
/// <summary> /// Recalculate the normals of a mesh based on an angle threshold. This takes /// into account distinct vertices that have the same position. /// </summary> /// <param name="mesh"></param> /// <param name="angle"> /// The smoothing angle. Note that triangles that already share /// the same vertex will be smooth regardless of the angle! /// </param> public static void RecalculateNormals(this Mesh mesh, float angle) { var triangles = mesh.GetTriangles(0); var vertices = mesh.vertices; var triNormals = new Vector3[triangles.Length / 3]; //Holds the normal of each triangle var normals = new Vector3[vertices.Length]; angle = angle * Mathf.Deg2Rad; var dictionary = new Dictionary <VertexKey, VertexEntry>(vertices.Length); //Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(key = new VertexKey(vertices[i1]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i2]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i3]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i3, triIndex); } //Foreach point in space (not necessarily the same vertex index!) //{ // Foreach triangle T1 that point belongs to // { // Foreach other triangle T2 (including self) that point belongs to and that // meets any of the following: // 1) The corresponding vertex is actually the same vertex // 2) The angle between the two triangles is less than the smoothing angle // { // > Add to temporary Vector3 // } // > Normalize temporary Vector3 to find the average // > Assign the normal to corresponding vertex of T1 // } //} foreach (var value in dictionary.Values) { for (var i = 0; i < value.Count; ++i) { var sum = new Vector3(); for (var j = 0; j < value.Count; ++j) { if (value.VertexIndex[i] == value.VertexIndex[j]) { sum += triNormals[value.TriangleIndex[j]]; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { sum += triNormals[value.TriangleIndex[j]]; } } } normals[value.VertexIndex[i]] = sum.normalized; } } mesh.normals = normals; }
public static void RecalculateNormals(Mesh mesh, float angle) { var triangles = mesh.triangles; var vertices = mesh.vertices; var weights = mesh.boneWeights == null || mesh.boneWeights.Length == 0 ? mesh.vertices.Select(v => new BoneWeight()).ToArray() : mesh.boneWeights; var triNormals = new Vector3[triangles.Length / 3]; var normals = new Vector3[vertices.Length]; angle = angle * Mathf.Deg2Rad; var dictionary = new Dictionary <VertexKey, VertexEntry>(vertices.Length); for (var i = 0; i < triangles.Length; i += 3) { var i1 = triangles[i]; var i2 = triangles[i + 1]; var i3 = triangles[i + 2]; var p1 = vertices[i2] - vertices[i1]; var p2 = vertices[i3] - vertices[i1]; var normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; VertexKey key; if (!dictionary.TryGetValue(key = new VertexKey(vertices[i1], weights[i1]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i1, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i2], weights[i2]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i2, triIndex); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i3], weights[i3]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i3, triIndex); } foreach (var value in dictionary.Values) { for (var i = 0; i < value.Count; ++i) { var sum = new Vector3(); for (var j = 0; j < value.Count; ++j) { if (value.VertexIndex[i] == value.VertexIndex[j]) { sum += triNormals[value.TriangleIndex[j]]; } else { float dot = Vector3.Dot( triNormals[value.TriangleIndex[i]], triNormals[value.TriangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { sum += triNormals[value.TriangleIndex[j]]; } } } normals[value.VertexIndex[i]] = sum.normalized; } } mesh.normals = normals; }
public EdgeEntry(uint id, VertexEntry v0, VertexEntry v1) : this() { this.Id = id; this.V0 = v0; this.V1 = v1; }
/// <summary> /// Recalculate the normals of a mesh based on an angle threshold. This takes /// into account distinct vertices that have the same position. /// </summary> /// <param name="mesh"></param> /// <param name="angleSameMaterial"> /// The smoothing angle. Note that triangles that already share the same vertex will be smooth regardless of the angle! /// If the vertex is not shared then triangle with normals within this angle and with the same material, are smoothed /// </param> /// <param name="angleDifferentMaterial"> /// See angleSameMaterial. But this is if the triangles are of different materials. /// </param> /// <param name="normalLock"> /// If provided, then for each normal in normals[], this says whether or not the vertex for this normal should /// be locked to that provided by normals[]. Otherwise, if false, that normal will be recalculated. /// </param> /// <param name="providedNormals"> /// Paired with normalLock to decide whether we should calculate the normal /// </param> public static void RecalculateNormals(this Mesh mesh, float angleSameMaterial, float angleDifferentMaterial, bool[] normalLock, Vector3[] providedNormals) { const float kEpsilon = 0.0001f; bool warnedAboutDegenTris = false; bool warnedAboutZeroSumNormal = false; angleSameMaterial = angleSameMaterial * Mathf.Deg2Rad; angleDifferentMaterial = angleDifferentMaterial * Mathf.Deg2Rad; if (providedNormals == null) { // If we were not given provided normals, then we don't do normal lock checking normalLock = null; } var vertices = mesh.vertices; var normals = new Vector3[vertices.Length]; var pointInSpaceToRefTrisDictionary = new Dictionary <VertexKey, VertexEntry>(vertices.Length); if (normalLock != null) { // Make sure all the arrays are the expected length Assert.True(normalLock.Length == providedNormals.Length); Assert.True(normalLock.Length == vertices.Length); } int numSubmeshes = mesh.subMeshCount; int numTotalTriangles = 0; for (int submeshIndex = 0; submeshIndex < numSubmeshes; ++submeshIndex) { int[] triangles = mesh.GetTriangles(submeshIndex); numTotalTriangles += triangles.Length / 3; } var triNormals = new Vector3[numTotalTriangles]; //Holds the normal of each triangle int triOffset = 0; for (int submesh_index = 0; submesh_index < numSubmeshes; ++submesh_index) { int[] triangles = mesh.GetTriangles(submesh_index); // Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Length; i += 3) { int i1 = triangles[i + 0]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; int i1_tri_id = 0; int i2_tri_id = 0; int i3_tri_id = 0; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; if (normal.magnitude < kEpsilon) { // Prevent a bad triangle from generating a bad normal if (!warnedAboutDegenTris) { warnedAboutDegenTris = true; Debug.LogWarningFormat("Degenerate triangles found during RecalculateNormals ({0})", mesh.name); } normal = Vector3.forward; } int triIndex = (i / 3) + triOffset; triNormals[triIndex] = normal; VertexEntry entry; VertexKey key; // For our purposes, each submesh is for a different material // But if we should ever have a material represented multiple times // in submeshes, then we need to adjust this as needed. int materialIndex = submesh_index; //For each of the three points of the triangle // Add this triangle as part of the triangles they're connected to. // NOTE!!!! We pass false here for triangleIsPortal, because we assume that by the time this gets called, there are no portal triangles in the mesh. // This is not necessarily the case if debugAddPortalsToRenderGeometry is true. If we want to support that, we will need some way to feed the flag // of whether each triangle is from a portal or not through the UnityEngine.Mesh and into this function somehow. -MFlavin 3/1/2017 if (!pointInSpaceToRefTrisDictionary.TryGetValue(key = new VertexKey(vertices[i1]), out entry)) { entry = new VertexEntry(); pointInSpaceToRefTrisDictionary.Add(key, entry); } entry.Add(i1, i1_tri_id, triIndex, materialIndex, false); if (!pointInSpaceToRefTrisDictionary.TryGetValue(key = new VertexKey(vertices[i2]), out entry)) { entry = new VertexEntry(); pointInSpaceToRefTrisDictionary.Add(key, entry); } entry.Add(i2, i2_tri_id, triIndex, materialIndex, false); if (!pointInSpaceToRefTrisDictionary.TryGetValue(key = new VertexKey(vertices[i3]), out entry)) { entry = new VertexEntry(); pointInSpaceToRefTrisDictionary.Add(key, entry); } entry.Add(i3, i3_tri_id, triIndex, materialIndex, false); } triOffset += triangles.Length / 3; } //Foreach point in space (not necessarily the same vertex index!) //{ // Foreach triangle T1 that point belongs to // { // Foreach other triangle T2 (including self) that point belongs to and that // meets any of the following: // 1) The corresponding vertex is actually the same vertex // 2) The angle between the two triangles is less than the smoothing angle // { // > Add to temporary Vector3 // } // > Normalize temporary Vector3 to find the average // > Assign the normal to corresponding vertex of T1 // } //} foreach (var refTriangles in pointInSpaceToRefTrisDictionary.Values) { for (var i = 0; i < refTriangles.Count; ++i) { var sum = new Vector3(); int materialI = refTriangles.MaterialIndex[i]; int vertexIndexI = refTriangles.VertexIndex[i]; int triangleIndexI = refTriangles.TriangleIndex[i]; for (var j = 0; j < refTriangles.Count; ++j) { int materialJ = refTriangles.MaterialIndex[j]; int vertexIndexJ = refTriangles.VertexIndex[j]; int triangleIndexJ = refTriangles.TriangleIndex[j]; if (vertexIndexI == vertexIndexJ) { // This is the same vertex, it is going to be shared no matter what because // the indices point to the same normal. sum += triNormals[triangleIndexJ]; } else { float dot = Vector3.Dot(triNormals[triangleIndexI], triNormals[triangleIndexJ]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); float smoothingAngle = (materialI == materialJ) ? angleSameMaterial : angleDifferentMaterial; if (acos <= smoothingAngle) { // Within the angle, factor it in sum += triNormals[triangleIndexJ]; } } } if (sum.magnitude <= kEpsilon) { // Prevent a bad normal from being created if (!warnedAboutZeroSumNormal) { warnedAboutZeroSumNormal = true; Debug.LogWarningFormat("Zero-sum normal found during RecalculateNormals ({0})", mesh.name); } sum = Vector3.forward; } if (normalLock != null && normalLock[vertexIndexI]) { // we must take the provided normal normals[vertexIndexI] = providedNormals[vertexIndexI]; } else { normals[vertexIndexI] = sum.normalized; } } } mesh.normals = normals; }
public static void Optimize(this BrickMeshInfo mesh, float angle) { if (mesh == null || mesh.Vertices.Count == 0) { return; } var triangles = mesh.Triangles; var vertices = mesh.Vertices; var colors = mesh.ColorIndices; var triNormals = new Vector3[triangles.Count / 3]; //Holds the normal of each triangle //Debug.Log(string.Format("Start optimize {0}: vtCnt:{1}, triCnt:{2}, colorCnt:{3}", // mesh.name, vertices.Count, triangles.Count, colors.Count)); angle = angle * Mathf.Deg2Rad; var dictionary = new Dictionary <VertexKey, VertexEntry>(vertices.Count); // Set vertex index dictionary var vtIndices = new Dictionary <int, VertexIndexEnry>(vertices.Count); for (int i = 0; i < vertices.Count; ++i) { vtIndices.Add(i, new VertexIndexEnry(i)); } // Goes through all the triangles and gathers up data to be used later for (var i = 0; i < triangles.Count; i += 3) { int i1 = triangles[i]; int i2 = triangles[i + 1]; int i3 = triangles[i + 2]; int color1 = colors[i1]; int color2 = colors[i2]; int color3 = colors[i3]; //Calculate the normal of the triangle Vector3 p1 = vertices[i2] - vertices[i1]; Vector3 p2 = vertices[i3] - vertices[i1]; Vector3 normal = Vector3.Cross(p1, p2).normalized; int triIndex = i / 3; triNormals[triIndex] = normal; VertexEntry entry; VertexKey key; //For each of the three points of the triangle // > Add this triangle as part of the triangles they're connected to. if (!dictionary.TryGetValue(key = new VertexKey(vertices[i1]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i1, triIndex, color1); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i2]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i2, triIndex, color2); if (!dictionary.TryGetValue(key = new VertexKey(vertices[i3]), out entry)) { entry = new VertexEntry(); dictionary.Add(key, entry); } entry.Add(i3, triIndex, color3); } bool isShrinkNeeded = false; // Shrink vertcies index dictionary foreach (var value in dictionary.Values) { for (var i = 0; i < value.Count; ++i) { for (var j = i + 1; j < value.Count; ++j) { if (value.vertexIndex[i] == value.vertexIndex[j]) { continue; } if (value.colorIndex[i] != value.colorIndex[j]) { continue; } float dot = Vector3.Dot( triNormals[value.triangleIndex[i]], triNormals[value.triangleIndex[j]]); dot = Mathf.Clamp(dot, -0.99999f, 0.99999f); float acos = Mathf.Acos(dot); if (acos <= angle) { var srcIndex = value.vertexIndex[j]; var targetIndex = value.vertexIndex[i]; //Debug.Log(string.Format("Mark replace: {0} to {1}", srcIndex, targetIndex)); vtIndices[srcIndex].replaceFlag = true; vtIndices[srcIndex].replaceIndex = targetIndex; isShrinkNeeded = true; } } } } if (isShrinkNeeded) { List <Vector3> shrinkedVertices = new List <Vector3>(); List <short> shrinkedColors = new List <short>(); var vtKeys = vtIndices.Keys.ToList(); int serialIndex = 0; foreach (var key in vtKeys) { if (vtIndices[key].replaceFlag) { int firstReplaceIndex = vtIndices[key].replaceIndex; int finalReplaceIndex = firstReplaceIndex; while (vtIndices[finalReplaceIndex].replaceFlag) { finalReplaceIndex = vtIndices[finalReplaceIndex].replaceIndex; if (finalReplaceIndex == firstReplaceIndex) { //Debug.Log(string.Format("Cancle Replace: {0} with {1}", vtIndices[key].replaceIndex, firstReplaceIndex)); vtIndices[key].replaceFlag = false; break; } } if (vtIndices[key].replaceFlag) { //Debug.Log(string.Format("Replace: {0} to {1}", vtIndices[key].replaceIndex, finalReplaceIndex)); vtIndices[key].replaceIndex = finalReplaceIndex; continue; } } shrinkedVertices.Add(vertices[key]); shrinkedColors.Add(colors[key]); vtIndices[key].validPos = serialIndex++; } for (var i = 0; i < triangles.Count; i++) { var oriIndex = triangles[i]; var resultIndex = vtIndices[oriIndex].replaceFlag ? vtIndices[vtIndices[oriIndex].replaceIndex].validPos : vtIndices[oriIndex].validPos; triangles[i] = resultIndex; } //Debug.Log(string.Format("Reduced vertices of {0} : {1} to {2}", mesh.name, vertices.Count, shrinkedVertices.Count)); mesh.Vertices = shrinkedVertices; mesh.ColorIndices = shrinkedColors; } }