create a Config abstraction on the Python side

This commit is contained in:
2025-04-08 05:05:12 +00:00
parent eb975c1972
commit a2baab41e9
2 changed files with 53 additions and 19 deletions

37
main.py
View File

@@ -24,6 +24,7 @@ import sys
sys.path.append(os.path.join(os.getcwd(), "src"))
from config import Config
import case
import pinephone
import ldtek_battery
@@ -33,8 +34,6 @@ from cadquery.vis import _to_assy
from vtkmodules.vtkRenderingCore import vtkRenderWindow, vtkWindowToImageFilter
from vtkmodules.vtkIOImage import vtkPNGWriter
DEFAULT_BATTERY = "ldtek"
logger = logging.getLogger(__name__)
@@ -77,29 +76,27 @@ def export_png_image(obj: cq.Workplane, file_: str, orientation: str) -> None:
exporter.Write()
def _model(as_assy: bool=False) -> cq.Workplane:
logger.info("computing model ...")
battery_name = os.environ.get("CASE_BATTERY", DEFAULT_BATTERY)
render_phone = os.environ.get("CASE_RENDER_PHONE", "") not in ("", "0")
render_phone_only = os.environ.get("CASE_RENDER_PHONE_ONLY", "") not in ("", "0")
def _model(config: Config, as_assy: bool=False) -> cq.Workplane:
phone = pinephone.PinePhone()
if render_phone_only:
if config.render_phone_only:
return case.orient_for_printing(phone)
battery = None
if battery_name == "ldtek":
if config.battery == "ldtek":
battery = ldtek_battery.LdtekBattery()
return case.case(phone, battery=battery, render_phone=render_phone, as_assy=as_assy)
elif config.battery:
assert False, f"unknown battery: {battery!r}"
return case.case(phone, battery=battery, render_phone=config.render_phone, as_assy=as_assy)
_computedModels: dict[(bool,), cq.Workplane] = {}
def model(as_assy: bool=False) -> cq.Workplane:
def model(config: Config, as_assy: bool=False) -> cq.Workplane:
""" memoized wrapper around `_model` """
global _computedModels
key = (as_assy, )
if key not in _computedModels:
_computedModels[key] = _model(as_assy=as_assy)
_computedModels[key] = _model(config, as_assy=as_assy)
return _computedModels[key]
def main() -> None:
@@ -117,17 +114,19 @@ def main() -> None:
args = parser.parse_args()
config = Config.from_env()
if args.render_phone:
os.environ["CASE_RENDER_PHONE"] = "1"
config.render_phone = args.render_phone
if args.render_phone_only:
os.environ["CASE_RENDER_PHONE_ONLY"] = "1"
config.render_phone_only = args.render_phone_only
if args.battery:
os.environ["CASE_BATTERY"] = args.battery
config.battery = args.battery
if args.export_stl:
model_ = model()
model_ = model(config)
logger.info("exporting stl to %s", args.export_stl)
cq.exporters.export(model_, args.export_stl)
@@ -139,7 +138,7 @@ def main() -> None:
orientation = "back"
if "front" in args.export_png:
orientation = "front"
model_ = model(as_assy=True)
model_ = model(config, as_assy=True)
logger.info("exporting png to %s", args.export_png)
export_png_image(model_, args.export_png, orientation)
@@ -147,7 +146,7 @@ def main() -> None:
vtk_file = args.export_vtk
js_var, _ext = os.path.splitext(os.path.basename(vtk_file))
js_file = f'{vtk_file}.js'
model_ = model()
model_ = model(config)
logger.info("exporting VTK (for web rendering) to %s", vtk_file)
cq.exporters.export(model_, vtk_file, cq.exporters.ExportTypes.VTP)
@@ -168,4 +167,4 @@ if __name__ == "__main__":
else:
# this `result` var should be picked up by cadquery, in case we were imported by it.
# note that we don't actually get here until the user presses the `>` render button.
result = model()
result = model(Config.from_env())

35
src/config.py Normal file
View File

@@ -0,0 +1,35 @@
import os
from dataclasses import dataclass
DEFAULT_BATTERY = "ldtek"
@dataclass
class Config:
battery: str = DEFAULT_BATTERY
render_phone: bool = False
render_phone_only: bool = False
@staticmethod
def from_env() -> 'Config':
self_ = Config()
self_.populate_from_env()
return self_
def populate_from_env(self):
"""
read environment variables, updating `self` with any config discovered
"""
battery = os.environ.get("CASE_BATTERY")
if battery is not None:
self.battery = battery
render_phone = os.environ.get("CASE_RENDER_PHONE")
if render_phone is not None:
self.render_phone = render_phone not in ("", "0")
render_phone_only = os.environ.get("CASE_RENDER_PHONE_ONLY")
if render_phone_only is not None:
self.render_phone_only = render_phone_only not in ("", "0")