The part script¶
One script per part, at parts/<name>/<name>.py. It is ordinary
build123d Python with a few conventions, so every tool
(and every agent) knows where to find the dimensions, the variants and the checks.
from dataclasses import dataclass
from build123d import Align, Box, Cylinder, Mode, Part
from b123d_print import View, Wall, hole_comp
BED = (Align.CENTER, Align.CENTER, Align.MIN)
@dataclass(frozen=True)
class Dims: # every dimension named, in mm, with its source
W: float = 30.0 # typed measurement
H: float = 8.0
HOLE_D: float = 3.4 # M3 clearance, target printed size
CBORE_D: float = 6.5
CBORE_DEPTH: float = 3.0
HOLE_COMP: float = hole_comp(__file__) # from YOUR config, default 0
VARIANTS = {"": {}, "wide": dict(W=40.0)} # overrides only
def build(d: Dims) -> Part: # print orientation, bed at Z=0
p = Box(d.W, d.W, d.H, align=BED)
p -= Cylinder((d.HOLE_D + d.HOLE_COMP) / 2, 50, mode=Mode.PRIVATE)
p -= Cylinder((d.CBORE_D + d.HOLE_COMP) / 2, d.CBORE_DEPTH, align=BED, mode=Mode.PRIVATE)
return p
def views(d): # sections saved with every export
return [View("XZ", 0.0, "through the hole")]
def checks(d): # how much material is left around the counterbore?
return [Wall("", "XY", d.CBORE_DEPTH / 2, near=(0, 0), radius=d.W, label="around the counterbore")]
if __name__ == "__main__":
from b123d_print import run
run(__file__)
What a script defines¶
| Name | Required | What |
|---|---|---|
Dims |
by convention | frozen dataclass; every dimension an UPPER_CASE field in mm with a comment saying where it came from; derived values as @property |
VARIANTS |
no (default: only the standard part) | {"": {}, "140": dict(PLATE_W=140.0)} — overrides only; "" is the standard part; output files get the key as a suffix |
build(d) |
yes | the printable part, or {"name": part} for several, in print orientation, bottom face on Z=0 |
assembly(d) |
no | [(part, color, label), ...] in assembled position, plus simple stand-ins for what the parts mate with (a board, a sensor, a screw); the overlap check uses it |
views(d) |
no | [View(...)] cross-sections saved with every export |
templates(d) |
no | [Template.slice(...), Template.face_of(...), Template.crop(...)] fit-test templates written with every export (arguments) |
checks(d) |
no | [Wall(...), Overhang(...), Probe(...), ...] — see Checks API |
original(d) |
no | for a remix: the original model placed as the remix is; default: what build(d) loaded with import_model. The automatic checks also run on it, so its findings are labeled inherited, and before_after and export compare the remix with it |
A script with only a module-level part = ... (no Dims) also works, without variants.
For the design review¶
Optional names the design review reads, in Dims (so a variant can
override them) or at module level:
| Name | Example | What |
|---|---|---|
STYLE |
STYLE: str = "modern" |
functional, modern, least_cost, rugged or soft; "" (the template's) uses the workspace's style, else functional |
SHOW |
SHOW = ["+Y", "+Z"] |
the sides seen in use, in print orientation; surface findings are limited to them |
UP |
UP = "+Y" |
the side that points up in use (print orientation), for the water-trap check; default +Z |
EDGES |
EDGES = "chamfer" |
the edge language: chamfer or fillet; functional with chamfer is the industrial look |
Values from the user's config¶
| Helper | Use |
|---|---|
hole_comp(__file__) |
HOLE_COMP: float = hole_comp(__file__); add it to hole diameters when cutting (Hole compensation) |
clearance(__file__) |
CLEARANCE: float = clearance(__file__); the default mating gap (0.2 mm) |
printer(__file__) |
the active printer profile, or None in generic mode |
Starting from an existing model¶
| Helper | Use |
|---|---|
import_model(path, scale?, max_triangles?, merge?, script?) |
an STL, 3MF or STEP as a solid to change: base = import_model("ref/bracket.stl"); paths are relative to the script's folder (ref/) or the workspace (refs/). See Remixing a part |
Never hard-code a hole compensation from somewhere else; keep hole fields at the size you want printed.
new_part / b123d-print new start from a template with all of this in place. The rules for
agents (and humans) writing scripts are in Workflow rules; the modeling API itself
is in the build123d docs. For real parts, see the
Examples.