refactor: Allow different types of handle joints

This commit is contained in:
Leni Aniva 2024-07-09 21:31:00 -07:00
parent 27ce94124f
commit 8b0c9a000d
Signed by: aniva
GPG Key ID: 4D9B1C8D10EA4C50
2 changed files with 76 additions and 51 deletions

View File

@ -1,10 +1,70 @@
""" """
This schematics file contains all designs related to tool handles This schematics file contains all designs related to tool handles
""" """
from dataclasses import dataclass from dataclasses import dataclass, field
from typing import Union, Optional
import cadquery as Cq import cadquery as Cq
import nhf.parts.metric_threads as metric_threads import nhf.parts.metric_threads as metric_threads
class TubeJoint:
def diam_insertion_internal(self):
"""
Maximum permitted diameter of the internal cavity
"""
def diam_connector_external(self):
"""
Maximum permitted diameter of the external size of the insertion
"""
def external_thread(self, length: float) -> Cq.Shape:
"""
Generates the external connector
"""
def internal_thread(self, length: float) -> Cq.Shape:
"""
Generates the internal connector
"""
@dataclass
class ThreadedJoint(TubeJoint):
pitch: float = 3
# Major diameter of the internal threads, following ISO metric screw thread
# standard. This determines the wall thickness of the insertion.
diam_threading: float = 27
def diam_insertion_internal(self):
r = metric_threads.metric_thread_major_radius(
self.diam_threading,
self.pitch,
internal=True)
return r * 2
def diam_connector_external(self):
r = metric_threads.metric_thread_minor_radius(
self.diam_threading,
self.pitch)
return r * 2
def external_thread(self, length: float):
return metric_threads.external_metric_thread(
self.diam_threading,
self.pitch,
length,
top_lead_in=True)
def internal_thread(self, length: float):
return metric_threads.internal_metric_thread(
self.diam_threading,
self.pitch,
length)
@dataclass
class BayonetJoint(TubeJoint):
"""
Bayonet type joint
"""
pass
@dataclass @dataclass
class Handle: class Handle:
""" """
@ -17,20 +77,16 @@ class Handle:
Note that all the radial sizes are diameters (in mm). Note that all the radial sizes are diameters (in mm).
""" """
# Outer and inner radius for the handle usually come in standard sizes # Outer and inner radii for the handle usually come in standard sizes
diam: float = 38 diam: float = 38
diam_inner: float = 33 diam_inner: float = 33
# Major diameter of the internal threads, following ISO metric screw thread joint: Optional[TubeJoint] = field(default_factory=lambda: ThreadedJoint())
# standard. This determines the wall thickness of the insertion.
diam_threading: float = 27.0
thread_pitch: float = 3.0
# Internal cavity diameter. This determines the wall thickness of the connector # Internal cavity diameter. This determines the wall thickness of the connector
diam_connector_internal: float = 18.0 diam_connector_internal: float = 18.0
# If set to true, do not generate threads # If set to true, do not generate the connections
simplify_geometry: bool = True simplify_geometry: bool = True
# Length for the rim on the female connector # Length for the rim on the female connector
@ -43,26 +99,12 @@ class Handle:
def __post_init__(self): def __post_init__(self):
assert self.diam > self.diam_inner, "Material thickness cannot be <= 0" assert self.diam > self.diam_inner, "Material thickness cannot be <= 0"
assert self.diam_inner > self.diam_insertion_internal, "Threading radius is too big" if self.joint:
assert self.diam_insertion_internal > self.diam_connector_external assert self.diam_inner > self.joint.diam_insertion_internal(), "Threading radius is too big"
assert self.diam_connector_external > self.diam_connector_internal, "Internal diameter is too large" assert self.joint.diam_insertion_internal() > self.joint.diam_connector_external()
assert self.joint.diam_connector_external() > self.diam_connector_internal, "Internal diameter is too large"
assert self.insertion_length > self.rim_length assert self.insertion_length > self.rim_length
@property
def diam_insertion_internal(self):
r = metric_threads.metric_thread_major_radius(
self.diam_threading,
self.thread_pitch,
internal=True)
return r * 2
@property
def diam_connector_external(self):
r = metric_threads.metric_thread_minor_radius(
self.diam_threading,
self.thread_pitch)
return r * 2
def segment(self, length: float): def segment(self, length: float):
result = ( result = (
Cq.Workplane() Cq.Workplane()
@ -76,20 +118,6 @@ class Handle:
result.faces(">Z").tag("mate2") result.faces(">Z").tag("mate2")
return result return result
def _external_thread(self, length=None):
if length is None:
length = self.insertion_length
return metric_threads.external_metric_thread(
self.diam_threading,
self.thread_pitch,
length,
top_lead_in=True)
def _internal_thread(self):
return metric_threads.internal_metric_thread(
self.diam_threading,
self.thread_pitch,
self.insertion_length)
def insertion(self, holes=[]): def insertion(self, holes=[]):
""" """
This type of joint is used to connect two handlebar pieces. Each handlebar This type of joint is used to connect two handlebar pieces. Each handlebar
@ -121,11 +149,11 @@ class Handle:
.circle(self.diam / 2) .circle(self.diam / 2)
.extrude(self.rim_length) .extrude(self.rim_length)
.faces(">Z") .faces(">Z")
.hole(self.diam_insertion_internal) .hole(self.joint.diam_insertion_internal())
) )
result.faces(">Z").tag("mate") result.faces(">Z").tag("mate")
if not self.simplify_geometry: if not self.simplify_geometry:
thread = self._internal_thread().val() thread = self.joint.internal_thread(self.connector_length).val()
result = result.union(thread) result = result.union(thread)
for h in holes: for h in holes:
cyl = Cq.Solid.makeCylinder( cyl = Cq.Solid.makeCylinder(
@ -157,13 +185,13 @@ class Handle:
result result
.faces(selector) .faces(selector)
.workplane() .workplane()
.circle(self.diam_connector_external / 2) .circle(self.joint.diam_connector_external() / 2)
.extrude(self.insertion_length) .extrude(self.insertion_length)
) )
if not solid: if not solid:
result = result.faces(">Z").hole(self.diam_connector_internal) result = result.faces(">Z").hole(self.diam_connector_internal)
if not self.simplify_geometry: if not self.simplify_geometry:
thread = self._external_thread().val() thread = self.joint.external_thread(self.insertion_length).val()
result = ( result = (
result result
.union( .union(
@ -193,11 +221,11 @@ class Handle:
result result
.faces(">Z") .faces(">Z")
.workplane() .workplane()
.circle(self.diam_connector_external / 2) .circle(self.joint.diam_connector_external() / 2)
.extrude(self.insertion_length) .extrude(self.insertion_length)
) )
if not self.simplify_geometry: if not self.simplify_geometry:
thread = self._external_thread().val() thread = self.joint.external_thread(self.insertion_length).val()
result = ( result = (
result result
.union( .union(
@ -215,7 +243,7 @@ class Handle:
result = ( result = (
Cq.Workplane('XY') Cq.Workplane('XY')
.cylinder( .cylinder(
radius=self.diam_connector_external / 2, radius=self.joint.diam_connector_external / 2,
height=length, height=length,
centered=(True, True, False), centered=(True, True, False),
) )
@ -223,7 +251,7 @@ class Handle:
result.faces(">Z").tag("mate") result.faces(">Z").tag("mate")
result.faces("<Z").tag("base") result.faces("<Z").tag("base")
if not self.simplify_geometry: if not self.simplify_geometry:
thread = self._external_thread(length=length).val() thread = self.joint.external_thread(length=length).val()
result = ( result = (
result result
.union(thread) .union(thread)

View File

@ -127,9 +127,6 @@ class Parameters(Model):
trident_handle: Handle = field(default_factory=lambda: Handle( trident_handle: Handle = field(default_factory=lambda: Handle(
diam=38, diam=38,
diam_inner=38-2 * 25.4/8, diam_inner=38-2 * 25.4/8,
# M27-3
diam_threading=27,
thread_pitch=3,
diam_connector_internal=18, diam_connector_internal=18,
simplify_geometry=False, simplify_geometry=False,
)) ))