cosplay: Touhou/Houjuu Nue #4

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

View File

@ -1050,6 +1050,8 @@ class ElbowJoint(Model):
parent_arm_radius: float = 40.0 parent_arm_radius: float = 40.0
lip_thickness: float = 5.0 lip_thickness: float = 5.0
# Extra bit on top of the lip to connect to actuator mount
child_lip_extra_length: float = 1.0
lip_length: float = 60.0 lip_length: float = 60.0
hole_pos: list[float] = field(default_factory=lambda: [15, 25]) hole_pos: list[float] = field(default_factory=lambda: [15, 25])
parent_arm_width: float = 10.0 parent_arm_width: float = 10.0
@ -1069,8 +1071,9 @@ class ElbowJoint(Model):
flexor: Optional[Flexor] = None flexor: Optional[Flexor] = None
# Rotates the entire flexor # Rotates the entire flexor
flexor_offset_angle: float = 0 flexor_offset_angle: float = 0
# Rotates the surface of the mount # Rotates the surface of the mount relative to radially inwards
flexor_mount_rot: float = 0 flexor_mount_angle_parent: float = 0
flexor_mount_angle_child: float = -90
def __post_init__(self): def __post_init__(self):
assert self.child_arm_radius > self.disk_joint.radius_housing assert self.child_arm_radius > self.disk_joint.radius_housing
@ -1133,7 +1136,8 @@ class ElbowJoint(Model):
) -> Cq.Location: ) -> Cq.Location:
# Moves the hole so the axle of the mount is perpendicular to it # Moves the hole so the axle of the mount is perpendicular to it
loc_mount = Cq.Location.from2d(self.flexor.mount_height, 0) * Cq.Location.rot2d(180) loc_mount = Cq.Location.from2d(self.flexor.mount_height, 0) * Cq.Location.rot2d(180)
loc_mount_orient = Cq.Location.rot2d(self.flexor_mount_rot * (-1 if child else 1)) mount_angle = self.flexor_mount_angle_child if child else self.flexor_mount_angle_parent
loc_mount_orient = Cq.Location.rot2d(mount_angle)
# Moves the hole to be some distance apart from 0 # Moves the hole to be some distance apart from 0
mount_r, mount_loc_angle, mount_parent_r = self.flexor.open_pos() mount_r, mount_loc_angle, mount_parent_r = self.flexor.open_pos()
loc_span = Cq.Location.from2d(mount_r if child else mount_parent_r, 0) loc_span = Cq.Location.from2d(mount_r if child else mount_parent_r, 0)
@ -1182,12 +1186,23 @@ class ElbowJoint(Model):
loc_cut_rel = Cq.Location((0, self.disk_joint.spring.radius_inner, -self.disk_joint.disk_bot_thickness)) loc_cut_rel = Cq.Location((0, self.disk_joint.spring.radius_inner, -self.disk_joint.disk_bot_thickness))
disk_cut = self.disk_joint._disk_cut().located( disk_cut = self.disk_joint._disk_cut().located(
loc_lip.inverse * loc_cut_rel * loc_disk) loc_lip.inverse * loc_cut_rel * loc_disk)
lip_extra = Cq.Solid.makeBox(
length=self.child_lip_extra_length,
width=self.total_thickness,
height=self.lip_thickness,
).located(Cq.Location((
self.lip_length / 2,
-self.total_thickness / 2,
0,
)))
result = ( result = (
Cq.Assembly() Cq.Assembly()
.add(self.disk_joint.disk(), name="disk", .add(self.disk_joint.disk(), name="disk",
loc=loc_rot_neutral * Cq.Location((0, 0, -dz), (0,0,1), angle)) loc=loc_rot_neutral * Cq.Location((0, 0, -dz), (0,0,1), angle))
.add(self.lip().cut(disk_cut), name="lip", .add(self.lip().cut(disk_cut), name="lip",
loc=loc_rot_neutral * loc_disk.inverse * loc_lip) loc=loc_rot_neutral * loc_disk.inverse * loc_lip)
.add(lip_extra, name="lip_extra",
loc=loc_rot_neutral * loc_disk.inverse * loc_lip)
) )
# Orientes the hole surface so it faces +X # Orientes the hole surface so it faces +X
loc_thickness = Cq.Location((-self.lip_thickness, 0, 0), (0, 1, 0), 90) loc_thickness = Cq.Location((-self.lip_thickness, 0, 0), (0, 1, 0), 90)

View File

@ -64,6 +64,7 @@ class WingProfile(Model):
actuator=LINEAR_ACTUATOR_50, actuator=LINEAR_ACTUATOR_50,
flexor_offset_angle=30, flexor_offset_angle=30,
parent_arm_width=15, parent_arm_width=15,
child_lip_extra_length=8,
flip=False, flip=False,
)) ))
# Distance between the two spacers on the elbow, halved # Distance between the two spacers on the elbow, halved
@ -99,12 +100,12 @@ class WingProfile(Model):
wrist_bot_loc: Cq.Location wrist_bot_loc: Cq.Location
wrist_height: float wrist_height: float
elbow_rotate: float = 10.0 elbow_rotate: float = 10.0
elbow_joint_overlap_median: float = 0.3
wrist_joint_overlap_median: float = 0.5
wrist_rotate: float = -30.0 wrist_rotate: float = -30.0
# Position of the elbow axle with 0 being bottom and 1 being top (flipped on the left side) # Position of the elbow axle with 0 being bottom and 1 being top (flipped on the left side)
elbow_axle_pos: float = 0.5 elbow_axle_pos: float
wrist_axle_pos: float = 0.0 wrist_axle_pos: float
elbow_joint_overlap_median: float
wrist_joint_overlap_median: float
# False for the right side, True for the left side # False for the right side, True for the left side
flip: bool flip: bool
@ -1089,6 +1090,10 @@ class WingR(WingProfile):
ring_radius_inner: float = 22.0 ring_radius_inner: float = 22.0
flip: bool = False flip: bool = False
elbow_axle_pos: float = 0.4
wrist_axle_pos: float = 0.0
elbow_joint_overlap_median: float = 0.35
wrist_joint_overlap_median: float = 0.5
def __post_init__(self): def __post_init__(self):
super().__post_init__() super().__post_init__()
@ -1099,6 +1104,8 @@ class WingR(WingProfile):
* Cq.Location.rot2d(self.arrow_angle) \ * Cq.Location.rot2d(self.arrow_angle) \
* Cq.Location.from2d(0, self.arrow_height + self.wrist_height) * Cq.Location.from2d(0, self.arrow_height + self.wrist_height)
self.ring_loc = self.wrist_top_loc * self.ring_rel_loc self.ring_loc = self.wrist_top_loc * self.ring_rel_loc
self.elbow_joint.flexor_offset_angle = 15
self.elbow_joint.flexor_mount_angle_child = -75
assert self.ring_radius > self.ring_radius_inner assert self.ring_radius > self.ring_radius_inner
assert 0 > self.blade_overlap_angle > self.arrow_angle assert 0 > self.blade_overlap_angle > self.arrow_angle
@ -1316,7 +1323,6 @@ class WingL(WingProfile):
flip: bool = True flip: bool = True
elbow_axle_pos: float = 0.4 elbow_axle_pos: float = 0.4
wrist_axle_pos: float = 0.5 wrist_axle_pos: float = 0.5
elbow_joint_overlap_median: float = 0.5 elbow_joint_overlap_median: float = 0.5
wrist_joint_overlap_median: float = 0.5 wrist_joint_overlap_median: float = 0.5