-
-
Save fragmuffin/266bee4babd9a25aea2d53c739144ee3 to your computer and use it in GitHub Desktop.
import cadquery | |
from Helpers import show | |
helical_radius = 6.0 | |
core_radius = 4.0 | |
pitch = 2.0 # length per revolution | |
length = 12.0 | |
def helical_path(p, l, r): | |
wire = cadquery.Wire.makeHelix(p, l, r, angle=0) | |
shape = cadquery.Wire.combine([wire]) | |
path = cadquery.Workplane("XY").newObject([shape]) | |
return path | |
# Inverted Thread profile | |
# FIXME: thread model must extend past helical_radius to make a clean cut | |
points = [ | |
(0.5 * pitch, helical_radius * 1.01), | |
(0, core_radius), | |
(-0.5 * pitch, helical_radius * 1.01), | |
] | |
# Inverted Thread: a single turn, around world origin | |
single_turn = helical_path(pitch, pitch, helical_radius).translate((0, 0, -pitch / 2)) | |
inv_thread = cadquery.Workplane("ZX").center(-pitch / 2., 0) \ | |
.moveTo(*points[0]).polyline(points[1:]).close() \ | |
.sweep(single_turn, isFrenet=True) | |
# cross-section face of thread (at origin) | |
cross_section = cadquery.Workplane("XY").workplane(offset=-pitch / 2.) \ | |
.circle(helical_radius).extrude(pitch / 2.) \ | |
.cut(inv_thread).faces(">Z") | |
cross_section_face = cross_section.val() # cadquery.Face | |
cross_section_wire = cross_section_face.Wires().pop() # cadquery.Wire | |
cross_section_wire.forConstruction = False | |
# Thread created from profile sweep | |
full_helix = helical_path(pitch, length, helical_radius) | |
my_model = cadquery.Workplane("XY").box(1,1,1) | |
my_model._addPendingWire(cross_section_wire) # FIXME: using private function | |
my_model.sweep(full_helix, isFrenet=True) | |
# Use the following to render your model with grey RGB and no transparency | |
#show(cross_section) | |
show(my_model, (204, 204, 204, 0.5)) |
@fragmuffin this is awesome!
This helps me understand what the cq direct API needs to look like as it relates to wires.
The cadquery newObject is also a backdoor in the current API, so we need to make it easier to decorate result objects with a selector.
The need to adjust the cut a slight amount to avoid an error is common. I have written many scripted features using Onshape (which is based on parasolid) and even there this is commonly necessary.
It's hard to get around the speed issue. Even with parasolid, it is slow to make real screw threads.
Other ideas for enhancements:
Internal threads
50% and 75% threads based on standards
Choose standard sizes
Taper thread entry and exit
Cut threads on existing cylinder
Trapezoidal thread profile
Multiple starts
Using the guidance of: https://www.freecadweb.org/wiki/Thread_for_Screw_Tutorial and attempting to implement in cadquery.
What's wrong with this implementation?
very slow
takes ~15sec to generate on my laptop
note: this could be drastically improved by
Thread Profile imperfect
if profile is <= outer radius, cut operation fails
this is why the thread's outer edge appears as a thicker line, because it's not just an edge, it's comprised of 2 very thin flat helical faces.
see
FIXME
in the codeUses backdoors
cadquery.Wire
'sforConstruction
attribute does not exist in aWire
instance unless explicitly setcadquery.Workplane
private function_addPendingWire
to use a face in a sweep