#!/bin/python3 from __future__ import annotations import json import subprocess import sys from pathlib import Path from utils import ask_float, ask_int, ask_yes_no, check_openscad BASE_DIR = Path(__file__).resolve().parent SCAD_DIR = BASE_DIR / "pill_container" OUT_DIR = BASE_DIR / "stl" DAYS_OF_WEEK = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday", ] def render_scad( scad_file: Path, out_file: Path, inner_dimension: float, cases: int, engraving: str, ) -> None: """Render one pill container to an STL file.""" cmd = [ "openscad", "-D", f"X={inner_dimension}", "-D", f"cases={cases}", "-D", f"engraving={json.dumps(engraving)}", "-D", 'part="plate"', "-o", str(out_file), str(scad_file), ] result = subprocess.run( cmd, cwd=BASE_DIR, text=True, capture_output=True, ) if result.returncode != 0: print(f"\nFailed to render {out_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() if not SCAD_DIR.exists(): raise SystemExit(f"Missing SCAD directory: {SCAD_DIR}") scad_file = SCAD_DIR / "pill_container.scad" if not scad_file.exists(): raise SystemExit(f"Missing OpenSCAD file: {scad_file}") print("Pill container generator\n") print("Dimensions less than 20 mm may result in unusable STL files.\n") use_day_engraving = ask_yes_no("Generate engraved containers for each day of the week? [y/n]: ") inner_dimension = ask_float("Inner compartment dimension in mm (recommended 20mm): ") cases = ask_int("Number of compartments (cases): ") OUT_DIR.mkdir(parents=True, exist_ok=True) if use_day_engraving: for day in DAYS_OF_WEEK: output_file = OUT_DIR / f"pill-container-{day.lower()}.stl" render_scad( scad_file=scad_file, out_file=output_file, inner_dimension=inner_dimension, cases=cases, engraving=day, ) else: output_file = OUT_DIR / "pill-container.stl" render_scad( scad_file=scad_file, out_file=output_file, inner_dimension=inner_dimension, cases=cases, engraving="", ) print("\nDone.") if __name__ == "__main__": main()