diff --git a/nhf/touhou/houjuu_nue/__init__.py b/nhf/touhou/houjuu_nue/__init__.py index 1c210b8..774be88 100644 --- a/nhf/touhou/houjuu_nue/__init__.py +++ b/nhf/touhou/houjuu_nue/__init__.py @@ -407,12 +407,15 @@ class Parameters(Model): ) hole_x = lip_ext - hole_dx / 2 for i in range(2): - plane = ( + x = hole_x - i * hole_dx + lip = lip.moveTo(x, 0).hole(self.wing_s1_spacer_hole_diam) + for i in range(2): + x = hole_x - i * hole_dx + ( lip - .moveTo(hole_x - i * hole_dx, 0) + .moveTo(x, 0) + .tagPlane(f"conn{1 - i}") ) - lip = plane.hole(self.wing_s1_spacer_hole_diam) - plane.tagPlane(f"hole{i}") loc_rotate = Cq.Location((0, 0, 0), (1, 0, 0), 180) result = ( @@ -473,7 +476,11 @@ class Parameters(Model): return result @target(name="wing/s1-shoulder-spacer", kind=TargetKind.DXF) - def wing_s1_shoulder_spacer(self) -> Cq.Workplane: + def wing_s1_shoulder_spacer(self, flipped=False) -> Cq.Workplane: + """ + if `flipped = True`, tag on the bottom face. This does not change the + geometry. + """ dx = self.wing_s1_shoulder_spacer_hole_dist result = ( Cq.Workplane('XZ') @@ -493,13 +500,13 @@ class Parameters(Model): result.faces(">Z").tag("mate2") # Tag the directrix - result.faces(">Y").tag("dir") + result.faces("Y").workplane() + plane = result.faces("Y").workplane() # Side closer to the parent is 0 - plane.moveTo(dx, 0).tagPlane("hole0") - plane.tagPlane("hole1") + plane.moveTo(dx if flipped else -dx, 0).tagPlane("conn0") + plane.tagPlane("conn1") return result @target(name="wing/r1s1", kind=TargetKind.DXF) @@ -509,7 +516,8 @@ class Parameters(Model): def wing_r1s1_panel(self, front=True) -> Cq.Workplane: profile = self.wing_r1s1_profile() anchors = [ - ("shoulder_bot", 10, 10), + ("shoulder_top", 10, 55), + ("shoulder_bot", 10, 5), ("middle", 50, -20), ("tip", 390, -150), ] @@ -530,45 +538,78 @@ class Parameters(Model): Cq.Assembly() .add(self.wing_r1s1_panel(front=True), name="panel_front", color=self.material_panel.color) + .constrain("panel_front", "Fixed") .add(self.wing_r1s1_panel(front=False), name="panel_back", color=self.material_panel.color) .constrain("panel_front@faces@>Z", "panel_back@faces@ Cq.Assembly: + def wing_r1_assembly(self, parts=["root", "shoulder", "s1"]) -> Cq.Assembly: result = ( Cq.Assembly() - .add(self.wing_root(), name="r1") - .add(self.shoulder_assembly(), name="shoulder") - .constrain("r1/scaffold", "Fixed") - .constrain("r1/scaffold?conn_top0", "shoulder/parent_top?conn0", "Plane") - .constrain("r1/scaffold?conn_top1", "shoulder/parent_top?conn1", "Plane") - .constrain("r1/scaffold?conn_bot0", "shoulder/parent_bot?conn0", "Plane") - .constrain("r1/scaffold?conn_bot1", "shoulder/parent_bot?conn1", "Plane") - .solve() ) - return result + if "root" in parts: + ( + result + .add(self.wing_root(), name="root") + .constrain("root/scaffold", "Fixed") + ) + if "shoulder" in parts: + result.add(self.shoulder_assembly(), name="shoulder") + + if "root" in parts and "shoulder" in parts: + ( + result + .constrain("root/scaffold?conn_top0", "shoulder/parent_top?conn0", "Plane") + .constrain("root/scaffold?conn_top1", "shoulder/parent_top?conn1", "Plane") + .constrain("root/scaffold?conn_bot0", "shoulder/parent_bot?conn0", "Plane") + .constrain("root/scaffold?conn_bot1", "shoulder/parent_bot?conn1", "Plane") + ) + + if "s1" in parts: + result.add(self.wing_r1s1_assembly(), name="s1") + + if "s1" in parts and "shoulder" in parts: + ( + result + .constrain("shoulder/child/lip_bot?conn0", + "s1/shoulder_bot_spacer?conn0", + "Plane") + .constrain("shoulder/child/lip_bot?conn1", + "s1/shoulder_bot_spacer?conn1", + "Plane") + .constrain("shoulder/child/lip_top?conn0", + "s1/shoulder_top_spacer?conn0", + "Plane") + .constrain("shoulder/child/lip_top?conn1", + "s1/shoulder_top_spacer?conn1", + "Plane") + ) + return result.solve() @assembly() def wings_assembly(self) -> Cq.Assembly: @@ -584,10 +625,10 @@ class Parameters(Model): .add(self.wing_root(), name="w0_l1") .constrain("harness/base", "Fixed") .constrain("w0_r1/joint?mate", "harness/r1?mate", "Plane") - .constrain("w0_r1/joint?directrix", "harness/r1?directrix", + .constrain("w0_r1/joint?dir", "harness/r1?dir", "Axis", param=7 * a_tooth) .constrain("w0_l1/joint?mate", "harness/l1?mate", "Plane") - .constrain("w0_l1/joint?directrix", "harness/l1?directrix", + .constrain("w0_l1/joint?dir", "harness/l1?dir", "Axis", param=-1 * a_tooth) .solve() ) diff --git a/nhf/touhou/houjuu_nue/test.py b/nhf/touhou/houjuu_nue/test.py index 42bd607..2f610d5 100644 --- a/nhf/touhou/houjuu_nue/test.py +++ b/nhf/touhou/houjuu_nue/test.py @@ -21,6 +21,9 @@ class Test(unittest.TestCase): self.assertLess(bbox.xlen, 255, msg=msg) self.assertLess(bbox.ylen, 255, msg=msg) self.assertLess(bbox.zlen, 255, msg=msg) + def test_wings_assembly(self): + p = M.Parameters() + p.wings_assembly() def test_trident_assembly(self): p = M.Parameters() assembly = p.trident_assembly()