Numberkruncher I modified your code to use uniform spatial partitioning. Now it should be like 100 times faster on large meshes. Hope this can help someone.
public static void AutoWeld (Mesh mesh, float threshold, float bucketStep) {
Vector3[] oldVertices = mesh.vertices;
Vector3[] newVertices = new Vector3[oldVertices.Length];
int[] old2new = new int[oldVertices.Length];
int newSize = 0;
// Find AABB
Vector3 min = new Vector3 (float.MaxValue, float.MaxValue, float.MaxValue);
Vector3 max = new Vector3 (float.MinValue, float.MinValue, float.MinValue);
for (int i = 0; i < oldVertices.Length; i++) {
if (oldVertices_.x < min.x) min.x = oldVertices*.x;*_
if (oldVertices_.y < min.y) min.y = oldVertices*.y;
if (oldVertices.z < min.z) min.z = oldVertices.z;
if (oldVertices.x > max.x) max.x = oldVertices.x;
if (oldVertices.y > max.y) max.y = oldVertices.y;
if (oldVertices.z > max.z) max.z = oldVertices.z;
}*_
// Make cubic buckets, each with dimensions “bucketStep”
int bucketSizeX = Mathf.FloorToInt ((max.x - min.x) / bucketStep) + 1;
int bucketSizeY = Mathf.FloorToInt ((max.y - min.y) / bucketStep) + 1;
int bucketSizeZ = Mathf.FloorToInt ((max.z - min.z) / bucketStep) + 1;
List[,] buckets = new List[bucketSizeX, bucketSizeY, bucketSizeZ];
// Make new vertices
for (int i = 0; i < oldVertices.Length; i++) {
// Determine which bucket it belongs to
int x = Mathf.FloorToInt ((oldVertices*.x - min.x) / bucketStep);*
int y = Mathf.FloorToInt ((oldVertices*.y - min.y) / bucketStep);*
int z = Mathf.FloorToInt ((oldVertices*.z - min.z) / bucketStep);*
// Check to see if it’s already been added
if (buckets[x, y, z] == null)
buckets[x, y, z] = new List (); // Make buckets lazily
for (int j = 0; j < buckets[x, y, z].Count; j++) {
Vector3 to = newVertices[buckets[x, y, z][j]] - oldVertices*;*
if (Vector3.SqrMagnitude (to) < threshold) {
old2new = buckets[x, y, z][j];
goto skip; // Skip to next old vertex if this one is already there
}
}
// Add new vertex
newVertices[newSize] = oldVertices*;*
buckets[x, y, z].Add (newSize);
old2new = newSize;
newSize++;
skip:;
}
// Make new triangles
int[] oldTris = mesh.triangles;
int[] newTris = new int[oldTris.Length];
for (int i = 0; i < oldTris.Length; i++) {
newTris = old2new[oldTris*];*
}
Vector3[] finalVertices = new Vector3[newSize];
for (int i = 0; i < newSize; i++)
finalVertices = newVertices*;*
mesh.Clear();
mesh.vertices = finalVertices;
mesh.triangles = newTris;
mesh.RecalculateNormals ();
mesh.Optimize ();
}
Thank you for clarifying that for me. My intention was not to reduce the number of vertices for improved performance, but rather to remove certain visual artefacts that occur on some joins. In Blender the process of welding solves the problem. My scene is procedurally generated at design time.
– Subantarctic