draftwright 0.2.13__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {draftwright-0.2.13 → draftwright-0.3.0}/CHANGELOG.md +80 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/PKG-INFO +2 -2
- {draftwright-0.2.13 → draftwright-0.3.0}/pyproject.toml +12 -2
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/__init__.py +4 -3
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/_core.py +7 -43
- draftwright-0.3.0/src/draftwright/_geometry.py +50 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/analysis.py +215 -142
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/_common.py +85 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/from_model.py +518 -3
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/holes.py +246 -105
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/orchestrator.py +61 -36
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/sections.py +27 -23
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/builder.py +8 -1
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/drawing.py +228 -114
- draftwright-0.3.0/src/draftwright/layout.py +404 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/linting/coverage.py +15 -11
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/linting/suggest.py +26 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/model/__init__.py +26 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/model/declare.py +532 -2
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/model/detect.py +216 -24
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/model/ir.py +182 -2
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/model/planner.py +1 -1
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/projection.py +4 -1
- draftwright-0.3.0/src/draftwright/recognition/__init__.py +125 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/recognition/_features.py +87 -32
- draftwright-0.3.0/src/draftwright/recognition/_record.py +28 -0
- draftwright-0.3.0/src/draftwright/recognition/chamfers.py +170 -0
- draftwright-0.3.0/src/draftwright/recognition/countersinks.py +145 -0
- draftwright-0.3.0/src/draftwright/recognition/fillets.py +161 -0
- draftwright-0.3.0/src/draftwright/recognition/flats.py +172 -0
- draftwright-0.3.0/src/draftwright/recognition/grooves.py +132 -0
- draftwright-0.3.0/src/draftwright/recognition/levels.py +175 -0
- draftwright-0.3.0/src/draftwright/recognition/plates.py +149 -0
- draftwright-0.3.0/src/draftwright/recognition/slots.py +675 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/recognition/turned.py +46 -18
- draftwright-0.3.0/src/draftwright/score.py +70 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/sheet.py +79 -178
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/sheet_dsl.py +88 -1
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/sheet_emit.py +42 -8
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/dshape.json +51 -33
- draftwright-0.3.0/tests/test_declare.py +1385 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_gdt_placement.py +1 -1
- draftwright-0.3.0/tests/test_import_boundaries.py +114 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_layout.py +3 -202
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_make_drawing.py +1148 -102
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_part_model.py +15 -10
- draftwright-0.3.0/tests/test_recogniser_contract.py +242 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_recognition.py +89 -89
- draftwright-0.3.0/tests/test_score.py +38 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_sheet_emit.py +235 -7
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_strip_layout.py +327 -16
- draftwright-0.3.0/tests/test_turned_steps.py +118 -0
- draftwright-0.2.13/src/draftwright/features.py +0 -23
- draftwright-0.2.13/src/draftwright/layout.py +0 -640
- draftwright-0.2.13/src/draftwright/recognition/__init__.py +0 -54
- draftwright-0.2.13/src/draftwright/recognition/levels.py +0 -51
- draftwright-0.2.13/src/draftwright/recognition/slots.py +0 -317
- draftwright-0.2.13/tests/test_declare.py +0 -647
- draftwright-0.2.13/tests/test_turned_steps.py +0 -87
- {draftwright-0.2.13 → draftwright-0.3.0}/.gitignore +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/LICENSE +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/README.md +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/skills/SKILL.md +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotate.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/annotations/__init__.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/cli.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/export.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fits.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/fonts/__init__.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/intents.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/linting/__init__.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/linting/issues.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/linting/structural.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/make_drawing.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/pmi.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/registry.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/src/draftwright/repair.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/_kernel.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/box.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/bracket.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/drive_screw_x.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/flange.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/holed_slot.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/plate_holes.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/side_drilled.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/slotted.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/layout_snapshots/turned_shaft.json +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_e2e_slice.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_e2e_standards.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_fits.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_layout_cleanliness.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_layout_property.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_layout_snapshot.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_lint_reconciliation.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_lint_structural.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_linting.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_object_aspects.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_pmi.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_registry.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_render_seam.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_sheet_gdt.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_sheet_notes.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_sheet_of.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_sheet_tables.py +0 -0
- {draftwright-0.2.13 → draftwright-0.3.0}/tests/test_tolerances.py +0 -0
|
@@ -1,5 +1,85 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v0.3.0 — 2026-07-14
|
|
4
|
+
|
|
5
|
+
**Breaking — feature-recogniser API renamed** (ADR 0013 / #568): *deliberate* breaks with
|
|
6
|
+
**no compatibility aliases**, hence the minor bump. Only import paths and callable
|
|
7
|
+
signatures change — but note this release also **changes drawing output**: new machined-
|
|
8
|
+
feature callouts, corrected leader anchors, and a reoriented isometric (see Added / Fixed).
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Machined-feature recognition — the #148 epic.** #135 deliberately handled only enclosed
|
|
13
|
+
rectangular through-slots; this broadens recognition, and each feature is recognised **and**
|
|
14
|
+
dimensioned **and** authorable (recognise + emit + declare, ADR 0011):
|
|
15
|
+
- **Blind slots + pockets** — floored recesses, `W × L × D DEEP` (#603).
|
|
16
|
+
- **Cross / intersecting slots** collapse into single continuous channels (#604).
|
|
17
|
+
- **Machined flats** on round stock — `{across} A/F` (#605).
|
|
18
|
+
- **Turned / circlip grooves** — `{width} WIDE × ø{floor}` (#606).
|
|
19
|
+
- **Slots / pockets in curved stock** — arc-bounded walls (#607).
|
|
20
|
+
- **Radiused-end (obround) slots** now report their **overall** length (#613).
|
|
21
|
+
- **Chamfer callouts** — `C{leg}` / `{leg}×{angle}°` off each bevel (#560).
|
|
22
|
+
- **Fillet radius callouts** — `R{radius}` off each rounded edge (#561).
|
|
23
|
+
- **Plate / wall thickness** dimensions on multi-plate prismatics (#559).
|
|
24
|
+
- **Prismatic step-position** dimensions locating each shoulder (#555).
|
|
25
|
+
- **Countersink callouts** — `ø6 THRU ⌵ ø14 × 90°` (major-ø + included angle), like the
|
|
26
|
+
counterbore `⊔ ø.. ↧..` (#558). The countersink rides on `HoleRecord`/`HoleFeature`, so
|
|
27
|
+
grouping and the callout-width layout estimate account for it.
|
|
28
|
+
- **Every recognised feature round-trips all three ADR-0011 surfaces (#574).** Beyond
|
|
29
|
+
detection, each feature now **emits** into the generated `--script` Sheet and is
|
|
30
|
+
**declarable** on the fluent `Sheet` surface — authored from scratch or read off a
|
|
31
|
+
build123d object: chamfer (#576), countersink (#575), plate (#577), step-position (#585),
|
|
32
|
+
fillet (#561), plus all the #148 features above.
|
|
33
|
+
- **`draftwright.score.feature_census(part)`** — a per-kind recognised-feature census, a
|
|
34
|
+
measurement tool for tracking recognition coverage (#608).
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- **Feature recognisers renamed `find_`/`analyse_` → `recognise_`** and their
|
|
39
|
+
tuning/dependencies made keyword-only: `find_holes`→`recognise_holes`,
|
|
40
|
+
`find_bosses`→`recognise_bosses`, `find_hole_patterns`→`recognise_hole_patterns`,
|
|
41
|
+
`find_slots`→`recognise_slots`, `find_plates`→`recognise_plates`,
|
|
42
|
+
`find_chamfers`→`recognise_chamfers`, `find_turned_steps`→`recognise_turned_steps`,
|
|
43
|
+
`find_step_shoulders`→`recognise_step_shoulders`, `analyse_face_levels`→
|
|
44
|
+
`recognise_face_levels` (the last was also re-exported at top level as
|
|
45
|
+
`draftwright.analyse_face_levels` → now `draftwright.recognise_face_levels`).
|
|
46
|
+
Cylinder-analysis substrate (`analyse_cylinders`, `full_cylinders`,
|
|
47
|
+
`feature_diameters`) keeps its names.
|
|
48
|
+
- **`recognise_step_shoulders` now returns `list[StepShoulder]`** (a frozen dataclass)
|
|
49
|
+
instead of raw `(axis, position)` tuples; `levels` is keyword-only.
|
|
50
|
+
- **`recognise_turned_steps` now returns `list[TurnedStep]`** (empty for a non-turned
|
|
51
|
+
part) instead of `TurnedProfile | None`. `TurnedStep` gained an `axis` field (each step
|
|
52
|
+
is now a self-contained record); `TurnedProfile` remains only as a pipeline aggregate
|
|
53
|
+
(`TurnedProfile.from_steps(steps)`), no longer a recogniser return.
|
|
54
|
+
- **`recognise_face_levels` now returns `list[FaceLevel]`** (a frozen `FaceLevel(z)`
|
|
55
|
+
record) instead of `list[float]`.
|
|
56
|
+
- **Recognition record classes renamed to avoid clashing with the IR `Feature` types:**
|
|
57
|
+
`draftwright.recognition.HoleFeature` → `HoleRecord`, `BossFeature` → `BossRecord`
|
|
58
|
+
(the IR `draftwright.model.ir.HoleFeature`/`BossFeature` are unchanged).
|
|
59
|
+
- **Page/scale sizing now reads the IR, not recognition records (ADR 0008 / #588).** The
|
|
60
|
+
part model is built up front and drives sheet sizing, so detected and declared parts share
|
|
61
|
+
one path and no recogniser record reaches the sheet estimators. Byte-identical to the old
|
|
62
|
+
estimators except a hole pattern that shares a machining spec with loose holes now sizes
|
|
63
|
+
separately (no phantom merged `N×`), which can shift a tightly-packed such part's layout.
|
|
64
|
+
|
|
65
|
+
### Fixed
|
|
66
|
+
|
|
67
|
+
- **Isometric view orientation (#620).** The iso camera viewed the *rear* (+Y) side against a
|
|
68
|
+
front-view orthographic set, mirroring asymmetric features; it now views from the same
|
|
69
|
+
front (−Y) / plan (+Z) / right (+X) combination.
|
|
70
|
+
- **Chamfer leaders (#621)** anchor on the bevel-face centroid (the diagonal middle), not the
|
|
71
|
+
supporting plane's parametric origin (which projected to a corner/endpoint).
|
|
72
|
+
- **Fillet leaders (#622)** anchor on the radius surface, not the face bounding-box centre
|
|
73
|
+
(which sat off the round, near the virtual sharp corner).
|
|
74
|
+
- **Authored `ref_pts`-only dimensions** now render (with Z-strip sizing) (#562).
|
|
75
|
+
- **Pitch-dim labels** are cleared off centrelines / bolt circles at creation time, not via
|
|
76
|
+
the repair loop (#129).
|
|
77
|
+
|
|
78
|
+
### Removed
|
|
79
|
+
|
|
80
|
+
- **`draftwright.features` compatibility module** — deleted. Import `recognise_slots`/
|
|
81
|
+
`Slot` from `draftwright.recognition` instead.
|
|
82
|
+
|
|
3
83
|
## v0.2.13 — 2026-07-09
|
|
4
84
|
|
|
5
85
|
**Compose-then-pack is now the layout authority.** This patch finishes the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: draftwright
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Automated technical-drawing generation for build123d
|
|
5
5
|
Project-URL: Homepage, https://github.com/pzfreo/draftwright
|
|
6
6
|
Project-URL: Repository, https://github.com/pzfreo/draftwright
|
|
@@ -682,7 +682,7 @@ Classifier: Programming Language :: Python :: 3.13
|
|
|
682
682
|
Classifier: Programming Language :: Python :: 3.14
|
|
683
683
|
Classifier: Topic :: Scientific/Engineering
|
|
684
684
|
Requires-Python: <3.15,>=3.10
|
|
685
|
-
Requires-Dist: build123d-drafting-helpers>=0.13.
|
|
685
|
+
Requires-Dist: build123d-drafting-helpers>=0.13.1
|
|
686
686
|
Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
|
|
687
687
|
Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
|
|
688
688
|
Requires-Dist: numpy>=1.24
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "draftwright"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.3.0"
|
|
8
8
|
description = "Automated technical-drawing generation for build123d"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { file = "LICENSE" }
|
|
@@ -17,7 +17,7 @@ dependencies = [
|
|
|
17
17
|
# 3.13+. Mirrors pzfreo/build123d-mcp's dependency handling.
|
|
18
18
|
"build123d>=0.9.0,<0.11 ; python_full_version < '3.13'",
|
|
19
19
|
"build123d>=0.11,<0.12 ; python_full_version >= '3.13'",
|
|
20
|
-
"build123d-drafting-helpers>=0.13.
|
|
20
|
+
"build123d-drafting-helpers>=0.13.1",
|
|
21
21
|
"numpy>=1.24",
|
|
22
22
|
"reportlab>=4.0",
|
|
23
23
|
"svglib>=1.5",
|
|
@@ -111,6 +111,7 @@ ignore = ["E501"]
|
|
|
111
111
|
|
|
112
112
|
[dependency-groups]
|
|
113
113
|
dev = [
|
|
114
|
+
"codespell>=2.3.0",
|
|
114
115
|
"mypy>=2.1.0",
|
|
115
116
|
"pytest>=8",
|
|
116
117
|
"pytest-cov>=5",
|
|
@@ -119,6 +120,15 @@ dev = [
|
|
|
119
120
|
"ruff>=0.4",
|
|
120
121
|
]
|
|
121
122
|
|
|
123
|
+
[tool.codespell]
|
|
124
|
+
# Spelling enforcement for the ADR 0013 contract (epic #584 WP3). Skips binary /
|
|
125
|
+
# generated / vendored assets: STEP fixtures, the lockfile, fonts, git internals.
|
|
126
|
+
skip = "*.stp,*.step,*.svg,*.dxf,*.pdf,uv.lock,.git,*.ttf,*.otf,src/draftwright/fonts/*"
|
|
127
|
+
# Valid words/identifiers codespell's dictionary misflags (calibrated from a clean run):
|
|
128
|
+
# `nd` a Dijkstra distance var, `tread` a real word (stair-tread faces), `accreting`
|
|
129
|
+
# a real word, `testof` the `TestOf` class name, and the valid hyphenated re-* forms.
|
|
130
|
+
ignore-words-list = "nd,tread,accreting,testof,re-using,re-declare,re-declared,re-declaring"
|
|
131
|
+
|
|
122
132
|
[tool.uv]
|
|
123
133
|
# On Python 3.13/3.14, build123d resolves to 0.11, whose OCP kernel is
|
|
124
134
|
# cadquery-ocp-novtk (VTK dropped from the transitive tree — fine here, draftwright
|
|
@@ -23,7 +23,7 @@ from typing import TYPE_CHECKING
|
|
|
23
23
|
# none of these names, so they stay sub-second instead of paying for the kernel
|
|
24
24
|
# on every TAB press (#313). Each name maps to the submodule that provides it.
|
|
25
25
|
_LAZY = {
|
|
26
|
-
"
|
|
26
|
+
"recognise_face_levels": "draftwright.recognition",
|
|
27
27
|
"dedup_diams": "draftwright.analysis",
|
|
28
28
|
"build_drawing": "draftwright.builder",
|
|
29
29
|
"generate_script": "draftwright.builder",
|
|
@@ -72,12 +72,13 @@ _sys.modules[__name__].__class__ = _DraftwrightModule
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
if TYPE_CHECKING: # static analysers / IDEs — no runtime import, no kernel cost
|
|
75
|
-
from draftwright.analysis import
|
|
75
|
+
from draftwright.analysis import dedup_diams
|
|
76
76
|
from draftwright.builder import build_drawing, generate_script, make_drawing
|
|
77
77
|
from draftwright.drawing import Drawing, FeatureInfo
|
|
78
78
|
from draftwright.export import fix_svg_page_size
|
|
79
79
|
from draftwright.linting import lint_feature_coverage
|
|
80
80
|
from draftwright.pmi import PmiRecord, extract_pmi
|
|
81
|
+
from draftwright.recognition import recognise_face_levels
|
|
81
82
|
from draftwright.sheet import choose_scale
|
|
82
83
|
from draftwright.sheet_dsl import Sheet
|
|
83
84
|
|
|
@@ -94,7 +95,7 @@ __all__ = [
|
|
|
94
95
|
"FeatureInfo",
|
|
95
96
|
"PmiRecord",
|
|
96
97
|
"Sheet",
|
|
97
|
-
"
|
|
98
|
+
"recognise_face_levels",
|
|
98
99
|
"build_drawing",
|
|
99
100
|
"choose_scale",
|
|
100
101
|
"dedup_diams",
|
|
@@ -31,6 +31,11 @@ from build123d_drafting.helpers import (
|
|
|
31
31
|
format_drawing_scale,
|
|
32
32
|
)
|
|
33
33
|
|
|
34
|
+
# The model-neutral geometry primitives (`_END_ON`, `_xyz`, `HoleRef`, `_axis_letter`)
|
|
35
|
+
# now live in the leaf `draftwright._geometry` so the IR waist (`model/`) can use them
|
|
36
|
+
# without importing this stage-level grab-bag (ADR 0008; #584 WP2). Re-exported here for
|
|
37
|
+
# the above-`_core` consumers (annotations/sheet/drawing/linting) that already import them.
|
|
38
|
+
from draftwright._geometry import _END_ON, HoleRef, _axis_letter, _xyz # noqa: F401
|
|
34
39
|
from draftwright.fits import FitClass
|
|
35
40
|
from draftwright.fonts import PLEX_MONO, PLEX_SANS_CONDENSED
|
|
36
41
|
from draftwright.layout import _greedy_strip_1d, _solve_strip_1d
|
|
@@ -43,39 +48,6 @@ _MARGIN = 10.0
|
|
|
43
48
|
|
|
44
49
|
_TB_CLEAR = _MARGIN + 1.0 # title-block inset: one extra mm over _MARGIN for clearance
|
|
45
50
|
|
|
46
|
-
# The orthographic view a feature is dimensioned end-on in — the view normal to its
|
|
47
|
-
# axis. Single source of truth shared by the planner (view choice) and the lint
|
|
48
|
-
# coverage checks (where to look for a feature's dims). Orientation is data.
|
|
49
|
-
_END_ON = {"x": "side", "y": "front", "z": "plan"}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
def _xyz(loc) -> tuple[float, float, float]:
|
|
53
|
-
"""A build123d ``Vector`` (has ``.X/.Y/.Z``) or an ``(x, y, z)`` sequence → an
|
|
54
|
-
``(x, y, z)`` float tuple. Shared by the detectors and the lint coverage checks
|
|
55
|
-
so the Vector-unpacking idiom lives in one place."""
|
|
56
|
-
if hasattr(loc, "X"):
|
|
57
|
-
return (loc.X, loc.Y, loc.Z)
|
|
58
|
-
x, y, z = loc
|
|
59
|
-
return (float(x), float(y), float(z))
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
@dataclass(frozen=True)
|
|
63
|
-
class HoleRef:
|
|
64
|
-
"""A position-keyed reference to a hole — the IR-typed value the cover / hole-table
|
|
65
|
-
bookkeeping matches on, so the shared escalation never needs a recogniser ``Hole``
|
|
66
|
-
object (ADR 0008 Amendment 6). Built from any location via :meth:`of` (rounded, so
|
|
67
|
-
two references at the same position compare equal)."""
|
|
68
|
-
|
|
69
|
-
x: float
|
|
70
|
-
y: float
|
|
71
|
-
z: float
|
|
72
|
-
|
|
73
|
-
@classmethod
|
|
74
|
-
def of(cls, loc) -> HoleRef:
|
|
75
|
-
x, y, z = _xyz(loc)
|
|
76
|
-
return cls(round(x, 3), round(y, 3), round(z, 3))
|
|
77
|
-
|
|
78
|
-
|
|
79
51
|
_FONT_SIZE = 3.0 # annotation text height (page-mm); the draft preset is built with this
|
|
80
52
|
|
|
81
53
|
|
|
@@ -161,14 +133,6 @@ def _text_width(text: str, font_size: float, font_path: str = PLEX_MONO) -> floa
|
|
|
161
133
|
)
|
|
162
134
|
|
|
163
135
|
|
|
164
|
-
def _axis_letter(obj) -> str:
|
|
165
|
-
"""Letter (``"x"``/``"y"``/``"z"``) of ``obj.axis``'s dominant component.
|
|
166
|
-
|
|
167
|
-
``obj`` is anything carrying an ``.axis`` 3-vector (a hole or a boss).
|
|
168
|
-
"""
|
|
169
|
-
return max(zip("xyz", obj.axis, strict=True), key=lambda t: abs(t[1]))[0]
|
|
170
|
-
|
|
171
|
-
|
|
172
136
|
_CONCENTRIC_TOL_MM = 0.5
|
|
173
137
|
|
|
174
138
|
|
|
@@ -506,12 +470,12 @@ class Analysis:
|
|
|
506
470
|
bbox_max: float
|
|
507
471
|
holes: list
|
|
508
472
|
patterns: list
|
|
509
|
-
bosses: list # external bosses (
|
|
473
|
+
bosses: list # external bosses (recognise_bosses), detected once — the one inventory (#244)
|
|
510
474
|
slots: list
|
|
511
475
|
z_diams: list[float]
|
|
512
476
|
cross_diams: list[float]
|
|
513
477
|
cyls: tuple[list, list]
|
|
514
|
-
prof: TurnedProfile | None # turned step profile (
|
|
478
|
+
prof: TurnedProfile | None # turned step profile (recognise_turned_steps), detected once
|
|
515
479
|
od_diam: float | None
|
|
516
480
|
is_rotational: bool
|
|
517
481
|
od_axis: str # rotation/turning axis of a rotational part ("z" default; "x"/"y" #222)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""Model-neutral geometry primitives — the leaf below both ``_core`` and ``model``.
|
|
2
|
+
|
|
3
|
+
These four helpers read an axis / coordinate / position off a build123d object
|
|
4
|
+
(or the IR) and carry no drawing, layout or page knowledge. They live here, not
|
|
5
|
+
in :mod:`draftwright._core`, so the IR waist (:mod:`draftwright.model`) can use
|
|
6
|
+
them without importing the stage-level drawing grab-bag (ADR 0008; #584 WP2).
|
|
7
|
+
This module imports nothing from ``draftwright`` — it is the bottom of the DAG.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
# Axis letter -> the orthographic view a feature on that axis reads end-on in.
|
|
15
|
+
_END_ON = {"x": "side", "y": "front", "z": "plan"}
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _xyz(loc) -> tuple[float, float, float]:
|
|
19
|
+
"""A build123d ``Vector`` (has ``.X/.Y/.Z``) or an ``(x, y, z)`` sequence → an
|
|
20
|
+
``(x, y, z)`` float tuple. Shared by the detectors and the lint coverage checks
|
|
21
|
+
so the Vector-unpacking idiom lives in one place."""
|
|
22
|
+
if hasattr(loc, "X"):
|
|
23
|
+
return (loc.X, loc.Y, loc.Z)
|
|
24
|
+
x, y, z = loc
|
|
25
|
+
return (float(x), float(y), float(z))
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
@dataclass(frozen=True)
|
|
29
|
+
class HoleRef:
|
|
30
|
+
"""A position-keyed reference to a hole — the IR-typed value the cover / hole-table
|
|
31
|
+
bookkeeping matches on, so the shared escalation never needs a recogniser ``Hole``
|
|
32
|
+
object (ADR 0008 Amendment 6). Built from any location via :meth:`of` (rounded, so
|
|
33
|
+
two references at the same position compare equal)."""
|
|
34
|
+
|
|
35
|
+
x: float
|
|
36
|
+
y: float
|
|
37
|
+
z: float
|
|
38
|
+
|
|
39
|
+
@classmethod
|
|
40
|
+
def of(cls, loc) -> HoleRef:
|
|
41
|
+
x, y, z = _xyz(loc)
|
|
42
|
+
return cls(round(x, 3), round(y, 3), round(z, 3))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _axis_letter(obj) -> str:
|
|
46
|
+
"""Letter (``"x"``/``"y"``/``"z"``) of ``obj.axis``'s dominant component.
|
|
47
|
+
|
|
48
|
+
``obj`` is anything carrying an ``.axis`` 3-vector (a hole or a boss).
|
|
49
|
+
"""
|
|
50
|
+
return max(zip("xyz", obj.axis, strict=True), key=lambda t: abs(t[1]))[0]
|