cosplay: Touhou/Houjuu Nue #4

Open
aniva wants to merge 189 commits from touhou/houjuu-nue into main
4 changed files with 32 additions and 17 deletions
Showing only changes of commit e744250c6c - Show all commits

View File

@ -21,7 +21,7 @@ class Role(Enum):
STRUCTURE = _color('gray', 0.4) STRUCTURE = _color('gray', 0.4)
DECORATION = _color('lightseagreen', 0.4) DECORATION = _color('lightseagreen', 0.4)
ELECTRONIC = _color('mediumorchid', 0.5) ELECTRONIC = _color('mediumorchid', 0.5)
MARKER = _color('white', 1.0) MARKER = _color('cyan', 1.0)
def __init__(self, color: Cq.Color): def __init__(self, color: Cq.Color):
self.color = color self.color = color

View File

@ -599,7 +599,9 @@ class Parameters(Model):
"s2/elbow_top_spacer?conn1", "s2/elbow_top_spacer?conn1",
"Plane") "Plane")
) )
return result.solve() if len(parts) > 1:
result.solve()
return result
@assembly() @assembly()
def wings_assembly(self) -> Cq.Assembly: def wings_assembly(self) -> Cq.Assembly:

View File

@ -262,7 +262,7 @@ class Beam:
.add(self.foot(), name="top", .add(self.foot(), name="top",
loc=Cq.Location((0, h, 0))) loc=Cq.Location((0, h, 0)))
.add(self.foot(), name="bot", .add(self.foot(), name="bot",
loc=Cq.Location((0, -h, 0), (0, 0, 1), 180)) loc=Cq.Location((0, -h, 0), (1, 0, 0), 180))
) )
return result return result
@ -424,7 +424,10 @@ class DiskJoint(Model):
)) ))
) )
result.faces(">Z").tag("mate") result.faces(">Z").tag("mate")
result.faces(">Z").workplane().tagPlane("dir", direction="+X") result.faces(">Z").workplane().tagPlane("dirX", direction="+X")
# two directional vectors are required to make the angle constrain
# unambiguous
result.faces(">Z").workplane().tagPlane("dirY", direction="+Y")
result = result.cut( result = result.cut(
self self
.wall() .wall()
@ -486,17 +489,15 @@ class DiskJoint(Model):
housing_lower: str, housing_lower: str,
housing_upper: str, housing_upper: str,
disk: str, disk: str,
angle: Tuple[float, float, float] = (0, 0, 0), angle: float,
) -> Cq.Assembly: ) -> Cq.Assembly:
"""
The angle supplied must be perpendicular to the disk normal.
"""
( (
assembly assembly
.constrain(f"{disk}?mate_bot", f"{housing_lower}?mate", "Plane") .constrain(f"{disk}?mate_bot", f"{housing_lower}?mate", "Plane")
.constrain(f"{disk}?mate_top", f"{housing_upper}?mate", "Plane") .constrain(f"{disk}?mate_top", f"{housing_upper}?mate", "Plane")
.constrain(f"{housing_lower}?dir", f"{housing_upper}?dir", "Axis") .constrain(f"{housing_lower}?dirX", f"{housing_upper}?dir", "Axis")
.constrain(f"{disk}?dir", "FixedRotation", angle) .constrain(f"{housing_lower}?dirX", f"{disk}?dir", "Axis", param=angle)
.constrain(f"{housing_lower}?dirY", f"{disk}?dir", "Axis", param=angle - 90)
) )
@ -519,7 +520,7 @@ class DiskJoint(Model):
housing_lower="housing_lower", housing_lower="housing_lower",
housing_upper="housing_upper", housing_upper="housing_upper",
disk="disk", disk="disk",
angle=(0, 0, angle), angle=angle,
) )
return result.solve() return result.solve()
@ -567,10 +568,16 @@ class ElbowJoint:
def child_joint(self) -> Cq.Assembly: def child_joint(self) -> Cq.Assembly:
angle = -self.disk_joint.tongue_span / 2 angle = -self.disk_joint.tongue_span / 2
dz = self.disk_joint.disk_thickness / 2 dz = self.disk_joint.disk_thickness / 2
# We need to ensure the disk is on the "other" side so
flip = Cq.Location((0, 0, 0), (0, 0, 1), 180)
result = ( result = (
self.child_beam.beam() self.child_beam.beam()
.add(self.disk_joint.disk(), name="disk", .add(self.disk_joint.disk(), name="disk",
loc=Cq.Location((-self.child_arm_radius, 0, -dz), (0, 0, 1), angle)) loc=flip * Cq.Location((-self.child_arm_radius, 0, -dz), (0, 0, 1), angle))
.constrain("disk", "Fixed")
.constrain("top", "Fixed")
.constrain("bot", "Fixed")
.solve()
) )
return result return result
@ -600,24 +607,27 @@ class ElbowJoint:
loc=axial_offset * Cq.Location((0, 0, housing_dz))) loc=axial_offset * Cq.Location((0, 0, housing_dz)))
.add(connector, name="connector", .add(connector, name="connector",
loc=axial_offset) loc=axial_offset)
.constrain("housing", "Fixed")
.constrain("connector", "Fixed")
.solve()
) )
return result return result
def assembly(self, angle: float = 0) -> Cq.Assembly: def assembly(self, angle: float = 0) -> Cq.Assembly:
da = self.disk_joint.tongue_span / 2 da = self.disk_joint.tongue_span / 2 + 180
result = ( result = (
Cq.Assembly() Cq.Assembly()
.add(self.child_joint(), name="child", color=Role.CHILD.color) .add(self.child_joint(), name="child", color=Role.CHILD.color)
.add(self.parent_joint_lower(), name="parent_lower", color=Role.CASING.color) .add(self.parent_joint_lower(), name="parent_lower", color=Role.CASING.color)
.add(self.parent_joint_upper(), name="parent_upper", color=Role.PARENT.color) .add(self.parent_joint_upper(), name="parent_upper", color=Role.PARENT.color)
.constrain("parent_lower", "Fixed") #.constrain("parent_lower", "Fixed")
) )
self.disk_joint.add_constraints( self.disk_joint.add_constraints(
result, result,
housing_lower="parent_lower", housing_lower="parent_lower",
housing_upper="parent_upper/housing", housing_upper="parent_upper/housing",
disk="child/disk", disk="child/disk",
angle=(0, 0, angle + da), angle=angle,
) )
return result.solve() return result.solve()

View File

@ -70,6 +70,9 @@ def make_arrow(size: float = 2) -> Cq.Workplane:
result.faces("<Z").tag("dir_rev") result.faces("<Z").tag("dir_rev")
return result return result
def to_marker_name(tag: str) -> str:
return tag.replace("?", "__T").replace("/", "__Z") + "_marker"
def mark_point(self: Cq.Assembly, def mark_point(self: Cq.Assembly,
tag: str, tag: str,
size: float = 2, size: float = 2,
@ -77,7 +80,7 @@ def mark_point(self: Cq.Assembly,
""" """
Adds a marker to make a point visible Adds a marker to make a point visible
""" """
name = f"{tag}_marker" name = to_marker_name(tag)
return ( return (
self self
.add(make_sphere(size), name=name, color=color) .add(make_sphere(size), name=name, color=color)
@ -93,7 +96,7 @@ def mark_plane(self: Cq.Assembly,
""" """
Adds a marker to make a plane visible Adds a marker to make a plane visible
""" """
name = tag.replace("?", "__") + "_marker" name = to_marker_name(tag)
return ( return (
self self
.add(make_arrow(size), name=name, color=color) .add(make_arrow(size), name=name, color=color)