""" Use CoACD to obtain convex collision mesh from an input mesh. """ # https://github.com/SarahWeiii/CoACD/blob/main/python/package/bin/coacd try: import trimesh except ModuleNotFoundError: print("trimesh is required. Please install with `pip install trimesh`") exit(1) import argparse import os import sys import coacd import numpy as np if __name__ == "__main__": parser = argparse.ArgumentParser() parser.add_argument( "-i", "--input", type=str, required=True, help="input model loaded by trimesh. Supported formats: glb, gltf, obj, off, ply, stl, etc.", ) parser.add_argument( "-o", "--output", type=str, required=True, help="output model exported by trimesh. Supported formats: glb, gltf, obj, off, ply, stl, etc.", ) parser.add_argument("--quiet", action="store_true", help="do not print logs") parser.add_argument( "-t", "--threshold", type=float, default=0.05, help="termination criteria in [0.01, 1] (0.01: most fine-grained; 1: most coarse)", ) parser.add_argument( "-pm", "--preprocess-mode", type=str, default="auto", help="No remeshing before running CoACD. Only suitable for manifold input.", ) parser.add_argument( "-r", "--resolution", type=int, default=2000, help="surface samping resolution for Hausdorff distance computation", ) parser.add_argument( "-nm", "--no-merge", action="store_true", help="If merge is enabled, try to reduce total number of parts by merging.", ) parser.add_argument( "-c", "--max-convex-hull", type=int, default=-1, help="max # convex hulls in the result, -1 for no limit, works only when merge is enabled", ) parser.add_argument( "-mi", "--mcts_iteration", type=int, default=150, help="Number of MCTS iterations.", ) parser.add_argument( "-md", "--mcts-max-depth", type=int, default=3, help="Maximum depth for MCTS search.", ) parser.add_argument( "-mn", "--mcts-node", type=int, default=20, help="Number of cut candidates for MCTS.", ) parser.add_argument( "-pr", "--prep-resolution", type=int, default=50, help="Preprocessing resolution.", ) parser.add_argument( "--pca", action="store_true", help="Use PCA to align input mesh. Suitable for non-axis-aligned mesh.", ) parser.add_argument("--seed", type=int, default=0, help="Random seed.") args = parser.parse_args() input_file = args.input output_file = args.output if not os.path.isfile(input_file): print(input_file, "is not a file") exit(1) if args.quiet: coacd.set_log_level("error") mesh = trimesh.load(input_file, force="mesh") mesh = coacd.Mesh(mesh.vertices, mesh.faces) result = coacd.run_coacd( mesh, threshold=args.threshold, max_convex_hull=args.max_convex_hull, preprocess_mode=args.preprocess_mode, preprocess_resolution=args.prep_resolution, resolution=args.resolution, mcts_nodes=args.mcts_node, mcts_iterations=args.mcts_iteration, mcts_max_depth=args.mcts_max_depth, pca=args.pca, merge=not args.no_merge, seed=args.seed, ) mesh_parts = [] for vs, fs in result: mesh_parts.append(trimesh.Trimesh(vs, fs)) scene = trimesh.Scene() np.random.seed(0) for p in mesh_parts: p.visual.vertex_colors[:, :3] = (np.random.rand(3) * 255).astype(np.uint8) scene.add_geometry(p) scene.export(output_file)