draftwright 0.1.7__tar.gz → 0.1.9__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.
Files changed (24) hide show
  1. draftwright-0.1.9/CHANGELOG.md +250 -0
  2. {draftwright-0.1.7 → draftwright-0.1.9}/PKG-INFO +1 -1
  3. {draftwright-0.1.7 → draftwright-0.1.9}/pyproject.toml +1 -1
  4. {draftwright-0.1.7 → draftwright-0.1.9}/skills/SKILL.md +4 -1
  5. {draftwright-0.1.7 → draftwright-0.1.9}/src/draftwright/__init__.py +2 -0
  6. {draftwright-0.1.7 → draftwright-0.1.9}/src/draftwright/make_drawing.py +1107 -178
  7. {draftwright-0.1.7 → draftwright-0.1.9}/tests/test_e2e_standards.py +2 -2
  8. {draftwright-0.1.7 → draftwright-0.1.9}/tests/test_make_drawing.py +869 -26
  9. draftwright-0.1.7/CHANGELOG.md +0 -148
  10. {draftwright-0.1.7 → draftwright-0.1.9}/.gitignore +0 -0
  11. {draftwright-0.1.7 → draftwright-0.1.9}/LICENSE +0 -0
  12. {draftwright-0.1.7 → draftwright-0.1.9}/README.md +0 -0
  13. {draftwright-0.1.7 → draftwright-0.1.9}/src/draftwright/pmi.py +0 -0
  14. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  15. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  16. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  17. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  18. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  19. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  20. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  21. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  22. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  23. {draftwright-0.1.7 → draftwright-0.1.9}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  24. {draftwright-0.1.7 → draftwright-0.1.9}/tests/test_pmi.py +0 -0
@@ -0,0 +1,250 @@
1
+ # Changelog
2
+
3
+ ## v0.1.9 — 2026-06-16
4
+
5
+ ### Added
6
+
7
+ - **Domain-semantic editing API.** `dwg.features(view)` returns detected holes
8
+ and features grouped by machining spec in page coordinates, and
9
+ `dwg.place_dim(p1, p2, side, view, draft, name=…)` places a dimension from
10
+ domain inputs — the vocabulary a script (or an AI assistant) needs to edit a
11
+ drawing without hand-computing page geometry (#25, #26).
12
+ - **`dwg.annotations()` and `dwg.get_annotation(name)`.** Introspect what is
13
+ already on the drawing — a `{name: type}` map and a name lookup — so a script
14
+ can make incremental edits without risking a silent name-collision replace
15
+ (#27).
16
+ - **`dwg.view_bounds(view)`.** Returns `(x_min, y_min, x_max, y_max)`, the page
17
+ bounding box of a view's projected geometry (or `None` for an unknown view),
18
+ so free-form notes and leader elbows can be placed just outside a view without
19
+ guessing offsets from `dwg.at()` (#28).
20
+ - **Lint findings carry a suggested fix.** Each repairable lint issue now
21
+ includes a ready-to-run domain-API call snippet, so acting on a finding is one
22
+ copy-paste away (#29).
23
+ - **Lint→repair loop.** `Drawing.repair()` — run by default in `build_drawing` —
24
+ mechanically resolves the lint codes that have a deterministic placement fix:
25
+ overlapping labels are pushed apart and wrong-side dimensions are flipped. A
26
+ pass that would net-increase the issue count is rolled back, so repair never
27
+ makes a drawing worse (#30).
28
+ - **TYP / representative dimensioning for uniform step patterns.** A run of
29
+ equal-rise, equal-going steps is dimensioned once and labelled representative
30
+ (TYP) instead of repeating identical dimensions down the ladder (#45).
31
+ - **Enlarged detail view for crowded step clusters (MVP).** When shoulders are
32
+ too closely spaced to dimension legibly at sheet scale, an opt-in
33
+ (`detail_view=True`) detail view re-draws them at a larger scale (#42).
34
+
35
+ ### Changed
36
+
37
+ - **BREAKING: the annotation list `dwg.annotations` is renamed to `dwg.items`.**
38
+ `dwg.annotations` is now a method (see Added); the ordered, mutable list of
39
+ annotation objects it used to be is now `dwg.items`. Pre-1.0 with no published
40
+ consumers, so the clearer name was taken now rather than spelling the new query
41
+ method awkwardly (#27).
42
+
43
+ ### Documentation
44
+
45
+ - ADRs 0001 (editing model) and 0002 (iteration loop) record the design
46
+ direction behind the domain API and the lint→repair loop (#51).
47
+
48
+ ## v0.1.8 — 2026-06-16
49
+
50
+ ### Changed
51
+
52
+ - **Automatic scale selection now minimises the sheet size.** The preference
53
+ ladder is page-major: every standard scale on the smallest sheet is tried
54
+ before the next sheet up, so a part lands on the smallest sheet it fits at the
55
+ largest scale that sheet allows. A 20 × 15 × 10 mm part is now drawn 2:1 on A4
56
+ instead of 5:1 on A3 — a smaller sheet is preferred over a larger enlargement
57
+ scale. Reductions keep their legibility-first balance, so a too-big part is
58
+ not over-reduced onto a small sheet.
59
+ - **A specified page now enlarges to the best fitting scale.** When the caller
60
+ fixes the page (`--page A3`) or scale, scale selection packs the isometric
61
+ view into the largest empty rectangle the placement engine actually uses (it
62
+ may sit in vertical headroom above the views), instead of charging it a column
63
+ in the view row. A long, short part — e.g. a 100 × 10 × 11 mm staircase — now
64
+ fills a requested A3 at 2:1 where it was previously under-scaled to 1:1.
65
+ Automatic selection (no page/scale given) keeps the conservative row model,
66
+ which reserves enough room to place every annotation rather than dropping some
67
+ onto a tighter sheet (staircase review).
68
+ - **Isometric view growth is capped.** The iso is fitted to fill its zone but no
69
+ longer grows past 1.3× sheet scale; on an oversized sheet it could previously
70
+ balloon to ~8× and dwarf the dimensioned orthographic views. Shrinking to fit
71
+ a small zone is unchanged.
72
+ - **Step heights are dimensioned only where legibly separable.** After the
73
+ adaptive cap (#36), a part with many closely-spaced shoulders (e.g. NIST
74
+ CTC-02 at 1:5) tried to dimension faces only ~1 mm apart on the page. A step
75
+ is now dimensioned only if it is both tall enough from the base *and* at least
76
+ one legible step-height above the previously dimensioned one; the rest surface
77
+ as `step_dim_dropped` (use a detail view). "Fits" is not the same as
78
+ "legible" (#41).
79
+ - **Hole-location dimensions are gated for legibility.** A hole-dense part (e.g.
80
+ NIST CTC-02, ~38 distinct hole locations) previously stacked every location
81
+ reference into a tall, busy tower above the views — "fits" is not "legible".
82
+ Each axis's references are now gated by inter-dimension page spacing
83
+ (`_legible_locations`, analogous to the step-height gate #41): only locations
84
+ at least one value-label footprint apart on the page are dimensioned; the rest
85
+ surface as `location_ref_dropped` (full fidelity belongs in a detail view,
86
+ #42). Sparse parts are unchanged (#43).
87
+ - **Tighter location-dimension tier pitch.** The vertical pitch between stacked
88
+ X/Y location dimensions is now derived from the label footprint
89
+ (`font_size + 2·pad_around_text`, ≈7 mm) instead of a looser `font_size·3`,
90
+ so location stacks pack closer (#41).
91
+
92
+ ### Fixed
93
+
94
+ - **Phantom step corridor no longer blocks a larger scale.** Page/scale
95
+ selection reserved a step-ladder corridor sized for *every* candidate
96
+ horizontal face, including ones the legibility gate would never dimension. A
97
+ part with many sub-legible faces (e.g. a staircase with 15 tiny treads) was
98
+ forced onto an oversized sheet at 1:1. Scale selection now iterates so the
99
+ reserved corridor matches the step count actually placed, freeing the part to
100
+ pick a tighter sheet (staircase.step review).
101
+ - **Engraved-text faces are no longer dimensioned as steps.** `analyse_face_levels`
102
+ gained a `min_area_frac` filter; a horizontal face counts as a step only if
103
+ its area is at least 1% of the part's plan footprint. This drops sub-feature
104
+ faces (fragments of engraved numbers/text) that were surfacing as phantom
105
+ shoulders — e.g. a 0.57 mm² digit face dimensioned as z=6.4 on staircase.step.
106
+ - **Overall-height dimension nests outside the step dims.** The overall height
107
+ is now placed last on the front view's right ladder so it sits outermost, with
108
+ the step-height dims inside it; extension lines nest instead of leapfrogging
109
+ (staircase.step review).
110
+
111
+ ## v0.1.7 — 2026-06-15
112
+
113
+ ### Added
114
+
115
+ - `Drawing.lint_summary()` — a JSON-friendly aggregate of `lint()` for
116
+ non-interactive callers (scripts, or an LLM via the API): severity counts,
117
+ per-code counts, a `geometry_issues` tally (standards/geometry checks vs pure
118
+ layout), a `passed` flag, a coarse 0–1 `score`, and the full issue list. Gives
119
+ a single signal to gate and optimise on without rendering the SVG (#32).
120
+
121
+ ### Changed
122
+
123
+ - **Adaptive annotation placement.** The three hard-coded cardinality caps —
124
+ four hole callouts per view, four hole location references per part, and three
125
+ step-height dimensions — are removed. The engine now places as many as the
126
+ available strip/corridor space allows (callouts largest-first, locations
127
+ nearest-datum-first, every legible step), so a part with room is dimensioned
128
+ completely instead of dropped to an arbitrary count. An annotation that
129
+ genuinely doesn't fit is never force-placed; it surfaces via lint
130
+ (`callout_dropped` / `location_ref_dropped`, warning severity). On the NIST
131
+ CTC parts this raises coverage substantially (e.g. CTC-02: 4 → 36 location
132
+ dimensions, 4 → 9 callouts) with no error-severity lint (#36).
133
+ - **No silent annotation drops.** Every place the layout has to drop an
134
+ annotation now records a machine-readable lint issue, surfaced by `lint()`,
135
+ so a short drawing always carries a reason. A dropped callout names its
136
+ diameter and is excluded from `feature_not_dimensioned` (no double-report).
137
+ `placement_unsatisfiable` (error severity) is reserved for the degenerate
138
+ case where space was reserved but an annotation still could not be placed
139
+ (#32).
140
+ - **Layout constants derived from first principles.** Bare, fixture-tuned
141
+ constants (strip slot widths, callout label widths, isometric fit factor) are
142
+ now computed from text metrics and page size rather than hard-coded, so the
143
+ layout generalises to unseen geometry instead of fitting the test cases (#31).
144
+ - `_auto_annotate` clears its build-time lint records on re-entry, and repeated
145
+ `lint()` calls are stable (#32).
146
+
147
+ ### Fixed
148
+
149
+ - AP242 / PMI STEP import segfault: STEP geometry is now read directly via
150
+ `STEPControl_Reader`, avoiding the XCAF/PMI read that crashed (SIGSEGV) on
151
+ with-PMI files such as NIST CTC-02 (#20).
152
+
153
+ ### Tests
154
+
155
+ - Overfitting guards pin the general layout behaviour on turned/hybrid parts
156
+ (flange OD + bolt circle), multi-bore parts, and the step-legibility boundary
157
+ (#13).
158
+ - The full NIST CTC set (AP203 and AP242) builds and is covered by the slow
159
+ end-to-end tier.
160
+
161
+ ## v0.1.6 — 2026-06-15
162
+
163
+ ### Fixed
164
+
165
+ - Section-view boolean cut on cast geometry: the exact `body - Box(...)` boolean
166
+ raised an uncatchable `Standard_DomainError` (C++ abort, SIGABRT) on some parts
167
+ (NIST CTC-04), crashing the whole drawing. `_fuzzy_cut()` now runs
168
+ `BRepAlgoAPI_Cut` with a small fuzzy tolerance and keeps solids-only, making
169
+ the section cut robust (#20, #22).
170
+
171
+ ### Tests
172
+
173
+ - NIST CTC-04 (both AP203 and AP242) now build with a clean section view and are
174
+ covered by the CTC build tests.
175
+ - Known: CTC-02 AP242 still segfaults inside OCCT's AP242/PMI STEP read (#20),
176
+ excluded from build tests.
177
+
178
+ ## v0.1.5 — 2026-06-15
179
+
180
+ ### Fixed
181
+
182
+ - CTC-02 spurious full-page line: build123d's `ExportSVG` projected
183
+ circle-edge-on edges (hole/fillet rims seen edge-on) as elliptical arcs with
184
+ a near-zero minor radius, which renderers blow up into full-page lines.
185
+ `sanitize_svg_arcs()` rewrites any arc with a sub-1e-3 mm radius into the
186
+ straight line it actually is, leaving real arcs untouched (#19). Not a PMI
187
+ issue — the file is AP203 geometry-only.
188
+
189
+ ### Tests
190
+
191
+ - Added the full NIST CTC set (01–05) as fixtures, both AP203 geometry-only and
192
+ AP242 (with-PMI) variants.
193
+ - Heavy end-to-end CTC fixture builds are marked `slow` and deselected from the
194
+ default `pytest` run (fast normal run, ~4.5 min); CI runs the fast tier across
195
+ the OS/Python matrix and the slow tier once.
196
+ - Known: AP242 CTC-02 and both CTC-04 variants crash OCCT on import (#20); their
197
+ fixtures are excluded from build tests.
198
+
199
+ ## v0.1.4 — 2026-06-15
200
+
201
+ ### Changed
202
+
203
+ - Feature annotations (hole callouts, location dimensions, section view) now
204
+ fire on feature presence independent of the turned/prismatic classification,
205
+ so turned-and-drilled parts (e.g. flanges) get both the OD/centreline base
206
+ set and per-hole callouts plus bolt-circle furniture (#10).
207
+ - Isometric view placement now uses a general largest-empty-rectangle search in
208
+ place of the wide/flat-on-A3 special case (#11).
209
+ - Concentric bore-leader stacking is generalised beyond three, and the
210
+ step-height dimension gate is now a single derived constant (#10, #12).
211
+
212
+ ### Internal
213
+
214
+ - Single-sourced duplicated geometry constants from the draft preset (#12).
215
+ - Minor comment and logging cleanups.
216
+
217
+ ## v0.1.0 — 2026-06-14
218
+
219
+ Initial release — spun out of `build123d-drafting-helpers` v0.9.1.
220
+
221
+ The automated drawing engine (`make_drawing`, `build_drawing`, `Drawing`)
222
+ was previously part of `build123d-drafting-helpers`. It is now a separate
223
+ AGPL-licensed package that depends on `build123d-drafting-helpers>=0.9.1`
224
+ for annotation primitives.
225
+
226
+ ### Migration from build123d-drafting-helpers
227
+
228
+ ```python
229
+ # Before
230
+ from build123d_drafting import make_drawing, Drawing, build_drawing
231
+
232
+ # After
233
+ from draftwright import make_drawing, Drawing, build_drawing
234
+ ```
235
+
236
+ ### Features (carried over from build123d-drafting-helpers)
237
+
238
+ - **`make_drawing`** / **`build_drawing`** — automatic multi-view technical
239
+ drawing from a build123d solid: view layout, scale selection, orthographic
240
+ projection, dimension placement, title block.
241
+ - **`Drawing`** — composable drawing object with `.lint()`, `.add()`,
242
+ `.export_svg()`, `.export_dxf()`.
243
+ - **`choose_scale`** — ISO/ASME standard scale selection.
244
+ - **`lint_feature_coverage`** — checks annotation coverage against detected
245
+ part features (holes, bosses, bolt circles).
246
+ - **Section A–A views** — automatic section view for blind/stepped holes,
247
+ with ISO 128-44 solid filled cutting-plane arrows and ISO 128-50 45°
248
+ hatching on the cut face.
249
+ - **`generate_script`** — generates a standalone drawing script from a STEP
250
+ file.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: draftwright
3
- Version: 0.1.7
3
+ Version: 0.1.9
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
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.1.7"
7
+ version = "0.1.9"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -75,9 +75,12 @@ dwg = build_drawing(part, out="drawings/bracket", title="BRACKET",
75
75
 
76
76
  # Available on dwg:
77
77
  # dwg.views {"front","plan","side","iso"} → (visible, hidden) compounds
78
- # dwg.annotations mutable list of annotation objects
78
+ # dwg.items mutable list of annotation objects
79
+ # dwg.annotations() → {name: type} of every named annotation
80
+ # dwg.get_annotation(name) → the named annotation object, or None
79
81
  # dwg.draft / dwg.scale / dwg.page_w / dwg.page_h
80
82
  # dwg.at(view, x, y, z) → page point (px, py, 0) mapped from world coordinates
83
+ # dwg.view_bounds(view) → (x_min, y_min, x_max, y_max) page bbox of the view, or None
81
84
 
82
85
  # Add a dimension/leader the automatic pass missed:
83
86
  dwg.add(Leader(tip=dwg.at("front", 10, 0, 5), elbow=(8, 40, 0),
@@ -13,6 +13,7 @@ Licensed under the GNU Affero General Public License v3 (AGPL-3.0).
13
13
 
14
14
  from draftwright.make_drawing import (
15
15
  Drawing,
16
+ FeatureInfo,
16
17
  analyse_face_levels,
17
18
  build_drawing,
18
19
  choose_scale,
@@ -26,6 +27,7 @@ from draftwright.pmi import PmiRecord, extract_pmi
26
27
 
27
28
  __all__ = [
28
29
  "Drawing",
30
+ "FeatureInfo",
29
31
  "PmiRecord",
30
32
  "analyse_face_levels",
31
33
  "build_drawing",