Cosplay/nhf/parts/item.py

68 lines
1.7 KiB
Python
Raw Permalink Normal View History

2024-07-19 00:58:10 -07:00
from typing import Union, Optional
from collections import Counter
from dataclasses import dataclass
import cadquery as Cq
from nhf.materials import Role, KEY_ROLE, KEY_ITEM
@dataclass(frozen=True)
class Item:
"""
A pre-fabricated item
"""
mass: float
#@property
#def mass(self) -> float:
# """
# Mass, in grams
# """
# return self._mass
#@mass.setter
#def mass(self, value):
# assert value >= 0, "Mass cannot be negative"
# self._mass = value
@property
def name(self) -> str:
pass
@property
def role(self) -> Optional[Role]:
return None
2024-07-21 00:04:59 -07:00
def generate(self, **kwargs) -> Union[Cq.Solid, Cq.Assembly, Cq.Workplane]:
2024-07-19 00:58:10 -07:00
"""
Creates an assembly for this item. Subclass should implement this
"""
return Cq.Assembly()
2024-07-19 14:06:13 -07:00
def assembly(self, **kwargs) -> Cq.Assembly:
2024-07-19 00:58:10 -07:00
"""
Interface for creating assembly with the necessary metadata
"""
2024-07-19 14:06:13 -07:00
a = self.generate(**kwargs)
2024-07-21 00:04:59 -07:00
if isinstance(a, Cq.Workplane) or isinstance(a, Cq.Solid):
2024-07-19 00:58:10 -07:00
a = Cq.Assembly(a)
2024-07-19 21:00:10 -07:00
if role := self.role:
a.metadata[KEY_ROLE] = role
a.color = role.color_avg()
2024-07-19 00:58:10 -07:00
assert isinstance(a, Cq.Assembly)
assert KEY_ITEM not in a.metadata
a.metadata[KEY_ITEM] = self
return a
@staticmethod
def count(a: Cq.Assembly) -> Counter:
"""
Counts the number of items
"""
occ = Counter()
for _, obj in a.traverse():
if KEY_ITEM not in obj.metadata:
continue
item = obj.metadata[KEY_ITEM]
assert isinstance(item, Item)
occ[item.name] += 1
return occ