Automated technical-drawing generation for build123d
Project description
draftwright
Automated technical-drawing generation for build123d. Point it at a solid (or a STEP file) and get a fully-annotated multi-view engineering drawing — orthographic views, dimensions, section A–A, ISO hatching, title block — ready to export as PDF, SVG, and DXF.
A mounting plate, generated automatically: three dimensioned orthographic views, a
counterbored bore callout (⌀18 THRU ⊔ ⌀30 ↓14), a 4× ⌀8 THRU hole-pattern callout,
Section A–A with ISO hatching, an isometric, and an ISO 7200 title block — every
annotation placed by the engine.
Quick start
pip install draftwright
Command line
Point it at a STEP file — that's the whole workflow:
draftwright my_part.step --title "Mounting Plate" --number DWG-001
# writes my_part.pdf (the default)
Choose formats, scale, and page; or emit an editable drawing script:
draftwright my_part.step --format pdf,dxf # also: svg, all
draftwright my_part.step --scale 2 --page A3 # override the auto scale / page
draftwright my_part.step --script # write an editable .py drawing script
draftwright --help lists every flag; --version prints the version.
Python
One call turns a build123d solid (or a STEP file) into a drawing. This is the exact part in the image above:
from build123d import Box, Cylinder, Pos
from draftwright import make_drawing
part = (
Box(100, 70, 24)
- Pos(0, 0, 0) * Cylinder(9, 40) # central bore, counterbored below
- Pos(0, 0, 8) * Cylinder(15, 20) # counterbore → triggers Section A–A
- Pos(-38, 24, 0) * Cylinder(4, 40) # 4× corner holes (recognised as a pattern)
- Pos(38, 24, 0) * Cylinder(4, 40)
- Pos(-38, -24, 0) * Cylinder(4, 40)
- Pos(38, -24, 0) * Cylinder(4, 40)
)
make_drawing(part, out="my_part", title="Mounting Plate", number="DWG-001")
# writes my_part.svg and my_part.dxf (or from a STEP file: make_drawing(step_file="p.step", out="my_part"))
For inspection and editing, get a composable Drawing:
from draftwright import build_drawing
dwg = build_drawing(part, title="Mounting Plate")
issues = dwg.lint() # list[LintIssue] — coverage, page bounds, ISO
svg_path, dxf_path = dwg.export("my_part")
What it produces
- Three orthographic views (front, plan, side) sized and scaled automatically to the page
- Dimensions on every principal envelope face, plus bore callouts (diameter, depth, counterbore, spotface) on all holes, and ø leader-callouts for the external stepped diameters of turned parts
- Section A–A with ISO 128-44 solid filled cutting-plane arrows and ISO 128-50 45° hatching on the cut face, triggered automatically when blind or stepped holes would otherwise be hidden-line-only
- Title block (ISO 7200) with part name, drawing number, scale, tolerance, and date
- Lint —
Drawing.lint()checks annotation coverage, page bounds, and ISO compliance and returns structuredLintIssueobjects
All output is real build123d geometry, so PDF, SVG, and DXF all come from the same source and dimensions are live on the DXF layer.
Requires Python ≥ 3.10 and build123d ≥ 0.9.0. Annotation primitives are provided by
build123d-drafting-helpers,
installed automatically as a dependency.
Going further
Scale and page control
from draftwright import choose_scale
# Auto-select the best ISO/ASME standard scale for an A3 sheet
scale, page_w, page_h, n_steps = choose_scale(80, 60, 20, page="A3")
# Override
make_drawing(part, out="drawing", scale=2.0, page="A2")
Edit, critique, and self-repair
Edit a Drawing in domain vocabulary — the engine places annotations
automatically, so you say what to dimension, not where:
dwg = build_drawing(part)
# Inspect detected features and add a dimension in domain terms (auto-placed):
for f in dwg.features("plan"):
dwg.place_dim(f.page_pos, (f.page_pos[0] + f.diameter, f.page_pos[1]),
"below", "plan", dwg.draft, name="dim_pocket")
crit = dwg.lint_summary() # {"passed", "score", "by_code", "issues":[…suggestion]}
dwg.repair() # auto-fix mechanically-fixable lint; never worsens
Each LintIssue carries a domain-meaningful code and, when computable, a
ready-to-apply suggestion. See docs/adr/ for the design (deterministic
generation, the lint→repair loop, and the constraint-based layout engine).
Architecture
draftwright is structured as a part-drawing compiler (ADR 0008): feature
detectors → a PartModel IR (Features exposing DimParameters) → a dimensioning
planner → renderers, feeding a shared layout/projection/export stack. It builds on
two libraries:
draftwright
└── build123d-drafting-helpers — Dimension, Leader, HoleCallout, …
└── build123d — CAD kernel
It owns feature recognition (recognition/) and linting (linting/); annotation
primitives (Dimension, Leader, etc.) live in build123d-drafting-helpers and can
be used independently. The compiler is largely converged in production — turned
dims/lengths, centre marks, envelope, slots, holes (callouts/locations/grouping),
the section A–A trigger, the prismatic step-ladder + rotational furniture, and PMI/GD&T
are all on the IR — the migration is complete (one path; the orchestrator is
build → plan → render). See
docs/target-architecture.md and
docs/adr/. The engine handles view layout (strip/zone model), scale
selection, annotation placement, and section rendering.
The codebase has been entirely written by LLM (Claude Code) under detailed guidance from a person.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file draftwright-0.2.5.tar.gz.
File metadata
- Download URL: draftwright-0.2.5.tar.gz
- Upload date:
- Size: 2.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fc450ee9157f2a2487e6c47aaafb42320c78912c9fe3e0cae8a42ef9bfd47fbc
|
|
| MD5 |
50937d618744969de5f686de2c9e16c4
|
|
| BLAKE2b-256 |
4b5360bf246426f2a794703f920a4f25855e3f75f8b3afe1f5092d735ab5d2db
|
Provenance
The following attestation bundles were made for draftwright-0.2.5.tar.gz:
Publisher:
publish.yml on pzfreo/draftwright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
draftwright-0.2.5.tar.gz -
Subject digest:
fc450ee9157f2a2487e6c47aaafb42320c78912c9fe3e0cae8a42ef9bfd47fbc - Sigstore transparency entry: 2073037192
- Sigstore integration time:
-
Permalink:
pzfreo/draftwright@b070861a1f73adb46c3d62bad2b9b6348455c9ba -
Branch / Tag:
refs/tags/v0.2.5 - Owner: https://github.com/pzfreo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b070861a1f73adb46c3d62bad2b9b6348455c9ba -
Trigger Event:
release
-
Statement type:
File details
Details for the file draftwright-0.2.5-py3-none-any.whl.
File metadata
- Download URL: draftwright-0.2.5-py3-none-any.whl
- Upload date:
- Size: 381.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
09e273028b9f4d354d2396e5875e8d28f3cf8475c35e1254ba290d0c322a32d0
|
|
| MD5 |
d9b923bf78a58d3a637b0d13ca8de0f0
|
|
| BLAKE2b-256 |
35daca51ffbf37af2606910c769bdb7a861022704f2b1caf2b37a47e137de13d
|
Provenance
The following attestation bundles were made for draftwright-0.2.5-py3-none-any.whl:
Publisher:
publish.yml on pzfreo/draftwright
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
draftwright-0.2.5-py3-none-any.whl -
Subject digest:
09e273028b9f4d354d2396e5875e8d28f3cf8475c35e1254ba290d0c322a32d0 - Sigstore transparency entry: 2073037203
- Sigstore integration time:
-
Permalink:
pzfreo/draftwright@b070861a1f73adb46c3d62bad2b9b6348455c9ba -
Branch / Tag:
refs/tags/v0.2.5 - Owner: https://github.com/pzfreo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b070861a1f73adb46c3d62bad2b9b6348455c9ba -
Trigger Event:
release
-
Statement type: