from pathlib import Path import numpy as np,trimesh,coacd,json ROOT=Path(__file__).resolve().parents[1];out=ROOT/'output/foundationpose_spider_20260915/collision';out.mkdir(exist_ok=True) coacd.set_log_level('warn');report={} for name,file in [('upper','上半.stl'),('lower','下半.stl')]: m=trimesh.load(ROOT/'docs'/file) if name=='upper':m=trimesh.load(ROOT/'output/depth_ablation_red_20260916/red_box_closed.ply',process=False) print(name,'watertight',m.is_watertight,flush=True) parts=coacd.run_coacd(coacd.Mesh(m.vertices,m.faces),threshold=.03,max_convex_hull=20,preprocess_mode='auto',preprocess_resolution=60,resolution=1500,mcts_nodes=10,mcts_iterations=60,mcts_max_depth=3,merge=True,seed=0) for i,(v,f) in enumerate(parts):trimesh.Trimesh(v,f,process=False).export(out/f'{name}_{i:03d}.obj') report[name]={'parts':len(parts),'mesh_volume_m3':m.volume,'hull_volume_sum_m3':sum(trimesh.Trimesh(v,f,process=False).volume for v,f in parts),'approximation':'CoACD convex decomposition, threshold .03; not exact CAD collision'} print(name,report[name],flush=True) (out/'manifest.json').write_text(json.dumps(report,indent=2))