"""Procedural watertight STL shapes (trimesh) for the v2 app. Geometry-neutral.""" from __future__ import annotations from pathlib import Path import trimesh def _save(mesh, out_path: Path): mesh.vertices -= mesh.bounds.mean(axis=0) # center out_path.parent.mkdir(parents=True, exist_ok=True) mesh.export(str(out_path)) def create_cylinder(radius, height, out_path): _save(trimesh.creation.cylinder(radius=radius, height=height), out_path) def create_sphere(radius, out_path): _save(trimesh.creation.icosphere(subdivisions=3, radius=radius), out_path) def create_box(length, width, height, out_path): _save(trimesh.creation.box(extents=[length, width, height]), out_path) def create_capsule(height, radius, out_path): _save(trimesh.creation.capsule(height=height, radius=radius), out_path) def create_cone(radius, height, out_path): _save(trimesh.creation.cone(radius=radius, height=height), out_path) def create_torus(major_radius, minor_radius, out_path): _save(trimesh.creation.torus(major_radius=major_radius, minor_radius=minor_radius), out_path)