#!/bin/python3 from __future__ import annotations import subprocess import sys from pathlib import Path from utils import ask_float, check_openscad BASE_DIR = Path(__file__).resolve().parent SCAD_DIR = BASE_DIR / "flower_pot" OUT_DIR = BASE_DIR / "stl" def render_scad( scad_file: Path, out_file: Path, pot_height: float, pot_diameter: float, reservoir_depth: float, ) -> None: cmd = [ "openscad", "-D", f"pot_height={pot_height}", "-D", f"pot_diameter={pot_diameter}", "-D", f"reservoir_depth={reservoir_depth}", "-D", 'part="print"', "-o", str(out_file), str(scad_file), ] print("\nRendering:") print(" ".join(f'"{arg}"' if " " in arg else arg for arg in cmd)) result = subprocess.run( cmd, cwd=BASE_DIR, text=True, capture_output=True, ) if result.returncode != 0: print(f"\nFailed to render {scad_file.name}") if result.stdout: print(result.stdout) if result.stderr: print(result.stderr, file=sys.stderr) raise SystemExit(result.returncode) print(f"Generated {out_file}") def main() -> None: check_openscad() scad_file = SCAD_DIR / "spiral_pot.scad" if not scad_file.exists(): raise SystemExit(f"Missing SCAD file: {scad_file}") print("Self-watering spiral flower pot generator") print("The model has built-in geometry constraints, so values that are too small may cause OpenSCAD assertions to fail.\n") pot_height = ask_float("Pot height (mm): ") pot_diameter = ask_float("Pot diameter (mm): ") reservoir_depth = ask_float("Reservoir depth (mm): ") OUT_DIR.mkdir(parents=True, exist_ok=True) # Keep the selected dimensions in the filename. diameter_str = f"{pot_diameter:g}" height_str = f"{pot_height:g}" reservoir_str = f"{reservoir_depth:g}" out_file = ( OUT_DIR / f"spiral_pot_{diameter_str}x{height_str}mm_{reservoir_str}mm_reservoir.stl" ) render_scad( scad_file, out_file, pot_height, pot_diameter, reservoir_depth, ) print("\nDone.") if __name__ == "__main__": main()