文件
phonerail/.claude/skills/solidworks-assembly/SKILL.md
T
zhou yang和Claude Opus 5 ff50ccd4b0 新增 solidworks-assembly skill:EasyEDA STEP → SolidWorks 装配与干涉检查
本机环境已实测:SOLIDWORKS 2025 SP01.1(RevisionNumber 33.1.1)、
Python 3.14.3 64 位 + pywin32,GetActiveObject 可挂已开实例。

已跑通的链路:
- EasyEDA get3DFile 导 STEP —— 桥有 30s 硬超时,必须异步启动+轮询;
  4MB 分块 base64 取回(刀片 31.2MB/25s,底板 53.9MB/44s)
- GetImportFileData + LoadFile4 导入(得到带位号的装配树,一块板 95 个文档)
- 遍历 GetDocuments 拿临时顶层 SLDASM → AddComponent4 插入(⛔ AddComponent5 恒返回 None)
- ToolsCheckInterference2(0, EMPTY, False, pc, pf) 5 参形式可调
- CloseAllDocuments(True) 清理(295 文档 0.9s)

⛔ 未完成:刀片摆位(CreateTransform 卡在 pywin32 封送)、
坐标系(插入后两板被重心归零,§14 的平移量不能直接用)。
⇒ 现状能装能查,但两板堆在原点,干涉结果无工程意义。

NOTES-probed.md 记了 18 节实测坑,包括:
- 无参成员是属性不是方法(含 GetMathUtility 这个例外)
- SaveAs3 返回 True 但写出的是废件(外部引用断链)
- LoadFile4 不会插进当前装配体
- 动态派发"找不到成员"时用 _oleobj_.GetIDsOfNames + Invoke 绕行

Co-Authored-By: Claude Opus 5 <[email protected]>
Claude-Session: https://claude.ai/code/session_0168Bu6SEx3cXXCJLkdnE6zB
2026-09-12 14:08:36 +08:00

98 行
4.7 KiB
Markdown
原始文件 Blame 文件历史

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
---
name: solidworks-assembly
description: 把 EasyEDA 的 PCB 导成 STEP、在本机 SOLIDWORKS 里装配并做干涉检查。用于「底板 + 刀片插在一起会不会撞」这类机械核对,也用于量插槽插入深度这类 EDA 侧算不出来的数。涉及 SolidWorks / STEP / 3D 装配 / 干涉检查 / 机械干涉 时触发。
---
# SolidWorks 装配与干涉检查(PhoneRail 专用)
> ⚠ **动手前先读 `NOTES-probed.md`** —— 那是本机逐条实测出来的 API 口径与坑,
> 每一条都踩过一次。不读会把同样的坑再踩一遍。
> 环境已实测:SOLIDWORKS 2025 SP01.1(`RevisionNumber` = `33.1.1`)、
> Python 3.14.3 **64 位** + pywin32(32 位 Python 连不上 64 位 SW,本机不存在这问题)。
## 什么时候用
- 底板与刀片、刀片与刀片之间的**机械干涉**核对(EDA 侧只能算 2.5D 净距,算不了竖插后的三维关系)
- 量 EDA 侧拿不到的机械数:插槽**插入深度**、塑料体内腔、刀片底边离底板多高
- ⚠ **但凡实物在手,优先用卡尺**。STEP 里的连接器是厂商**标称模型**,不含公差;
3D 能替代"按标称值推算",替代不了实测。
## 整条链(每一步都已实测通过)
### 1. 从 EasyEDA 导出 STEP
```python
# 桥有 30 s 硬超时,大板同步调用必断 ⇒ 异步启动 + 轮询
START = "window.__gen={state:'running'}; (async()=>{ ... get3DFile(name,'step',['Component Model'],'Outfit',true) ... })(); return {started:true};"
# 再每 5 s 查 window.__gen.state,done 后用 4 MB 分块 base64 取回
```
实测:刀片 31.2 MB(生成 22.6 s + 取回 2 s)、底板 53.9 MB(生成 40 s + 取回 4 s)。
归档在 `.claude/r2/3d/`(已 `.gitignore`)。细节见 NOTES §6。
### 2. 导入 SolidWorks
```python
app = wc.GetActiveObject('SldWorks.Application') # 挂已开着的实例
data = app.GetImportFileData(step_path)
err = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_I4, 0)
app.LoadFile4(step_path, 'r', data, err) # err.value == 0 即成功
```
导进来是**带位号的装配树**(`R1~R0402~…`、`U4~TSSOP-24~…`),一块板 95 个文档。
⛔ 第三参不能传 `None`(报"类型不匹配");⛔ `OpenDoc6` 导 STEP 返回 None。见 NOTES §3。
### 3. 找到可插引用 + 装配
```python
# 导入后**不要关文档**,遍历 GetDocuments 找:有路径 + GetType==2 + .SLDASM
p = ... # → %TEMP%\swx…\IC~~\PhoneRail_base.step.SLDASM
c = asm.AddComponent4(p, '', 0.0, 0.0, 0.0) # ✅ 用 AddComponent4
```
⛔ **`AddComponent5`(8 参)在本机恒返回 `None`**,换参数没用,直接用 `AddComponent4`。
⛔ 别走"另存再插":`SaveAs3` 出来的是废件、`CopyDocument` 返回 2、`OpenDoc7` 打不开 STEP。
见 NOTES §11/§12/§15。
### 4. 干涉检查
```python
pc = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_VARIANT, None)
pf = wc.VARIANT(pythoncom.VT_BYREF | pythoncom.VT_VARIANT, None)
n = asm.ToolsCheckInterference2(0, EMPTY, False, pc, pf) # 5 参,少一个都报"非选择性的参数"
```
⛔ 第 2 参只能传 `EMPTY`(`VARIANT(VT_DISPATCH, None)`),塞零部件元组会报"服务器出现意外情况"。
### 5. 清理
```python
app.CloseAllDocuments(True) # 295 个文档 0.9 s 关完,SW 不退出
```
⛔ 一关就清空 `%TEMP%\swx…\IC~~\`,所以第 3 步必须在清理**之前**做完。
## ⛔ 未完成的两步(别当成能用)
1. **刀片摆位**。变换矩阵算好了(NOTES §14),但 `CreateTransform` 卡在 pywin32 封送:
`GetMathUtility` 要用 dispid 绕行才拿得到(NOTES §17),拿到后 `CreateTransform`
**又**报"找不到成员"——同一个病一层套一层,未解。
2. **坐标系**:`AddComponent4` 插进总装后,两块板都被**重心归零**
(刀片 `x -45~45 / y -34~34`、底板 `x -49~49 / y -49~49`),
NOTES §14 那套"原点 = 板左下角"的平移量**不能直接用**,要按 `GetBox` 现算。
⇒ 现状:能装、能查干涉,但**两块板都堆在原点**,查出来的干涉没有工程意义。
要么解掉上面两点,要么在 SolidWorks 里手工拖一次(更快)。
## 调试时的通用招数
动态派发报"找不到成员"时,先确认名字在不在:
```python
did = app._oleobj_.GetIDsOfNames('GetMathUtility') # 在 → 返回 dispid
raw = app._oleobj_.Invoke(did, 0, pythoncom.DISPATCH_METHOD, 1)
```
还有一条贯穿始终的规律:**无参成员基本都是属性**(`app.GetDocumentCount` / `doc.GetTitle` /
`doc.EditRebuild3` 都不加括号),有参的才是方法。但**有例外**(`GetMathUtility`),
拿不准就去 `sldworks.tlb` 查 `invkind`(NOTES §8 给了读法)。