draftwright 0.1.4__tar.gz → 0.1.5__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 (23) hide show
  1. {draftwright-0.1.4 → draftwright-0.1.5}/PKG-INFO +1 -1
  2. {draftwright-0.1.4 → draftwright-0.1.5}/pyproject.toml +6 -2
  3. {draftwright-0.1.4 → draftwright-0.1.5}/src/draftwright/make_drawing.py +50 -0
  4. draftwright-0.1.5/tests/fixtures/nist_ctc_01_asme1_ap203.stp +5506 -0
  5. draftwright-0.1.5/tests/fixtures/nist_ctc_02_asme1_ap203.stp +24369 -0
  6. draftwright-0.1.5/tests/fixtures/nist_ctc_02_asme1_ap242.stp +22900 -0
  7. draftwright-0.1.5/tests/fixtures/nist_ctc_03_asme1_ap203.stp +5833 -0
  8. draftwright-0.1.5/tests/fixtures/nist_ctc_03_asme1_ap242.stp +6325 -0
  9. draftwright-0.1.5/tests/fixtures/nist_ctc_04_asme1_ap203.stp +14677 -0
  10. draftwright-0.1.5/tests/fixtures/nist_ctc_04_asme1_ap242.stp +21445 -0
  11. draftwright-0.1.5/tests/fixtures/nist_ctc_05_asme1_ap203.stp +7005 -0
  12. draftwright-0.1.5/tests/fixtures/nist_ctc_05_asme1_ap242.stp +14204 -0
  13. {draftwright-0.1.4 → draftwright-0.1.5}/tests/test_e2e_standards.py +44 -0
  14. {draftwright-0.1.4 → draftwright-0.1.5}/tests/test_make_drawing.py +46 -0
  15. {draftwright-0.1.4 → draftwright-0.1.5}/.gitignore +0 -0
  16. {draftwright-0.1.4 → draftwright-0.1.5}/CHANGELOG.md +0 -0
  17. {draftwright-0.1.4 → draftwright-0.1.5}/LICENSE +0 -0
  18. {draftwright-0.1.4 → draftwright-0.1.5}/README.md +0 -0
  19. {draftwright-0.1.4 → draftwright-0.1.5}/skills/SKILL.md +0 -0
  20. {draftwright-0.1.4 → draftwright-0.1.5}/src/draftwright/__init__.py +0 -0
  21. {draftwright-0.1.4 → draftwright-0.1.5}/src/draftwright/pmi.py +0 -0
  22. {draftwright-0.1.4 → draftwright-0.1.5}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  23. {draftwright-0.1.4 → draftwright-0.1.5}/tests/test_pmi.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: draftwright
3
- Version: 0.1.4
3
+ Version: 0.1.5
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.4"
7
+ version = "0.1.5"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -57,7 +57,11 @@ include = [
57
57
  [tool.pytest.ini_options]
58
58
  testpaths = ["tests"]
59
59
  timeout = 300
60
- addopts = "--tb=short --cov=src/draftwright --cov-report=term-missing --cov-report=xml"
60
+ # `slow` covers the heavy end-to-end builds over the large NIST CTC fixtures
61
+ # (minutes each). They are deselected by default for a fast normal run; run the
62
+ # full suite with `-m ""` or just the slow tier with `-m slow` (CI runs both).
63
+ markers = ["slow: heavy end-to-end CTC fixture builds (deselected by default)"]
64
+ addopts = "--tb=short --cov=src/draftwright --cov-report=term-missing --cov-report=xml -m 'not slow'"
61
65
 
62
66
  [tool.coverage.run]
63
67
  source = ["src/draftwright"]
@@ -118,6 +118,53 @@ def fix_svg_page_size(svg_path: str, page_w: float, page_h: float) -> None:
118
118
  Path(svg_path).write_text(data, encoding="utf-8")
119
119
 
120
120
 
121
+ # Below this, an elliptical-arc radius (page-mm) is treated as degenerate.
122
+ # Real feature arcs are orders of magnitude larger; the bad ones are ~1e-7.
123
+ _MIN_ARC_RADIUS = 1e-3
124
+
125
+ _SVG_NUM = r"(-?\d+\.?\d*(?:[eE][-+]?\d+)?)"
126
+ _SVG_ARC_RE = re.compile(
127
+ r"A\s*"
128
+ + _SVG_NUM
129
+ + r"[ ,]+"
130
+ + _SVG_NUM
131
+ + r"[ ,]+"
132
+ + _SVG_NUM
133
+ + r"[ ,]+([01])[ ,]*([01])[ ,]+"
134
+ + _SVG_NUM
135
+ + r"[ ,]+"
136
+ + _SVG_NUM
137
+ )
138
+
139
+
140
+ def sanitize_svg_arcs(svg_path: str) -> int:
141
+ """Rewrite near-degenerate elliptical arcs as straight line segments.
142
+
143
+ build123d's ``ExportSVG`` projects a circular edge seen edge-on (a hole or
144
+ fillet rim whose plane is parallel to the view direction) as an elliptical
145
+ arc with a vanishing minor radius (``ry`` ≈ 1e-7). The SVG spec says a
146
+ zero-radius arc is a straight line, but because the radius is not *exactly*
147
+ zero, renderers (librsvg, cairosvg) treat it as a hugely eccentric ellipse
148
+ and draw a spurious full-page line. Each such arc (``A rx ry rot lf sf x
149
+ y``) with ``rx`` or ``ry`` below :data:`_MIN_ARC_RADIUS` is replaced by
150
+ ``L x y`` — its true geometry. Returns the number of arcs rewritten.
151
+ """
152
+ data = Path(svg_path).read_text(encoding="utf-8")
153
+ n = 0
154
+
155
+ def _repl(m):
156
+ nonlocal n
157
+ if abs(float(m.group(1))) < _MIN_ARC_RADIUS or abs(float(m.group(2))) < _MIN_ARC_RADIUS:
158
+ n += 1
159
+ return f"L {m.group(6)} {m.group(7)}"
160
+ return m.group(0)
161
+
162
+ fixed = _SVG_ARC_RE.sub(_repl, data)
163
+ if n:
164
+ Path(svg_path).write_text(fixed, encoding="utf-8")
165
+ return n
166
+
167
+
121
168
  # ---------------------------------------------------------------------------
122
169
  # Geometry analysis
123
170
  # ---------------------------------------------------------------------------
@@ -1305,6 +1352,9 @@ class Drawing:
1305
1352
  svg_path = out + ".svg"
1306
1353
  svg.write(svg_path)
1307
1354
  fix_svg_page_size(svg_path, self.page_w, self.page_h)
1355
+ n_arcs = sanitize_svg_arcs(svg_path)
1356
+ if n_arcs:
1357
+ _log.info("Rewrote %d degenerate (near-zero-radius) arc(s) as line segments", n_arcs)
1308
1358
  _log.info("SVG → %s", svg_path)
1309
1359
 
1310
1360
  dxf = ExportDXF()