cosplay: Touhou/Houjuu Nue #4
|
@ -129,6 +129,7 @@ class LinearActuator(Item):
|
|||
combine='cut',
|
||||
)
|
||||
)
|
||||
back.faces(">X").tag("dir")
|
||||
back.copyWorkplane(Cq.Workplane('XZ')).tagPlane('conn')
|
||||
result = (
|
||||
Cq.Assembly()
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Reference in New Issue