cosplay: Touhou/Houjuu Nue #1
|
@ -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)
|
||||||
|
|
|
@ -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__':
|
||||||
|
|
|
@ -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()
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue