pill container: script to generate the STL files
This commit is contained in:
1 parent
16e69fb10d
commit
7620cec17d
3 files changed
+138
No files matched your search
@@ -28,3 +28,10 @@ To generate the box and lid STL file:
|
|||||||
```bash
|
```bash
|
||||||
python parametric_box.py
|
python parametric_box.py
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### pill_container
|
||||||
|
Parameterized pill containers with a sliding lid.
|
||||||
|
To generate the box and lid STL file:
|
||||||
|
```bash
|
||||||
|
python pill_container.py
|
||||||
|
```
|
||||||
@@ -0,0 +1,118 @@
|
|||||||
|
#!/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
|
||||||
|
|
||||||
|
|
||||||
|
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:
|
||||||
|
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()
|
||||||
@@ -26,3 +26,16 @@ def ask_float(prompt: str) -> float:
|
|||||||
return value
|
return value
|
||||||
except ValueError:
|
except ValueError:
|
||||||
print("Please enter a valid number.")
|
print("Please enter a valid number.")
|
||||||
|
|
||||||
|
def ask_yes_no(prompt: str) -> bool:
|
||||||
|
"""Prompt the user for a yes/no answer."""
|
||||||
|
while True:
|
||||||
|
answer = input(prompt).strip().lower()
|
||||||
|
|
||||||
|
if answer in {"y", "yes"}:
|
||||||
|
return True
|
||||||
|
|
||||||
|
if answer in {"n", "no"}:
|
||||||
|
return False
|
||||||
|
|
||||||
|
print("Please enter yes or no. [y/n]")
|
||||||
Reference in new issue
Block a user