中望CAD LISP二次开发入门实践:用脚本批量生成图框、自动标注与图层管理

中望CAD与AutoCAD兼容的不仅是DWG格式,还包括LISP(AutoLISP/Visual LISP)应用程序接口。这意味着大量现有的CAD自动化脚本可以直接在中望CAD上运行,也可以自行编写脚本来消除重复劳动。
本文面向有基本编程经验但未接触过CAD二次开发的技术人员,通过三个实际场景的LISP脚本案例,展示如何用代码提升绘图效率。
一、LISP在CAD中的角色与加载方式
LISP是CAD领域历史最悠久的脚本语言,直接嵌入CAD进程内运行,可以调用几乎所有CAD命令和对象模型。每个LISP脚本本质是一个或多个函数定义,保存在.lsp文本文件中。
加载方式有三种:
- 手动加载:在命令行输入
(load "D:/scripts/my_tools.lsp"),括号和路径中的正斜杠都不能省。 - 自动加载:将.lsp文件放入中望CAD安装目录的Support文件夹,在acad.lsp或zwcad.lsp启动文件中添加load语句,每次启动CAD自动加载。
- 菜单按钮绑定:写一个简单的defun c:xxx函数,在CUI界面中将该命令绑定到工具栏按钮,点击即执行。
调试建议:在CAD命令行直接输入单行LISP表达式即可测试,无需反复修改文件。例如输入 (setq pt1 (getpoint "\n请拾取一个点: ")) 就能立即看到交互效果。
二、案例一:批量生成A3图框
场景:一个项目有20张图纸需要统一插入A3图框,手动操作需要反复INSERT→选块→定位→缩放,20张图纸就是80次操作。
脚本逻辑:
- 提示用户选择图纸目录
- 遍历目录中所有.dwg文件
- 对每个文件:打开 → 插入图框块到(0,0)坐标 → 缩放到A3图幅(420×297) → 保存关闭
完整脚本:
(defun c:BatchAddFrame ()
;; 批量给当前目录下所有DWG插入A3图框
(setq file_list (vl-directory-files (getvar "dwgprefix") "*.dwg" 1))
(foreach fname file_list
(if (/= (strcase fname) (strcase (getvar "dwgname")))
(progn
(command "._OPEN" (strcat (getvar "dwgprefix") fname))
;; 插入A3图框块到原点
(if (tblsearch "block" "A3-FRAME")
(command "._INSERT" "A3-FRAME" "0,0" "1" "1" "0")
(princ "\n【警告】未找到A3-FRAME图块,跳过"))
(command "._ZOOM" "E")
(command "._QSAVE")
)
)
)
(princ "\n批量图框插入完成。")
)
代码要点:vl-directory-files遍历目录、tblsearch检查图块是否存在(防御性编程)、command调用CAD原生命令、foreach循环逐个处理。
使用方式:将A3-FRAME图块定义在当前图纸中,或将包含该块定义的模板文件设为当前图纸,然后执行 BatchAddFrame。
三、案例二:自动标注所选多段线的所有边
场景:画完一张平面图后,需要手动标注每段墙体的长度。一段一段点,20段墙就是40次点击。
脚本逻辑:
- 提示用户选择多段线
- 提取多段线的每个顶点坐标
- 在每段边的外侧创建对齐标注
(defun c:AutoDimPL ()
;; 自动标注所选多段线的所有边长
(setq ent (car (entsel "\n选择要标注的多段线: ")))
(if (and ent (= (cdr (assoc 0 (entget ent))) "LWPOLYLINE"))
(progn
(setq obj (vlax-ename->vla-object ent))
(setq coords (vlax-get obj 'Coordinates))
(setq len (length coords))
(setq i 0)
(while (< i (- len 2))
(setq pt1 (list (nth i coords) (nth (1+ i) coords) 0))
(setq pt2 (list (nth (+ i 2) coords) (nth (+ i 3) coords) 0))
;; 计算标注偏移方向(向外侧偏移)
(setq mid (list (/ (+ (car pt1) (car pt2)) 2.0)
(/ (+ (cadr pt1) (cadr pt2)) 2.0)))
(setq ang (+ (angle pt1 pt2) (/ pi 2)))
(setq pt3 (polar mid ang 8.0)) ;; 偏移8个单位
;; 创建对齐标注
(command "._DIMALIGNED" pt1 pt2 pt3)
(setq i (+ i 2))
)
)
(princ "\n【错误】请选择一条多段线。")
)
(princ)
)
代码要点:entget获取图元数据、assoc 0判断图元类型、vlax-get获取ActiveX属性、极坐标计算标注偏移位置。
四、案例三:根据图层名规则自动创建图层组
场景:拿到一套含50个图层的图纸,需要按专业分类创建图层过滤器。手动操作:图层特性管理器 → 新建过滤器 → 输入过滤条件 → 15个专业各做一次。
脚本逻辑:
- 提取当前图纸所有图层名
- 按前缀(第一个连字符前的内容)分组
- 为每个分组创建图层状态(Layer State)
(defun c:AutoGroupLayers ()
;; 按图层名前缀自动创建图层状态分组
(setq layer_list '())
(setq tbl (tblnext "layer" T))
(while tbl
(setq lname (cdr (assoc 2 tbl)))
(setq prefix (substr lname 1 (vl-string-search "-" lname)))
(if prefix
(if (not (member prefix layer_list))
(setq layer_list (cons prefix layer_list))
)
)
(setq tbl (tblnext "layer"))
)
;; 为每个前缀创建图层状态
(foreach prefix layer_list
(command "._LAYER" "A" "S" prefix "" (strcat prefix "-*") "")
)
(princ (strcat "\n已为" (itoa (length layer_list)) "个图层分组创建图层状态。"))
(princ)
)
代码要点:tblnext遍历符号表、vl-string-search查找分隔符位置、substr截取前缀字符串、_LAYER A S保存图层状态。
运行后,图层状态管理器下拉列表中会出现按专业分组的选项,一键切换即可仅显示对应专业的图层。
五、LISP编程的几个关键注意点
函数命名:自定义命令必须以 c: 开头(c=command),否则只能在LISP内部调用,不能在命令行直接输入。
括号配对:LISP的嵌套括号极多,建议用支持括号高亮的编辑器(VS Code + AutoCAD AutoLISP扩展、或中望CAD自带的VLIDE编辑器)。括号不匹配后调试非常痛苦。
局部变量声明:在 defun 后的斜杠对中声明所有局部变量,避免污染全局命名空间:
(defun c:MyCmd ( / var1 var2 var3)
错误处理:长脚本加错误捕获防止中断:(setq olderr *error* *error* myErrorHandler),自定义错误函数中恢复系统变量。
性能优化:批量处理大量图元时,在循环前后加上 (command "._UNDO" "BE") 和 (command "._UNDO" "E") 将整个操作打包成一个UNDO步骤;同时 (setvar "CMDECHO" 0) 关闭命令回显,能提升30-50%的执行速度。
中望CAD的LISP兼容性很好,大部分为AutoCAD编写的LISP脚本可以直接运行。如果你的工作中存在大量重复性操作——批量出图、批量改属性、批量统计——花几天时间学写LISP脚本,长期看是最划算的时间投资。
下载地址:中望CAD最新下载
AI辅助创作声明:本文由AI辅助整理与撰写,内容已经过人工审校与调整。

浙公网安备 33010602011771号