Screws: metric screws, nuts & screw holes

Pure-Python port of the core of BOSL2’s screws.scad, built on top of the threading thread generator. Three classes turn a metric screw name into ready-to-print geometry:

from pybosl2.parts.screws import Screw, Nut, ScrewHole
Screw("M6", 20, head=ScrewHeadType.SOCKET, drive=ScrewDriveType.HEX).show()
Nut("M6").show()
ScrewHole("M6", 20, head=ScrewHeadType.FLAT).show()

A screw is specified by name – "M6" (coarse pitch looked up from the ISO table), "M8x1" (an explicit fine pitch), a bare number, or a {"diameter": ..., "pitch": ...} dict. Screws are built head-up: the shaft occupies z in [-length, 0] (tip at the bottom) and the head sits above z = 0, so a screw drops straight into a mating ScrewHole cut with its mouth at z = 0.

The dimension tables (ISO coarse/fine pitches, and the socket-cap, hex, button, pan, countersunk, setscrew and nut head sizes) are transcribed verbatim from screws.scad and checked in tests/test_screws.py; the assembled geometry is verified watertight with the right head, shaft and thread in tests/test_stl_render.py.

Coverage of BOSL2 screws.scad

BOSL2 feature

Status

Notes

screw_info

ported

replaced by ScrewSpec.

screw

ported

threaded/plain/partly-threaded shaft, plus socket / hex / button / pan / flat / setscrew heads.

nut

ported

hex or square nut with a matching threaded hole; "normal" / "thin" / "thick" thickness.

screw_hole

ported

clearance hole (close/normal/loose fit), flat-head countersink, counterbore, or tapped hole.

hex / slot drive recess

ported

the two most common recesses; cut into the head (or the shaft top for a setscrew).

phillips / torx drive recesses

ported separately

available as masks in Screw drives: Phillips, hex, Torx & Robertson recesses (screw_drive); not yet wired into Screw’s drive= argument.

UTS / imperial specs, shoulder screws, named anchors, per-tolerance thread classes

not ported

a follow-up; this port covers the metric fastener geometry the toolkit needs.

Examples

An M8 socket cap screw with a hex drive recess:

from pybosl2.parts.enums import ScrewHeadType, ScrewDriveType
from pybosl2.parts.screws import Screw
Screw("M8", 24, head=ScrewHeadType.SOCKET, drive=ScrewDriveType.HEX, fa=6, fs=1).show()
Loading 3-D preview…

⬇ Download STL mesh

A countersunk (flat-head) screw:

from pybosl2.parts.enums import ScrewHeadType
from pybosl2.parts.screws import Screw
Screw("M6", 20, head=ScrewHeadType.FLAT, fa=6, fs=1).show()
Loading 3-D preview…

⬇ Download STL mesh

A screw threaded into its matching hex nut (shown side by side):

from pybosl2.parts.enums import ScrewHeadType, ScrewDriveType
from pybosl2.parts.screws import Screw, Nut
screw = Screw("M6", 18, head=ScrewHeadType.BUTTON, drive=ScrewDriveType.HEX, fa=6, fs=1).shape()
nut = Nut("M6", slop=0.1, fa=6, fs=1).shape().right(18)
(screw | nut).show()
Loading 3-D preview…

⬇ Download STL mesh

API reference

class pybosl2.parts.screws.Screw(spec, length, head=ScrewHeadType.SOCKET, drive=ScrewDriveType.NONE, thread=ThreadPitchClass.COARSE, thread_len=None, pitch=None, fn=None, fa=None, fs=None)[source]

Bases: object

A metric screw: threaded (or plain) shaft plus a head with an optional drive recess.

Examples

An M6×20 socket-head cap screw:

from pybosl2.parts.enums import ScrewHeadType, ScrewDriveType
from pybosl2.parts.screws import Screw
Screw("M6", length=20, head=ScrewHeadType.SOCKET, drive=ScrewDriveType.HEX).show()
Loading 3-D preview…

⬇ Download STL mesh

Parameters:
spec : str | dict[str, float] | float

length : float

head : ScrewHeadType

drive : ScrewDriveType

thread : ThreadPitchClass

thread_len : float | None

pitch : float | None

fn : int | None

fa : float | None

fs : float | None

property spec : ScrewSpec

The resolved ScrewSpec.

property diameter : float

Nominal screw diameter in mm.

property pitch : float

Thread pitch in mm.

property head : ScrewHeadType

Head style.

property head_size : float | None

Head diameter / across-flats in mm.

property head_height : float

Head height in mm (0 for headless).

property drive : ScrewDriveType

Drive recess type.

property length : float

Shaft length below the head in mm.

shape()[source]

Build and return the screw geometry (result is cached).

Return type:

CsgSolid

show()[source]

Display the screw in the viewer.

Return type:

None

class pybosl2.parts.screws.Nut(spec, thickness='normal', shape=NutShape.HEX, thread=ThreadPitchClass.COARSE, nutwidth=None, slop=0.0, pitch=None, fn=None, fa=None, fs=None)[source]

Bases: object

A hex or square nut with a threaded hole.

Examples

An M8 hex nut of normal thickness:

from pybosl2.parts.screws import Nut
Nut("M8").show()
Loading 3-D preview…

⬇ Download STL mesh

Parameters:
spec : str | dict[str, float] | float

thickness : float | str

shape : NutShape

thread : ThreadPitchClass

nutwidth : float | None

slop : float

pitch : float | None

fn : int | None

fa : float | None

fs : float | None

property spec : ScrewSpec

The resolved ScrewSpec.

property diameter : float

Nominal diameter in mm.

property pitch : float

Thread pitch in mm.

property shape_nut : NutShape

Nut outer shape.

shape()[source]

Build and return the nut geometry (result is cached).

Return type:

CsgSolid

show()[source]

Display the nut in the viewer.

Return type:

None

class pybosl2.parts.screws.ScrewHole(spec, length, head=ScrewHeadType.NONE, counterbore=0.0, fit='normal', thread=ThreadPitchClass.NONE, pitch=None, fn=None, fa=None, fs=None)[source]

Bases: object

A hole cutter for a screw: clearance shaft plus optional countersink/counterbore.

Returns a solid to subtract from your part. The clearance shaft occupies z in [-length, 0] with its mouth at z = 0; countersinks/counterbores open upward from there.

Examples

Drill a clearance hole for an M6 bolt through a 10 mm plate:

from pybosl2.parts.enums import ScrewHeadType
from pybosl2.parts.screws import ScrewHole
from pybosl2.solid import cuboid
(cuboid([20, 20, 10])
 - ScrewHole("M6", length=10, head=ScrewHeadType.SOCKET, fit="normal").shape()).show()
Loading 3-D preview…

⬇ Download STL mesh

Parameters:
spec : str | dict[str, float] | float

length : float

head : ScrewHeadType

counterbore : float

fit : str

thread : ThreadPitchClass

pitch : float | None

fn : int | None

fa : float | None

fs : float | None

property fit : str

Clearance fit class ("close" / "normal" / "loose").

property length : float

Hole depth in mm.

shape()[source]

Build and return the hole cutter geometry (result is cached).

Return type:

CsgSolid

show()[source]

Display the hole cutter in the viewer.

Return type:

None

class pybosl2.parts.screws.ScrewSpec(spec, head=ScrewHeadType.NONE, thread=ThreadPitchClass.COARSE, drive=ScrewDriveType.NONE, pitch=None)[source]

Bases: object

Resolved dimensions for a metric screw.

Construct directly (replaces the old _parse_spec helper): ScrewSpec("M6"), ScrewSpec("M8x1", head=ScrewHeadType.HEX), etc. Construct directly (replaces the old _parse_spec helper): ScrewSpec("M6"), ScrewSpec("M8x1", head=ScrewHeadType.HEX), etc.

Attributes are set by the constructor and may be read freely.

Parameters:
spec : str | dict[str, float] | float

head : ScrewHeadType

thread : ThreadPitchClass

drive : ScrewDriveType

pitch : float

system : str
diameter : float
pitch : float
drive : ScrewDriveType
head : ScrewHeadType
drive_size : float | None
drive_depth : float | None
head_size : float | None
head_size_sharp : float | None
head_angle : float | None
head_height : float
class pybosl2.parts.screws.ThreadPitches(coarse, fine=None, extra_fine=None, super_fine=None)[source]

Bases: object

ISO metric thread pitches (mm) for one nominal diameter.

Positional args are coarse / fine / extra_fine / super_fine; None marks a pitch class that is undefined for this size.

Parameters:
coarse : float

fine : float | None

extra_fine : float | None

super_fine : float | None

coarse : float
fine : float | None = None
extra_fine : float | None = None
super_fine : float | None = None
pitch(thread=ThreadPitchClass.COARSE)[source]

Return the pitch for a thread class, falling back to coarse if it’s undefined for this size.

Parameters:
thread : ThreadPitchClass

Return type:

float

Examples

These mirror the examples in BOSL2’s screws.scad, rendered live through PythonSCAD. Examples that rely on BOSL2’s attachment/anchor system, or on features not in this port, are omitted.

screw

An M6 screw:

from pybosl2.parts.screws import Screw
Screw("M6", length=12).show()
Loading 3-D preview…

⬇ Download STL mesh

A socket-head M6:

from pybosl2.parts.enums import ScrewHeadType
from pybosl2.parts.screws import Screw
Screw("M6", head=ScrewHeadType.SOCKET, length=12).show()
Loading 3-D preview…

⬇ Download STL mesh

A Torx button-head M6:

from pybosl2.parts.enums import ScrewHeadType
from pybosl2.parts.screws import Screw
Screw("M6", head=ScrewHeadType.BUTTON, drive="torx", length=12).show()
Loading 3-D preview…

⬇ Download STL mesh

nut

An M6 nut:

from pybosl2.parts.screws import Nut
Nut("M6").show()
Loading 3-D preview…

⬇ Download STL mesh

screw_hole

A threaded screw-hole mask:

from pybosl2.parts.screws import ScrewHole
ScrewHole("M6", length=10).show()
Loading 3-D preview…

⬇ Download STL mesh