cosplay: Touhou/Houjuu Nue #4

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

View File

@ -129,6 +129,7 @@ class LinearActuator(Item):
combine='cut',
)
)
back.faces(">X").tag("dir")
back.copyWorkplane(Cq.Workplane('XZ')).tagPlane('conn')
result = (
Cq.Assembly()

View File

@ -170,23 +170,21 @@ class WingProfile(Model):
def shoulder_height(self) -> float:
return self.shoulder_joint.height
def outer_profile_s0(self) -> Cq.Sketch:
def outer_profile_s0(self) -> Cq.Edge:
"""
The outer boundary of s0 top/bottom slots
"""
tip_x = self.shoulder_tip_x
tip_y = self.shoulder_tip_y
return (
Cq.Sketch()
.spline([
return Cq.Edge.makeSpline(
[
Cq.Vector(*p)
for p in [
(0, 0),
(-30.0, 80.0),
(tip_x, tip_y)
])
#.segment(
# (tip_x, tip_y),
# (tip_x - 10, tip_y),
#)
(tip_x, tip_y),
]
]
)
def inner_profile_s0(self) -> Cq.Edge:
"""
@ -199,18 +197,17 @@ class WingProfile(Model):
dx1 = self.shoulder_base_bezier_x
dy1 = self.shoulder_base_bezier_y
sw = self.shoulder_width
return Cq.Edge.makeBezier(
[
Cq.Vector(*p)
for p in [
points = [
(tip_x, tip_y - sw),
(tip_x + dx2, tip_y - sw + dy2),
(-self.base_width + dx1, dy1),
(-self.base_width, 0),
]
]
return Cq.Edge.makeBezier(
[Cq.Vector(x, y) for x, y in points]
)
@property
def shoulder_angle_neutral(self) -> float:
"""
@ -224,24 +221,16 @@ class WingProfile(Model):
def profile_s0(self, top: bool = True) -> Cq.Sketch:
tip_x = self.shoulder_tip_x
tip_y = self.shoulder_tip_y
dx2 = self.shoulder_tip_bezier_x
dy2 = self.shoulder_tip_bezier_y
dx1 = self.shoulder_base_bezier_x
dy1 = self.shoulder_base_bezier_y
sw = self.shoulder_width
sketch = (
self.outer_profile_s0()
Cq.Sketch()
.edge(self.outer_profile_s0())
.segment((-self.base_width, 0), (0, 0))
.segment(
(tip_x, tip_y),
(tip_x, tip_y - sw),
)
.bezier([
(tip_x, tip_y - sw),
(tip_x + dx2, tip_y - sw + dy2),
(-self.base_width + dx1, dy1),
(-self.base_width, 0),
])
.edge(self.inner_profile_s0())
.assemble()
.push([self.shoulder_axle_loc.to2d_pos()])
.circle(self.shoulder_joint.radius, mode='a')
@ -265,7 +254,7 @@ class WingProfile(Model):
def outer_shell_s0(self) -> Cq.Workplane:
t = self.panel_thickness_s0
profile = Cq.Wire.assembleEdges(self.outer_profile_s0().edges().vals())
profile = self.outer_profile_s0()
result = (
Cq.Workplane('XZ')
.rect(t, self.root_height + t*2, centered=(False, False))
@ -277,17 +266,35 @@ class WingProfile(Model):
return result
def inner_shell_s0(self) -> Cq.Workplane:
t = self.panel_thickness_s0
#profile = Cq.Wire.assembleEdges(self.inner_profile_s0())
profile = self.inner_profile_s0()
result = (
Cq.Workplane('XZ')
.moveTo(-t, 0)
.rect(t, self.root_height + t*2, centered=(False, False))
.sweep(self.inner_profile_s0())
.sweep(profile, normal=(0,-1,0))
)
plane = result.copyWorkplane(Cq.Workplane('XZ'))
plane.moveTo(t, 0).tagPlane("bot")
plane.moveTo(t, self.root_height + t*2).tagPlane("top")
plane.moveTo(0, 0).tagPlane("bot")
plane.moveTo(0, self.root_height + t*2).tagPlane("top")
return result
@target(name="profile-s0-outer-shell", kind=TargetKind.DXF)
def outer_shell_s0_profile(self) -> Cq.Sketch:
"""
This part should be laser cut and then bent on a falsework to create the required shape.
"""
length = self.outer_profile_s0().Length()
height = self.root_height + self.panel_thickness_s0 * 2
return Cq.Sketch().rect(length, height)
@target(name="profile-s0-inner-shell", kind=TargetKind.DXF)
def inner_shell_s0_profile(self) -> Cq.Sketch:
"""
This part should be laser cut and then bent on a falsework to create the required shape.
"""
length = self.inner_profile_s0().Length()
height = self.root_height + self.panel_thickness_s0 * 2
return Cq.Sketch().rect(length, height)
@submodel(name="spacer-s0-shoulder-inner")
def spacer_s0_shoulder(self, left: bool=True) -> MountingBox:
"""
@ -331,7 +338,7 @@ class WingProfile(Model):
)
@submodel(name="spacer-s0-shoulder-outer")
def spacer_s0_shoulder_outer(self) -> MountingBox:
return self.spacer_s0_shoulder_inner(left=False)
return self.spacer_s0_shoulder(left=False)
@submodel(name="spacer-s0-base")
def spacer_s0_base(self) -> MountingBox:
@ -428,7 +435,7 @@ class WingProfile(Model):
("shoulder_right",
self.shoulder_axle_loc * axle_rotate * self.shoulder_joint.parent_lip_loc(left=False)),
("shoulder_act",
self.shoulder_axle_loc * axle_rotate * Cq.Location.from2d(120, -40)),
self.shoulder_axle_loc * axle_rotate * Cq.Location.from2d(120, -40, -30)),
("base", Cq.Location.from2d(base_dx, base_dy, 90)),
("electronic_mount", Cq.Location.from2d(-35, 65, 60)),
]
@ -436,11 +443,11 @@ class WingProfile(Model):
self.profile_s0(top=top),
self.panel_thickness_s0,
tags,
reverse=not top,
reverse=top,
)
h = self.panel_thickness if top else 0
h = 0 if top else self.panel_thickness_s0
result.copyWorkplane(Cq.Workplane('XZ')).moveTo(0, h).tagPlane("corner")
result.copyWorkplane(Cq.Workplane('XZ')).moveTo(-self.base_width, h).tagPlane("corner_left")
result.copyWorkplane(Cq.Workplane('XZ')).moveTo(-self.base_width, self.panel_thickness_s0 - h).tagPlane("corner_left")
return result
@assembly()
@ -449,9 +456,9 @@ class WingProfile(Model):
ignore_electronics: bool=False) -> Cq.Assembly:
result = (
Cq.Assembly()
.addS(self.surface_s0(top=True), name="bot",
.addS(self.surface_s0(top=False), name="bot",
material=self.mat_panel, role=self.role_panel)
.addS(self.surface_s0(top=False), name="top",
.addS(self.surface_s0(top=True), name="top",
material=self.mat_panel, role=self.role_panel,
loc=Cq.Location((0, 0, self.root_height + self.panel_thickness)))
.constrain("bot", "Fixed")
@ -462,10 +469,10 @@ class WingProfile(Model):
material=self.mat_panel, role=self.role_panel)
.constrain("bot?corner", "outer_shell?bot", "Plane", param=0)
.constrain("top?corner", "outer_shell?top", "Plane", param=0)
#.addS(self.inner_shell_s0(), name="inner_shell",
# material=self.mat_panel, role=self.role_panel)
#.constrain("bot?corner_left", "inner_shell?bot", "Point")
#.constrain("top?corner_left", "inner_shell?top", "Point")
.addS(self.inner_shell_s0(), name="inner_shell",
material=self.mat_panel, role=self.role_panel)
.constrain("bot?corner_left", "inner_shell?bot", "Plane", param=0)
.constrain("top?corner_left", "inner_shell?top", "Plane", param=0)
)
for o, tag in [
(self.spacer_s0_shoulder(left=True).generate(), "shoulder_left"),
@ -1122,6 +1129,9 @@ class WingProfile(Model):
"Plane", param=0)
.constrain("s0/shoulder_act?conn0", f"{tag_bracket}?conn_side",
"Plane")
# Directional constraints should be provided by the line
.constrain(f"{tag_bracket}?conn_mid", "s0/shoulder_act?top", "Axis", param=0)
.constrain(f"{tag_act}/back?dir", "s0/shoulder_act?conn0", "Axis", param=0)
)
if "root" in parts:
result.addS(self.root_joint.assembly(