Skip to content

Instantly share code, notes, and snippets.

@simonwittber
Created May 29, 2019 14:56
Show Gist options
  • Save simonwittber/0297a2a8127efddd818d624ce14bd6a8 to your computer and use it in GitHub Desktop.
Save simonwittber/0297a2a8127efddd818d624ce14bd6a8 to your computer and use it in GitHub Desktop.
Extract a submesh from a mesh into a new mesh instance, for Unity3D.
public static Mesh Extract(Mesh m, int meshIndex)
{
var vertices = m.vertices;
var normals = m.normals;
var newVerts = new List<Vector3>();
var newNorms = new List<Vector3>();
var newTris = new List<int>();
var triangles = m.GetTriangles(meshIndex);
for (var i = 0; i < triangles.Length; i += 3)
{
var A = triangles[i + 0];
var B = triangles[i + 1];
var C = triangles[i + 2];
newVerts.Add(vertices[A]);
newVerts.Add(vertices[B]);
newVerts.Add(vertices[C]);
newNorms.Add(normals[A]);
newNorms.Add(normals[B]);
newNorms.Add(normals[C]);
newTris.Add(newTris.Count);
newTris.Add(newTris.Count);
newTris.Add(newTris.Count);
}
var mesh = new Mesh();
mesh.indexFormat = newVerts.Count > 65536 ? IndexFormat.UInt32 : IndexFormat.UInt16;
mesh.SetVertices(newVerts);
mesh.SetNormals(newNorms);
mesh.SetTriangles(newTris, 0, true);
return mesh;
}
@janTrstek
Copy link

public static Mesh Extract(Mesh m, int meshIndex)
{
    var vertices = m.vertices;
    var normals = m.normals;
    var uvs = m.uv;

    var newVerts = new List<Vector3>();
    var newNorms = new List<Vector3>();
    var newUVs = new List<Vector2>();
    var newTris = new List<int>();
    var triangles = m.GetTriangles(meshIndex);
    for (var i = 0; i < triangles.Length; i += 3)
    {
        var A = triangles[i + 0];
        var B = triangles[i + 1];
        var C = triangles[i + 2];
        newVerts.Add(vertices[A]);
        newVerts.Add(vertices[B]);
        newVerts.Add(vertices[C]);
        newNorms.Add(normals[A]);
        newNorms.Add(normals[B]);
        newNorms.Add(normals[C]);
        newUVs.Add(uvs[A]);
        newUVs.Add(uvs[B]);
        newUVs.Add(uvs[C]);
        newTris.Add(newTris.Count);
        newTris.Add(newTris.Count);
        newTris.Add(newTris.Count);
    }
    var mesh = new Mesh();
    mesh.indexFormat = newVerts.Count > 65536 ? IndexFormat.UInt32 : IndexFormat.UInt16;
    mesh.SetVertices(newVerts);
    mesh.SetNormals(newNorms);
    mesh.SetUVs(0, newUVs);
    mesh.SetTriangles(newTris, 0, true);

    return mesh;
}

thx for this,
upper copy paste is modified to also include UVs

@taigama
Copy link

taigama commented Nov 4, 2024

I updated the codes for Reversing Translation from the GameObject which contain the MeshFilter and MeshRenderer which render the mesh.

public static Mesh ExtractSubMesh(Mesh m, int meshIndex, Transform meshRenderHolder)
{
    Vector3 pos = meshRenderHolder.position;
    Quaternion rot = meshRenderHolder.rotation;
    rot.y = -rot.y;// correct the translation calculation
    
    var vertices = m.vertices;
    var normals = m.normals;
    var uvs = m.uv;
    var newVerts = new List<Vector3>();
    var newNorms = new List<Vector3>();
    var newUVs = new List<Vector2>();
    var newTris = new List<int>();
    var triangles = m.GetTriangles(meshIndex);
    int totalTris = 0;

    
    for (var i = 0; i < triangles.Length; i += 3)
    {
        var A = triangles[i + 0];
        var B = triangles[i + 1];
        var C = triangles[i + 2];

        newVerts.Add(rot * (vertices[A] - pos));
        newVerts.Add(rot * (vertices[B] - pos));
        newVerts.Add(rot * (vertices[C] - pos));

        newNorms.Add(rot * normals[A]);
        newNorms.Add(rot * normals[B]);
        newNorms.Add(rot * normals[C]);

        newUVs.Add(uvs[A]);
        newUVs.Add(uvs[B]);
        newUVs.Add(uvs[C]);

        newTris.Add(totalTris++);
        newTris.Add(totalTris++);
        newTris.Add(totalTris++);
    }

    var mesh = new Mesh();
    mesh.indexFormat = newVerts.Count > 65536 ? IndexFormat.UInt32 : IndexFormat.UInt16;
    mesh.SetVertices(newVerts);
    mesh.SetNormals(newNorms);
    mesh.SetUVs(0, newUVs);
    mesh.SetTriangles(newTris, 0, true);
    mesh.RecalculateBounds();
    
    mesh.name = m.name + '_' + meshIndex;

    return mesh;
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment