swforge 0.9.1__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 (59) hide show
  1. swforge-0.9.1/.gitignore +45 -0
  2. swforge-0.9.1/CHANGELOG.en.md +169 -0
  3. swforge-0.9.1/CHANGELOG.md +148 -0
  4. swforge-0.9.1/LICENSE +21 -0
  5. swforge-0.9.1/MANIFEST.in +13 -0
  6. swforge-0.9.1/PKG-INFO +402 -0
  7. swforge-0.9.1/README.en.md +352 -0
  8. swforge-0.9.1/README.md +369 -0
  9. swforge-0.9.1/demo/demo.py +378 -0
  10. swforge-0.9.1/docs/bilibili-script.md +400 -0
  11. swforge-0.9.1/docs/competitive-analysis.md +301 -0
  12. swforge-0.9.1/docs/limitations.en.md +85 -0
  13. swforge-0.9.1/docs/limitations.md +83 -0
  14. swforge-0.9.1/docs/pitfalls.en.md +159 -0
  15. swforge-0.9.1/docs/pitfalls.md +147 -0
  16. swforge-0.9.1/docs/why-getactiveobject-fails.md +411 -0
  17. swforge-0.9.1/examples/manage_sw_documents.py +51 -0
  18. swforge-0.9.1/examples/v03_demo.json +22 -0
  19. swforge-0.9.1/examples/v04_demo.json +158 -0
  20. swforge-0.9.1/examples/verify_drawing.py +63 -0
  21. swforge-0.9.1/examples/verify_mcp.py +106 -0
  22. swforge-0.9.1/pyproject.toml +57 -0
  23. swforge-0.9.1/setup.cfg +4 -0
  24. swforge-0.9.1/src/swforge/__init__.py +60 -0
  25. swforge-0.9.1/src/swforge/assembly.py +322 -0
  26. swforge-0.9.1/src/swforge/batch.py +263 -0
  27. swforge-0.9.1/src/swforge/cleanup.py +214 -0
  28. swforge-0.9.1/src/swforge/cli.py +363 -0
  29. swforge-0.9.1/src/swforge/colors.py +280 -0
  30. swforge-0.9.1/src/swforge/dims.py +336 -0
  31. swforge-0.9.1/src/swforge/drawing.py +897 -0
  32. swforge-0.9.1/src/swforge/gb_materials.py +268 -0
  33. swforge-0.9.1/src/swforge/interference.py +222 -0
  34. swforge-0.9.1/src/swforge/mates.py +452 -0
  35. swforge-0.9.1/src/swforge/modeling.py +829 -0
  36. swforge-0.9.1/src/swforge/probe.py +284 -0
  37. swforge-0.9.1/src/swforge/resources.py +312 -0
  38. swforge-0.9.1/src/swforge/server.py +410 -0
  39. swforge-0.9.1/src/swforge/session.py +377 -0
  40. swforge-0.9.1/src/swforge/spec.py +92 -0
  41. swforge-0.9.1/src/swforge.egg-info/PKG-INFO +402 -0
  42. swforge-0.9.1/src/swforge.egg-info/SOURCES.txt +57 -0
  43. swforge-0.9.1/src/swforge.egg-info/dependency_links.txt +1 -0
  44. swforge-0.9.1/src/swforge.egg-info/entry_points.txt +3 -0
  45. swforge-0.9.1/src/swforge.egg-info/requires.txt +13 -0
  46. swforge-0.9.1/src/swforge.egg-info/top_level.txt +1 -0
  47. swforge-0.9.1/tests/conftest.py +107 -0
  48. swforge-0.9.1/tests/test_api_reliability.py +162 -0
  49. swforge-0.9.1/tests/test_document_safety.py +302 -0
  50. swforge-0.9.1/tests/test_geometry.py +118 -0
  51. swforge-0.9.1/tests/test_honesty.py +60 -0
  52. swforge-0.9.1/tests/test_integration.py +145 -0
  53. swforge-0.9.1/tests/test_mcp.py +178 -0
  54. swforge-0.9.1/tests/test_smoke.py +95 -0
  55. swforge-0.9.1/tests/test_v03_integration.py +177 -0
  56. swforge-0.9.1/tests/test_v04.py +67 -0
  57. swforge-0.9.1/tests/test_v04_live.py +76 -0
  58. swforge-0.9.1/tests/test_v08.py +218 -0
  59. swforge-0.9.1/tests/test_v09.py +282 -0
@@ -0,0 +1,45 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ .eggs/
6
+ build/
7
+ dist/
8
+ .venv/
9
+ venv/
10
+ .pytest_cache/
11
+ .ruff_cache/
12
+ .mypy_cache/
13
+
14
+ # SolidWorks 产物(不提交二进制)
15
+ *.SLDPRT
16
+ *.SLDASM
17
+ *.SLDDRW
18
+ *.sldmat
19
+ !examples/*.sldmat
20
+ *.step
21
+ *.x_t
22
+ *.igs
23
+ *.stl
24
+ *.buildlog.txt
25
+ *.operations.jsonl
26
+ *.verification.json
27
+
28
+ # 运行日志与临时
29
+ _tmp/
30
+ *.log
31
+ out/
32
+
33
+ # 编辑器
34
+ .vscode/
35
+ .idea/
36
+ *.swp
37
+
38
+ # OS
39
+ Thumbs.db
40
+ desktop.ini
41
+ # 演示产物
42
+ demo/out/
43
+
44
+ demo/batch_parts/
45
+
@@ -0,0 +1,169 @@
1
+ [中文](CHANGELOG.md) | **English**
2
+
3
+ # Changelog
4
+
5
+ This project adheres to [Semantic Versioning](https://semver.org/).
6
+
7
+ ## [0.9.1] - 2026-11-03
8
+
9
+ First release published to PyPI. All fixes relative to v0.9.0, no new features.
10
+
11
+ ### Added
12
+ - **PyPI publishing** `.github/workflows/publish.yml`: tag to publish, using
13
+ Trusted Publishing (OIDC) so no token is stored in the repository. Three
14
+ pre-publish checks: exactly one wheel, package version matches the tag, and
15
+ the sdist carries docs/.
16
+ - **MCP server usability for external agents**: 17 lines of `instructions`
17
+ (the first thing an agent reads), a fix so `serverInfo.version` reports
18
+ swforge's version instead of the MCP SDK's, and multi-client setup in the
19
+ README.
20
+ - `tests/test_mcp.py`, six contract tests driving a real stdio session.
21
+
22
+ ### Fixed
23
+ - `swforge --help` crashed on a non-Chinese Windows: with a cp1252 stdout,
24
+ printing Chinese raised `UnicodeEncodeError`. Now `errors='replace'` keeps it
25
+ from crashing, and JSON output escapes to `\uXXXX` on a single-byte codec so
26
+ it stays machine-readable.
27
+ - `produce()` connected to SolidWorks even for a fresh drawing (regression
28
+ introduced in v0.9.0), dragging pure-logic unit tests into a real connection.
29
+ It now connects only when the target file already exists.
30
+ - CI: `package build` failed because PowerShell does not expand `dist/*.whl`;
31
+ switched to bash and to `python -m swforge.cli`.
32
+ - CI: the marker check moved from a static text scan to a runtime guard in
33
+ conftest. The static version produced four false positives on tests that only
34
+ exercise parameter validation.
35
+
36
+ ## [0.9.0] - 2026-11-03
37
+
38
+ ### Added
39
+ - **Batch drawings** `swforge batch`: one folder of parts becomes a stack of GB-framed
40
+ drawings. Measured 5 parts in 15.7 s; one failure does not sink the batch; existing
41
+ drawings are skipped so an interrupted run resumes.
42
+ - **API capability probe** `swforge capabilities --api`: reflects over the locally
43
+ installed Interop library and reports, for 28 risky APIs, whether each exists and its
44
+ highest overload. Measured 0.43 s with a clear verdict. A wrong declared type triggers
45
+ a global scan that reports the real location (`InsertModelAnnotations4` lives on
46
+ `IDrawingDoc`).
47
+ - **Overall dimensions now work on revolved parts**: fall back from vertices to edge
48
+ endpoints, then to single-entity dimensions, so cylinders and rings get outer and
49
+ inner diameters (measured flange 120/60, bushing 40/24).
50
+ - **CI**: `.github/workflows/tests.yml`, Python 3.10-3.13 matrix running the 106 offline
51
+ tests, plus package build, sdist content check and an `sw` marker guard.
52
+ - Tests 124 -> **138** (106 offline + 32 live).
53
+
54
+ ### Fixed
55
+ - `produce()` returned `err=1` when the target drawing already existed, because the
56
+ previous drawing was still open and locked the file. It now closes any document
57
+ pointing at the target path first.
58
+ - `add_dimensions(overall=True)` referenced an undefined `overall_result` (NameError).
59
+ - sdist did not carry `docs/` or `demo/`; `MANIFEST.in` added, 65 files now.
60
+ - Batch failed from the 5th part on after hitting SolidWorks' 8-document cap; documents
61
+ are now released after each part.
62
+
63
+ ### Docs
64
+ - README gained a "Not yet" section and a three-layer "Verification boundary" table
65
+ (L1 offline / L2 CI / L3 live).
66
+ - Chinese and English READMEs kept in sync.
67
+
68
+ ## [0.8.0] - 2026-11-03
69
+
70
+ ### Added
71
+ - **Overall dimensions** `dims.py`: explicit overall length/height generated from each
72
+ view's extreme visible vertices (`InsertModelAnnotations4` cannot produce overall
73
+ dimensions and deduplicates across views)
74
+ - **Mates** `mates.py`: concentric / coincident with automatic face selection
75
+ (equal-radius cylinders, parallel planes), implemented in C# early binding
76
+ - **Exact interference** `interference.py`: body boolean intersection, measured 500.000 mm³
77
+ - Tests 111 → **124**
78
+
79
+ ### Fixed
80
+ - Interference intersection returning error code 1: `swBodyOperationNonApiBody` —
81
+ document bodies are not API temporary bodies and need `Copy2(False)` first
82
+ - Mate success criterion: `swAddMateError_NoError = 1` (not 0)
83
+ - Assembly coordinate units: `AddComponent5` expects metres; millimetres were being
84
+ passed, placing parts 60 metres away
85
+ - Drawing template selection: now scans by year and prefers Chinese `gb_<paper>.drwdot`
86
+ - `_ensure_mm_units` could not read the unit value (`_value()` calling a method that
87
+ requires arguments)
88
+
89
+ ## [0.7.0] - 2026-11-03
90
+
91
+ ### Added
92
+ - GB frame and title block (auto-filled material / weight / scale)
93
+ - Millimetre unit verification
94
+
95
+ ### Changed
96
+ - `_default_template()` prefers Chinese GB templates (previously preferred the English
97
+ template, which produced inches and no frame)
98
+ - `add_dimensions(..., relayout=True)`: automatically re-lays out views after annotation
99
+
100
+ ### Known issues
101
+ - Interference intersection returned `(None, 1)`, unresolved
102
+ - Mates not implemented
103
+
104
+ ## [0.6.0] - 2026-11-02
105
+
106
+ ### Added
107
+ - `revolve()` on all three axes (volume error 0.00% on all three)
108
+ - Automatic annotation `add_dimensions()` / `count_dimensions()`
109
+ - Assembly `AssemblyBuilder` (insert + fix)
110
+
111
+ ### Fixed
112
+ - `_view_list()` used `GetViews`, which returns a native PyIDispatch; the exception was
113
+ silently swallowed by `except: continue`, so counting always returned 0 views
114
+
115
+ ### Discovered
116
+ - `AddComponent5` requires the part to be **opened first**, otherwise it silently returns None
117
+
118
+ ## [0.5.0] - 2026-11-02
119
+
120
+ ### Added
121
+ - Two-level connection fallback (`GetActiveObject` → `CreateInstance`) with actionable errors
122
+ - GB material library `gb_materials.py`: 20 grades, auto-deployed into SolidWorks' scan path
123
+ - Honesty regression tests (4)
124
+
125
+ ### Fixed
126
+ - **Physical material was never assigned to SolidWorks**, so the default density was
127
+ 1000 kg/m³ (water) — mass was wrong by 7.85×
128
+
129
+ ## [0.4.1] - 2026-11-02
130
+
131
+ ### Added
132
+ - Three-tier resource guard (ok / warn / critical) plus safe sweeping `sweep_documents()`
133
+
134
+ ### Fixed
135
+ - `conftest.py` cleaned the project root but missed pytest's temp dir, so the live suite
136
+ locked itself out at the 8th document
137
+ - `max_documents=0` was rejected as an invalid parameter
138
+
139
+ ## [0.4.0] - 2026-11-01
140
+
141
+ ### Added
142
+ - Document cap and automatic release in batch runs
143
+ - Straight-edge selection rule `edges_rule` plus read-only preview `preview_edges`
144
+ - PDF content verification (PDFium parse + render)
145
+
146
+ ## [0.3.0] - 2026-11-01
147
+
148
+ ### Added
149
+ - Three-axis cylinders, revolve about Y, all-edge fillet and chamfer
150
+ - Single-STA serialization (MCP concurrency safety)
151
+
152
+ ### Fixed
153
+ - World coordinates no longer mirror Z; `merge` actually takes effect; body count is read
154
+ back from SolidWorks instead of counting successful features
155
+
156
+ ## [0.2.0] - 2026-11-01
157
+
158
+ ### Added
159
+ - Colour coverage 57% → **100%** (face-level write + readback)
160
+ - View layout solver (measured sizes + long-align / height-align / auto scale)
161
+ - MCP server (15 tools)
162
+ - 5 integration tests
163
+
164
+ ### Fixed
165
+ - `swAllBodies = -1` (was mistakenly 2), so `purge_*` had been iterating 0 bodies
166
+
167
+ ## [0.1.0] - 2026-11-01
168
+
169
+ First usable version: DSL → C# modeling, coloring, import cleanup, PDF atlas, CLI.
@@ -0,0 +1,148 @@
1
+ **中文** | [English](CHANGELOG.en.md)
2
+
3
+ # Changelog
4
+
5
+ 本项目遵循 [语义化版本](https://semver.org/lang/zh-CN/)。
6
+
7
+ ## [0.9.1] - 2026-11-03
8
+
9
+ 首个发布到 PyPI 的版本。相比 v0.9.0 全是修复,没有新功能。
10
+
11
+ ### 新增
12
+ - **PyPI 发布流程** `.github/workflows/publish.yml`:打标签即发布,
13
+ 用 Trusted Publishing(OIDC),仓库里不存任何 token。
14
+ 发布前做三项校验:wheel 数量、包版本与标签一致、sdist 含 docs/。
15
+ - **MCP 服务器对外可用性**:补 17 行 `instructions`(Agent 读到的第一段话),
16
+ 修正 `serverInfo.version` 报成 SDK 版本的问题,README 补多客户端配置。
17
+ - `tests/test_mcp.py` 6 条契约测试,走真实 stdio 协议。
18
+
19
+ ### 修复
20
+ - `swforge --help` 在非中文 Windows 上崩溃:stdout 编码为 cp1252 时
21
+ 打印中文抛 `UnicodeEncodeError`。现在用 `errors='replace'` 兜底,
22
+ 且 JSON 输出在单字节编码下自动转义成 `\uXXXX`,保证机器可读。
23
+ - `produce()` 在全新出图时也白连一次 SolidWorks(v0.9.0 引入的回归),
24
+ 导致纯逻辑单测被拖进真实连接。改成只有旧文件存在时才连。
25
+ - CI:`package build` 因 PowerShell 不展开 `dist/*.whl` 通配符而失败;
26
+ 改成 bash 并统一用 `python -m swforge.cli`。
27
+ - CI:marker 检查从静态文本扫描改为 conftest 运行时守卫。
28
+ 静态版误报了 4 个「只测参数校验」的合法用例。
29
+
30
+ ## [0.9.0] - 2026-11-03
31
+
32
+ ### 新增
33
+ - **批量出图** `swforge batch`:一个文件夹的零件 → 一批带 GB 图框的工程图。
34
+ 实测 5 件 15.7 秒;单件失败不影响整批;默认跳过已存在的图,断了能续跑。
35
+ - **API 能力探测** `swforge capabilities --api`:用反射查本机 Interop 库,
36
+ 逐个确认 28 个风险 API 存在性与最高重载参数个数,实测 0.43 秒给出明确结论。
37
+ 类型写错会自动全局扫描纠正(`InsertModelAnnotations4` 实际在 `IDrawingDoc` 上)。
38
+ - **总尺寸支持回转体**:没有可见顶点时退回「边端点」→ 再退回「单实体标注」,
39
+ 圆柱/圆环现在能拿到外径和内径(实测法兰 120/60、轴套 40/24)。
40
+ - **CI**:`.github/workflows/tests.yml`,Python 3.10~3.13 矩阵跑 106 项离线测试,
41
+ 外加打包构建、sdist 内容检查、`sw` marker 守卫。
42
+ - 测试 124 → **138 项**(106 离线 + 32 实机)。
43
+
44
+ ### 修复
45
+ - `produce()` 在目标图已存在时返回 `err=1`:上一张图还开着锁住文件。
46
+ 现在出图前先关掉指向同一路径的已打开文档。
47
+ - `add_dimensions(overall=True)` 引用未定义的 `overall_result`(NameError)。
48
+ - sdist 不含 `docs/` 和 `demo/`:加 `MANIFEST.in`,现在 65 个文件。
49
+ - 批量出图第 5 件撞 SolidWorks 8 文档上限后整批失败:每件结束显式释放文档。
50
+
51
+ ### 文档
52
+ - README 增加「尚未做到」小节和「验证边界」三层表(L1 离线 / L2 CI / L3 实机)
53
+ - 中英文 README 同步更新
54
+
55
+ ## [0.8.0] - 2026-11-03
56
+
57
+ ### 新增
58
+ - **总尺寸标注** `dims.py`:按视图可见顶点极值显式生成总长/总高
59
+ (`InsertModelAnnotations4` 拿不到总尺寸,且会跨视图去重)
60
+ - **配合** `mates.py`:同心 / 重合,自动选面(等径圆柱、平行平面),C# 早期绑定实现
61
+ - **精确干涉** `interference.py`:实体布尔求交,实测 500.000 mm³
62
+ - 测试 111 → **124 项**
63
+
64
+ ### 修复
65
+ - 干涉求交返回错误码 1:`swBodyOperationNonApiBody` —— 文档体不是 API 临时体,
66
+ 需先 `Copy2(False)`
67
+ - 配合判据:`swAddMateError_NoError = 1`(不是 0)
68
+ - 装配坐标单位:`AddComponent5` 内部要米,此前把毫米当米传,零件被放到 60 米外
69
+ - 工程图模板选型:改为按年份扫描 + 中文 `gb_<纸张>.drwdot` 优先
70
+ - `_ensure_mm_units` 读不到单位值(`_value()` 无参调用带参方法)
71
+
72
+ ## [0.7.0] - 2026-11-03
73
+
74
+ ### 新增
75
+ - GB 图框与标题栏(自动带材料 / 重量 / 比例)
76
+ - 毫米单位校验
77
+
78
+ ### 变更
79
+ - `_default_template()` 优先中文 GB 模板(此前优先英文模板导致英寸 + 无图框)
80
+ - `add_dimensions(..., relayout=True)`:标注后自动重排
81
+
82
+ ### 已知问题
83
+ - 干涉求交返回 `(None, 1)`,未解决
84
+ - 配合未实现
85
+
86
+ ## [0.6.0] - 2026-11-02
87
+
88
+ ### 新增
89
+ - `revolve()` 支持 x/y/z 三轴(三轴体积误差 0.00%)
90
+ - 自动标注 `add_dimensions()` / `count_dimensions()`
91
+ - 装配 `AssemblyBuilder`(插入 + 固定)
92
+
93
+ ### 修复
94
+ - `_view_list()` 用 `GetViews` 拿原生 PyIDispatch 被 `except: continue` 静默吞掉,
95
+ 导致统计永远返回 0 视图
96
+
97
+ ### 发现
98
+ - `AddComponent5` 要求零件**先打开**,否则静默返回 None
99
+
100
+ ## [0.5.0] - 2026-11-02
101
+
102
+ ### 新增
103
+ - 连接两级 fallback(`GetActiveObject` → `CreateInstance`)+ 可操作错误提示
104
+ - GB 材质库 `gb_materials.py`:20 个牌号 + 自动部署到 SW 扫描目录
105
+ - 诚实性回归测试(4 项)
106
+
107
+ ### 修复
108
+ - **物理材料从未赋给 SW**,默认密度 1000 kg/m³(水),质量错 7.85 倍
109
+
110
+ ## [0.4.1] - 2026-11-02
111
+
112
+ ### 新增
113
+ - 资源守卫三档分级(ok / warn / critical)+ 安全清扫 `sweep_documents()`
114
+
115
+ ### 修复
116
+ - `conftest.py` 清理根目录漏了 pytest 临时目录,导致实测套件跑到第 8 个文档自锁
117
+ - `max_documents=0` 被判为参数非法
118
+
119
+ ## [0.4.0] - 2026-11-01
120
+
121
+ ### 新增
122
+ - 文档数量上限与批处理自动释放
123
+ - 直边选边规则 `edges_rule` + 只读预览 `preview_edges`
124
+ - PDF 内容验证(PDFium 解析 + 渲染)
125
+
126
+ ## [0.3.0] - 2026-11-01
127
+
128
+ ### 新增
129
+ - 三轴圆柱、绕 Y 轴旋转、全边圆角与倒角
130
+ - 单 STA 线程串行化(MCP 并发安全)
131
+
132
+ ### 修复
133
+ - 世界坐标不再镜像 Z;`merge` 真正生效;实体数改为从 SW 回读
134
+
135
+ ## [0.2.0] - 2026-11-01
136
+
137
+ ### 新增
138
+ - 配色覆盖率 57% → **100%**(面级写入 + 回读)
139
+ - 视图排版求解器(实测尺寸 + 长对正 / 高平齐 / 自动缩放)
140
+ - MCP 服务器(15 工具)
141
+ - 集成测试 5 项
142
+
143
+ ### 修复
144
+ - `swAllBodies = -1`(原误写成 2),`purge_*` 一直遍历 0 个实体
145
+
146
+ ## [0.1.0] - 2026-11-01
147
+
148
+ 首个可用版本:DSL → C# 建模、分色、导入清理、PDF 图集、CLI。
swforge-0.9.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-sw-toolkit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,13 @@
1
+ include LICENSE
2
+ include README.md
3
+ include README.en.md
4
+ include CHANGELOG.md
5
+ include CHANGELOG.en.md
6
+ include .gitignore
7
+ recursive-include docs *.md
8
+ recursive-include demo *.py
9
+ recursive-include examples *.py *.json
10
+ recursive-include tests *.py
11
+ global-exclude __pycache__
12
+ global-exclude *.py[cod]
13
+ global-exclude *.SLDPRT *.SLDDRW *.SLDASM *.pdf