diff --git a/nhf/touhou/yasaka_kanako/onbashira.py b/nhf/touhou/yasaka_kanako/onbashira.py index a576050..56e368b 100644 --- a/nhf/touhou/yasaka_kanako/onbashira.py +++ b/nhf/touhou/yasaka_kanako/onbashira.py @@ -21,6 +21,9 @@ class Onbashira(Model): side_thickness: float = 25.4 / 8 + section1_gohei_loc: float = 30.0 + gohei_bolt_diam: float = 6.0 + # Joints between two sets of side panels angle_joint_thickness: float = 15.0 # Z-axis size of each angle joint @@ -349,6 +352,104 @@ class Onbashira(Model): return result + @target(name="side-panel1", kind=TargetKind.DXF) + def profile_side_panel1(self) -> Cq.Sketch: + return ( + self.profile_side_panel( + length=self.side_length1, + hasFrontHole=False, + hasBackHole=True, + ) + .push([ + (0, self.side_length1/2 - self.section1_gohei_loc) + ]) + .circle(self.gohei_bolt_diam/2, mode="s") + ) + def side_panel1(self) -> Cq.Workplane: + l = self.side_length1 + w = self.side_width + sketch = self.profile_side_panel1() + result = ( + Cq.Workplane() + .placeSketch(sketch) + .extrude(self.side_thickness) + ) + # Bevel the edges + intersector = ( + Cq.Workplane('XZ') + .polyline([ + (-w/2, 0), + (w/2, 0), + (0, self.bulk_radius), + ]) + .close() + .extrude(l) + .translate(Cq.Vector(0, l/2, 0)) + ) + # Intersect the side panel + result = result * intersector + + # Mark all attachment points + t = self.side_thickness + for i, (x, y) in enumerate(self.angle_joint_bolt_position): + px = x + py = l / 2 - y + result.tagAbsolute(f"holeFPI{i}", (+px, py, t), direction="+Z") + result.tagAbsolute(f"holeFSI{i}", (-px, py, t), direction="+Z") + result.tagAbsolute(f"holeFPO{i}", (+px, py, 0), direction="-Z") + result.tagAbsolute(f"holeFSO{i}", (-px, py, 0), direction="-Z") + result.tagAbsolute(f"holeBPI{i}", (+px, -py, t), direction="+Z") + result.tagAbsolute(f"holeBSI{i}", (-px, -py, t), direction="+Z") + result.tagAbsolute(f"holeBPO{i}", (+px, -py, 0), direction="-Z") + result.tagAbsolute(f"holeBSO{i}", (-px, -py, 0), direction="-Z") + + return result + @target(name="side-panel2", kind=TargetKind.DXF) + def profile_side_panel2(self) -> Cq.Sketch: + return ( + self.profile_side_panel( + length=self.side_length2, + hasFrontHole=True, + hasBackHole=True, + ) + ) + @target(name="side-panel3", kind=TargetKind.DXF) + def profile_side_panel3(self) -> Cq.Sketch: + return ( + self.profile_side_panel( + length=self.side_length3, + hasFrontHole=True, + hasBackHole=True, + ) + ) + + def assembly_section1(self) -> Cq.Assembly: + a = Cq.Assembly() + side = self.side_panel1() + r = self.bulk_radius + for i in range(self.n_side): + a = a.addS( + side, + name=f"side{i}", + material=self.material_side, + role=Role.STRUCTURE | Role.DECORATION, + loc=Cq.Location.rot2d(i*360/self.n_side) * Cq.Location(-r,0,0,90,0,90), + ) + return a + def assembly_section(self, **kwargs) -> Cq.Assembly: + a = Cq.Assembly() + side = self.side_panel(**kwargs) + r = self.bulk_radius + for i in range(self.n_side): + a = a.addS( + side, + name=f"side{i}", + material=self.material_side, + role=Role.STRUCTURE | Role.DECORATION, + loc=Cq.Location.rot2d(i*360/self.n_side) * Cq.Location(-r,0,0,90,0,90), + ) + return a + @target(name="angle-joint") def angle_joint(self) -> Cq.Workplane: """ @@ -509,19 +610,6 @@ class Onbashira(Model): result.tagAbsolute("holeStatorR", (ri * math.cos(th), ri * math.sin(th), -h/2), direction="-Z") return result - def assembly_section(self, **kwargs) -> Cq.Assembly: - a = Cq.Assembly() - side = self.side_panel(**kwargs) - r = self.bulk_radius - for i in range(self.n_side): - a = a.addS( - side, - name=f"side{i}", - material=self.material_side, - role=Role.STRUCTURE | Role.DECORATION, - loc=Cq.Location.rot2d(i*360/self.n_side) * Cq.Location(-r,0,0,90,0,90), - ) - return a def assembly_ring(self, flanged=False) -> Cq.Assembly: a = Cq.Assembly() side = self.angle_joint_flanged() if flanged else self.angle_joint() @@ -542,7 +630,7 @@ class Onbashira(Model): a = ( a .add( - self.assembly_section(length=self.side_length1, hasFrontHole=False, hasBackHole=True), + self.assembly_section1(), name="section1", ) .add(