乐于分享
好东西不私藏

【lisp】源码:多重插入块与普通块的转换

【lisp】源码:多重插入块与普通块的转换

源码:https://tool.zml84.xyz/lisp/view/?uuid=ccf97316-7f08-4154-9f44-9314427e50e7

代码共包含三个自定义命令,分别用于多重插入块与普通块的相互转换,以及批量炸开匿名块。


一、C:MB2B —— 多重插入块 → 普通块

「功能」将用户点选的多重插入块(MINSERT)转换为普通块插入(INSERT),只保留第一个插入实例(原行列信息被丢弃)。

「逻辑分析」

(DEFUN C:MB2B (/ ss e)  (while (SETQ ss (ENTSEL"\n点取多重块: "))    (setq e (entget (car ss)))    (if (= (cdr (assoc0 e)) "INSERT")      (PROGN; 将行间距(44)、列间距(45)设为0        (setq e (subst (cons440) (assoc44 e) e))        (setq e (subst (cons450) (assoc45 e) e)); 将行数(70)、列数(71)设为0(即单行单列)        (setq e (subst (cons700) (assoc70 e) e))        (setq e (subst (cons710) (assoc71 e) e)); 修改对象类名:AcDbMInsertBlock → AcDbBlockReference        (setq e (subst (list100"AcDbBlockReference")                       (list100"AcDbMInsertBlock")                       e))        (entmake e)   ; 生成新普通块        (entdel (car ss)) ; 删除原多重块        (princ"**操作完成。")      )    )  )  (princ))

「关键组码说明」(DXF 组码):

  • 44:列间距(多重块专属)
  • 45:行间距
  • 70:行数(多重块)
  • 71:列数
  • 100:子类标记,区分块引用类型(AcDbBlockReference 为普通块,AcDbMInsertBlock 为多重插入块)

「注意」

  • 多重块的行列数组会被“压平”成单个插入,「原布局信息完全丢失」,适用于需要简化或编辑的场景。
  • 若点选的不是 INSERT 图元,则无操作。

二、C:B2MB —— 普通块 → 多重插入块

「功能」将普通块转换为多重插入块,默认生成 1 行 × 1 列(即与普通块外观一致,但类型变为多重块)。

「逻辑分析」

(DEFUN C:B2MB (/ ss e)  (while (SETQ ss (ENTSEL"\n点取块: "))    (setq e (entget (car ss)))    (if (= (cdr (assoc0 e)) "INSERT")      (PROGN        (setq e (subst (cons701) (assoc70 e) e)) ; 行数=1        (setq e (subst (cons711) (assoc71 e) e)) ; 列数=1        (setq e (subst (list100"AcDbMInsertBlock")                       (list100"AcDbBlockReference")                       e))        (entmake e)        (entdel (car ss))        (princ"**操作完成。")      )    )  )  (princ))

「说明」

  • 原普通块的插入点、比例、旋转角度等均保留。
  • 转换后虽然仍是“多重块”,但行列数均为 1,实际效果与普通块无异。用户后续可通过属性面板调整行列数。
  • 注意:7071 默认可能为 0(普通块无此定义),此处强行设为 1。

三、C:ExAllnb —— 炸开所有匿名块(含嵌套)

「功能」批量炸开当前图纸中所有「匿名块」(块名以 *U* 开头的块),并自动处理嵌套情况,直至全部炸开。

「逻辑分析」

(defun c:ExAllnb (/ ss)  (setvar"EXPLMODE"1)   ; 允许炸开非均匀比例块  (setvar"qaflags"1)    ; 简化 EXPLODE 命令的交互(默认选择集全部炸开)  (while (setq SS (ssget"X"                        '((0 . "INSERT")                          (100 . "AcDbBlockReference")                          (2 . "`*U*")                         )                 )         )    (princ"\n发现匿名块: ")    (princ (sslength SS))    (command"_.EXPLODE" SS "")  ; 炸开当前找到的所有匿名块  )  (setvar"qaflags"0)    ; 恢复默认值  (princ))

「关键点」

  • 「匿名块」:由 AutoCAD 自动生成的块,名称格式为 *U数字,常见于动态块或某些插件操作。
  • 「循环处理」:因为炸开嵌套块可能会产生新的匿名块(例如嵌套中的匿名块),所以用 while 循环反复搜索,直到图纸中不再存在符合条件的块。
  • 「系统变量」
    • EXPLMODE = 1:允许炸开具有非均匀缩放(不等比)的块,否则可能失败。
    • QAFLAGS = 1:使 EXPLODE 命令直接处理选择集,无需确认(加速批量操作)。
  • 「选择集过滤」(2 . "U")中的反引号 `` `` 用于转义通配符 *,表示匹配以 *U 开头的块名(AutoCAD 中匿名块的实际名称)。

四、整体注意事项

  1. 「操作不可逆」entmake + entdel 会直接修改图形,请提前备份或确认。
  2. 「多重块与普通块」:多重块在属性面板中可调整行列间距,但普通块无此功能;转换时信息会丢失。
  3. 「匿名块炸开」:该命令会「炸开所有匿名块」,包括可能由动态块生成的部分,炸开后可能变为基本图元,失去块定义,请谨慎使用。
  4. 「兼容性」:代码基于 AutoCAD 的 DXF 组码,适用于大多数 AutoCAD 版本,但匿名块命名规则可能在不同版本中略有差异(*U* 通常不变)。

五、使用场景建议

  • MB2B:当多重块需要编辑内部图形或调整属性时,先转为普通块。
  • B2MB:需要将普通块快速转为多重块以便阵列或重复利用时。
  • ExAllnb:清理图纸中由外部参照或插件留下的匿名块,减少文件冗余或便于后续编辑。

以上即为对3段代码的完整解读。

完整源码:https://tool.zml84.xyz/lisp/view/?uuid=ccf97316-7f08-4154-9f44-9314427e50e7