- OpenSCAD 100%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
The README covers all 21 standards and the drive, the frames, the API, what is drawn and why, mating threads, holes and pockets, and the viewers; CLAUDE.md how the registry and the shared shapes fit together, the misprints, the checks and the standards still wanted. The picture is now one M8 of every standard, drawn from docs/overview.scad. |
||
| docs | ||
| previews | ||
| src | ||
| .gitignore | ||
| CLAUDE.md | ||
| iso-fasteners.scad | ||
| preview.scad | ||
| README.md | ||
iso-fasteners: ISO metric fasteners for OpenSCAD
Screws, bolts, set screws, nuts and washers built from the dimension tables of their ISO standards, with an optional real thread, and cutters for the holes they go in: clearance holes, counterbores, countersinks, threaded holes and pockets. Made for checking fits and collisions in 3D-printed parts, and for drawing assemblies.
| Kind | Standard | Part | Sizes |
|---|---|---|---|
| screw | ISO 4762:2004 | hexagon socket head cap screw | M1.6 to M64 |
| ISO 7380-1:2011 | hexagon socket button head screw | M3 to M16 | |
| ISO 7380-2:2011 | hexagon socket button head screw with collar | M3 to M16 | |
| ISO 10642:2004 + Amd 1:2012 | hexagon socket countersunk head screw | M3 to M20 | |
| ISO 4014:2011 | hexagon head bolt | M1.6 to M64 | |
| ISO 4017:2011 | hexagon head screw, threaded to the head | M1.6 to M64 | |
| set screw | ISO 4026:2003 | hexagon socket set screw, flat point | M1.6 to M24 |
| ISO 4027:2003 | cone point | M1.6 to M24 | |
| ISO 4028:2003 | dog point | M1.6 to M24 | |
| ISO 4029:2003 | cup point | M1.6 to M24 | |
| nut | ISO 4032:2012 | hexagon regular nut (style 1) | M1.6 to M64 |
| ISO 4033:2012 | hexagon high nut (style 2) | M5 to M36 | |
| ISO 4035:2012 | hexagon thin nut (style 0) | M1.6 to M64 | |
| ISO 4161:2012 | hexagon nut with flange | M5 to M20 | |
| washer | ISO 7089:2000 | plain washer, normal series, grade A | M1.6 to M64 |
| ISO 7090:2000 | plain washer, chamfered, normal series | M5 to M64 | |
| ISO 7091:2000 | plain washer, normal series, grade C | M1.6 to M64 | |
| ISO 7092:2000 | plain washer, small series | M1.6 to M36 | |
| ISO 7093-1:2000 | plain washer, large series, grade A | M3 to M36 | |
| ISO 7093-2:2000 | plain washer, large series, grade C | M3 to M36 | |
| ISO 7094:2000 + Cor 1 | plain washer, extra large series | M5 to M36 | |
| drive | ISO 10664:2014 | hexalobular socket (no screw uses it yet) | 1 to 100 |
Every size the standards list, preferred and non-preferred. Metric coarse thread (ISO 261).
iso-fasteners.scad the library: include or use this one file; it draws nothing by itself
src/ its parts: registry and lookups, threads, drives, shapes, one file per kind, holes
preview.scad the viewer for everything
previews/ one viewer per kind (screws, set screws, nuts, washers) and the drives
docs/ the picture above
Use
Add it to your project as a git submodule:
git submodule add https://git.octr.is/rbanic/iso-fasteners.git iso-fasteners
include <iso-fasteners/iso-fasteners.scad> // use <...> works too
$fa = 1; $fs = 0.05; // the library follows your $fa / $fs (or $fn)
// a plate with a counterbored hole, an M5 x 20 socket head screw in it, head 5 mm down,
// and an M5 nut sunk flush in a pocket on the far side
difference() {
translate([-10, -10, -25]) cube([20, 20, 25]);
screw_hole("ISO4762", "M5", 20, sink = 5);
translate([0, 0, -25]) mirror([0, 0, 1]) fastener_pocket("ISO4032", "M5", 4.7);
}
translate([0, 0, -5]) screw("ISO4762", "M5", 20, thread = true);
translate([0, 0, -25 + 4.7]) mirror([0, 0, 1]) nut("ISO4032", "M5", thread = true);
include and use both work. use keeps the library's names out of your
file; include also gives you the tables (ISO4762, ISO4032, ...). The
library sets no $fa, $fs or $fn of its own: round features and the
thread's helix take their facets from yours.
A size of a standard is a spec, a key-value list: S = fspec("ISO4032", "M8"), read with fval(S, "m_max"). Every table column is named after the
symbol and the limit it holds (dk_max, s_min, e_min); the symbols are
explained at the top of each file in src/.
Frames
Every part and every cutter is drawn in the frame of the surface it sits on: the origin on that surface, the part's material, or the hole, going down -Z.
- A screw with a head stands on z = 0 and its nominal length
lcounts from there; a countersunk head sits in the surface with its top at z = 0 andlcounts from the top, as its standard defines it. The tip is at z = -l. - A set screw's socket end is on z = 0, its point at z = -l.
- A nut or a washer stands on z = 0 (its bearing face), centred on the axis.
- To sink a part, draw it
translate([0, 0, -sink])and give the cutter the samesink. Cutters poke 1 mm out of the surface so they cut cleanly. - One hex corner points along +X; one lobe of a hexalobular socket does too.
Modules
| Module | Draws |
|---|---|
screw(std, size, l, thread = false) |
a screw or bolt with a head. std is "ISO4762", "ISO7380-1", "ISO7380-2", "ISO10642", "ISO4014" or "ISO4017"; size is "M8" etc. |
set_screw(std, size, l, thread = false) |
a set screw: "ISO4026" .. "ISO4029" |
nut(std, size, thread = false) |
a nut: "ISO4032", "ISO4033", "ISO4035", "ISO4161" |
washer(std, size) |
a washer: "ISO7089" .. "ISO7094" ("ISO7093-1", "ISO7093-2") |
fastener(std, size, l, thread = false) |
any of the above, by its standard |
screw_hole(std, size, l, sink = 0, fit = "medium", clearance = 0.5, depth) |
the cutter for a screw's hole: clearance hole, counterbore or countersink (see Holes) |
tapped_hole(d, depth, thread = false, allowance = 0.2, chamfer = 0, plain = 0) |
the cutter for a threaded hole |
fastener_pocket(std, size, sink, clearance = 0.5) |
a pocket for any part: a nut's hexagon (and flange), a washer's or a head's circle |
metric_thread(d, p, l, internal = false) |
an ISO metric thread from z = 0 to l; internal gives the space inside a nut |
hex_socket(s, e, t), hexalobular_socket(no, t) |
the drives, as cutters |
hex_body(s, h), countersink(da, theta) |
the shapes the parts share: a chamfered hexagon, a countersink |
Functions
| Function | Returns |
|---|---|
fspec(std, size), fval(S, key) |
one size of one standard as a key-value list; one of its values |
fastener_standards(kind), fastener_sizes(std), fastener_lengths(S) |
the standards (of a kind: "screw", "set screw", "nut", "washer"); a standard's sizes; its lengths for one size |
screw_lg(S, l), screw_b(S, l), screw_full_thread(S, l) |
grip length (from the bearing face to the first full thread), thread length, whether that length is threaded to the head |
screw_head_d(S), screw_head_top(S), screw_head_under(S) |
the head's widest diameter; z of its top and its underside |
nut_height(S), washer_height(S), fastener_width(S) |
heights; any part's widest diameter |
set_screw_short(S, l), set_screw_t(S, l) |
whether a length is one of the standard's short ones; the socket depth for it |
thread_pitch(d), clearance_d(d, fit) |
ISO 261 coarse pitch; ISO 273 clearance hole, fit = "fine", "medium" or "coarse" |
thread_d2(d, p), thread_d3(d, p), thread_D1(d, p) |
pitch diameter, external root diameter, internal minor diameter (tap drill) |
A size or standard that doesn't exist stops with a message listing the ones that do. A length outside the standard's range still draws; the viewers say so.
What is drawn
The most metal the standard allows, so a fit checked against the model errs towards a collision: heads, nuts and washers at their largest, sockets and bores at their smallest. Where a standard gives only one limit, that one is used. Where it leaves a shape open, the choice is in the comment at the top of the file that draws it; in short:
- Heads. ISO 4762: a cylinder with its top edge rounded and its bottom edge chamfered to the bearing face. ISO 7380: a dome through the edge of the flat on top, cut off at the head diameter; on 7380-2 it sits on a collar. ISO 10642: the 90 degree cone, its edge truncated halfway between the standard's limits. ISO 4014/4017: the hexagon with sharp corners at the largest width across flats, its top chamfered at 15 degrees (the least of the standard's 15 to 30), on a washer face as wide as the flats; the taller of the two product grades' head heights.
- Sockets. Hexagon: corners cut by the across-corners circle, a 120 degree drill point below. Hexalobular: twelve tangent arcs at the smallest socket the GO gauge must enter.
- Shank and thread. Up to the standard's limit a screw is threaded to
within 3P of the head (ISO 4017: its own
a), longer ones have a plain shank and the thread length b. A screw threaded to the head has a short neck at the pitch diameter under it. The thread runs out over 2P, and the point is chamfered at 45 degrees to just under the root (ISO 4753). - Set screws. The socket end chamfered to the root diameter (90 degrees, 120 on the short lengths); flat, cone, dog or cup point; the socket depth and point shape follow the standard's short and long lengths.
- Nuts. The hexagon with sharp corners, both faces chamfered at 15 degrees; the thread countersunk at both faces as little as allowed. ISO 4161's flange: a 15 degree cone through its thickness at the bearing diameter, a rounded edge.
- Washers. A ring at the smallest bore, largest outside and thickest; ISO 7090's chamfer at its smallest.
- Thread (
thread = true). The ISO 68-1 profile: 60 degree flanks, flat crest, rounded root on external threads (ISO 965-1), right hand, at basic size. Off, the thread is a plain cylinder at d on screws, the minor diameter D1 in nuts. - Not modelled. Head markings, washer faces made only to order, the socket's mouth chamfer, ISO 4161's fillet between hexagon and flange, thread tolerance classes.
Threads that mate
Every thread keeps the phase of z = 0 in the frame it is drawn in. So a screw
or set screw drawn in the same frame as its tapped_hole() mates with it,
and a nut mates on a bolt when the nut's face is a whole number of pitches
from the bolt's z = 0 (or turn the nut by 360 * offset / P degrees).
A screw's incomplete thread, just above its full thread, is wider at the
root than an internal thread's crests: driven into a full thread it would
jam. tapped_hole(..., plain = screw_lg(S, l)) makes the top of the hole
plain, so a screw seated on the surface clears.
Holes
- Clearance hole: ISO 273 fine, medium (default) or coarse, through to
past the tip unless you give
depth. - Counterbore for a head on the surface when
sink > 0: the head's widest diameter (the collar's on 7380-2, a hex head's corners) plusclearance(0.5 mm), because printed holes come out small. - Countersink for ISO 10642: the head's own 90 degree cone, so the head
bears on it and sits where drawn: flush at
sink = 0. A 90 degree cone made wider is the same cone moved down, so givesinkinstead of a clearance. Withsink > 0a counterbore runs on above it. - Under the head the hole is chamfered at 45 degrees out to da, where the fillet under the head may end, as ISO 273 recommends.
- Threaded hole (
tapped_hole): the internal thread modelled, for threads printed into the part, or a plain hole at the minor diameter, to tap or for a screw to cut its own thread in plastic.allowance(0.2 mm on the diameter) is a starting point: print a test piece. - Pocket (
fastener_pocket): a nut's hexagon (with its flange), a washer's circle or a head's circle, grown byclearance,sinkdeep. A nut in a pocket as deep asnut_height(S)sits flush.
The viewers
Open preview.scad for everything (threads off by default: everything with
threads takes a minute or two), or one of previews/screws.scad,
set-screws.scad, nuts.scad, washers.scad, drives.scad. Each shows
every size of every standard of its kind, one row per standard, a size in
the same column in every row.
| Setting | Does |
|---|---|
STANDARD |
all, or one standard |
SIZE |
all, or one size: across every standard that has it, with its dimensions and hole in the console |
LENGTH |
nominal length; 0 = the standard's length nearest 3 d (set screws 1.5 d) |
THREAD |
model the thread |
SHOW |
part, cutter (the hole or pocket), or fit (a block with the cutter and the part in it) |
CUTAWAY |
cut the front half away |
FIT, SINK, CLEARANCE |
the hole: ISO 273 series, how far the part sits below the surface, counterbore or pocket clearance |
Speed and size
A plain M3 x 20 screw is about 12 000 facets at $fa = 1, $fs = 0.05. The
thread follows $fa/$fs: a threaded M3 x 20 is about 300 000 facets and
renders in under a second with the Manifold backend (--backend=manifold, or
Preferences > Advanced). For assemblies with many parts, leave thread off
or use coarser $fa/$fs.
Sources
The dimensions are from each standard's tables, including the length ranges and which lengths are threaded to the head or count as short: ISO 4762:2004, ISO 7380-1:2011, ISO 7380-2:2011, ISO 10642:2004 and Amd 1:2012, ISO 4014:2011, ISO 4017:2011, ISO 4026 to 4029:2003, ISO 4032, 4033, 4035 and 4161:2012, ISO 7089 to 7094:2000 (7094 with Cor 1:2000), ISO 10664:2014, ISO 261:1998 and ISO 273:1979. The thread follows ISO 68-1, ISO 724 and ISO 965-1. The standards are copyrighted and not in this repository; they're sold by ISO and national standards bodies. A few printed values are misprints (ISO 4017's swapped washer-face heights, for one); the tables say where, and none of them reaches the drawing.
Checked:
- Every size of every standard against its table: head or body height, width across flats and corners, head, flange and outside diameters, length (set screws at their shortest and longest), washers' bores by volume.
- The thread against a mating internal thread (clear with 0.01 mm on the diameter, colliding with 0.1 mm less).
- Every screw standard in its own hole, flush and sunk, thread on and off: seated it touches with zero volume, lifted 0.01 mm it's clear, pushed 0.01 mm it collides. Nuts in their pockets the same way.
- Threaded nuts on threaded bolts, set screws and screws in threaded holes: clear in phase, colliding half a pitch off or with 0.1 mm less.
- The hexalobular outline reproduces the standard's A and B on all 24 sizes.
License
Not chosen yet.
