3D 模型静默截图(等轴测白底)
当用户要求「不给模型开 SolidWorks,直接把等轴测图截出来」、「批量给一堆装配体出缩略图」、「后台静默截图」时,用本技能。
它解决什么问题
SolidWorks 自己的 SaveBMP / SaveAs 必须把文档窗口显示在屏幕可见区域内才能渲染,批量跑会不停抢焦点、弹窗、把用户正在画的图顶掉。这个技能改用 eDrawings ActiveX 内核挂在屏幕外的隐藏窗口里渲染(CreateWindowEx 位置 -20000,-20000),SolidWorks 进程全程不启动、不参与 ROT,可以和用户手上的工作并行。
支持格式
SLDPRT / SLDASM、STEP / STP、IGES / IGS、Parasolid X_T / X_B、Inventor ipt / iam、Creo asm/prt(含 .asm.N 版本化文件)、NX prt、JT、STL。
落地三步
-
解压到任意目录,例如:
Windows: C:\Users\<你的用户名>\.workbuddy\skills\sw-silent-shot\
也可以放在任何位置,直接调脚本即可。 -
装依赖(缺哪个装哪个):
pip install comtypes pywin32 pillow numpy -
自检(必须跑,会用一张内置最小 STEP 走完整链路):
python scripts/shot.py --selftest
全部通过会打印SELFTEST OK。没打印 OK 就是环境没对上,别往下用。
环境要求
| 项 | 要求 |
|---|---|
| 系统 | Windows(ActiveX + COM,必须是 Windows) |
| Python | 3.8+ |
| 引擎 | eDrawings 2020(或更高)已安装。核心文件通常在 C:\Program Files\Common Files\eDrawings2020\EModelView.dll,版本号或安装路径不同就改 _engine.py 里的 EMODEL_DLL |
| 位数 | eDrawings 内核对位数敏感,32 位内核遇到超大模型会慢,属正常 |
用法
单文件 → 单张图
python scripts/shot.py "E:\模型\某装配体.SLDASM" -o "E:\输出"
产出 E:\输出\某装配体.png。
整个目录批量(每套取一个代表模型,图名 = 文件夹名)
python scripts/shot.py "E:\参考模型\某某178套" -o "E:\参考模型\某某178套" --batch
扫描一级子目录,每个递归挑体积最大的代表模型,输出 <文件夹名>.png 到 -o。已存在的图自动跳过,加 --force 重出。
常用参数
| 参数 | 作用 |
|---|---|
-o / --out |
输出目录(默认与源文件同目录) |
--batch |
整目录批量模式 |
--angle N |
视角,6=等轴测(默认);0正视 1后视 2左视 3右视 4上视 5下视 7反向等轴测 |
--size 1920x1200 |
渲染尺寸,默认 1920x1200(实际导出 1918x1198) |
--limit N |
只跑前 N 套,试跑用 |
--force |
重出已存在的图 |
--timeout S |
单张超时,默认 120 |
--settle S |
打开后基础等待秒数,默认 3.0;超大模型可加到 6 |
--no-white |
保留 eDrawings 默认渐变灰底 |
--keep-axis |
保留左下角 XYZ 坐标轴(默认已保留) |
代表模型的选择规则(--batch)
按优先级,取体积最大者:
- 真装配体:
.iam(Inventor)、.asm(Creo / Solid Edge) - 单一通用格式:
.step .stp .igs .iges .x_t .x_b .jt .stl .3dxml .sat(转换成功率最高) - Creo 版本化文件:
.asm.N/.prt.N(取版本号最大) - 零件:
.ipt .prt .sldprt .par(该目录没有装配体时的兜底)
自动跳过 OldVersions、__MACOSX、备份、backup 等目录。
改代码前必读的坑(都是实机踩出来的)
- 绝对不要用
ctrl.ComponentCount判断"模型加载完没" —— 它是带索引的参数化属性,恒抛异常,用了会误判成"已加载"、立刻 Save、得到"导出无文件"。曾害 30 个大装配体被误判为"引擎吃不下"。正确做法是调UpdateScene()强制刷新 + 自适应等待。 UpdateScene()是 Save 前必需的,不调会导出空白。- 白底是三件套:
BackgroundColorOverride=True+BackgroundColor=0xFFFFFF+BackgroundColorGradient=False。只设颜色关不掉渐变。 - 必须 pump 消息循环(
PeekMessage / TranslateMessage / DispatchMessage),否则 ActiveX 不渲染、Save 直接卡死。 - 宿主窗口放屏幕外:
CreateWindowEx位置传-20000,-20000,SW_HIDE风格,用户看不到。 - Save 是异步的,调用后要轮询"文件出现 + 大小变化",不能马上读。而且 eDrawings 的 Save 不覆盖已有文件,判成功要看
getsize/getmtime有没有变。 - Save 路径必须绝对路径,相对路径会按 SW 的工作目录解析。
- 路径必须精确到真实文件。这条坑得最久:模型常藏在"文件夹 > 中文名子文件夹 > 同名子文件夹 > 文件"里,凭文件夹名拼错路径时
OpenDoc不报错,后续Save会"成功"却写不出文件,甚至卡几分钟,看起来像引擎不行。shot.py已内置os.path.exists前置校验,自己写代码务必先确认存在。 - 个别装配体会让
OpenDoc永久挂起(COM 内部死锁,Python 层面任何超时都救不了,进程内 watchdog 线程也救不了,因为主线程卡在 COM 里出不来)。唯一解法是子进程隔离 + 外部超时。而且不能按体积预判 —— 实测 27MB 的会挂死,517MB 的 117 秒正常出图。同样体积的其它装配体又可能完全正常(29MB 只花 13 秒)。 - 批量要防挂死,别在一个进程里连跑几十个,用外壳循环让卡死的那个被外部杀掉、不影响后面的:
bash for f in "路径A" "路径B" "路径C"; do timeout 150 python scripts/shot.py "$f" -o "输出目录" || echo "挂死跳过: $f" done
超时返回码 124 就是挂死。 - eDrawings 那个红色"文档可能已过时"警告是 HTML 覆盖层,API 关不掉 —— 用
strip_warning()做图像处理抹白(按红色阈值局部处理,保留左下角坐标轴)。 - 超大模型能吃:实测 517MB STEP 117 秒、244MB STEP 43 秒、177MB 45~60 秒、170MB IGS 115 秒。别凭体积提前判它打不开。
- 换模型必须重新
OpenDoc,同一个控件实例可以连续打开多个模型,但每次都要重新设视角 +UpdateScene。
已知边界(别硬扛)
- NX 的
.prt分不清零件与装配(NX 装配也是 .prt),整包散装 prt 只能取最大件,出的是单个零件。 - Creo
.asm.N多数能直接开,个别报错就把.asm.13复制一份改名.asm再试。 - 颜色来自模型自身材质:STEP/IGES 自带颜色会保留,无材质的显示灰色。
- 做不了:工程图、剖视图、BOM、测量。这些必须开 SolidWorks。
- 加密或带密码的模型:eDrawings 会弹框卡住,跳过。
- 不做移屏、不碰 SolidWorks:如果用户主动要求用 SolidWorks 内核(需要更高保真度),那是另一条路,请让用户关闭 SolidWorks 后用隐藏实例跑,不要在他使用中抢占。
- 只要 200px 级缩略图的话,Windows 资源管理器大图标视图就够,不用出图。
实测数据(供你判断耗时)
单张 10~30 秒是常态。极端值:517MB STEP 117 秒、244MB STEP 43 秒、170MB IGES 115 秒。
完整跑过两批:178 套 SLDASM(出 177 张,1 张因上述 COM 死锁永久挂起)、33 套混合通用格式(33/33 全成,12 分钟 0 失败)。
文件结构
sw-silent-shot/
├─ SKILL.md ← 完整说明书
└─ scripts/
├─ shot.py ← CLI:参数解析、目录扫描、代表模型选择、自检
└─ _engine.py ← 渲染引擎(与实机验证 210 张的批量脚本同一份代码)
shot.py 只做调度,打开/设视角/导出/去红字都在 _engine.py。改渲染行为改 _engine.py,改输入输出规则改 shot.py。
自检
python scripts/shot.py --selftest
会用一张内置的最小 STEP 走完整链路,输出到临时目录并校验边缘率,全部通过打印 SELFTEST OK。
有不清楚的直接问,别自己猜着改引擎 —— 上面每条坑都对应过一次返工。