seedling tray generation script
This commit is contained in:
@@ -1 +1,2 @@
|
|||||||
stl/
|
stl/
|
||||||
|
__pycache__/
|
||||||
|
|||||||
+2
-12
@@ -5,24 +5,14 @@ import subprocess
|
|||||||
import sys
|
import sys
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from utils import ask_float
|
||||||
|
|
||||||
|
|
||||||
BASE_DIR = Path(__file__).resolve().parent
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
SCAD_DIR = BASE_DIR / "flower_pot"
|
SCAD_DIR = BASE_DIR / "flower_pot"
|
||||||
OUT_DIR = BASE_DIR / "stl"
|
OUT_DIR = BASE_DIR / "stl"
|
||||||
|
|
||||||
|
|
||||||
def ask_float(prompt: str) -> float:
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
value = float(input(prompt).strip())
|
|
||||||
if value <= 0:
|
|
||||||
print("Please enter a positive number.")
|
|
||||||
continue
|
|
||||||
return value
|
|
||||||
except ValueError:
|
|
||||||
print("Please enter a valid number.")
|
|
||||||
|
|
||||||
|
|
||||||
def render_scad(scad_file: Path, out_file: Path, base_radius: float, wall_height: float, wall_height_tray: float) -> None:
|
def render_scad(scad_file: Path, out_file: Path, base_radius: float, wall_height: float, wall_height_tray: float) -> None:
|
||||||
cmd = (
|
cmd = (
|
||||||
f'openscad '
|
f'openscad '
|
||||||
|
|||||||
@@ -0,0 +1,97 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
from utils import ask_int, ask_float
|
||||||
|
|
||||||
|
|
||||||
|
BASE_DIR = Path(__file__).resolve().parent
|
||||||
|
SCAD_DIR = BASE_DIR / "seedlings_tray"
|
||||||
|
OUT_DIR = BASE_DIR / "stl"
|
||||||
|
|
||||||
|
|
||||||
|
def render_scad(
|
||||||
|
scad_file: Path,
|
||||||
|
out_file: Path,
|
||||||
|
cols: int,
|
||||||
|
rows: int,
|
||||||
|
cell_size: float,
|
||||||
|
tray_height: float,
|
||||||
|
render_mode: str,
|
||||||
|
) -> None:
|
||||||
|
cmd = (
|
||||||
|
f'openscad '
|
||||||
|
f'-D cols={cols} '
|
||||||
|
f'-D rows={rows} '
|
||||||
|
f'-D cell_size={cell_size} '
|
||||||
|
f'-D tray_height={tray_height} '
|
||||||
|
f'-D \'render_mode="{render_mode}"\' '
|
||||||
|
f'-o "{out_file}" '
|
||||||
|
f'"{scad_file}"'
|
||||||
|
)
|
||||||
|
|
||||||
|
result = subprocess.run(
|
||||||
|
["bash", "-lc", 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:
|
||||||
|
if not SCAD_DIR.exists():
|
||||||
|
raise SystemExit(f"Missing SCAD directory: {SCAD_DIR}")
|
||||||
|
|
||||||
|
print("Dimensions less than 20 mm may result in unusable STL files.\n")
|
||||||
|
|
||||||
|
cols = ask_int("Number of columns (cols): ")
|
||||||
|
rows = ask_int("Number of rows (rows): ")
|
||||||
|
cell_size = ask_float("Inner cell size in mm (cell_size): ")
|
||||||
|
tray_height = ask_float("Tray height in mm (tray_height): ")
|
||||||
|
|
||||||
|
OUT_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
scad_file = SCAD_DIR / "seedlings-tray.scad"
|
||||||
|
if not scad_file.exists():
|
||||||
|
raise SystemExit(f"Missing file: {scad_file}")
|
||||||
|
|
||||||
|
# Render the tray only
|
||||||
|
render_scad(
|
||||||
|
scad_file,
|
||||||
|
OUT_DIR / "seedlings-tray.stl",
|
||||||
|
cols,
|
||||||
|
rows,
|
||||||
|
cell_size,
|
||||||
|
tray_height,
|
||||||
|
"tray_only",
|
||||||
|
)
|
||||||
|
|
||||||
|
# Render all plates in a grid
|
||||||
|
render_scad(
|
||||||
|
scad_file,
|
||||||
|
OUT_DIR / "plates.stl",
|
||||||
|
cols,
|
||||||
|
rows,
|
||||||
|
cell_size,
|
||||||
|
tray_height,
|
||||||
|
"plates_only",
|
||||||
|
)
|
||||||
|
|
||||||
|
print("\nDone.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/python3
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
|
||||||
|
def ask_int(prompt: str) -> int:
|
||||||
|
"""Prompt user for a positive integer."""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
value = int(input(prompt).strip())
|
||||||
|
if value <= 0:
|
||||||
|
print("Please enter a positive integer.")
|
||||||
|
continue
|
||||||
|
return value
|
||||||
|
except ValueError:
|
||||||
|
print("Please enter a valid integer.")
|
||||||
|
|
||||||
|
|
||||||
|
def ask_float(prompt: str) -> float:
|
||||||
|
"""Prompt user for a positive float."""
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
value = float(input(prompt).strip())
|
||||||
|
if value <= 0:
|
||||||
|
print("Please enter a positive number.")
|
||||||
|
continue
|
||||||
|
return value
|
||||||
|
except ValueError:
|
||||||
|
print("Please enter a valid number.")
|
||||||
Reference in New Issue
Block a user