Why tq-threads
🧩 Manifold by construction
The thread surface is a helical height-field turned into one closed polyhedron — no boolean unions to go non-manifold. It renders cleanly and slices.
📐 Standards-based, clean-room
Built only from public standards (ISO 68-1/261/262/273/4032/4762/7089/10642, ASME B1.1). No third-party thread library was copied or consulted.
🖨️ Printable-first
Fit clearance, internal-oversize / external-undersize compensation, lead-in chamfers, rounded roots, and real $fn/$fa/$fs are all parameters.
🔩 Batteries included
101 presets (M1.6–M64 coarse + full ISO 261 fine + UNC/UNF #0–1″), plus bolts, nuts, washers, countersunk & wood screws, augers, Phillips drives, clearance/counterbore/countersink holes, standoffs, couplers, and child‑difference tq_tap/tq_drill wrappers. Square, rectangular, narrow-tooth, and groove profiles are generic printable forms; tune clearance for FDM fit.
⚖️ MIT licensed
Permissive and GPL-2.0-compatible, so it drops into a GPL-2.0-only project (e.g. TinkerQuarry) unchanged.
✅ Tested & CI
Compile-time preset assertions, split render cells, negative/assert tests, independent STL mesh checks, and GitHub Actions running the same proof on every push.
Architecture
Quick start
// install: git submodule / OPENSCADPATH / vendor the .scad include <tq_threads.scad>; $fn = 64; // M8 × 1.25 threaded rod, 20 mm tq_thread_preset("M8", 20); // tapped M6 hole through a block difference() { cube([20,20,12], center=true); tq_threaded_hole(d=6, pitch=1.0, depth=12); } // a cap screw + matching nut (same clearance ⇒ they fit) tq_bolt(8, 1.25, 20, head="socket", shank=4); tq_nut(8, 1.25);
Install
# 1) git submodule (versioned projects) git submodule add https://github.com/scottconverse/tq-threads libs/tq-threads # include <libs/tq-threads/tq_threads.scad>; # 2) drop on the OpenSCAD library path # ~/Documents/OpenSCAD/libraries/ (Win/macOS) # ~/.local/share/OpenSCAD/libraries/ (Linux) # 3) or download the release .zip and vendor the .scad
Only tq_threads.scad is needed at runtime. Coexists with BOSL2, NopSCADlib, etc. (everything is namespaced tq_*).
Migrating from threads.scad?
metric_thread(d,p,l)→tq_thread(d,p,l)english_thread()→tq_thread_tpi()ScrewHole()→difference(){…; tq_threaded_hole()}
Full table in the manual.
Presets
Metric coarse: M1.6 M2 M2.5 M3 M3.5 M4 M5 M6 M7 M8 M10 M12 M14 M16 M18 M20 M22 M24 M27 M30 M33 M36 M39 M42 M45 M48 M52 M56 M60 M64
Metric fine: M8x1 M10x1.25 M10x1 M12x1.5 M12x1.25 M16x1.5 M20x1.5 M24x2 · Unified: 1/4-20 1/4-28 3/8-16 3/8-24 1/2-13 1/2-20