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
6 Share
Download All Files

Thing Apps Enabled

Order This Printed View All Apps



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

Thing Statistics

107409Views 19836Downloads


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:

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

// axial distance from crest to crest

// radial distance from center to mid-profile

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

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

// 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

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

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

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

// 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:

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

// 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:

// outer radius of the nut


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.

All Apps

Auto-magically prepare your 3D models for 3D printing. A cloud based 3D models Preparing and Healing solution for 3D Printing, MakePrintable provides features for model repairing, wall thickness...

App Info Launch App

Kiri:Moto is an integrated cloud-based slicer and tool-path generator for 3D Printing, CAM / CNC and Laser cutting. *** 3D printing mode provides model slicing and GCode output using built-in...

App Info Launch App
KiriMoto Thing App

With 3D Slash, you can edit 3d models like a stonecutter. A unique interface: as fun as a building game! The perfect tool for non-designers and children to create in 3D.

App Info Launch App

Print through a distributed network of 3D printing enthusiasts from across the US, at a fraction of the cost of the competitors. We want to change the world for the better through technology, an...

App Info Launch App

Quickly Scale, Mirror or Cut your 3D Models

App Info Launch App

Treatstock is an online platform that offers decentralized manufacturing services such as 3D printing and CNC machining for business-to-business and business-to-consumer sales all over the world. W...

App Info Launch App

3D print your favourite design with NinjaPrototype, a professional 3D manufacture with consistent quality and speed.

App Info Launch App

Hi, nice lib, but thread in the nut is not going all the way through -- you can see it with no chamfer. Just increase length of thread by pitch in difference function.

Comments deleted.

First of all, thank you Mathieu! This is a brilliant library!
I was in need of some nuts for a few lead screws with multiple starts and variable lead. The library does not do this by default, but for someone who is familiar with OpenSCAD I'm sure it would be easy to add the option in a more elegant fashion than what I did with it.
This is what I'm talking about http://www.thingiverse.com/make:186226 - it's more of a hack and slash solution since it's my first time with OpenSCAD but it serves its purpose.
If at some point you have the time to include something like this in the main branch, I'm sure others will find it useful!

Screw Library

I trying to make an adapter for my sink. The pitch isn't right even though "pitch" is. This profileratio comment is vague for me, "// ratio between the lengths of the raised part of the profile and the pitch". What is the raised part of the profile?

I finally got a multistart thread to work but I have the problem that the overall length of the thread is short. This can be compensated if you always make the thread length longer but I would like to calculate the compensation. Any one know what is formula for the additional length required on a multistart thread? Below is my current code when rendered you will see that the thread is not complete throughout the nut. Also if you increase the start count the length gets even shorter.


If you still need this, I managed to get something working with multiple starts http://www.thingiverse.com/make:186226

Screw Library
Comments deleted.

Syvwlch, thank you very much for the library, it is very useful.

The only problem I had with the library was the fact that I had to repair STL (non manifold edges) when I substracted a thread from an object. Finally I found a couple of hours today to analyze the problem and fix it. The details are below (and the pull request is waiting for your review on github).

The fix (or hack or workaround if you like) makes the thread slices little higher to overlap with each other vertically, and as a result OpenSCAD happily generates the ideal STL. I have only smoke tested the fix on a couple of projects, and it seems to be working there. The Thread_Library.scad modifications (sorry, I can't find how to insert a code snippet into comment):

  1. Add function:
    function moveUp(vector, o = 0.1) = [vector[0], vector[1], vector[2] + o];
  2. Modify polyPoints definition in slice module:
    barycenter(ATop,ABottom,AThreadPosition+AThreadRatio/2) + unitVector(ATop-ABottom)AThreadDepth/2tan(AThreadAngle),
    barycenter(ATop,ABottom,AThreadPosition+AThreadRatio/2) - unitVector(ATop-ABottom)AThreadDepth/2tan(AThreadAngle) + unitVector(ATop-AShaftTop)AThreadDepth,
    barycenter(ATop,ABottom,AThreadPosition-AThreadRatio/2) + unitVector(ATop-ABottom)
    AThreadDepth/2tan(AThreadAngle) + unitVector(ATop-AShaftTop)AThreadDepth,
    barycenter(ATop,ABottom,AThreadPosition-AThreadRatio/2) - unitVector(ATop-ABottom)AThreadDepth/2tan(AThreadAngle),
    barycenter(BTop,BBottom,BThreadPosition+BThreadRatio/2) + unitVector(BTop-BBottom)BThreadDepth/2tan(BThreadAngle),
    barycenter(BTop,BBottom,BThreadPosition+BThreadRatio/2) - unitVector(BTop-BBottom)BThreadDepth/2tan(BThreadAngle) + unitVector(BTop-BShaftTop)BThreadDepth,
    barycenter(BTop,BBottom,BThreadPosition-BThreadRatio/2) + unitVector(BTop-BBottom)
    BThreadDepth/2tan(BThreadAngle) + unitVector(BTop-BShaftTop)BThreadDepth,
    barycenter(BTop,BBottom,BThreadPosition-BThreadRatio/2) - unitVector(BTop-BBottom)BThreadDepth/2tan(BThreadAngle),

ERROR: CSG generation failed! (no top level object found)

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!

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?


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?

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

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

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:

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: ../libraries/install/include/CGAL/Nef_S2/SM_overlayer.h
Line: 285

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

Do you have any ideas?

Super-duper useful! Thanks so much for sharing this.

I am lost trying to make a multi start nut

wish I could find a good tutorial for open scad

Cool ! Very cool ! Thanks !

hey I got a question can this make a thread that is non standard and how do measure the thread ?

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

hey very nice idea !! good work here

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

 Ok I think I figured it out, for an 8tpi 8 start thread...

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



then just create 8 threads each starting 45degrees apart by rotating the thread.

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:


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).

I'm using OpenSCAD 2011.12 and wanted to use a larger angle to reduce the overhangs when prin

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

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.

Great library. The models look awesome...on the screen at least!

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
ructure is in place?


I started with printing the full screw (as presented) to see how the overhang would come out from my Ultimaker.
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.
Yes, the intention is providi
ng a library, but .... a pity, I am not so much a sketcher.


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

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


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

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?

Here's my snippet:

Does the image below look about right?

I generated it with:


Looks like I broke two things when I changed to vectorial math for the thread profile. One is that I changed the thr
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.

Thanks! I couldn't figure out what was going on there.

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.

I used the following:

stepsPerTurn=24 ,

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.

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

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...

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

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.

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

Fantastic library!

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? :)
I know it's not difficult, but that would be very handy.

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.

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

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 :)

I meant something like this:

I thought it was already there :-?

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...

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

I like the structural system you designed it for, where has that led?

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.

You just need to make sure to feed them the same parameters.

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

Worm gears... great idea! :-)

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

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.

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

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
its current extrude/twist method. Definitely an interesting challenge!

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

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

Let me see if I can find the pictures...

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

They mesh better than it looks...
a href="http://aubenc.imgur.com/playing_with_wormshttp://aubenc.imgur.com/playin..."
More pics here

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

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

Simple, non-throated worm gear, animated:


Worm Drive, Non-Throated
by syvwlch

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

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

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.

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.

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

Yup, it worked great!

I have to say, this pile-o-polyhedron method works really, really well.

Much better view, the tolerances work perfectly!

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.

I'll package that up into a module so that it's not so confusing.

I love it!

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

Publish or perish. :-)

I'll be stealing ideas from your version in 3, 2, 1....

I guess it will look more like "I was stealing yours" :-D :-D :-D