| name | cad-automation |
| description | CAD自动化绘图skill,内置完整的AutoCAD二次开发知识体系。支持通过Python(pyautocad/win32com)/AutoLISP/C#/VBA连接AutoCAD进行自动化绘图、编辑、图层管理、标注、块与属性、三维建模、批量处理、文件转换等。也涵盖国产中望CAD/浩辰CAD的兼容性。 |
| category | engineering-cad |
| version | 1.1.0 |
| author | Delancy |
CAD 自动化绘图 Skill(优化版)
本skill提供AutoCAD自动化绘图的完整知识体系,涵盖Python COM自动化、AutoLISP插件开发、国产CAD兼容等核心内容。
0. 2026-06-11 优化版使用原则
本版把 CAD 自动化从“只会调用 AutoCAD”升级为“三栈协同”:
| 场景 | 首选技术 | 原因 | 降级方案 |
|---|
| 已安装 AutoCAD、要直接生成 DWG | win32com / pyautocad | 可调用真实 AutoCAD,适合出 DWG、标注、图层、打印 | SendCommand / SCR |
| 没有 CAD 软件、要稳定生成交换文件 | ezdxf | 离线生成 DXF,适合 CI、服务器、批量草图 | 生成 SVG/JSON 几何清单 |
| 参数化 3D、模具/夹具/结构件建模 | CadQuery / FreeCAD | 适合尺寸驱动和 STEP/STL 输出 | 先生成 2D 总图,再转 3D |
| 国产 CAD 兼容 | COM + 英文命令 + DXF | 中望/浩辰对 COM 和 DXF 兼容度通常较高 | AutoLISP |
执行铁律
- 先判断环境:
AutoCAD.Application 能连接则走 COM,不能连接则走离线 DXF。
- 模型空间永远按 1:1、毫米单位绘制;图纸空间只处理视口和出图比例。
- 每次自动绘图都要创建标准图层、锁定 WCS、清理选择集、执行
AUDIT/PURGE/ZOOM E/REGENALL。
- 输出前至少做 L3 验证:对象数量、关键图层、关键几何尺寸、文字/标注存在性。
- 使用外部开源项目的思路、API 或示例时,在交付包中保留
ATTRIBUTION.md,注明来源、许可证和本项目的使用方式。
外部开源资料吸收范围
本 skill 只吸收公开文档中的工程方法,不复制大段源代码。参考项目:
| 项目 | 作用 | 许可证 | 使用方式 |
|---|
reclosedev/pyautocad | AutoCAD ActiveX 自动化封装、坐标与对象遍历思路 | BSD-2-Clause | 作为 COM 自动化路线参考 |
mozman/ezdxf | 离线 DXF 创建/读写/修改 | MIT | 作为无 AutoCAD 环境的 fallback |
CadQuery/cadquery | Python 参数化 3D CAD | Apache-2.0 | 作为 3D 参数化建模路线参考 |
| 开源CAD自动化项目 | 行业最佳实践参考 | 多种 | 作为技术路线与接口设计参考 |
⚠️ Python AutoCAD COM 关键踩坑
环境
- AutoCAD 2020+ (中文版), Python 3.10+ + pyautocad/pywin32, Windows 11
连接方式
| 方式 | 结果 |
|---|
pyautocad.Autocad(create_if_not_exists=True) | ✅ 推荐,自动处理COM |
win32com.client.Dispatch("AutoCAD.Application") | ✅ 底层连接 |
win32com.client.GetActiveObject("AutoCAD.Application") | ✅ 连接已运行的实例 |
win32com.client.Dispatch("AutoCAD.Application.24") | ✅ 指定版本(2021=24,2022=24.1,2023=24.2,2024=24.3) |
核心踩坑
- pyautocad 安全数组: 坐标必须用
APoint(x,y,z) 包装
- COM对象生命周期:
GetActiveObject失败则需Dispatch
- 单位: AutoCAD内部使用绘图单位,默认公制mm
- 中文命令: 用
acad.doc.SendCommand("_LINE ") 带下划线前缀
- 选择集:
acad.doc.SelectionSets 使用后必须Delete(),否则累积报错
- 中望/浩辰兼容: pyautocad同样支持(COM接口兼容),但部分VLAX函数需要适配
一、AutoCAD 基础知识
1.1 AutoCAD 概述
AutoCAD是Autodesk公司开发的通用CAD软件,支持建筑、机械、电气、土木等领域。
1.2 坐标系
- WCS (世界坐标系): 绝对坐标系,原点固定
- UCS (用户坐标系): 可自定义原点和方向
- 极坐标:
@距离<角度 (如 @100<45)
- 相对坐标:
@x,y (如 @50,30)
1.3 文件类型
| 类型 | 扩展名 | 说明 |
|---|
| 图形文件 | .dwg | 标准图形文件 |
| 交换格式 | .dxf | 文本/二进制交换格式 |
| 模板 | .dwt | 含预设样式模板 |
| 标准 | .dws | 图层/标注/文字标准 |
| 脚本 | .scr | 批量命令脚本 |
| 线型 | .lin | 自定义线型定义 |
| 填充 | .pat | 自定义填充图案 |
1.4 常用API对象层次
AutoCAD.Application
├── ActiveDocument (Document)
│ ├── ModelSpace (模型空间)
│ ├── PaperSpace (图纸空间)
│ ├── Layers (图层集合)
│ ├── Linetypes (线型集合)
│ ├── TextStyles (文字样式)
│ ├── DimStyles (标注样式)
│ ├── Blocks (块集合)
│ ├── SelectionSets (选择集)
│ ├── Groups (组集合)
│ └── Utility (角度/距离/坐标工具)
├── Documents
├── Preferences (系统配置)
└── MenuGroups (菜单组)
二、绘图命令 (Drawing)
2.1 基本图元
from pyautocad import Autocad, APoint, aDouble
acad = Autocad(create_if_not_exists=True)
line = acad.model.AddLine(APoint(0,0,0), APoint(100,50,0))
circle = acad.model.AddCircle(APoint(50,50,0), 30)
arc = acad.model.AddArc(APoint(50,50,0), 30, 0, 3.14159)
pts = aDouble(0,0, 100,0, 100,50, 50,50)
pline = acad.model.AddLightWeightPolyline(pts)
pline.Closed = True
pline.Color = 1
ellipse = acad.model.AddEllipse(APoint(50,50,0), APoint(30,0,0), 0.5)
fit_pts = aDouble(0,0,0, 20,30,0, 50,10,0, 80,,, ,,)
spline = acad.model.AddSpline(fit_pts, aDouble(,,), aDouble(,,))
text = acad.model.AddText(, APoint(,,), )
mtext = acad.model.AddMText(APoint(,,), , )
point = acad.model.AddPoint(APoint(,,))
2.2 填充 (Hatch)
outer_loop = [pline]
hatch = acad.model.AddHatch(0, "ANSI31", True)
hatch.AppendOuterLoop(outer_loop)
hatch.Evaluate()
hatch.PatternScale = 2.0
hatch.PatternAngle = 0.785
hatch.Color = 3
2.3 SendCommand 方式 (兼容性最好)
acad.doc.SendCommand("_CIRCLE 50,50 30 ")
acad.doc.SendCommand("_LINE 0,0 100,50 \n")
三、编辑命令 (Modify)
3.1 基本编辑
obj.Move(APoint(0,0,0), APoint(50,0,0))
new_obj = obj.Copy()
new_obj.Move(APoint(0,0,0), APoint(100,0,0))
obj.Rotate(APoint(0,0,0), 1.5708)
obj.ScaleEntity(APoint(0,0,0), 2.0)
obj.Mirror(APoint(0,0,0), APoint(0,100,0))
obj.Offset(10)
obj.ArrayRectangular(3, 2, 1, 100, 50, 0)
3.2 通过SendCommand操作
acad.doc.SendCommand("_MOVE\n")
acad.doc.SendCommand("_COPY\n")
acad.doc.SendCommand("_ROTATE\n")
acad.doc.SendCommand("_SCALE\n")
acad.doc.SendCommand("_MIRROR\n")
acad.doc.SendCommand("_OFFSET 10\n")
acad.doc.SendCommand("_TRIM\n")
acad.doc.SendCommand("_EXTEND\n")
acad.doc.SendCommand("_FILLET R 5\n_FILLET\n")
acad.doc.SendCommand("_CHAMFER D 3 3\n_CHAMFER\n")
四、图层管理 (Layers)
layer = acad.doc.Layers.Add("WALL")
layer.Color = 1
layer.Linetype = "Continuous"
acad.doc.ActiveLayer = acad.doc.Layers("WALL")
for layer in acad.doc.Layers:
print(f"{layer.Name}: color={layer.Color}, linetype={layer.Linetype}")
ref = acad.doc.Layers("WALL")
ref.Lock = True
ref.Freeze = False
ref.LayerOn = True
line.Layer = "DIM"
acad.doc.SendCommand("_LAYMCH\n")
acad.doc.SendCommand("_LAYISO\n")
acad.doc.SendCommand("_LAYUNISO\n")
ACI常用色号
| 色号 | 颜色 | 适用 |
|---|
| 1 | 红 | 标注/重点 |
| 2 | 黄 | 中心线 |
| 3 | 绿 | 辅助线 |
| 4 | 青 | 文字 |
| 5 | 蓝 | 轮廓 |
| 6 | 品红 | 剖面 |
| 7 | 白/黑 | 默认 |
| 8 | 灰 | 参考线 |
五、标注与文字 (Dimensions & Text)
5.1 标注
p1 = APoint(0, 0, 0)
p2 = APoint(100, 0, 0)
text_pos = APoint(50, -20, 0)
dim = acad.model.AddDimAligned(p1, p2, text_pos)
dim = acad.model.AddDimRotated(p1, p2, text_pos, 0)
dim_rad = acad.model.AddDimRadial(APoint(50,50,0), circle, 10)
dim_dia = acad.model.AddDimDiametric(APoint(50,50,0), circle, 10)
dim_ang = acad.model.AddDimAngular(APoint(0,0,0), p1, p2, APoint(30,30,0))
dim_ord = acad.model.AddDimOrdinate(APoint(50,50,0), APoint(50,0,0), True)
dim_style = acad.doc.DimStyles.Add("GB_DIM")
dim.TextHeight = 3.5
dim.ArrowheadSize = 2.5
dim.DecimalSeparator = "."
5.2 公差与粗糙度
acad.doc.SendCommand("_TOLERANCE\n")
leader = acad.model.AddLeader(points, annotation, 0)
5.3 特殊字符
| 代码 | 字符 |
|---|
| %%c | φ 直径 |
| %%d | ° 度 |
| %%p | ± 正负号 |
| %%u | 下划线开关 |
| \P | 换行(MTEXT) |
六、块与属性 (Blocks & Attributes)
6.1 块定义
block = acad.doc.Blocks.Add(APoint(0,0,0), "MyBlock")
block.AddCircle(APoint(0,0,0), 10)
block.AddLine(APoint(-10,0,0), APoint(10,0,0))
insert_pt = APoint(50, 50, 0)
block_ref = acad.model.InsertBlock(insert_pt, "MyBlock", 1, 1, 1, 0)
6.2 带属性的块
att = block.AddAttribute(
5,
0,
"标签",
APoint(0,15,0),
"TAG",
"默认值"
)
for att in block_ref.GetAttributes():
if att.TagString == "TAG":
att.TextString = "零件-001"
att.Update()
6.3 外部参照 (Xref)
xref = acad.model.AttachExternalReference(
"D:/ref/base.dwg",
"base",
APoint(0,0,0),
1, 1, 1, 0
)
七、选择集与过滤
ss = acad.doc.SelectionSets.Add("SS1")
ss.Select(5)
ss.Select(0, APoint(0,0,0), APoint(100,100,0))
import win32com.client
ft = win32com.client.VARIANT(0, [0, "CIRCLE", 40, 10.0])
fd = win32com.client.VARIANT(0, [0, ">="])
ss.Select(5, 0, 0, ft, fd)
for obj in ss:
print(f"对象类型: {obj.ObjectName}, 图层: {obj.Layer}")
ss.Delete()
DXF组码常用过滤
| 组码 | 含义 | 示例 |
|---|
| 0 | 对象类型 | "CIRCLE","LINE","TEXT" |
| 8 | 图层名 | "WALL","DIM" |
| 62 | 颜色 | 1(红), 2(黄) |
| 40 | 半径(圆)/字高(文字) | 10.0 |
| 10 | 中心点/插入点 | 坐标 |
八、三维建模 (3D Modeling)
8.1 基本3D实体
box = acad.model.AddBox(APoint(0,0,0), 100, 50, 30)
cyl = acad.model.AddCylinder(APoint(50,50,0), 20, 100)
sphere = acad.model.AddSphere(APoint(50,50,30), 25)
cone = acad.model.AddCone(APoint(50,50,0), 15, 50)
torus = acad.model.AddTorus(APoint(50,50,0), 30, 10)
8.2 拉伸与旋转
regions = acad.model.AddRegion([pline])[0]
height = 50
taper_angle = 0
solid = acad.model.AddExtrudedSolid(regions, height, taper_angle)
solid = acad.model.AddRevolvedSolid(regions, APoint(0,0,0), APoint(0,0,100), 360)
8.3 布尔运算
solid1.Boolean(0, solid2)
solid1.Boolean(1, solid2)
solid1.Boolean(2, solid2)
8.4 SendCommand 3D
acad.doc.SendCommand("_BOX\n0,0,0\nL\n100\n50\n30\n")
acad.doc.SendCommand("_CYLINDER\n50,50,0\n20\n100\n")
acad.doc.SendCommand("_SUBTRACT\n")
acad.doc.SendCommand("_UNION\n")
九、图纸空间与打印
9.1 布局操作
for layout in acad.doc.Layouts:
print(f"布局: {layout.Name}")
acad.doc.Layouts.Add("A3_打印")
acad.doc.ActiveLayout = acad.doc.Layouts("A3_打印")
vp = acad.doc.PaperSpace.AddPViewport(
APoint(10,10,0),
200,
150
)
vp.Display(True)
9.2 打印/导出PDF
acad.doc.SendCommand("_PLOT\n")
acad.doc.SendCommand("_EXPORTPDF\n")
plot_cfg = acad.doc.Plot
plot_cfg.ConfigName = "DWG To PDF.pc3"
plot_cfg.PaperUnits = 1
plot_cfg.StandardScale = 0
plot_cfg.PlotType = 4
acad.doc.Plot.PlotToFile("D:/output.pdf")
十、AutoLISP 自动化 (CAD知识库核心)
10.1 LISP基础
来自"CAD学习知识库"的308个插件揭示了LISP在工程领域的真实生产力。
;; 基础结构
(defun c:命令名 (/ 局部变量1 局部变量2)
(setq var1 value1) ; 设置变量
(setq ss (ssget)) ; 获取选择集
(princ "\\n提示文字") ; 命令行输出
(princ) ; 静默退出
)
;; 选择集遍历
(defun c:changecolor (/ ss i en)
(setq ss (ssget))
(setq i 0)
(repeat (sslength ss)
(setq en (ssname ss i))
(setq ed (entget en))
(entmod (subst (cons 62 1) (assoc 62 ed) ed)) ; 改为红色
(setq i (1+ i))
)
)
;; 坐标标注 (from ZBBZ.lsp)
(defun c:zbbz ()
;; 创建标注图层
(entmake (list '(0 . "LAYER") '(100 . "AcDbLayerTableRecord")
'(2 . "UserDimCoors") '(70 . 0) '(62 . 7) '(6 . "Continuous")))
;; 设置当前图层
(setvar "CLAYER" "UserDimCoors")
;; 获取点
(while (setq pt (getpoint "\\n拾取标注点:"))
(setq x (rtos (car pt) 2 3))
(setq y (rtos (cadr pt) 2 3))
(setq str (strcat "X=" x "\\PY=" y))
(entmake (list '(0 . "MTEXT") (cons 1 str) (cons 10 pt) '(40 . 3.5)))
)
)
10.2 批量处理框架 (mini_系列)
CAD学习知识库中最核心的模式——mini_前缀系列,提供了专业级工程自动化框架:
;; mini_ 系列的核心模式: 配置-选择-处理
(defun c:mini_任务名 ( / old_cmd config_file sel_set result)
;; 1. 保存当前环境
(setq old_cmd (getvar "CMDECHO"))
(setvar "CMDECHO" 0)
;; 2. 加载配置(如有)
;; (load "mini_config.lsp")
;; 3. 选择对象
(princ "\\n选择对象: ")
(setq sel_set (ssget))
;; 4. 处理逻辑
;; ...
;; 5. 恢复环境
(setvar "CMDECHO" old_cmd)
(princ)
)
10.3 LISP常用函数速查
| 函数 | 用途 |
|---|
(ssget) | 选择对象返回选择集 |
(entget en) | 获取实体数据表 |
(entmod data) | 修改实体数据 |
(entmake data) | 创建新实体 |
(ssadd en ss) | 添加实体到选择集 |
(sslength ss) | 选择集数量 |
(ssname ss i) | 获取第i个实体名 |
(command "CMD" ...) | 执行AutoCAD命令 |
(vla-get-property obj) | 获取ActiveX属性 |
(vlax-curve-getArea obj) | 获取曲线面积 |
(vlax-curve-getDistAtPoint obj pt) | 获取点到起点距离 |
10.4 LISP→Python 对照
| AutoLISP | Python(pyautocad) |
|---|
(setq p (getpoint)) | p = acad.doc.Utility.GetPoint() |
(command "LINE" p1 p2 "") | acad.model.AddLine(p1, p2) |
(entget (car (entsel))) | acad.doc.Utility.GetEntity() |
(ssget) | acad.doc.SelectionSets.Add("SS") |
(vl-load-com) | pyautocad自动处理 |
(entmod ...) | obj.Layer = "NEW" 等属性赋值 |
十一、批量处理与文件操作
11.1 批量打开/处理/保存
import os
from pyautocad import Autocad
acad = Autocad(create_if_not_exists=True)
def batch_process_dwgs(folder):
"""批量处理DWG文件"""
for f in os.listdir(folder):
if not f.endswith('.dwg'):
continue
path = os.path.join(folder, f)
doc = acad.app.Documents.Open(path)
doc = acad.app.ActiveDocument
doc.Save()
doc.Close()
print(f"已处理: {f}")
batch_process_dwgs("D:/projects/drawings/")
11.2 文件格式转换
import os
def convert_dwg_to_dxf(folder):
"""批量DWG→DXF"""
for f in os.listdir(folder):
if f.endswith('.dwg'):
path = os.path.join(folder, f)
out = path.replace('.dwg', '.dxf')
acad.doc.SendCommand(f'_OPEN "{path}"\n')
time.sleep(1)
acad.doc.SendCommand(f'_SAVEAS DXF 2018 "{out}"\n')
time.sleep(0.5)
acad.doc.SendCommand('_CLOSE\n')
formats = {
'.dxf': 'DXF',
'.dwt': 'DWT',
'.pdf': 'PDF',
'.dwf': 'DWF',
'.stl': 'STL',
'.iges': 'IGS',
'.step': 'STP',
}
11.3 运行脚本
acad.doc.SendCommand("_SCRIPT D:/scripts/draw.scr\n")
acad.doc.SendCommand("(load \"D:/plugins/mytool.lsp\")\n")
acad.doc.SendCommand("MYTOOL\n")
acad.doc.SendCommand("_-VBARUN MyMacro\n")
十二、中望CAD/浩辰CAD兼容
12.1 COM接口兼容性
来自"AutoCAD知识库"的国产CAD适配经验:
try:
acad = win32com.client.Dispatch("ZWCAD.Application")
except:
acad = win32com.client.Dispatch("AutoCAD.Application")
try:
acad = win32com.client.Dispatch("GStarCAD.Application")
except:
acad = win32com.client.Dispatch("AutoCAD.Application")
def get_cad():
for progid in ["AutoCAD.Application", "ZWCAD.Application", "GStarCAD.Application"]:
try:
return win32com.client.Dispatch(progid)
except:
continue
raise Exception("未找到可用的CAD程序")
12.2 差异点
| 特性 | AutoCAD | 中望CAD | 浩辰CAD |
|---|
| COM Dispatch | ✅ | ✅ | ✅ |
| pyautocad | ✅ | ✅ | ✅ |
| AutoLISP | ✅ | ✅ | ✅ |
| VLISP扩展 | ✅ | 部分支持 | 部分支持 |
| ObjectARX | ✅ | ZRX | GRX |
| SendCommand | ✅ | ✅ | ✅ |
| 三维建模 | ✅ | ✅ | ✅ |
十三、AI+CAD 前沿 (AI+CAD知识库)
13.1 Text-to-CAD / AI生成CAD
目前主流的AI+CAD方向:
- 自然语言→CAD模型: CADAM、Leo AI、MecAgent等
- LLM生成CAD代码: 通过大模型生成AutoLISP/Python/C#代码,再由AutoCAD执行
- 特征识别: AI识别工程图中的几何特征
- 智能标注: 自动提取模型项目生成标注
13.2 AI辅助CAD工作流
def ai_create_rounded_rect(length=100, width=50, radius=5):
"""AI生成的带倒角矩形"""
acad = Autocad(create_if_not_exists=True)
pts = aDouble(0,0, length,0, length,width, 0,width)
pline = acad.model.AddLightWeightPolyline(pts)
pline.Closed = True
acad.doc.SendCommand(f"_FILLET R {radius}\n_FILLET P\n")
pline.Highlight(True)
acad.doc.SendCommand("P L\n")
return pline
13.3 重要开源项目
| 项目 | 说明 |
|---|
| Pointer-CAD | DeepSeek+港大,LLM生成B-Rep实体 |
| Zero-to-CAD | Autodesk, 大规模CAD构造序列 |
| text-to-cad | Jake, 自然语言→可编辑CAD |
| VideoCAD | MIT, 视频学习CAD操作 |
| WHUCAD | 武大, 首个CAD智能核心开源 |
| LLM4CAD | UT Austin, 多模态LLM→3D CAD |
| CADAM | 自然语言→参数化3D模型 |
十四、常见问题与调试
14.1 常见错误
| 问题 | 原因 | 解决方案 |
|---|
| pyautocad连接失败 | AutoCAD未运行 | 手动启动,或用create_if_not_exists=True |
| COM错误"RPC服务器不可用" | AutoCAD已关闭 | 重新dispatch |
| 选择集"已存在" | 未Delete旧选择集 | 每次用完ss.Delete() |
| SendCommand无反应 | 命令格式错误 | 空格代替回车确认, \n代替回车 |
| 中文乱码 | 编码问题 | SendCommand前确保AutoCAD设为GBK |
| LISP加载失败 | 路径含中文 | 用英文路径或(findfile) |
| 三维操作报错 | 未切换到3D视图 | acad.doc.SendCommand("_VSCURRENT _R\n") |
14.2 调试技巧
obj = acad.model(0)
for prop in dir(obj):
if not prop.startswith('_'):
try:
val = getattr(obj, prop)
print(f"{prop} = {val}")
except:
pass
for i in range(acad.app.Documents.Count):
doc = acad.app.Documents(i)
print(f"文档 {i}: {doc.Name}")
ss = acad.doc.SelectionSets.Add("DEBUG")
ss.Select(5)
print(f"当前图形有 {ss.Count} 个对象")
for obj in ss:
print(f" {obj.ObjectName}: Layer={obj.Layer}, Color={obj.Color}")
ss.Delete()
十五、工作流程总结
AI自动化CAD标准流程
用户需求 → 分析绘图策略 → 选择APILISP/SendCommand → 生成代码 → 连接CAD执行 → 验证结果
功能矩阵
| 功能 | Python | LISP | SendCommand |
|---|
| 基本绘图 | ✅ | ✅ | ✅ |
| 编辑操作 | ✅ | ✅ | ✅ |
| 图层管理 | ✅ | ✅ | ✅ |
| 标注 | ✅ | ✅ | ✅ |
| 块/属性 | ✅ | ✅ | ✅ |
| 选择集过滤 | ✅ | ✅ | ✅ |
| 三维建模 | ✅ | ⚠️ | ✅ |
| 图纸空间 | ✅ | ⚠️ | ✅ |
| 批量处理 | ✅ | ✅ | ⚠️ |
| 文件转换 | ✅ | ⚠️ | ✅ |
| 外部参照 | ✅ | ✅ | ✅ |
选择指南
- 快速原型: SendCommand(最通用,中望/浩辰全兼容)
- 生产自动化: Python + pyautocad(类型安全,逻辑复杂)
- 插件开发: AutoLISP(AutoCAD原生,用户自定义命令)
- 企业级: C# .NET API(性能最强,DLL部署)
- AI辅助: LLM → Python/LISP代码 → COM执行
注意: 所有代码单位为绘图单位(默认mm),使用前确认AutoCAD图形单位设置。国产CAD(中望/浩辰)COM接口基本兼容,部分VLAX函数差异请查阅对应API文档。
十六、CAD 核心铁律速查(2026-06-01 从 SW skill 架构移植)
以下铁律来自 solidworks-automation v4.4.0 的成功验证模式,针对 CAD 场景做了适配。
铁律 0:启动即清理——关闭孤儿文档 + 清理选择集 🔴
SW对应: solidworks-automation Sec 24 铁律0 (CloseDoc 启动清理)
CAD病灶: 反复调试运行时,AutoCAD 同样会积累未保存的 Drawing*.dwg,且 COM 选择集(SelectionSets)使用后不 Delete() 会累积导致后续操作报错。
import win32com.client
acad = win32com.client.Dispatch("AutoCAD.Application")
for ss in acad.ActiveDocument.SelectionSets:
try:
ss.Delete()
except:
pass
doc = acad.ActiveDocument
if doc.Name.startswith("Drawing") and doc.ModelSpace.Count == 0:
doc.New("acadiso.dwt")
LISP 等效:
;; 启动清理
(defun startup_clean ()
;; 清除所有选择集
(while (setq ss (ssget "_X"))
(setq ss nil))
;; 确保在模型空间
(setvar "TILEMODE" 1)
(princ)
)
铁律 1:选择集用完必 Delete——CAD 的"GetBodies2 防假跑" 🔴
SW对应: GetBodies2 实体计数验证
CAD病灶: SelectionSets.Add("SS1") 使用后不 Delete,再次运行同名选择集会报 "已存在" → 程序中断。
def safe_select(acad, filter_type=None):
ss_name = "TEMP_SS"
try:
acad.ActiveDocument.SelectionSets(ss_name).Delete()
except:
pass
ss = acad.ActiveDocument.SelectionSets.Add(ss_name)
ss.Select(5)
result = list(ss)
ss.Delete()
return result
验证机制——CAD 等效于 GetBodies2:
def verify_drawing(acad, expected_objects: int = None):
"""验证图纸状态——CAD 的 GetBodies2 等效"""
model = acad.ActiveDocument.ModelSpace
count = model.Count
doc = acad.ActiveDocument
doc.SendCommand("_AUDIT Y\n")
doc.SendCommand("_PURGE A * N\n")
ss = safe_select(acad)
obj_count = len(ss)
return {
"object_count": obj_count,
"model_count": count,
"passed": expected_objects is None or obj_count >= expected_objects
}
铁律 2:三级执行策略——CAD 等效于 Python→VBA→C# 🔴
SW对应: Sec 24 铁律8 (Tier 1 Python COM → Tier 2 VBA宏 → Tier 3 C# exe)
| 级别 | 方案 | 适用场景 | 限制 |
|---|
| Tier 1 | Python + pyautocad | 图元创建、图层管理、标注 | COM 对象生命周期管理 |
| Tier 2 | SendCommand / SCR 脚本 | 复杂编辑(TRIM/FILLET/CHAMFER) | 异步执行、错误处理弱 |
| Tier 3 | AutoLISP / C# .NET | 插件开发、性能敏感、批量 | LISP 调试困难;C# 需 AutoCAD .NET SDK |
降级逻辑:
def try_execute(operation, *args):
"""CAD 三级降级执行"""
try:
return operation(*args)
except:
pass
try:
cmd = build_sendcommand(operation, *args)
acad.doc.SendCommand(cmd)
return True
except:
pass
try:
acad.doc.SendCommand(f'(load "fallback.lsp")\n')
acad.doc.SendCommand(f'FALLBACK\n')
return True
except:
return False
铁律 3:CAD 六大隐藏地雷 ⚡
SW对应: Sec 21.2 五大 Interop DLL 地雷
| # | 地雷 | 现象 | 正确做法 |
|---|
| 1 | 选择集不 Delete | "选择集已存在" 错误 | 用完立即 ss.Delete() |
| 2 | SendCommand 编码 | 中文命令乱码/无效 | 用英文命令+下划线前缀 _LINE |
| 3 | UCS 混淆 | 坐标与实际位置不符 | SendCommand("_UCS _W\n") 先切到世界坐标系 |
| 4 | 对象捕捉干扰 | SendCommand 点选位置错误 | SendCommand("_NON\n") 临时关闭对象捕捉 |
| 5 | LISP command 与 vl-cmdf | command 受 UNDO 影响 | 批量操作用 vl-cmdf |
| 6 | pyautocad APoint 缺失 | 类型错误 | 所有坐标必须 APoint(x,y,z) 包装 |
def safe_sendcommand(acad, cmd):
"""发送命令前先重置 UCS + 关闭对象捕捉"""
acad.doc.SendCommand("_UCS _W\n")
acad.doc.SendCommand("_NON\n")
time.sleep(0.05)
acad.doc.SendCommand(cmd)
铁律 4:执行后强制审计——CAD 的 ForceRebuild3 🔴
SW对应: ForceRebuild3 + GetBodies2 双重验证
def verify_and_audit(acad):
"""CAD 执行后验证——等效于 SW 的 ForceRebuild3"""
doc = acad.ActiveDocument
doc.SendCommand("_AUDIT Y\n")
time.sleep(0.2)
doc.SendCommand("_PURGE A * N\n")
time.sleep(0.2)
doc.SendCommand("_ZOOM _E\n")
time.sleep(0.2)
doc.SendCommand("_REGENALL\n")
return True
铁律 5:编码与坐标系——SendCommand 两条前置命令 🔴
每次 SendCommand 前强制执行的固定管线:
def sendcommand_pipeline(acad, *commands):
"""SendCommand 安全管线——两条前置 + N条主命令"""
acad.doc.SendCommand("_UCS _W\n")
time.sleep(0.05)
acad.doc.SendCommand("_NON\n")
time.sleep(0.05)
for cmd in commands:
acad.doc.SendCommand(cmd)
time.sleep(0.1)
acad.doc.SendCommand("_REGENALL\n")
十六、知识库更新记录
| 版本 | 日期 | 核心变更 | 来源 |
|---|
| v1.1.0 | 2026-06-01 | 新增铁律速查:启动清理/选择集防泄漏/三级降级/六大地雷/审计验证/SendCommand管线 | 架构优化 |
| v1.0.0 | 2026-05-24 | 初始版本,含14大章节:绘图/编辑/图层/标注/块/选择集/3D/打印/LISP/批量/AI+CAD | 知识体系构建 |
十七、冲压模具自动绘图专项流程
当用户要求“画冲压模具、落料模、冲孔模、复合模、级进模、模架、凸模、凹模、卸料板、导柱导套”时,按本流程执行。
17.1 先问或默认的关键参数
如果用户没有给参数,使用以下可生产草图默认值,并在输出中说明:
| 参数 | 默认值 | 说明 |
|---|
| 模架外形 | 500 x 360 mm | 小型冲孔/落料模 |
| 上模座厚度 | 45 mm | 装配剖视可标注 |
| 卸料板厚度 | 18 mm | 位于凸模下方 |
| 凹模板厚度 | 30 mm | 位于下模座上方 |
| 下模座厚度 | 50 mm | 基准底板 |
| 工件/冲裁轮廓 | 180 x 90 mm,R12 | 可替换为用户轮廓 |
| 冲孔 | 4 x %%c18 | 默认四孔 |
| 单边间隙 | 材厚 x 5%-8% | 未知材厚时标为“按材料复核” |
| 导柱 | 4 x %%c32 | 布置在四角 |
17.2 推荐图层
| 图层 | 色号 | 内容 |
|---|
DIE_OUTLINE | 7 | 模座、模板外形 |
DIE_WORK | 1 | 凸模、凹模刃口、冲裁轮廓 |
DIE_GUIDE | 2 | 导柱、导套、中心线 |
DIE_FASTENER | 3 | 螺钉、销钉、沉孔 |
DIE_DIM | 4 | 尺寸标注 |
DIE_TEXT | 5 | 标题、技术要求、明细 |
DIE_AUX | 8 | 构造线、基准线 |
17.3 自动绘图顺序
- 创建图层、文字样式、标注样式。
- 绘制模架总平面:上/下模座外形、凹模板、卸料板投影。
- 绘制工作部分:冲裁轮廓、凸模轮廓、凹模刃口轮廓、冲孔。
- 绘制导向部分:四角导柱导套、中心线和定位基准。
- 绘制紧固定位:螺钉、销钉、沉孔符号。
- 添加尺寸:外形尺寸、导柱距、工件中心距、孔径、刃口间隙说明。
- 添加技术要求:材料、热处理、刃口间隙、配合研磨、未注倒角。
- 执行
AUDIT/PURGE/ZOOM E/REGENALL,再保存 DWG。
17.4 L3 验证标准
冲压模具图至少要通过以下检查:
required_layers = {
"DIE_OUTLINE", "DIE_WORK", "DIE_GUIDE",
"DIE_FASTENER", "DIE_DIM", "DIE_TEXT"
}
minimum_objects = 40
required_text = ["冲压模具", "凹模板", "凸模", "卸料板", "导柱", "技术要求"]
如果对象数不足、关键图层缺失、工作刃口没有闭合轮廓,必须重新生成;不能只报告“绘制成功”。
17.5 AutoCAD COM 最小测试脚本
桌面打包目录已提供 scripts/draw_stamping_die_smoke_test.py。该脚本已在本机 AutoCAD 2024 上实测通过,并生成 test_output/stamping_die_smoke_test_20260611_134736.dwg。