feat: Add build system

This commit is contained in:
Leni Aniva 2024-07-03 23:15:39 -07:00
parent e75e640623
commit 6201683c00
Signed by: aniva
GPG Key ID: 4D9B1C8D10EA4C50
5 changed files with 99 additions and 2 deletions

3
.gitignore vendored
View File

@ -7,3 +7,6 @@ result
# Python # Python
__pycache__ __pycache__
*.py[cod] *.py[cod]
# Model build output
/build

81
nhf/build.py Normal file
View File

@ -0,0 +1,81 @@
"""
The NHF build system
Usage: For any parametric assembly, inherit the `Model` class, and mark the
output objects with the `@target` decorator
"""
from pathlib import Path
from typing import Union
import cadquery as Cq
from colorama import Fore, Style
class Target:
def __init__(self,
method,
name: str):
self._method = method
self.name = name
def __call__(self, obj, *args, **kwargs):
return self._method(obj, *args, **kwargs)
@classmethod
def methods(cls, subject):
"""
List of all methods of a class or objects annotated with this decorator.
"""
def g():
for name in dir(subject):
method = getattr(subject, name)
if isinstance(method, Target):
yield name, method
return {name: method for name, method in g()}
def target(name, **kwargs):
"""
Decorator for annotating a build output
"""
def f(method):
return Target(method, name=name, **kwargs)
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:
"""
Base class for a parametric assembly
"""
def target_names(self) -> list[str]:
"""
List of decorated target functions
"""
return list(Target.methods(self).keys())
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"
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}", end="")
_to_shape(model).exportStl(str(output_file))
if verbose >= 1:
print("\r", end="")
print(f"{Fore.GREEN}Built{Style.RESET_ALL} {output_file}")

View File

@ -1,4 +1,9 @@
""" """
To build, execute
```
python3 nhf/touhou/houjuu_nue/__init__.py
```
This cosplay consists of 3 components: This cosplay consists of 3 components:
## Trident ## Trident
@ -32,11 +37,12 @@ import nhf.handle
from nhf import Material from nhf import Material
from nhf.joints import HirthJoint from nhf.joints import HirthJoint
from nhf.handle import Handle from nhf.handle import Handle
from nhf.build import Model, target
import nhf.touhou.houjuu_nue.wing as MW import nhf.touhou.houjuu_nue.wing as MW
import nhf.touhou.houjuu_nue.trident as MT import nhf.touhou.houjuu_nue.trident as MT
@dataclass @dataclass
class Parameters: class Parameters(Model):
""" """
Defines dimensions for the Houjuu Nue cosplay Defines dimensions for the Houjuu Nue cosplay
""" """
@ -179,6 +185,7 @@ class Parameters:
(-dx, dx), (-dx, dx),
] ]
@target(name="hs_joint_parent")
def hs_joint_parent(self): def hs_joint_parent(self):
""" """
Parent part of the Houjuu-Scarlett joint, which is composed of a Hirth Parent part of the Houjuu-Scarlett joint, which is composed of a Hirth
@ -322,3 +329,8 @@ class Parameters:
def trident_assembly(self): def trident_assembly(self):
return MT.trident_assembly(self.trident_handle) return MT.trident_assembly(self.trident_handle)
if __name__ == '__main__':
p = Parameters()
p.build_all()

2
poetry.lock generated
View File

@ -857,4 +857,4 @@ files = [
[metadata] [metadata]
lock-version = "2.0" lock-version = "2.0"
python-versions = "^3.10" python-versions = "^3.10"
content-hash = "caf46b526858dbf2960b0204782140ad072d96f7b3f161ac7e9db0d9b709b25a" content-hash = "ec47ccffd60fbda610a5c3725fc064a08b1b794f23084672bd62beb20b1b19f7"

View File

@ -10,6 +10,7 @@ python = "^3.10"
cadquery = "^2.4.0" cadquery = "^2.4.0"
build123d = "^0.5.0" build123d = "^0.5.0"
numpy = "^1.26.4" numpy = "^1.26.4"
colorama = "^0.4.6"
[build-system] [build-system]
requires = ["poetry-core"] requires = ["poetry-core"]