cosplay: Touhou/Houjuu Nue #4

Open
aniva wants to merge 189 commits from touhou/houjuu-nue into main
2 changed files with 77 additions and 33 deletions
Showing only changes of commit 234e1b7adc - Show all commits

View File

@ -407,12 +407,15 @@ class Parameters(Model):
) )
hole_x = lip_ext - hole_dx / 2 hole_x = lip_ext - hole_dx / 2
for i in range(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 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) loc_rotate = Cq.Location((0, 0, 0), (1, 0, 0), 180)
result = ( result = (
@ -473,7 +476,11 @@ class Parameters(Model):
return result return result
@target(name="wing/s1-shoulder-spacer", kind=TargetKind.DXF) @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 dx = self.wing_s1_shoulder_spacer_hole_dist
result = ( result = (
Cq.Workplane('XZ') Cq.Workplane('XZ')
@ -493,13 +500,13 @@ class Parameters(Model):
result.faces(">Z").tag("mate2") result.faces(">Z").tag("mate2")
# Tag the directrix # Tag the directrix
result.faces(">Y").tag("dir") result.faces("<Y").tag("dir")
# Tag the holes # Tag the holes
plane = result.faces(">Y").workplane() plane = result.faces("<Y" if flipped else ">Y").workplane()
# Side closer to the parent is 0 # Side closer to the parent is 0
plane.moveTo(dx, 0).tagPlane("hole0") plane.moveTo(dx if flipped else -dx, 0).tagPlane("conn0")
plane.tagPlane("hole1") plane.tagPlane("conn1")
return result return result
@target(name="wing/r1s1", kind=TargetKind.DXF) @target(name="wing/r1s1", kind=TargetKind.DXF)
@ -509,7 +516,8 @@ class Parameters(Model):
def wing_r1s1_panel(self, front=True) -> Cq.Workplane: def wing_r1s1_panel(self, front=True) -> Cq.Workplane:
profile = self.wing_r1s1_profile() profile = self.wing_r1s1_profile()
anchors = [ anchors = [
("shoulder_bot", 10, 10), ("shoulder_top", 10, 55),
("shoulder_bot", 10, 5),
("middle", 50, -20), ("middle", 50, -20),
("tip", 390, -150), ("tip", 390, -150),
] ]
@ -530,45 +538,78 @@ class Parameters(Model):
Cq.Assembly() Cq.Assembly()
.add(self.wing_r1s1_panel(front=True), name="panel_front", .add(self.wing_r1s1_panel(front=True), name="panel_front",
color=self.material_panel.color) color=self.material_panel.color)
.constrain("panel_front", "Fixed")
.add(self.wing_r1s1_panel(front=False), name="panel_back", .add(self.wing_r1s1_panel(front=False), name="panel_back",
color=self.material_panel.color) color=self.material_panel.color)
.constrain("panel_front@faces@>Z", "panel_back@faces@<Z", "Point", .constrain("panel_front@faces@>Z", "panel_back@faces@<Z", "Point",
param=self.wing_s1_thickness) param=self.wing_s1_thickness)
) )
for tag in ["shoulder_bot", "middle", "tip"]: for tag in ["shoulder_top", "shoulder_bot"]:
name = f"{tag}_spacer"
flipped = tag.endswith("top")
(
result
.add(self.wing_s1_shoulder_spacer(flipped=flipped), name=name,
color=self.material_bracket.color)
.constrain(f"panel_front?{tag}", f"{name}?mate1", "Plane")
.constrain(f"panel_back?{tag}", f"{name}?mate2", "Plane")
.constrain(f"{name}?dir", "FixedAxis", param=(0, 1, 0))
)
for tag in ["middle", "tip"]:
( (
result result
.add(self.wing_s1_spacer(), name=f"{tag}_spacer", .add(self.wing_s1_spacer(), name=f"{tag}_spacer",
color=self.material_bracket.color) color=self.material_bracket.color)
.constrain(f"panel_front?{tag}", f"{tag}_spacer?mate1", "Plane") .constrain(f"panel_front?{tag}", f"{tag}_spacer?mate1", "Plane")
.constrain(f"panel_back?{tag}", f"{tag}_spacer?mate2", "Plane") .constrain(f"panel_back?{tag}", f"{tag}_spacer?mate2", "Plane")
.constrain(f"{name}?dir", "FixedAxis", param=(0, 1, 0))
) )
( return result.solve()
result
.add(self.shoulder_assembly(), name="shoulder")
.constrain("shoulder_bot_spacer?dir",
"shoulder/child/core?mate_bot",
"Plane")
)
result.solve()
return result
@assembly() @assembly()
def wing_r1_assembly(self) -> Cq.Assembly: def wing_r1_assembly(self, parts=["root", "shoulder", "s1"]) -> Cq.Assembly:
result = ( result = (
Cq.Assembly() 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() @assembly()
def wings_assembly(self) -> Cq.Assembly: def wings_assembly(self) -> Cq.Assembly:
@ -584,10 +625,10 @@ class Parameters(Model):
.add(self.wing_root(), name="w0_l1") .add(self.wing_root(), name="w0_l1")
.constrain("harness/base", "Fixed") .constrain("harness/base", "Fixed")
.constrain("w0_r1/joint?mate", "harness/r1?mate", "Plane") .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) "Axis", param=7 * a_tooth)
.constrain("w0_l1/joint?mate", "harness/l1?mate", "Plane") .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) "Axis", param=-1 * a_tooth)
.solve() .solve()
) )

View File

@ -21,6 +21,9 @@ class Test(unittest.TestCase):
self.assertLess(bbox.xlen, 255, msg=msg) self.assertLess(bbox.xlen, 255, msg=msg)
self.assertLess(bbox.ylen, 255, msg=msg) self.assertLess(bbox.ylen, 255, msg=msg)
self.assertLess(bbox.zlen, 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): def test_trident_assembly(self):
p = M.Parameters() p = M.Parameters()
assembly = p.trident_assembly() assembly = p.trident_assembly()