1. 选择集:批量操作CAD图元的高效工具
在CAD绘图中,我们经常需要对大量图元进行相同操作。比如要把图纸中所有半径小于5mm的圆放大两倍,或者要把特定图层上的所有文字改成统一字体。这时候如果一个个手动修改,不仅效率低下还容易出错。AutoLISP的选择集功能就是为解决这类问题而生的。
选择集的核心函数是ssget,它就像个智能筛选器,能根据我们设定的条件批量抓取图元。我常用的是三种基础筛选模式:
- "W"窗口模式:完全包含在矩形框内的图元才会被选中
- "C"交叉模式:与矩形框相交的图元都会被选中
- "F"围栏模式:与指定折线相交的图元都会被选中
实际项目中,我更喜欢用动态判断模式。比如这个智能框选函数会根据鼠标移动方向自动切换W/C模式:
(defun smart-select () (setq p1 (getpoint "\n请指定第一角点:")) (setq p2 (getcorner p1 "\n请指定对角点:")) (if (> (car p1) (car p2)) (ssget "c" p1 p2) (ssget "w" p1 p2) ) )更强大的是带过滤条件的选择集。最近做厂房图纸标准化时,我用这个函数快速选中了所有需要修改的消防设备:
(setq ss (ssget "x" '((0 . "INSERT") (8 . "消防设备") (2 . "消防栓*")) ))选择集创建后,还能用ssadd和ssdel动态增删成员。记得有次图纸评审,需要临时隐藏某些构件,我就是用选择集动态管理显示对象的。
2. 命令行设置:自动化标准化的秘密武器
CAD高手和新手的区别,往往体现在对标准化流程的把控上。通过AutoLISP控制命令行设置,可以实现一键标准化操作。比如新图纸创建时自动建立规范图层体系:
(defun init-layers () (command "_.-layer" "_m" "建筑" "_c" "7" "" "") (command "_.-layer" "_m" "电气" "_c" "1" "" "_l" "dashed" "" "") (command "_.-layer" "_m" "标注" "_c" "2" "" "_lw" "0.15" "" "") )字体设置是另一个痛点。我们公司要求所有图纸使用统一字体组合,这个LISP脚本可以确保字体样式符合规范:
(defun set-textstyle () (command "_.-style" "工程字" "simplex.shx,hztxt.shx" "0" "0.7" "0" "" "" "") )线型设置有个实用技巧:先检查是否已加载,避免重复加载报错。这是我常用的安全加载函数:
(defun safe-load-ltype (ltypeName fileName) (if (null (tblsearch "ltype" ltypeName)) (command "_.-linetype" "_l" ltypeName fileName "" "") ) )3. 符号表:深入CAD数据库的核心
符号表是CAD图纸的骨架,存储着图层、线型、标注样式等核心数据。通过tblnext和tblsearch函数,我们可以像查字典一样遍历这些关键信息。
有次客户发来的图纸莫名崩溃,我用这个诊断脚本快速找出了损坏的图层:
(defun check-layers () (setq layer (tblnext "layer" T)) (while layer (if (= (cdr (assoc 70 layer)) 1) (princ (strcat "\n锁定图层:" (cdr (assoc 2 layer)))) ) (setq layer (tblnext "layer")) ) )创建新图层时,我习惯先检查是否已存在同名图层。这个防冲突函数帮了大忙:
(defun create-layer (name color linetype) (if (null (tblsearch "layer" name)) (progn (command "_.-layer" "_m" name "_c" color "" "_l" linetype "" "") (princ (strcat "\n已创建图层:" name)) ) (princ (strcat "\n图层已存在:" name)) ) )4. 实战案例:批量更新图纸标注样式
最近接手一个老项目,需要将数百张图纸的标注样式从英制改为公制。通过组合运用上述技术,我开发了这个自动化工具:
(defun c:update-dim () ; 设置新标注样式 (command "_.-dimstyle" "_r" "GB-35") ; 选择所有标注 (setq ss (ssget "x" '((0 . "DIMENSION")))) (setq n 0) ; 批量更新 (repeat (sslength ss) (setq ent (entget (ssname ss n))) (setq new-ent (subst (cons 3 "GB-35") (assoc 3 ent) ent)) (entmod new-ent) (setq n (1+ n)) ) (princ (strcat "\n共更新了 " (itoa n) " 个标注")) )这个工具将原本需要数天的工作压缩到几分钟完成。关键在于:
- 先用符号表确保目标样式存在
- 通过选择集精准抓取所有标注对象
- 结合命令行设置保证样式参数正确
- 最后用选择集遍历完成批量更新
5. 调试技巧与性能优化
开发复杂LISP程序时,我总结了几条实用经验:
选择集操作要特别注意内存管理。大型图纸中,用完的选择集记得用sssetfirst nil释放:
(setq ss (ssget "_X")) ;...处理代码... (sssetfirst nil ss)符号表查询比较耗时,可以缓存常用数据。比如这个图层属性缓存器:
(setq layer-cache '()) (defun get-layer-prop (layerName prop) (or (cdr (assoc (cons layerName prop) layer-cache)) (progn (setq data (tblsearch "layer" layerName)) (setq layer-cache (cons (cons (cons layerName prop) (cdr (assoc prop data))) layer-cache)) (cdr (assoc prop data)) ) ) )错误处理也很重要。这是我常用的选择集安全获取函数:
(defun safe-ssget (msg filter) (setq ss nil) (while (null ss) (princ msg) (setq ss (ssget filter)) (if (null ss) (princ "\n未选择有效对象,请重试")) ) ss )6. 扩展应用:构建自己的CAD工具箱
把这些功能模块化后,可以组合出各种实用工具。比如这个智能图层管理器:
(defun c:laymgr () (init-layers) ; 初始化标准图层 (setq ss (smart-select)) ; 智能选择对象 (command "_.chprop" ss "" "_la" "建筑" "") ; 修改图层 (update-dim-style ss) ; 同步标注样式 )我还开发了图纸批量处理工具,可以自动完成:
- 图层标准化
- 文字样式统一
- 标注更新
- 图框替换
- 打印样式设置
把这些LISP文件放在CAD支持路径下,通过自定义菜单或快捷键调用,工作效率能提升数倍。