2024-07-19 00:58:10 -07:00
|
|
|
from dataclasses import dataclass
|
|
|
|
import math
|
|
|
|
import cadquery as Cq
|
|
|
|
from nhf import Item, Role
|
|
|
|
import nhf.utils
|
|
|
|
|
2024-07-19 14:06:13 -07:00
|
|
|
@dataclass(frozen=True)
|
|
|
|
class FlatHeadBolt(Item):
|
|
|
|
diam_head: float
|
|
|
|
height_head: float
|
|
|
|
diam_thread: float
|
|
|
|
height_thread: float
|
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self) -> str:
|
|
|
|
return f"Bolt M{int(self.diam_thread)} h{int(self.height_thread)}mm"
|
|
|
|
|
2024-07-21 05:46:18 -07:00
|
|
|
@property
|
|
|
|
def role(self) -> Role:
|
|
|
|
return Role.CONNECTION
|
|
|
|
|
2024-07-19 14:06:13 -07:00
|
|
|
|
|
|
|
def generate(self) -> Cq.Assembly:
|
|
|
|
head = Cq.Solid.makeCylinder(
|
|
|
|
radius=self.diam_head / 2,
|
|
|
|
height=self.height_head,
|
|
|
|
)
|
|
|
|
rod = (
|
|
|
|
Cq.Workplane('XY')
|
|
|
|
.cylinder(
|
|
|
|
radius=self.diam_thread/ 2,
|
|
|
|
height=self.height_thread,
|
|
|
|
centered=(True, True, False))
|
|
|
|
)
|
|
|
|
rod.faces("<Z").tag("tip")
|
|
|
|
rod.faces(">Z").tag("root")
|
2024-07-21 05:46:18 -07:00
|
|
|
rod = rod.union(head.located(Cq.Location((0, 0, self.height_thread))))
|
|
|
|
return rod
|
2024-07-19 14:06:13 -07:00
|
|
|
|
|
|
|
|
2024-07-19 00:58:10 -07:00
|
|
|
@dataclass(frozen=True)
|
|
|
|
class ThreaddedKnob(Item):
|
|
|
|
"""
|
2024-07-19 21:00:10 -07:00
|
|
|
A threaded rod with knob on one side
|
2024-07-19 00:58:10 -07:00
|
|
|
"""
|
2024-07-19 14:06:13 -07:00
|
|
|
diam_thread: float
|
|
|
|
height_thread: float
|
2024-07-19 00:58:10 -07:00
|
|
|
diam_knob: float
|
|
|
|
|
|
|
|
diam_neck: float
|
|
|
|
height_neck: float
|
|
|
|
height_knob: float
|
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self) -> str:
|
2024-07-19 14:06:13 -07:00
|
|
|
return f"Knob M{int(self.diam_thread)} h{int(self.height_thread)}mm"
|
2024-07-19 00:58:10 -07:00
|
|
|
|
|
|
|
def generate(self) -> Cq.Assembly:
|
|
|
|
knob = Cq.Solid.makeCylinder(
|
|
|
|
radius=self.diam_knob / 2,
|
|
|
|
height=self.height_knob,
|
|
|
|
)
|
|
|
|
neck = Cq.Solid.makeCylinder(
|
|
|
|
radius=self.diam_neck / 2,
|
|
|
|
height=self.height_neck,
|
|
|
|
)
|
2024-07-19 14:06:13 -07:00
|
|
|
thread = (
|
2024-07-19 00:58:10 -07:00
|
|
|
Cq.Workplane('XY')
|
|
|
|
.cylinder(
|
2024-07-19 14:06:13 -07:00
|
|
|
radius=self.diam_thread / 2,
|
|
|
|
height=self.height_thread,
|
2024-07-19 00:58:10 -07:00
|
|
|
centered=(True, True, False))
|
|
|
|
)
|
2024-07-19 14:06:13 -07:00
|
|
|
thread.faces("<Z").tag("tip")
|
|
|
|
thread.faces(">Z").tag("root")
|
2024-07-19 00:58:10 -07:00
|
|
|
|
|
|
|
return (
|
|
|
|
Cq.Assembly()
|
2024-07-19 14:06:13 -07:00
|
|
|
.addS(thread, name="thread", role=Role.CONNECTION)
|
2024-07-19 00:58:10 -07:00
|
|
|
.addS(neck, name="neck", role=Role.HANDLE,
|
2024-07-19 14:06:13 -07:00
|
|
|
loc=Cq.Location((0, 0, self.height_thread)))
|
2024-07-19 00:58:10 -07:00
|
|
|
.addS(knob, name="knob", role=Role.HANDLE,
|
2024-07-19 14:06:13 -07:00
|
|
|
loc=Cq.Location((0, 0, self.height_thread + self.height_neck)))
|
2024-07-19 00:58:10 -07:00
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
class HexNut(Item):
|
2024-07-19 14:06:13 -07:00
|
|
|
diam_thread: float
|
2024-07-19 00:58:10 -07:00
|
|
|
pitch: float
|
|
|
|
|
2024-07-19 14:06:13 -07:00
|
|
|
thickness: float
|
|
|
|
width: float
|
2024-07-19 00:58:10 -07:00
|
|
|
|
|
|
|
def __post_init__(self):
|
2024-07-19 14:06:13 -07:00
|
|
|
assert self.width > self.diam_thread
|
2024-07-19 00:58:10 -07:00
|
|
|
|
|
|
|
@property
|
|
|
|
def name(self):
|
2024-07-19 14:06:13 -07:00
|
|
|
return f"HexNut M{int(self.diam_thread)}-{self.pitch}"
|
2024-07-19 00:58:10 -07:00
|
|
|
|
|
|
|
@property
|
2024-07-19 21:00:10 -07:00
|
|
|
def role(self) -> Role:
|
2024-07-19 00:58:10 -07:00
|
|
|
return Role.CONNECTION
|
|
|
|
|
|
|
|
def generate(self) -> Cq.Workplane:
|
2024-07-19 14:06:13 -07:00
|
|
|
r = self.width / math.sqrt(3)
|
2024-07-19 00:58:10 -07:00
|
|
|
result = (
|
|
|
|
Cq.Workplane("XY")
|
|
|
|
.sketch()
|
|
|
|
.regularPolygon(r=r, n=6)
|
2024-07-19 14:06:13 -07:00
|
|
|
.circle(r=self.diam_thread/2, mode='s')
|
2024-07-19 00:58:10 -07:00
|
|
|
.finalize()
|
2024-07-19 14:06:13 -07:00
|
|
|
.extrude(self.thickness)
|
2024-07-19 00:58:10 -07:00
|
|
|
)
|
|
|
|
result.faces("<Z").tag("bot")
|
|
|
|
result.faces(">Z").tag("top")
|
2024-07-19 15:06:57 -07:00
|
|
|
result.copyWorkplane(Cq.Workplane('XY')).tagPlane("dirX", direction="+X")
|
2024-07-19 00:58:10 -07:00
|
|
|
return result
|