File size: 3,898 Bytes
e479c46 | 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 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | """
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)
|