from nhf.build import Model, TargetKind, target, assembly, submodel from nhf.materials import Role, Material import nhf.utils import math from dataclasses import dataclass import cadquery as Cq @dataclass class Onbashira(Model): n_side: int = 6 # Dimensions of each side panel side_width: float = 200.0 side_length: float = 600.0 side_thickness: float = 25.4 / 8 material_side: Material = Material.WOOD_BIRCH material_brace: Material = Material.ALUMINUM def __post_init__(self): assert self.n_side >= 3 @property def angle_side(self) -> float: return 360 / self.n_side @property def angle_dihedral(self) -> float: return 180 - self.angle_side @property def barrel_radius(self) -> float: """ Calculate radius of the barrel to the centre """ return self.side_width / 2 / math.tan(math.radians(self.angle_side / 2)) @target(name="side-panel", kind=TargetKind.DXF) def profile_side_panel(self) -> Cq.Sketch: return ( Cq.Sketch() .rect(self.side_width, self.side_length) ) def side_panel(self) -> Cq.Workplane: w = self.side_width l = self.side_length result = ( Cq.Workplane() .placeSketch(self.profile_side_panel()) .extrude(self.side_thickness) ) intersector = ( Cq.Workplane('XZ') .polyline([ (-w/2, 0), (w/2, 0), (0, self.barrel_radius), ]) .close() .extrude(l) .translate(Cq.Vector(0, l/2,0)) ) # Intersect the side panel return result * intersector def assembly(self) -> Cq.Assembly: a = Cq.Assembly() side = self.side_panel() r = self.barrel_radius for i in range(6): a = a.addS( side, name=f"side{i}", material=self.material_side, role=Role.STRUCTURE | Role.DECORATION, loc=Cq.Location(0,0,0,0,i*60,0) * Cq.Location(0,0,-r) ) return a