小毛草 发表于 2025-12-26 13:22:12

块内所有对象的图层移动到当前层,颜色改为随层(包括嵌套块)

;;;;;;;;;;;;;;;;块内所有对象的图层移动到当前层,颜色改为随层(包括嵌套块)
(defun c:vvx (/ blkrefs ss i blkref blkname totalCount result processedBlocks allProcessedBlocks)
; 错误处理函数
(defun *error* (msg)
    (if (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))
      (princ (strcat "\n错误: " msg))
    )
    (setvar "CMDECHO" 1); 确保命令回显恢复
    (princ)
)

; 递归函数:处理块定义及其嵌套块
(defun ProcessBlockDefinition (blkname processedBlocks / blkdef ent obj subBlkName count)
    (setq count 0)
   
    ; 检查是否已经处理过此块(避免无限递归)
    (if (not (member blkname processedBlocks))
      (progn
      ; 添加到已处理列表
      (setq processedBlocks (cons blkname processedBlocks))
      
      ; 获取块定义
      (if (setq blkdef (tblobjname "BLOCK" blkname))
          (progn
            (setq ent (entnext blkdef)); 获取块定义中的第一个图元
            
            ; 遍历块定义中的所有图元
            (while (and ent (not (eq "ENDBLK" (cdr (assoc 0 (entget ent))))))
            (setq obj (entget ent))
            
            ; 检查是否为嵌套块引用
            (if (= "INSERT" (cdr (assoc 0 obj)))
                (progn
                  ; 获取嵌套块名
                  (setq subBlkName (cdr (assoc 2 obj)))
                  
                  ; 递归处理嵌套块,传递已处理块列表
                  (setq countResult (ProcessBlockDefinition subBlkName processedBlocks))
                  (setq count (+ count (car countResult)))
                  (setq processedBlocks (cadr countResult))
                  
                  ; 修改嵌套块引用本身的图层和颜色
                  (setq obj (subst (cons 8 (getvar "CLAYER")) (assoc 8 obj) obj)) ; 修改图层
                  (setq obj (subst (cons 62 256) (assoc 62 obj) obj)) ; 修改颜色为随层
                  (if (entmod obj)
                  (setq count (1+ count))
                  )
                )
                ; 不是块引用,直接修改图层和颜色
                (progn
                  (setq obj (subst (cons 8 (getvar "CLAYER")) (assoc 8 obj) obj)) ; 修改图层
                  (setq obj (subst (cons 62 256) (assoc 62 obj) obj)) ; 修改颜色为随层
                  (if (entmod obj)
                  (setq count (1+ count))
                  )
                )
            )
            
            (setq ent (entnext ent)); 获取下一个图元
            )
          )
          (princ (strcat "\n警告: 无法找到块定义 \"" blkname "\""))
      )
      )
      ; 如果已经处理过,返回0
      (setq count 0)
    )
   
    (list count processedBlocks); 返回处理的对象数量和更新后的已处理块列表
)

(setvar "CMDECHO" 0); 关闭命令回显

; 选择多个块参照
(princ "\n选择块参照(可多选): ")
(if (setq ss (ssget '((0 . "INSERT"))))
    (progn
      (setq totalCount 0)
      (setq allProcessedBlocks '()); 所有已处理块列表
      (setq blkrefs '()); 存储所有选择的块名
      
      ; 先收集所有选择的块名
      (setq i 0)
      (repeat (sslength ss)
      (setq blkref (ssname ss i))
      (setq blkname (cdr (assoc 2 (entget blkref))))
      (if (not (member blkname blkrefs))
          (setq blkrefs (cons blkname blkrefs))
      )
      (setq i (1+ i))
      )
      
      (princ (strcat "\n已选择 " (itoa (length blkrefs)) " 个不同的块"))
      
      ; 处理每个块
      (foreach blkname blkrefs
      (princ (strcat "\n正在处理块: " blkname))
      
      ; 处理块定义及其所有嵌套块
      (setq result (ProcessBlockDefinition blkname allProcessedBlocks))
      (setq blockCount (car result))
      (setq allProcessedBlocks (cadr result))
      (setq totalCount (+ totalCount blockCount))
      
      (princ (strcat " - 处理了 " (itoa blockCount) " 个对象"))
      )
      
      ; 刷新图形以显示更改
      (command "_.REGEN")
      
      (princ (strcat "\n\n已处理 " (itoa (length blkrefs)) " 个块内的 " (itoa totalCount) " 个对象的图层和颜色"))
      (princ (strcat "\n图层设置为: " (getvar "CLAYER") ",颜色设置为: 随层"))
      (if (> (length allProcessedBlocks) (length blkrefs))
      (princ (strcat "\n处理的块包括: " (vl-princ-to-string allProcessedBlocks)))
      )
    )
    (princ "\n未选择对象或选择无效。")
)

(setvar "CMDECHO" 1); 恢复命令回显
(princ)
)

yjwht 发表于 2025-12-26 14:11:05

在浩辰CAD2019上试了一下,可以用!减少了大量图层。线型、线宽保持不变。
现在的图纸图层多(不信我附张图,你数一下有多少图层)。
要炸开块处理工作量大,这个程序很实用。

kozmosovia 发表于 2025-12-26 14:17:24

yjwht 发表于 2025-12-26 14:11
在浩辰CAD2019上试了一下,可以用!减少了大量图层。线型、线宽保持不变。
现在的图纸图层多(不信我附张 ...

layer界面选中图层可以直接合并的。

yjwht 发表于 2025-12-26 19:16:31

本帖最后由 yjwht 于 2025-12-26 19:22 编辑

kozmosovia 发表于 2025-12-26 14:17
layer界面选中图层可以直接合并的。
AutoCAD可以直接合并,浩辰CAD中没有,如下图。不过浩辰也有转换图层的功能C:\Users\admin\Desktop\Snipaste_2025-12-26_19-13-18.png

rzzhangquan 发表于 2025-12-26 23:34:16

感谢分享!

hsh305 发表于 4 天前

好用,非常nice

qwsss31 发表于 4 天前

不说不知道,一说才知道

海盗曹 发表于 4 天前

点赞,下载,收藏!

aeo000000 发表于 昨天 17:02

改成0层比较好,然后插入到当前层
页: [1]
查看完整版本: 块内所有对象的图层移动到当前层,颜色改为随层(包括嵌套块)