File size: 1,446 Bytes
a43a8dc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8f5179d
 
 
 
 
6d6ac37
 
 
 
8f5179d
 
 
 
 
6d6ac37
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
import pymeshlab
import trimesh
import open3d as o3d

def mesh_to_pymesh(vertices, faces):
    mesh = pymeshlab.Mesh(vertex_matrix=vertices, face_matrix=faces)
    ms = pymeshlab.MeshSet()
    ms.add_mesh(mesh)
    return ms

def pymesh_to_trimesh(mesh):
    verts = mesh.vertex_matrix()#.tolist()
    faces = mesh.face_matrix()#.tolist()
    return trimesh.Trimesh(vertices=verts, faces=faces)  #, vID, fID

def simplify_mesh(mesh: trimesh.Trimesh, n_faces):
    if mesh.faces.shape[0] > n_faces:
        ms = mesh_to_pymesh(mesh.vertices, mesh.faces)
        ms.meshing_merge_close_vertices()
        ms.meshing_decimation_quadric_edge_collapse(targetfacenum = n_faces)
        return pymesh_to_trimesh(ms.current_mesh())
    else:
        return mesh

def repair_mesh_manifold(mesh_path):
    """Clean up non-manifold geometry (diso extraction / decimation can
    introduce it) so open3d's compute_uvatlas doesn't reject the mesh with
    UVAtlasPartition failed. pymeshlab can't write .glb directly, so route
    through trimesh for I/O like simplify_mesh does."""
    mesh = trimesh.load(mesh_path, force="mesh")
    ms = mesh_to_pymesh(mesh.vertices, mesh.faces)
    ms.meshing_remove_duplicate_faces()
    ms.meshing_remove_duplicate_vertices()
    ms.meshing_remove_unreferenced_vertices()
    ms.meshing_repair_non_manifold_edges()
    ms.meshing_repair_non_manifold_vertices()
    pymesh_to_trimesh(ms.current_mesh()).export(mesh_path)