cosplay: Touhou/Houjuu Nue #4
|
@ -44,10 +44,7 @@ class MountingBox(Model):
|
||||||
thickness: float = 1.0
|
thickness: float = 1.0
|
||||||
|
|
||||||
# List of (x, y), diam
|
# List of (x, y), diam
|
||||||
holes: list[Hole] = field(default_factory=lambda: [
|
holes: list[Hole] = field(default_factory=lambda: [])
|
||||||
Hole(x=5, y=5, diam=3),
|
|
||||||
Hole(x=20, y=10, diam=5),
|
|
||||||
])
|
|
||||||
hole_diam: Optional[float] = None
|
hole_diam: Optional[float] = None
|
||||||
|
|
||||||
centred: Tuple[bool, bool] = (False, True)
|
centred: Tuple[bool, bool] = (False, True)
|
||||||
|
|
|
@ -178,7 +178,7 @@ class RootJoint(Model):
|
||||||
Specify knob position to determine the position of the knob from fully
|
Specify knob position to determine the position of the knob from fully
|
||||||
inserted (0) or fully uninserted (1)
|
inserted (0) or fully uninserted (1)
|
||||||
"""
|
"""
|
||||||
knob_h = self.total_height + self.child_mount_thickness
|
knob_h = self.hex_nut.thickness
|
||||||
result = (
|
result = (
|
||||||
Cq.Assembly()
|
Cq.Assembly()
|
||||||
.addS(self.parent(), name="parent",
|
.addS(self.parent(), name="parent",
|
||||||
|
|
|
@ -20,8 +20,8 @@ class WingProfile(Model):
|
||||||
|
|
||||||
name: str = "wing"
|
name: str = "wing"
|
||||||
|
|
||||||
root_joint: RootJoint = field(default_factory=lambda: RootJoint())
|
|
||||||
base_width: float = 80.0
|
base_width: float = 80.0
|
||||||
|
root_joint: RootJoint = field(default_factory=lambda: RootJoint())
|
||||||
|
|
||||||
panel_thickness: float = 25.4 / 16
|
panel_thickness: float = 25.4 / 16
|
||||||
spacer_thickness: float = 25.4 / 8
|
spacer_thickness: float = 25.4 / 8
|
||||||
|
@ -32,7 +32,7 @@ class WingProfile(Model):
|
||||||
shoulder_width: float = 36.0
|
shoulder_width: float = 36.0
|
||||||
shoulder_tip_x: float = -260.0
|
shoulder_tip_x: float = -260.0
|
||||||
shoulder_tip_y: float = 165.0
|
shoulder_tip_y: float = 165.0
|
||||||
shoulder_mid_x: float = -105.0
|
shoulder_mid_x: float = -125.0
|
||||||
shoulder_mid_y: float = 75.0
|
shoulder_mid_y: float = 75.0
|
||||||
|
|
||||||
s1_thickness: float = 25.0
|
s1_thickness: float = 25.0
|
||||||
|
@ -95,7 +95,7 @@ class WingProfile(Model):
|
||||||
assert self.wrist_joint.total_thickness < min(self.s2_thickness, self.s3_thickness)
|
assert self.wrist_joint.total_thickness < min(self.s2_thickness, self.s3_thickness)
|
||||||
|
|
||||||
self.shoulder_joint.angle_neutral = -self.shoulder_angle_neutral - self.shoulder_angle_bias
|
self.shoulder_joint.angle_neutral = -self.shoulder_angle_neutral - self.shoulder_angle_bias
|
||||||
self.shoulder_axle_loc = Cq.Location.from2d(self.shoulder_tip_x, self.shoulder_tip_y - self.shoulder_width / 2, -self.shoulder_angle_bias)
|
self.shoulder_axle_loc = Cq.Location.from2d(self.shoulder_tip_x, self.shoulder_tip_y - self.shoulder_width / 2, self.shoulder_angle_bias)
|
||||||
|
|
||||||
assert self.spacer_thickness == self.root_joint.child_mount_thickness
|
assert self.spacer_thickness == self.root_joint.child_mount_thickness
|
||||||
|
|
||||||
|
@ -193,7 +193,8 @@ class WingProfile(Model):
|
||||||
@submodel(name="spacer-s0-shoulder")
|
@submodel(name="spacer-s0-shoulder")
|
||||||
def spacer_s0_shoulder(self) -> MountingBox:
|
def spacer_s0_shoulder(self) -> MountingBox:
|
||||||
"""
|
"""
|
||||||
Should be cut
|
Shoulder side serves double purpose for mounting shoulder joint and
|
||||||
|
structural support
|
||||||
"""
|
"""
|
||||||
holes = [
|
holes = [
|
||||||
hole
|
hole
|
||||||
|
@ -215,7 +216,7 @@ class WingProfile(Model):
|
||||||
@submodel(name="spacer-s0-shoulder")
|
@submodel(name="spacer-s0-shoulder")
|
||||||
def spacer_s0_base(self) -> MountingBox:
|
def spacer_s0_base(self) -> MountingBox:
|
||||||
"""
|
"""
|
||||||
Should be cut
|
Base side connects to H-S joint
|
||||||
"""
|
"""
|
||||||
assert self.root_joint.child_width < self.base_width
|
assert self.root_joint.child_width < self.base_width
|
||||||
assert self.root_joint.child_corner_dx * 2 < self.base_width
|
assert self.root_joint.child_corner_dx * 2 < self.base_width
|
||||||
|
@ -237,17 +238,40 @@ class WingProfile(Model):
|
||||||
centred=(True, True),
|
centred=(True, True),
|
||||||
flip_y=self.flip,
|
flip_y=self.flip,
|
||||||
)
|
)
|
||||||
|
@submodel(name="spacer-s0-mid3")
|
||||||
|
def spacer_s0_mid3(self) -> MountingBox:
|
||||||
|
return MountingBox(
|
||||||
|
length=self.root_height,
|
||||||
|
width=40,
|
||||||
|
thickness=self.spacer_thickness,
|
||||||
|
flip_y=self.flip
|
||||||
|
)
|
||||||
|
@submodel(name="spacer-s0-mid2")
|
||||||
|
def spacer_s0_mid2(self) -> MountingBox:
|
||||||
|
return MountingBox(
|
||||||
|
length=self.root_height,
|
||||||
|
width=60,
|
||||||
|
thickness=self.spacer_thickness,
|
||||||
|
flip_y=self.flip
|
||||||
|
)
|
||||||
|
|
||||||
def surface_s0(self, top: bool = False) -> Cq.Workplane:
|
def surface_s0(self, top: bool = False) -> Cq.Workplane:
|
||||||
base_dx = -(self.base_width - self.root_joint.child_width) / 2
|
base_dx = -(self.base_width - self.root_joint.child_width) / 2 - 10
|
||||||
base_dy = self.root_joint.hirth_joint.joint_height
|
base_dy = self.root_joint.hirth_joint.joint_height
|
||||||
loc_tip = Cq.Location(0, -self.shoulder_joint.parent_lip_width / 2)
|
loc_tip = Cq.Location(0, -self.shoulder_joint.parent_lip_width / 2)
|
||||||
|
mid_spacer_loc = (
|
||||||
|
Cq.Location.from2d(0, -self.shoulder_width/2) *
|
||||||
|
self.shoulder_axle_loc *
|
||||||
|
Cq.Location.rot2d(self.shoulder_joint.angle_neutral)
|
||||||
|
)
|
||||||
tags = [
|
tags = [
|
||||||
("shoulder",
|
("shoulder",
|
||||||
self.shoulder_axle_loc *
|
self.shoulder_axle_loc *
|
||||||
self.shoulder_joint.parent_arm_loc() *
|
self.shoulder_joint.parent_arm_loc() *
|
||||||
loc_tip),
|
loc_tip),
|
||||||
("base", Cq.Location.from2d(base_dx, base_dy, 90)),
|
("base", Cq.Location.from2d(base_dx, base_dy, 90)),
|
||||||
|
("mid3", mid_spacer_loc * Cq.Location.from2d(90, 0)),
|
||||||
|
("mid2", mid_spacer_loc * Cq.Location.from2d(150, 0)),
|
||||||
]
|
]
|
||||||
result = extrude_with_markers(
|
result = extrude_with_markers(
|
||||||
self.profile_s0(),
|
self.profile_s0(),
|
||||||
|
@ -279,7 +303,9 @@ class WingProfile(Model):
|
||||||
)
|
)
|
||||||
for o, tag in [
|
for o, tag in [
|
||||||
(self.spacer_s0_shoulder().generate(), "shoulder"),
|
(self.spacer_s0_shoulder().generate(), "shoulder"),
|
||||||
(self.spacer_s0_base().generate(), "base")
|
(self.spacer_s0_base().generate(), "base"),
|
||||||
|
(self.spacer_s0_mid3().generate(), "mid3"),
|
||||||
|
(self.spacer_s0_mid2().generate(), "mid2"),
|
||||||
]:
|
]:
|
||||||
top_tag, bot_tag = "top", "bot"
|
top_tag, bot_tag = "top", "bot"
|
||||||
if self.flip:
|
if self.flip:
|
||||||
|
|
Loading…
Reference in New Issue