Hey! This thing is still a Work in Progress. Files, instructions, and other stuff might change!

Screw Library

by syvwlch, published

Screw Library by syvwlch May 25, 2011


This is the Thing page for the Screw Library I am working on. I could be talked into releasing it as Public Domain, but have left it as CC-BY-SA for now, at least until it's fully stabilized.

The latest code is available on GitHub here:


Currently, the library allows you to create a threaded rod with a trapezoidal profile, like the Acme or metric lead screws that are so common in CNC machines.

The trapezoidThread module creates the rod along Z, centered in X and Y, but not in Z. Same logic as cylinders with center=false.

The parameters are the following:

length // axial length of the threaded rod // used to calculate how many turns to create // the rod is NOT trimmed to this length!!!

pitch // axial distance from crest to crest

pitchRadius // radial distance from center to mid-profile

threadHeightToPitch // ratio between profile height and pitch // default value is 0.5

profileRatio // ratio between raised profile and pitch // default value is 0.5

threadAngle // angle between the two faces of the thread, in degrees // std value for Acme is 29 or for metric lead screw is 30 // default value is 30

RH // true if thread winds clockwise along shaft // i.e.follows the Right Hand Rule // default value is true

clearance // radial clearance, normalized to thread height // default value is 0.1

backlash // axial clearance, normalized to pitch // default value is 0.1

stepsPerTurn // number of facets to create per turn // default value is 24

You can create a triangular profile thread by setting profileRatio to zero, but that is cumbersome. I will create a separate module for that and add it to this page, later.


I have added a trapezoidThreadNegativeSpace module to create a negative space of a thread with the proper clearances to screw on, as long as you give it the same parameters. It can add two chamfered holes at the entries. It takes the following parameters on top of the ones needed for trapezoidThread:

length // thickness of the part to be drilled out by this object

countersunk // depth of the 45 degree chamfers, normalized to pitch // default value is zero, no chamfer

I have also added a trapezoidNut module which uses the above negative space module to create a hexagonal lead nut with the right clearances to screw onto any thread that shares the same parameters. It takes the following additional parameters:

radius // outer radius of the nut

Recent Comments

view all
Do not attempt to print these files as they will NOT fit together.
Just to help others, here what I do

Since compiling a thread take a lot of time and decrease real time rendering while working on a object. I find a elegant solution
that resolve all this issues.

You make the screw needed, compile it, save the STL of the screw, repair it (you need they are some bug in the thread logic)

And on your model you are working, use the STL object instead, like import("myobject.stl") in openscad.

for example:

cube([50, 50, 50], center = true);

this make a cube with a threaded hole in it... super fast rendering and compiling..

Thanks a lot for this post, very usefull!


Liked By

view all


Give a Shout Out

If you print this Thing and display it in public proudly give attribution by printing and displaying this tag. Print Thing Tag


Obviously, the intent is not to print threaded rod. :-)

Rather, this should allow you to subtract threaded rod from an object to make it a lead nut.

To create two meshing threaded rods like in the demo images, they need to have different handedness (RH) but the same pitch, pitch radius and threadHeightToPitch. Their profileRatios must be complementary (sum up to 1) and they must be separated by a distance of twice their pitch radius.

Have fun with it and don't be shy about reporting bugs or requesting changes or extensions.

Do not attempt to print these files as they will NOT fit together.

Just to help others, here what I do

Since compiling a thread take a lot of time and decrease real time rendering while working on a object. I find a elegant solution that resolve all this issues.

You make the screw needed, compile it, save the STL of the screw, repair it (you need they are some bug in the thread logic)

And on your model you are working, use the STL object instead, like import("myobject.stl") in openscad.

for example:

difference() {

cube([50, 50, 50], center = true);


this make a cube with a threaded hole in it... super fast rendering and compiling..

Thanks a lot for this post, very usefull!

Great job for the lib.

I have an issue when I try to use trapezoidThreadNegativeSpace on a big object, let say I have a piece that have some hole and stuff, not to big but I want a threaded hole 1/2 for about 50mm, on render, its fail (WARNING: Normalized tree is growing past 100000 elements. Aborting normalization.)

Also when compiling with render its also fail (CGAL error in CGAL_Nef_polyhedron's union operator: CGAL ERROR: assertion violation! Expr: itl != it->second.end() File: /home/don/openscad_deps/mxe/usr/i686-pc-mingw32/include/CGAL/Nef_3/SNC_external_structure.h Line: 1102 CGAL error in CGAL_Nef_polyhedron's union operator: CGAL ERROR: assertion violation! Expr: G.mark(v1,0)==G.mark(v2,0)&& G.mark(v1,1)==G.mark(v2,1) File: /home/don/openscad_deps/mxe/usr/i686-pc-mingw32/include/CGAL/Nef_S2/SM_overlayer.h Line: 285)

So it work for small object when when object are just a bit bigger in size (more complex then a hex or square) its start to fail.

Does the lib need some update to optimize then rendering ? Or its just made to do bolt?


Oct 29, 2014 - Modified Oct 29, 2014

I have two acme rods 3/8" single start and 3/8" double start. I was able to make a single start nut with the following:

difference() {

cylinder(r=10, h=10, $fn=6);


How do you make a multi-start nut?

<p>This library is amazing! <br>I'm struggling to compile and render a screw using the settings below though:</p>

<p>trapezoidThread(length=15, pitch=1.3, pitchRadius=4.4, threadHeightToPitch=1, profileRatio=.3 );</p>

<p>With the library posted here the model compiles, but won't render; OpenSCAD gets about 99.9% of the way through and then just hangs there for hours. With the library on github I get the following error at about 99.9% again:</p>

<p>CGAL error in CGAL_Nef_polyhedron's union operator: CGAL ERROR: assertion violation!<br>Expr: G.mark(v1,0)==G.mark(v2,0)&& G.mark(v1,1)==G.mark(v2,1)<br>File: ../libraries/install/include/CGAL/Nef_S2/SM_overlayer.h<br>Line: 285</p>

<p>The github version spits that error out for as long as I'm willing to let it run.</p>

<p>Do you have any ideas?</p>

<p>Super-duper useful! Thanks so much for sharing this.</p>

<p>I am lost trying to make a multi start nut </p>

<p>wish I could find a good tutorial for open scad</p>

<p>Cool ! Very cool ! Thanks !</p>

<p>hey I got a question can this make a thread that is non standard and how do measure the thread ?<br>terramir</p>

<p>This is excellent. I hope there will be a supplemental to common large threadings (garden hoses, bottle caps, etc.).</p>

<p>hey very nice idea !! good work here</p>

<p>How would you do a multi start thread? I need to print something for an 8-start lead screw. -Thanks </p>

<p> Ok I think I figured it out, for an 8tpi 8 start thread...</p>

<p>p, li { white-space: pre-wrap; }</p>

<p> threadHeightToPitch=0.5/8,<br> <br> profileRatio=0.5/8,<br> pitch=3.175*8,</p>

<p>then just create 8 threads each starting 45degrees apart by rotating the thread.</p>


<p>There seems to be a bug... when I increase the thread angle, a gap appears between the threads and the shaft. It's easiest to see when you take a difference and seems to reproduce with the following:</p>


<p>This already shows erroneous shapes at the apex of the cut thread. Larger angles show even larger gap (or larger extra polygons if the thread was subtracted from a shape). </p>

<p>I'm using OpenSCAD 2011.12 and wanted to use a larger angle to reduce the overhangs when prin<br>ting.</p>

<p>I checked out the latest code with git and now the problem seems to be gone.</p>

<p>This is wonderful, thanks! I now have printed 5/16" ACME nuts running my Z leadscrews. Printed well in PLA at 0.1mm layers with 0.2 clearance/backlash set.</p>

<p>Great library. The models look awesome...on the screen at least!</p>

<p>Overhang is a big issue on my makerbot, because skeinforge thinks it can print a circular shell in empty space, so it just ends up drooping. Anybody know a mod/setting that will tell it to print the overhang layers as loops or radial lines, and then switch back to normal shells once the support st<br>ructure is in place?</p>


<p>I started with printing the full screw (as presented) to see how the overhang would come out from my Ultimaker.<br>Then I started with the full nut, but unfortunately the scale of the nut (as presented) does not match with the screw, consequently I stopped the printing. <br>Yes, the intention is providi<br>ng a library, but .... a pity, I am not so much a sketcher.</p>


<p>Is there chart available for "pitch" and "pitchRadius" and how they should be set for standard bolts like M3 or 1/2"x32?</p>

<p>I've been setting pitchRadius to half the nominal size but I'm not certain that is the correct way to do this.</p>


<p>This chart looks pretty good. Use the pitch diameter/2. These are internal threads based on my hand calculations.</p>

<p>I love this. I'm trying to use it to generate threads to make a device to screw onto the end of a dremel tool which I believe has triangular 3/4-12 60 degree threads. I can't seem to get it to work for 60 degree threads. Have you tried that yet? Am I missing something?</p>

<p>Here's my snippet:<br>trapezoidThread(<br> length=6,<br> pitch=2.12,<br> pitchRadius=8.607, <br> threadHeightToPitch=cos(30), <br> profileRatio=0.0, <br> threadAngle=60,<br> stepsPerTurn=24 <br>);</p>

syvwlch - in reply to jag

<p>Does the image below look about right?</p>

<p>I generated it with:</p>

<p>trapezoidThread( <br>length=60, <br>pitch=2.12, <br>pitchRadius=8.607, <br>threadHeightToPitch=cos(30), <br>profileRatio=0.615, <br>threadAngle=30, <br>stepsPerTurn=24 <br>);</p>

<p>Looks like I broke two things when I changed to vectorial math for the thread profile. One is that I changed the thr<br>ead angle definition so that you have to specify half the previous value. The other is that profile ratio is less than intuitive now, 0 does not correspond to a triangular profile like you would expect. I will fix both in the next release but in the mean-time the above is probably what you want.</p>

jag - in reply to syvwlch

<p>Thanks! I couldn't figure out what was going on there.</p>

jag - in reply to jag

<p>Next question, which I fear is more complicated. Why can't I make a nut with these settings? It looks like the sections aren't overlapping enough or something. </p>

<p>I used the following:</p>

<p>trapezoidNut( <br>length=6, <br>pitch=2.12, <br>pitchRadius=8.607, <br>threadHeightToPitch=cos(30), <br>profileRatio=0.615, <br>threadAngle=30, <br>stepsPerTurn=24 ,<br>radius=25.4/2 <br>);</p>

syvwlch - in reply to jag

<p>Yeah, have not figured out a good way to make that look good in F5 (compile) mode. If you hit F6 (compile and render) the nut should be fine.</p>

<p>Hum... I suppose I could use the render() command to force it to render, but then F5 would be sloooooow.</p>

jag - in reply to syvwlch

<p>Unfortunately, when I render it I get just the hexagon without the threads cut out. When I remove all of the parameters related to the thread profile so that it uses the defaults and does a trapezoidal thread, it renders fine except for a stray triangle. I'm wondering if the polygons for the triangular threads aren't watertight so it can't boolean them. I haven't really worked with polygons before though...</p>

syvwlch - in reply to jag

<p>Ok, that's weird. I'll have to replicate it on this end. :(</p>

<p>Ok, so I get a nut with a threaded hole in it, but with the triangle sticking out into the center, with your parameters. If I add the parameter countersunk=0.2, I get a nut without the triangle.</p>

<p>I can't seem to replicate the nut with no hole at all... I'll keep playing with it.</p>

<p>Fantastic library!</p>

<p>Could we have a function that allows to create a thread with an exagonal head (a bolt), if you are still interested in writing code after you got a makerbot? :)<br>I know it's not difficult, but that would be very handy.</p>

syvwlch - in reply to caru

<p>Yes, I can do that. I've disappeared down a rabbit hole made of printer assembly and trying to get the throated worm drive to work... but there are a couple simple upgrades to this library that I can definitely publish as is.</p>

<p>That includes progressive starts to the threads, and definitely bolts. I'll try to get that out the door soon!</p>

caru - in reply to syvwlch

<p>If by progressive starts to thread you mean to eliminate that plain cylinder portion at the ends of the of the rod, i vote for it :)</p>

syvwlch - in reply to caru

<p>I meant something like this:</p>

caru - in reply to syvwlch

<p>I thought it was already there :-?</p>

<p>in this picture, at the top there is also that ugly plain cylinder portion i was talking about... that's wasted space / wasted print time in my opinion...</p>

<p>Well, this is far superior to the one I did. Great Job! :)</p>

<p>I like the structural system you designed it for, where has that led?</p>

<p>Added a negative space version of the thread module, which can be used to create a threaded hole with all the right clearances and some chamfered entries in anything you want, as well as a module to create an hexagonal nut that will screw onto the threaded rod.</p>

<p>You just need to make sure to feed them the same parameters.</p>

<p>I was wanting to play with some worm gears. This will make it relatively easy.</p>

<p>Worm gears... great idea! :-)</p>

<p>I, too, want to experiment with worm gears. if your looking for a new challenge, make a meshing wheel to go with the worm. =-X</p>

<p>If we're talking about non-throated worm-drives, we actually have everything we need between this library and the involute gear library, from what I understand.</p>

<p>Making a throated-drive by throating the worm is doable with this library since I can control the radius of the threaded rod.</p>

<p>Making a double-throated worm drive, by also throating the wheel... That would require a serious revamp of the gear library using the pile-o-polyhedron method rather than <br>its current extrude/twist method. Definitely an interesting challenge!</p>

<p>What the poor man did, months ago, is a difference between a cylinder* and the thread**</p>

<p>*For the cylinder the radius was computed based on number of teeth and how deep we wanted the worm to go.<br>** Only a section of the thread rotated conveniently for the difference.</p>

<p>Let me see if I can find the pictures...</p>

<p>Btw, the scad involved was too bad to upload it, may be one day I find the t<br>ime to find it and clean it...</p>

<p>They mesh better than it looks...<br><<br>a href="http://aubenc.imgur.com/playing_with_worms&quot;&lt;br&gt;&gt;&lt;br&gt;More pics here<br><<br>/a<br>></p>

<p>Seems to me like you should post more of your old files. :-)</p>

<p>I would really love to do so, unfortunately my old files are such a mess... :'(</p>

<p>Simple, non-throated worm gear, animated:</p>


Worm Drive, Non-Throated
by syvwlch

<p>Now I need to play with this to make negative threads for nuts etc, maybe I'll revisit my<br><<br>i<br>><br> Bolt Pencil Case<br><<br>/i<br>><br> and do it properly this time :)</p>

<p>Making a lead nut right now, using difference() and setting clearance and backlash to negative values. I hope it fits the screw! :-)</p>

<p>I'm sure it will. When I was making mine (yes I also have the trapezoid polygon somewhere) it was working. But the scad was too ugly and print it it's a pain.</p>

<p>In fact, I jumped from twist a extrusion to use polyhedrons because of the fit. No way to get a nice fit with something twisted, because of the twist of the faces.</p>

<p>Give a cent for every time I wrote "twist"... too late over here... I'm going to sleep</p>

<p>Yup, it worked great!</p>

<p>I have to say, this pile-o-polyhedron method works really, really well.</p>

<p>Much better view, the tolerances work perfectly!</p>

<p>Just a slight correction to a previous comment: for the negative space to drill the nut, I set clearance to zero and made the pitchRadius larger by 0.1*pitch. Clearance adds depth at the bottom of the thread, but for the negative space version you need to increase height at the top of the thread.</p>

<p>I'll package that up into a module so that it's not so confusing.</p>

<p>I love it!</p>

<p>Anyway... :-D I'm going to upload my poor man version :-P in 3.... 2.......... 1...................</p>

<p>Publish or perish. :-)</p>

<p>I'll be stealing ideas from your version in 3, 2, 1....</p>

<p>I guess it will look more like "I was stealing yours" :-D :-D :-D</p>

<p>This is so awesome!</p>