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) |