#!/bin/python3 from __future__ import annotations import subprocess import sys from pathlib import Path from utils import check_openscad, ask_optional_float BASE_DIR = Path(__file__).resolve().parent SCAD_DIR = BASE_DIR / "esp32" SCAD_FILE = SCAD_DIR / "esp32s3_devkitc1_case.scad" OUT_DIR = BASE_DIR / "stl" BOARD_PARAMS = [ ("pcb_l", "PCB length, USB-C end to antenna end (pcb_l) in mm"), ("pcb_w", "PCB width (pcb_w) in mm"), ("pin_below", "PCB underside to pin tips (pin_below) in mm"), ("header_x0", "First pin centre, measured from the USB end (header_x0) in mm"), ] def render_scad(scad_file: Path, out_file: Path, part: str, overrides: dict[str, float]) -> None: cmd = ["openscad", "-D", f'part="{part}"'] for name, value in overrides.items(): cmd += ["-D", f"{name}={value}"] cmd += ["-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 {part} from {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() if not SCAD_DIR.exists(): raise SystemExit(f"Missing SCAD directory: {SCAD_DIR}") if not SCAD_FILE.exists(): raise SystemExit(f"Missing file: {SCAD_FILE}") print("ESP32-S3-DevKitC-1 case generator (base + lid).") print("Measure your board and enter the values, or press Enter to keep the defaults of the .scad file.\n") overrides: dict[str, float] = {} for name, prompt in BOARD_PARAMS: value = ask_optional_float(f"{prompt}") if value is not None: overrides[name] = value OUT_DIR.mkdir(parents=True, exist_ok=True) render_scad(SCAD_FILE, OUT_DIR / "esp32s3_devkitc1_case.stl", "print", overrides) print("\nDone.") if __name__ == "__main__": main()