| | import logging |
| |
|
| | import numpy as np |
| |
|
| | try: |
| | import pymeshlab |
| |
|
| | PYMESHLAB_AVAILABLE = True |
| | except ImportError: |
| | logging.warning( |
| | "pymeshlab is not installed or could not be loaded. Please install it with `pip install pymeshlab`." |
| | ) |
| | PYMESHLAB_AVAILABLE = False |
| | from typing import Any |
| |
|
| | |
| | class pymeshlab: |
| | MeshSet = Any |
| | Mesh = Any |
| |
|
| |
|
| | def create_pymeshset(vertices: np.ndarray, faces: np.ndarray): |
| | """ |
| | Creates a MeshLab MeshSet given a list of vertices and faces. |
| | """ |
| | assert PYMESHLAB_AVAILABLE, "pymeshlab is not installed or could not be loaded." |
| | |
| | mesh_set = pymeshlab.MeshSet() |
| | input_mesh = pymeshlab.Mesh(vertex_matrix=vertices, face_matrix=faces) |
| | mesh_set.add_mesh(input_mesh, "input_mesh") |
| | logging.info("Mesh successfully added to pymeshlab MeshSet.") |
| | return mesh_set |
| |
|
| |
|
| | def cleanup(ms: pymeshlab.MeshSet): |
| | """ |
| | General cleanup for a given Mesh. Removes degenerate elements from the |
| | geometry. |
| | """ |
| | ms.meshing_remove_null_faces() |
| | ms.meshing_remove_folded_faces() |
| | ms.meshing_remove_duplicate_vertices() |
| | ms.meshing_remove_duplicate_faces() |
| | ms.meshing_remove_t_vertices() |
| | ms.meshing_remove_unreferenced_vertices() |
| |
|
| |
|
| | def remove_floaters(ms: pymeshlab.MeshSet, threshold: float = 0.005): |
| | """ |
| | Remove any floating artifacts that exist from our mesh generation. |
| | """ |
| | assert PYMESHLAB_AVAILABLE, "pymeshlab is not installed or could not be loaded." |
| | ms.meshing_remove_connected_component_by_diameter( |
| | mincomponentdiag=pymeshlab.PercentageValue(15), removeunref=True |
| | ) |
| |
|
| |
|
| | def simplify_mesh(ms: pymeshlab.MeshSet, target_face_num: int): |
| | """ |
| | Simplify the mesh to the target number of faces. |
| | """ |
| | ms.meshing_decimation_quadric_edge_collapse( |
| | targetfacenum=target_face_num, |
| | qualitythr=0.4, |
| | preservenormal=True, |
| | autoclean=True, |
| | ) |
| |
|
| |
|
| | def save_mesh(ms: pymeshlab.MeshSet, output_path: str): |
| | """ |
| | Save the mesh to a file. |
| | """ |
| | ms.save_current_mesh(output_path) |
| | logging.info(f"Mesh saved to {output_path}.") |
| |
|
| |
|
| | def postprocess_mesh(ms: pymeshlab.MeshSet, target_face_num: int, output_path: str): |
| | """ |
| | Postprocess the mesh to the target number of faces. |
| | """ |
| | cleanup(ms) |
| | remove_floaters(ms) |
| | simplify_mesh(ms, target_face_num) |
| |
|