diff --git a/nhf/build.py b/nhf/build.py index 5da3d01..c3b0e4a 100644 --- a/nhf/build.py +++ b/nhf/build.py @@ -2,25 +2,69 @@ The NHF build system Usage: For any parametric assembly, inherit the `Model` class, and mark the -output objects with the `@target` decorator +output objects with the `@target` decorator. Each marked function should only +take `self` as an argument. +```python +class BuildScaffold(Model): + + @target(name="obj1") + def o1(self): + return Cq.Solid.makeBox(10, 10, 10) + + def o2(self): + return Cq.Solid.makeCylinder(10, 20) +``` """ +from enum import Enum from pathlib import Path from typing import Union from functools import wraps from colorama import Fore, Style import cadquery as Cq +class TargetKind(Enum): + + STL = "stl", + DXF = "dxf", + + def __init__(self, ext: str): + self.ext = ext + class Target: def __init__(self, method, - name: str): + name: str, + kind: TargetKind = TargetKind.STL, + **kwargs): self._method = method self.name = name + self.kind = kind + self.kwargs = kwargs def __str__(self): return f"" def __call__(self, obj, *args, **kwargs): + """ + Raw call function which passes arguments directly to `_method` + """ return self._method(obj, *args, **kwargs) + def file_name(self, file_name): + return f"{file_name}.{self.kind.ext}" + def write_to(self, obj, path: str): + x = self._method(obj) + if self.kind == TargetKind.STL: + assert isinstance(x, Union[ + Cq.Workplane, Cq.Shape, Cq.Compound, Cq.Assembly]) + if isinstance(x, Cq.Workplane): + x = x.val() + if isinstance(x, Cq.Assembly): + x = x.toCompound() + x.exportStl(path, **self.kwargs) + elif self.kind == TargetKind.DXF: + assert isinstance(x, Cq.Workplane) + Cq.exporters.exportDXF(x, path, **self.kwargs) + else: + assert False, f"Invalid kind: {self.kind}" @classmethod def methods(cls, subject): @@ -49,13 +93,6 @@ def target(name, **deco_kwargs): return wrapper return f -def _to_shape(x: Union[Cq.Workplane, Cq.Shape, Cq.Compound, Cq.Assembly]) -> Cq.Shape: - if isinstance(x, Cq.Workplane): - x = x.val() - if isinstance(x, Cq.Assembly): - x = x.toCompound() - return x - class Model: """ @@ -76,22 +113,21 @@ class Model: total += 1 return total - def build_all(self, output_dir: Union[Path, str] ="build", verbose=1): + def build_all(self, output_dir: Union[Path, str] = "build", verbose=1): """ Build all targets in this model """ output_dir = Path(output_dir) output_dir.mkdir(exist_ok=True, parents=True) - for k, f in Target.methods(self).items(): - output_file = output_dir / f"{k}.stl" + for k, target in Target.methods(self).items(): + output_file = output_dir / target.file_name(k) if output_file.is_file(): if verbose >= 1: print(f"{Fore.GREEN}Skipping{Style.RESET_ALL} {output_file}") continue - model = f(self) if verbose >= 1: print(f"{Fore.BLUE}Building{Style.RESET_ALL} {output_file}") - _to_shape(model).exportStl(str(output_file)) + target.write_to(self, str(output_file)) if verbose >= 1: print(f"{Fore.GREEN}Built{Style.RESET_ALL} {output_file}") diff --git a/nhf/touhou/houjuu_nue/__init__.py b/nhf/touhou/houjuu_nue/__init__.py index 37a91a4..ba99b00 100644 --- a/nhf/touhou/houjuu_nue/__init__.py +++ b/nhf/touhou/houjuu_nue/__init__.py @@ -33,7 +33,7 @@ from dataclasses import dataclass, field import unittest import cadquery as Cq from nhf import Material -from nhf.build import Model, target +from nhf.build import Model, TargetKind, target from nhf.parts.joints import HirthJoint from nhf.parts.handle import Handle import nhf.touhou.houjuu_nue.wing as MW @@ -113,11 +113,6 @@ class Parameters(Model): "Wing root must be large enough to accomodate joint" - def print_geometries(self): - return [ - self.hs_joint_parent() - ] - def harness_profile(self) -> Cq.Sketch: """ Creates the harness shape @@ -148,6 +143,7 @@ class Parameters(Model): ) return sketch + @target(name="harness", kind=TargetKind.DXF) def harness(self) -> Cq.Shape: """ Creates the harness shape @@ -249,7 +245,8 @@ class Parameters(Model): result.faces(" Cq.Shape: + @target(name="wing_root") + def wing_root(self) -> Cq.Assembly: """ Generate the wing root which contains a Hirth joint at its base and a rectangular opening on its side, with the necessary interfaces.