cosplay: Touhou/Houjuu Nue #4

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

View File

@ -28,6 +28,10 @@ class HirthJoint:
def tooth_angle(self): def tooth_angle(self):
return 360 / self.n_tooth return 360 / self.n_tooth
@property
def total_height(self):
return self.base_height + self.tooth_height
def generate(self, is_mated=False, tol=0.01): def generate(self, is_mated=False, tol=0.01):
""" """
@ -97,7 +101,7 @@ class HirthJoint:
) )
return result return result
def assembly(self): def assembly(self, offset: int = 1):
""" """
Generate an example assembly Generate an example assembly
""" """
@ -118,7 +122,7 @@ class HirthJoint:
self.generate(is_mated=True) self.generate(is_mated=True)
.union(tab) .union(tab)
) )
angle = 1 * self.tooth_angle angle = offset * self.tooth_angle
result = ( result = (
Cq.Assembly() Cq.Assembly()
.add(obj1, name="obj1", color=Role.PARENT.color) .add(obj1, name="obj1", color=Role.PARENT.color)

View File

@ -32,7 +32,7 @@ shoulder, elbow, wrist in analogy with human anatomy.
from dataclasses import dataclass, field from dataclasses import dataclass, field
import unittest import unittest
import cadquery as Cq import cadquery as Cq
from nhf import Material from nhf import Material, Role
from nhf.build import Model, TargetKind, target from nhf.build import Model, TargetKind, target
from nhf.parts.joints import HirthJoint from nhf.parts.joints import HirthJoint
from nhf.parts.handle import Handle from nhf.parts.handle import Handle
@ -194,18 +194,6 @@ class Parameters(Model):
coupling, a cylindrical base, and a mounting base. coupling, a cylindrical base, and a mounting base.
""" """
hirth = self.hs_hirth_joint.generate() hirth = self.hs_hirth_joint.generate()
#hirth = (
# hirth
# .faces("<Z")
# .workplane()
# .transformed(
# offset=Cq.Vector(0, 0, -self.hs_joint_ring_thickness / 2),
# rotate=Cq.Vector(90, 0, 0))
# # This hole will drill only to the centre and not through. This is
# # intended.
# .hole(5)
# .val()
#)
conn = self.hs_joint_harness_conn() conn = self.hs_joint_harness_conn()
result = ( result = (
Cq.Workplane('XY') Cq.Workplane('XY')
@ -214,6 +202,7 @@ class Parameters(Model):
self.hs_joint_base_width, self.hs_joint_base_width,
self.hs_joint_base_thickness, self.hs_joint_base_thickness,
centered=(True, True, False)) centered=(True, True, False))
.translate((0, 0, -self.hs_joint_base_thickness))
.edges("|Z") .edges("|Z")
.fillet(self.hs_joint_corner_fillet) .fillet(self.hs_joint_corner_fillet)
.faces(">Z") .faces(">Z")
@ -224,11 +213,13 @@ class Parameters(Model):
cboreDiameter=self.hs_joint_corner_cbore_diam, cboreDiameter=self.hs_joint_corner_cbore_diam,
cboreDepth=self.hs_joint_corner_cbore_depth) cboreDepth=self.hs_joint_corner_cbore_depth)
) )
# Creates a plane parallel to the holes but shifted to the base
plane = result.faces(">Z").workplane(offset=-self.hs_joint_base_thickness) plane = result.faces(">Z").workplane(offset=-self.hs_joint_base_thickness)
for i, (px, py) in enumerate(conn): for i, (px, py) in enumerate(conn):
( (
plane plane
.moveTo(px, py) .pushPoints([(px, py)])
.circle(1, forConstruction='True') .circle(1, forConstruction='True')
.edges() .edges()
.tag(f"h{i}") .tag(f"h{i}")
@ -237,7 +228,7 @@ class Parameters(Model):
result result
.faces(">Z") .faces(">Z")
.workplane() .workplane()
.union(hirth.translate((0, 0, self.hs_joint_base_thickness)), tol=0.1) .union(hirth, tol=0.1)
.clean() .clean()
) )
result = ( result = (
@ -304,34 +295,49 @@ class Parameters(Model):
# Assemblies # # Assemblies #
###################### ######################
def trident_assembly(self):
return MT.trident_assembly(self.trident_handle)
def harness_assembly(self): def harness_assembly(self):
harness = self.harness() harness = self.harness()
result = ( result = (
Cq.Assembly() Cq.Assembly()
.add(harness, name="harness", color=Material.WOOD_BIRCH.color) .add(harness, name="base", color=Material.WOOD_BIRCH.color)
.constrain("harness", "Fixed") .constrain("base", "Fixed")
) )
for name in ["l1", "l2", "l3", "r1", "r2", "r3"]: for name in ["l1", "l2", "l3", "r1", "r2", "r3"]:
j = self.hs_joint_parent() j = self.hs_joint_parent()
( (
result result
.add(j, name=f"hs_{name}", color=Material.PLASTIC_PLA.color) .add(j, name=name, color=Role.PARENT.color)
#.constrain(f"harness?{name}", f"hs_{name}p?mate", "Point") .constrain("base?mount", f"{name}?base", "Axis")
.constrain("harness?mount", f"hs_{name}?base", "Axis")
) )
for i in range(4): for i in range(4):
result.constrain(f"harness?{name}_{i}", f"hs_{name}?h{i}", "Point") result.constrain(f"base?{name}_{i}", f"{name}?h{i}", "Point")
angle = 6 * self.hs_hirth_joint.tooth_angle
(
result.add(self.wing_root(), name="w0_r1", color=Material.PLASTIC_PLA.color)
.constrain("w0_r1?mate", "hs_r1?mate", "Plane")
.constrain("w0_r1?directrix", "hs_r1?directrix", "Axis", param=angle)
)
result.solve() result.solve()
return result return result
def trident_assembly(self): def wings_assembly(self):
return MT.trident_assembly(self.trident_handle) """
Assembly of harness with all the wings
"""
a_tooth = self.hs_hirth_joint.tooth_angle
result = (
Cq.Assembly()
.add(self.harness_assembly(), name="harness", loc=Cq.Location((0, 0, 0)))
.add(self.wing_root(), name="w0_r1")
.add(self.wing_root(), name="w0_l1")
.constrain("harness/base", "Fixed")
.constrain("w0_r1/joint?mate", "harness/r1?mate", "Plane")
.constrain("w0_r1/joint?directrix", "harness/r1?directrix",
"Axis", param=7 * a_tooth)
.constrain("w0_l1/joint?mate", "harness/l1?mate", "Plane")
.constrain("w0_l1/joint?directrix", "harness/l1?directrix",
"Axis", param=-1 * a_tooth)
.solve()
)
return result
if __name__ == '__main__': if __name__ == '__main__':

View File

@ -18,13 +18,16 @@ class Test(unittest.TestCase):
self.assertLess(bbox.xlen, 255, msg=msg) self.assertLess(bbox.xlen, 255, msg=msg)
self.assertLess(bbox.ylen, 255, msg=msg) self.assertLess(bbox.ylen, 255, msg=msg)
self.assertLess(bbox.zlen, 255, msg=msg) self.assertLess(bbox.zlen, 255, msg=msg)
def test_wings(self): def test_wing_root(self):
p = M.Parameters() p = M.Parameters()
p.wing_root() p.wing_root()
def test_harness(self): def test_wings_assembly(self):
p = M.Parameters()
p.wings_assembly()
def test_harness_assembly(self):
p = M.Parameters() p = M.Parameters()
p.harness_assembly() p.harness_assembly()
def test_trident(self): def test_trident_assembly(self):
p = M.Parameters() p = M.Parameters()
assembly = p.trident_assembly() assembly = p.trident_assembly()
bbox = assembly.toCompound().BoundingBox() bbox = assembly.toCompound().BoundingBox()

View File

@ -4,6 +4,7 @@ This file describes the shapes of the wing shells. The joints are defined in
""" """
import math import math
import cadquery as Cq import cadquery as Cq
from nhf import Material, Role
from nhf.parts.joints import HirthJoint from nhf.parts.joints import HirthJoint
def wing_root_profiles( def wing_root_profiles(
@ -125,7 +126,7 @@ def wing_root_profiles(
def wing_root(joint: HirthJoint, def wing_root(joint: HirthJoint,
bolt_diam: int = 12): bolt_diam: int = 12) -> Cq.Assembly:
""" """
Generate the contiguous components of the root wing segment Generate the contiguous components of the root wing segment
""" """
@ -192,11 +193,12 @@ def wing_root(joint: HirthJoint,
.faces("<Z") .faces("<Z")
.hole(bolt_diam) .hole(bolt_diam)
) )
color = Material.PLASTIC_PLA.color
result = ( result = (
result Cq.Assembly()
.union(j.translate((0, 0, -10))) .add(result, name="scaffold", color=color)
#.union(Cq.Solid.makeCylinder(57, 5).moved(Cq.Location((0, 0, -10)))) .add(j, name="joint", color=Role.CHILD.color,
.union(Cq.Solid.makeCylinder(20, 5).moved(Cq.Location((0, 0, -10)))) loc=Cq.Location((0, 0, -joint.total_height)))
.clean()
) )
return result return result