No description
  • OpenSCAD 100%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Roberto Anić Banić c80776e44e Document every kind, the shared parts and how a standard is added
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.
2026-10-18 13:16:35 +02:00
docs Document every kind, the shared parts and how a standard is added 2026-10-18 13:16:35 +02:00
previews Add the ISO 10664 hexalobular socket as a drive 2026-10-18 13:08:11 +02:00
src Add the ISO 10664 hexalobular socket as a drive 2026-10-18 13:08:11 +02:00
.gitignore Ignore the standards clone under the standards repo's own name 2026-10-18 12:29:57 +02:00
CLAUDE.md Document every kind, the shared parts and how a standard is added 2026-10-18 13:16:35 +02:00
iso-fasteners.scad Add hexagon socket set screws (ISO 4026-4029) and keep every thread in phase 2026-10-18 13:03:12 +02:00
preview.scad Build the library from shared parts around a registry of standards 2026-10-18 12:50:24 +02:00
README.md Document every kind, the shared parts and how a standard is added 2026-10-18 13:16:35 +02:00

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.

One M8 of every standard: socket, button, collar, countersunk and hex heads, set screws, nuts and washers

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 l counts from there; a countersunk head sits in the surface with its top at z = 0 and l counts 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 same sink. 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) plus clearance (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 give sink instead of a clearance. With sink > 0 a 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 by clearance, sink deep. A nut in a pocket as deep as nut_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.