界面已本地化;技能介绍与说明文档按所选语言由 AI 自动翻译,代码、命令、路径和专业术语保留原文,以原作者文档为准。
探索技能
开发与工程 · SKILL.md

cad-automation

cad-automation

【开发与工程】CAD自动化绘图skill,内置完整的AutoCAD二次开发知识体系。支持通过Python(pyautocad/win32com)/AutoLISP/C#/VBA连接AutoCAD进行自动化绘图、编辑、图层管理、标注、块与属性、三维建模、批量处理、文件转换等。也涵盖国产中望CAD/浩辰CAD的兼容性。

独立 GitHub 快照 · 自动分类 · 以原作者文档为准

技能说明

GitHub

name: cad-automation description: CAD自动化绘图skill,内置完整的AutoCAD二次开发知识体系。支持通过Python(pyautocad/win32com)/AutoLISP/C#/VBA连接AutoCAD进行自动化绘图、编辑、图层管理、标注、块与属性、三维建模、批量处理、文件转换等。也涵盖国产中望CAD/浩辰CAD的兼容性。 category: engineering-cad version: 1.2.0 author: Delancy

CAD 自动化绘图 Skill(优化版)

本skill提供AutoCAD自动化绘图的完整知识体系,涵盖Python COM自动化、AutoLISP插件开发、国产CAD兼容等核心内容。

0. 2026-06-11 优化版使用原则

本版把 CAD 自动化从“只会调用 AutoCAD”升级为“三栈协同”:

场景首选技术原因降级方案
已安装 AutoCAD、要直接生成 DWGwin32com / pyautocad可调用真实 AutoCAD,适合出 DWG、标注、图层、打印SendCommand / SCR
没有 CAD 软件、要稳定生成交换文件ezdxf离线生成 DXF,适合 CI、服务器、批量草图生成 SVG/JSON 几何清单
参数化 3D、模具/夹具/结构件建模CadQuery / FreeCAD适合尺寸驱动和 STEP/STL 输出先生成 2D 总图,再转 3D
国产 CAD 兼容COM + 英文命令 + DXF中望/浩辰对 COM 和 DXF 兼容度通常较高AutoLISP

执行铁律

  1. 先判断环境:AutoCAD.Application 能连接则走 COM,不能连接则走离线 DXF。
  2. 模型空间永远按 1:1、毫米单位绘制;图纸空间只处理视口和出图比例。
  3. 每次自动绘图都要创建标准图层、锁定 WCS、清理选择集、执行 AUDIT/PURGE/ZOOM E/REGENALL。
  4. 输出前至少做 L3 验证:对象数量、关键图层、关键几何尺寸、文字/标注存在性。
  5. 使用外部开源项目的思路、API 或示例时,在交付包中保留 ATTRIBUTION.md,注明来源、许可证和本项目的使用方式。

外部开源资料吸收范围

本 skill 只吸收公开文档中的工程方法,不复制大段源代码。参考项目:

项目作用许可证使用方式
reclosedev/pyautocadAutoCAD ActiveX 自动化封装、坐标与对象遍历思路BSD-2-Clause作为 COM 自动化路线参考
mozman/ezdxf离线 DXF 创建/读写/修改MIT作为无 AutoCAD 环境的 fallback
CadQuery/cadqueryPython 参数化 3D CADApache-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)

核心踩坑

  1. pyautocad 安全数组: 坐标必须用 APoint(x,y,z) 包装
  2. COM对象生命周期: GetActiveObject失败则需Dispatch
  3. 单位: AutoCAD内部使用绘图单位,默认公制mm
  4. 中文命令: 用 acad.doc.SendCommand("_LINE ") 带下划线前缀
  5. 选择集: acad.doc.SelectionSets 使用后必须Delete(),否则累积报错
  6. 中望/浩辰兼容: 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)

# 圆弧 (center, radius, start_angle弧度, end_angle弧度)
arc = acad.model.AddArc(APoint(50,50,0), 30, 0, 3.14159)

# 轻量多段线 (2D, 推荐)
pts = aDouble(0,0, 100,0, 100,50, 50,50)  # x,y交替
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,60,0, 100,0,0)
spline = acad.model.AddSpline(fit_pts, aDouble(1,1,0), aDouble(1,0,0))

# 文字
text = acad.model.AddText("设计说明", APoint(10,10,0), 5)
mtext = acad.model.AddMText(APoint(10,10,0), 50, "多行\\P文字")

# 点
point = acad.model.AddPoint(APoint(50,50,0))

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  # 45°
hatch.Color = 3

2.3 SendCommand 方式 (兼容性最好)

acad.doc.SendCommand("_CIRCLE 50,50 30 ")
acad.doc.SendCommand("_LINE 0,0 100,50 \n")
# \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)  # 90°

# 缩放 (基点, 比例因子)
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)  # rows,cols,levels,row_sp,col_sp,level_sp

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")  # 圆角R5
acad.doc.SendCommand("_CHAMFER D 3 3\n_CHAMFER\n") # 倒角3x3

四、图层管理 (Layers)

# 创建图层
layer = acad.doc.Layers.Add("WALL")
layer.Color = 1     # 红色 (ACI色号)
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"

# 批量修改图层 (SendCommand)
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)  # leader_length
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) # X坐标

# 标注样式
dim_style = acad.doc.DimStyles.Add("GB_DIM")
dim.TextHeight = 3.5    # 字高
dim.ArrowheadSize = 2.5 # 箭头大小
dim.DecimalSeparator = "."

5.2 公差与粗糙度

# 公差标注(通过SendCommand兼容性好)
acad.doc.SendCommand("_TOLERANCE\n")
# 或使用Leader+文字模拟
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,              # 模式(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)  # acSelectionSetAll

# 窗口选择
ss.Select(0, APoint(0,0,0), APoint(100,100,0))  # acSelectionSetWindow

# 过滤选择 (所有圆,半径>10)
import win32com.client
ft = win32com.client.VARIANT(0, [0, "CIRCLE", 40, 10.0])  # DXF组码过滤
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)  # acUnion

# 差集
solid1.Boolean(1, solid2)  # acSubtraction

# 交集
solid1.Boolean(2, solid2)  # acIntersection

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

# 通过SendCommand
acad.doc.SendCommand("_PLOT\n")        # 打印
acad.doc.SendCommand("_EXPORTPDF\n")   # 导出PDF

# 通过API
plot_cfg = acad.doc.Plot  # ActivePlotConfiguration
plot_cfg.ConfigName = "DWG To PDF.pc3"
plot_cfg.PaperUnits = 1   # mm
plot_cfg.StandardScale = 0  # acScaleToFit
plot_cfg.PlotType = 4      # acExtents
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 对照

AutoLISPPython(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',     # 3D打印
    '.iges': 'IGS',    # 通用三维
    '.step': 'STP',    # 通用三维
}

11.3 运行脚本

# 运行SCR脚本
acad.doc.SendCommand("_SCRIPT D:/scripts/draw.scr\n")

# 加载LISP插件
acad.doc.SendCommand("(load \"D:/plugins/mytool.lsp\")\n")
acad.doc.SendCommand("MYTOOL\n")  # 执行LISP命令

# 运行VBA宏
acad.doc.SendCommand("_-VBARUN MyMacro\n")

十二、中望CAD/浩辰CAD兼容

12.1 COM接口兼容性

来自"AutoCAD知识库"的国产CAD适配经验:

# 中望CAD (ZWCAD)
try:
    acad = win32com.client.Dispatch("ZWCAD.Application")
except:
    acad = win32com.client.Dispatch("AutoCAD.Application")

# 浩辰CAD (GStarCAD)
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✅ZRXGRX
SendCommand✅✅✅
三维建模✅✅✅

十三、AI+CAD 前沿 (AI+CAD知识库)

13.1 Text-to-CAD / AI生成CAD

目前主流的AI+CAD方向:

  1. 自然语言→CAD模型: CADAM、Leo AI、MecAgent等
  2. LLM生成CAD代码: 通过大模型生成AutoLISP/Python/C#代码,再由AutoCAD执行
  3. 特征识别: AI识别工程图中的几何特征
  4. 智能标注: 自动提取模型项目生成标注

13.2 AI辅助CAD工作流

# 通过AI生成AutoCAD脚本
# 示例:用户说 "画一个100x50的矩形,四周倒角R5"
# AI自动生成:

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

# 结合LLM的CAD Agent模式
# 1. LLM解析用户意图
# 2. 生成CAD操作序列
# 3. 通过COM/SendCommand执行
# 4. 验证结果反馈

13.3 重要开源项目

项目说明
Pointer-CADDeepSeek+港大,LLM生成B-Rep实体
Zero-to-CADAutodesk, 大规模CAD构造序列
text-to-cadJake, 自然语言→可编辑CAD
VideoCADMIT, 视频学习CAD操作
WHUCAD武大, 首个CAD智能核心开源
LLM4CADUT 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执行 → 验证结果

功能矩阵

功能PythonLISPSendCommand
基本绘图✅✅✅
编辑操作✅✅✅
图层管理✅✅✅
标注✅✅✅
块/属性✅✅✅
选择集过滤✅✅✅
三维建模✅⚠️✅
图纸空间✅⚠️✅
批量处理✅✅⚠️
文件转换✅⚠️✅
外部参照✅✅✅

选择指南

  • 快速原型: 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() 会累积导致后续操作报错。

# ═══════ CAD启动首行代码 ═══════
import win32com.client
acad = win32com.client.Dispatch("AutoCAD.Application")

# 1. 清理所有孤儿选择集
for ss in acad.ActiveDocument.SelectionSets:
    try:
        ss.Delete()
    except:
        pass

# 2. 如果当前文档为空(Drawing1.dwg),新建正式文档
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 1Python + pyautocad图元创建、图层管理、标注COM 对象生命周期管理
Tier 2SendCommand / SCR 脚本复杂编辑(TRIM/FILLET/CHAMFER)异步执行、错误处理弱
Tier 3AutoLISP / C# .NET插件开发、性能敏感、批量LISP 调试困难;C# 需 AutoCAD .NET SDK

降级逻辑:

def try_execute(operation, *args):
    """CAD 三级降级执行"""
    # Tier 1: pyautocad
    try:
        return operation(*args)
    except:
        pass
    # Tier 2: SendCommand
    try:
        cmd = build_sendcommand(operation, *args)
        acad.doc.SendCommand(cmd)
        return True
    except:
        pass
    # Tier 3: 加载 LISP 脚本
    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()
2SendCommand 编码中文命令乱码/无效用英文命令+下划线前缀 _LINE
3UCS 混淆坐标与实际位置不符SendCommand("_UCS _W\n") 先切到世界坐标系
4对象捕捉干扰SendCommand 点选位置错误SendCommand("_NON\n") 临时关闭对象捕捉
5LISP command 与 vl-cmdfcommand 受 UNDO 影响批量操作用 vl-cmdf
6pyautocad APoint 缺失类型错误所有坐标必须 APoint(x,y,z) 包装
# 地雷3-4 的防护模板
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
    
    # 1. 审计
    doc.SendCommand("_AUDIT Y\n")
    time.sleep(0.2)
    
    # 2. 清理(去除垃圾对象)
    doc.SendCommand("_PURGE A * N\n")
    time.sleep(0.2)
    
    # 3. 缩放范围(检查视觉完整性)
    doc.SendCommand("_ZOOM _E\n")
    time.sleep(0.2)
    
    # 4. 重生成(刷新显示)
    doc.SendCommand("_REGENALL\n")
    
    return True

铁律 5:编码与坐标系——SendCommand 两条前置命令 🔴

每次 SendCommand 前强制执行的固定管线:

def sendcommand_pipeline(acad, *commands):
    """SendCommand 安全管线——两条前置 + N条主命令"""
    # === 前置1: 锁定WCS ===
    acad.doc.SendCommand("_UCS _W\n")
    time.sleep(0.05)
    
    # === 前置2: 关闭对象捕捉 ===
    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.02026-06-01新增铁律速查:启动清理/选择集防泄漏/三级降级/六大地雷/审计验证/SendCommand管线架构优化
v1.0.02026-05-24初始版本,含14大章节:绘图/编辑/图层/标注/块/选择集/3D/打印/LISP/批量/AI+CAD知识体系构建
v1.2.02026-10-07新增第十八章:轴承座零件图全流程二次实证(COM忙等重试/文档生命周期/SendCommand挂起陷阱→PurgeAll/标注API实测/填充中文出图/验证L2-L4)大作业实战


十七、冲压模具自动绘图专项流程

当用户要求“画冲压模具、落料模、冲孔模、复合模、级进模、模架、凸模、凹模、卸料板、导柱导套”时,按本流程执行。

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_OUTLINE7模座、模板外形
DIE_WORK1凸模、凹模刃口、冲裁轮廓
DIE_GUIDE2导柱、导套、中心线
DIE_FASTENER3螺钉、销钉、沉孔
DIE_DIM4尺寸标注
DIE_TEXT5标题、技术要求、明细
DIE_AUX8构造线、基准线

17.3 自动绘图顺序

  1. 创建图层、文字样式、标注样式。
  2. 绘制模架总平面:上/下模座外形、凹模板、卸料板投影。
  3. 绘制工作部分:冲裁轮廓、凸模轮廓、凹模刃口轮廓、冲孔。
  4. 绘制导向部分:四角导柱导套、中心线和定位基准。
  5. 绘制紧固定位:螺钉、销钉、沉孔符号。
  6. 添加尺寸:外形尺寸、导柱距、工件中心距、孔径、刃口间隙说明。
  7. 添加技术要求:材料、热处理、刃口间隙、配合研磨、未注倒角。
  8. 执行 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。


十八、2026-10-07 二次实战验证:通用零件图全流程(轴承座,本机实证)

用经典 CAD 课程大作业"轴承座零件图"(A3 图框+标题栏+主/俯/左三视图+左视全剖+剖面线+ 10 处尺寸标注+技术要求+粗糙度属性块+PDF/PNG 出图,82 实体,纯绘制 5.5s / 含出图 11.7s) 在 AutoCAD 2024 简体中文 (24.3) + Python 3.14 + pywin32 上实测。 本节修正/补充 十六(铁律) 与 十七(冲压专项) 中未经本次验证的写法。

18.1 COM 忙等重试(必须)🔴

  • AutoCAD 忙时抛 -2147418111 被呼叫方拒绝接收呼叫。属性访问本身也会被拒: R(app.Documents.Add) 是错的——属性求值发生在重试之外;必须 R(lambda: app.Documents.Add()) 把整条属性链包进重试。
  • 同族错误码:-2147417846(RPC_RETRYLATER)、-2147417848。重试 60×0.5s 足够覆盖常规忙窗。

18.2 文档生命周期 🔴

  • 绝不让 Documents 归零:全部关闭后 COM 集合方法解析直接 AttributeError <unknown>.Count/.Add。
  • Documents.Add() 后立刻取 ActiveDocument 需 sleep(1.0) + 忙等重试。
  • 清空旧图用纯 COM 逆序删除:for i in reversed(range(ms.Count)): ms.Item(i).Delete()。 不要用 _ERASE _ALL——空文档上会挂在"选择对象:"提示上(见 18.3)。
  • 残留草稿清理只动 Drawing*.dwg 自动命名文档;窗口标题带 * 表示有未保存修改。

18.3 SendCommand 是最大的坑(能不用就不用)🔴

  • _AUDIT _Y 发现错误时会追加"写审计报告文件?"提示——命令串没准备这个答案, 同步 SendCommand 永久挂起(实测卡死 12 分钟)。_PURGE _A _* _N 的应答序列同样易错位。
  • 清理一律用 doc.PurgeAll()(纯 API,无提示)。SendCommand 只用于无追加提示的命令 (_ZOOM _E / _REGENALL 实测安全)。AUDIT 对纯生成图形可省略。
  • 解除挂起:doc.SendCommand(chr(3)*2)(Ctrl+C)。COM 已卡死 + 锁屏/UIPI 时键盘不可达, 最后手段 taskkill /IM acad.exe /F(先核对窗口内无用户未保存数据)。

18.4 标注 API 实测 ⚡

  • AddDimDiametric 是 3 参 (Object, ChordPoint, LeaderLength),4 参 TypeError。
  • 迭代 ModelSpace 拿到的圆/弧引用再传给标注类 API,易报"对象已被删除"(-2145386420)。
  • 最稳写法:直径类尺寸用跨象限点 AddDimAligned(p1, p2, tp) + TextOverride="%%c50" (%%c=⌀ %%d=° %%p=±);半径用手工引线+文字。
  • 标注样式直接设系统变量(A3 实测:DIMTXT 3.5 / DIMASZ 2.5 / DIMEXO 0.8 / DIMEXE 2.0 / DIMDEC 0 / LTSCALE 4 / DIMSCALE 1)。

18.5 填充 / 中文 / 出图(实测可用)✅

  • 填充:AddHatch(0,"ANSI31",True) → AppendOuterLoop(VARIANT(VT_ARRAY|VT_DISPATCH,[闭合pline])) → 内孔 AppendInnerLoop(岛)→ PatternScale → Evaluate()。边界用闭合 LightWeightPolyline。
  • 中文样式:TextStyle.FontFile="gbenor.shx"; BigFontFile="gbcbig.shx";重名样式要复用 (TextStyles.Add 重名会炸,先查 Name in [s.Name for s in doc.TextStyles])。
  • Linetypes.Load 对已加载线型抛"记录名重复" → 先遍历查重再 Load。
  • 出图:先 SetVariable("BACKGROUNDPLOT", 0)(否则 PlotToFile 异步返回拿不到文件); PDF:layout.ConfigName="DWG To PDF.pc3",纸张从 GetCanonicalMediaNames() 里选 ISO_A3_(420.00_x_297.00_MM);PNG:PublishToWeb PNG.pc3(XGA_Hi-Res_(1600.00_x_1200.00_Pixels)); PlotType=1(Extents) + StandardScale=0(ScaleToFit) + CenterPlot=True;PlotToFile 后轮询文件落盘。

18.6 验证分层 L2/L3/L4 落地

  • L2:ModelSpace.Count;L3:按 (ObjectName, Layer) 分类型清点(本例 82 实体: 10 标注 / 4 圆 / 4 弧 / 2 填充 / 9 虚线 / 7 中心线 / 26 实线 / 9 文字 / 2 块参照)+ PurgeAll()。
  • L4:PNG 出图后视觉审查——本次实测抓出 3 处纯数据检查抓不到的问题: A—A 视图名与 60 尺寸文字重叠、粗糙度符号压 120 尺寸线、填充对象误落 WALL 层,修复后复检通过。

18.7 环境事实

  • 本机 AutoCAD 2024 简体中文装于 E:\CAD\CAD\AutoCAD 2024\(注册表 HKLM\SOFTWARE\Autodesk\AutoCAD\R24.3\ACAD-7101:804\AcadLocation),ProgID AutoCAD.Application。
  • 完整实测脚本(探针 / 绘图 / 关窗三件套)见仓库 examples/bearing-seat/脚本/(本次实战沉淀)。
我的收藏