明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 8758|回复: 14

[源码] 【分享】新做了一个图层锁定变灰的程序

  [复制链接]
发表于 2014-3-6 21:03 | 显示全部楼层 |阅读模式
本帖最后由 happysheep 于 2014-3-14 16:31 编辑

在论坛上从诸位前辈的代码中学到了很多东西,谢谢大家!

程序使用LAY启动,功能如下:

单选反锁(S)<默认>:选择一个对象,除此对象所在层以外的所有层,锁定并变成灰色;
锁定指定层(L):选择一个或多个对象,其所在的层锁定并变成灰色。如果对象是外部引用或块,其内部的层也如此处理。此命令对嵌套的外部引用或块同样有效。
单独解锁一层(U):选择一个
或多个对象,其所在的层解锁并恢复原色。如果对象是外部引用或块,其内部的层也如此处理。此命令对嵌套的外部引用或块同样有效。
全部解锁(UU) :将图中所有图层解锁并恢复颜色。


程序现在的问题是,
1. 标注中的数字,原本是白色,锁定时被变为随层,解锁时变回来。但程序中用的是命令entupd,运行时间较长,有没有更好的办法?
变为随层:
  1. (if (= (vla-get-ObjectName obj) "AcDbRotatedDimension")
  2.     (vla-put-textcolor obj acbylayer)
  3.   )
变回白色:
  1.   (if (= (vla-get-ObjectName obj) "AcDbRotatedDimension")
  2.     (vla-put-textcolor obj acWhite)
  3.   )


2. 为了解决标注文字颜色不随层的问题,单独把嵌套的外部引用中的所有对象递归遍历了一遍,造成程序运行时间较长,如何解决?
  1. (defun Dim-Restore-Recursion (obj / SubObj)
  2.   (if (= (vla-get-ObjectName obj) "AcDbRotatedDimension")</span>
  3.     (vla-put-textcolor obj acWhite)
  4.   )
  5.   (if (= (vla-get-ObjectName obj) "AcDbBlockReference")</span>
  6.     (vlax-for SubObj
  7.          (vla-item (vla-get-blocks doc)
  8.              (vla-get-name obj) ;获得块名
  9.          )     
  10.       (Dim-Restore-Recursion SubObj)
  11.     )
  12.   )
  13. )

以下是程序全文:
  1. ;;;程序开始
  2. (vl-load-com)

  3. ;;;生成图层列表
  4. (defun laytab ()
  5.   (setq first T)
  6.   (setq layertab '())
  7.   (while (setq lay1 (tblnext "layer" first))
  8.     (if  (= first T)
  9.       (setq first nil)
  10.     )
  11.     (if  (/= lay1 nil)
  12.       (progn (setq lay2 (cdr (assoc 2 lay1)))
  13.        (setq layertab (cons lay2 layertab))
  14.       )
  15.     )
  16.   )
  17. )

  18. ;;;用递归实现遍历所有对象,颜色变灰、图层锁定
  19. (defun Change-Lock-Recursion (obj / layname vla_lay SubObj laycolor layhandle)
  20.   ;;颜色变灰、图层锁定
  21.   (setq layname (vlax-get-property obj 'Layer))
  22.   (setq vla_lay (vla-item (vla-get-layers doc) layname))
  23.   (setq laycolor (vlax-get-property vla_lay 'Color))
  24.   (if (/= laycolor 252)
  25.     (progn
  26.     (setq layhandle (vla-get-handle vla_lay))
  27.    (VLAX-LDATA-PUT "data" layhandle laycolor)
  28.     (vlax-put-property vla_lay 'Color 252)
  29.     (vla-put-lock vla_lay :vlax-true)
  30.     )          ;如果颜色不是252,则存颜色并改成252
  31.   )
  32.   ;;颜色变灰、图层锁定结束
  33.   (if (= (vla-get-ObjectName obj) "AcDbBlockReference")
  34.     (vlax-for SubObj
  35.          (vla-item (vla-get-blocks doc)
  36.              (vla-get-name obj) ;获得块名
  37.          )      ;获取当前文档中的所有块,按照名字从中找到操作者选择的块,返回块中所有对象的集合
  38.       (Change-Lock-Recursion SubObj)  ;obj依次为块内每一个图元的对象
  39.     )          ;调用自己,递归,遍历引用中的每层引用
  40.   )
  41. )


  42. (defun Dim-Color-Recursion (obj / SubObj)
  43.   ;;如果是标注,则把文字颜色改为随层
  44.   (if (= (vla-get-ObjectName obj) "AcDbRotatedDimension")
  45.     (vla-put-textcolor obj acbylayer)
  46.   )
  47. ;;;
  48.   (if (= (vla-get-ObjectName obj) "AcDbBlockReference")
  49.     (vlax-for SubObj
  50.          (vla-item (vla-get-blocks doc)
  51.              (vla-get-name obj) ;获得块名
  52.          )      ;获取当前文档中的所有块,按照名字从中找到操作者选择的块,返回块中所有对象的集合
  53.       (Dim-Color-Recursion SubObj)  ;obj依次为块内每一个图元的对象
  54.     )          ;调用自己,递归,遍历引用中的每层引用
  55.   )
  56. )

  57. ;;;选择锁定
  58. (defun lockl (e / obj layname vla_lay laycolor)
  59.   (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  60.   (setq obj (vlax-ename->vla-object e))
  61.   (setq layname (vlax-get-property obj 'Layer))
  62.   (setq vla_lay (vla-item (vla-get-layers doc) layname))
  63.   (setq laycolor (vlax-get-property vla_lay 'Color))
  64.   (if (/= laycolor 252)
  65.     (progn
  66.       (Dim-Color-Recursion obj)
  67.       (Change-Lock-Recursion obj)
  68.       (entupd e)
  69.     )
  70.   )          ;不regen的话,标注文字颜色无法刷新
  71. )

  72. ;;;用递归实现遍历所有对象,颜色恢复、图层解锁
  73. (defun Restore-Unlock-Recursion  (obj / SubObj)
  74.   ;;颜色恢复、图层解锁
  75.   (setq layname (vlax-get-property obj 'Layer))
  76.   (setq vla_lay (vla-item (vla-get-layers doc) layname))
  77.   (setq layhandle (vla-get-handle vla_lay))
  78.   (vla-put-lock vla_lay :vlax-false)  ;不管怎样,先解锁
  79.   (if (setq laycolor (VLAX-LDATA-get "data" layhandle))
  80.     (progn
  81.       (vlax-put-property vla_lay 'Color laycolor)
  82.       (vlax-ldata-delete "data" layhandle)
  83.     )
  84.   )
  85.   ;;颜色恢复、图层解锁结束
  86.   (if (= (vla-get-ObjectName obj) "AcDbBlockReference")
  87.     (vlax-for SubObj
  88.          (vla-item (vla-get-blocks doc)
  89.              (vla-get-name obj) ;获得块名
  90.          )      ;获取当前文档中的所有块,按照名字从中找到操作者选择的块,返回块中所有对象的集合
  91.       (Restore-Unlock-Recursion SubObj)  ;obj依次为块内每一个图元的对象
  92.     )          ;调用自己,递归,遍历引用中的每层引用
  93.   )
  94. )

  95. (defun Dim-Restore-Recursion (obj / SubObj)
  96.   ;;如果是标注,则把文字颜色改回白色
  97.   (if (= (vla-get-ObjectName obj) "AcDbRotatedDimension")
  98.     (vla-put-textcolor obj acWhite)
  99.   )
  100. ;;;
  101.   (if (= (vla-get-ObjectName obj) "AcDbBlockReference")
  102.     (vlax-for SubObj
  103.          (vla-item (vla-get-blocks doc)
  104.              (vla-get-name obj) ;获得块名
  105.          )      ;获取当前文档中的所有块,按照名字从中找到操作者选择的块,返回块中所有对象的集合
  106.       (Dim-Restore-Recursion SubObj)  ;obj依次为块内每一个图元的对象
  107.     )          ;调用自己,递归,遍历引用中的每层引用
  108.   )
  109. )

  110. ;;;单选解锁
  111. (defun unlock (e / obj)
  112.   (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  113.   (setq obj (vlax-ename->vla-object e))
  114.   (Restore-Unlock-Recursion obj)
  115.   (Dim-Restore-Recursion obj)
  116.   (entupd e)     ;否则标注文字颜色无法刷新
  117. )

  118. ;;;单选反锁……选定对象以外的层都锁定改色
  119. (defun locks (e / n m laycolor layname layhandle)
  120.   (setq n (length layertab))
  121.   (setq m 0)
  122.   (setq obj (vlax-ename->vla-object e))
  123.   (setq h (vlax-get-property obj 'Layer))
  124.   (vla-put-ActiveLayer
  125.     (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  126.     (vla-item (vla-get-layers doc) h)
  127.   )          ;置为当前层
  128.   (while (/= m n)
  129.     (if  (/= h (setq layname (nth m layertab)))
  130.       (progn
  131.   (setq vla_lay (vla-item (vla-get-layers doc) layname))
  132.   (setq laycolor (vlax-get-property vla_lay 'Color))
  133.   (setq layhandle (vla-get-handle vla_lay))
  134.   (VLAX-LDATA-PUT "data" layhandle laycolor)
  135.   (vlax-put-property vla_lay 'Color 252)
  136.   (vla-put-lock vla_lay :vlax-true)
  137.       )
  138.     )
  139.     (setq m (+ m 1))
  140.   )
  141. )

  142. ;;;全部解锁
  143. (defun unall (/ n m vla_lay laycolor layname layhandle)
  144.   (setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))
  145.   (setq n (length layertab))
  146.   (setq m 0)
  147.   (while (/= m n)
  148.     (setq layname (nth m layertab))
  149.     (setq vla_lay (vla-item (vla-get-layers doc) layname))
  150.     (setq layhandle (vla-get-handle vla_lay))
  151.     (vla-put-lock vla_lay :vlax-false)  ;先解锁
  152.     (if  (setq laycolor (VLAX-LDATA-get "data" layhandle))
  153.           ;如果词典里有该层信息,则改颜色
  154.       (progn
  155.   (vlax-put-property vla_lay 'Color laycolor)
  156.   (vlax-ldata-delete "data" layhandle)
  157.       )
  158.     )
  159.     (setq m (+ m 1))
  160.   )
  161. )

  162. ;;;选择锁定
  163. (defun ll (/ n m e_ss e)
  164.   (setvar "cmdecho" 0)
  165.   (command "_.undo" "be")
  166.   (prompt "\n选择需要锁定的图层上的对象:")
  167.   (if (setq e_ss (ssget))
  168.     (progn (setq n (sslength e_ss))
  169.      (setq m 0)
  170.      (while (/= m n)
  171.        (setq e (ssname e_ss m))
  172.        (lockl e)
  173.        (setq m (+ m 1))
  174.      )
  175.     )
  176.   )
  177.   (command "_.undo" "e")
  178.   (setvar "cmdecho" 1)
  179. )
  180. ;;;选择解锁
  181. (defun ul (/ n m e_ss e)
  182.   (setvar "cmdecho" 0)
  183.   (command "_.undo" "be")
  184.   (prompt "\n选择需要解锁的图层上的对象:")
  185.   (if (setq e_ss (ssget))
  186.     (progn (setq n (sslength e_ss))
  187.      (setq m 0)
  188.      (while (/= m n)
  189.        (setq e (ssname e_ss m))
  190.        (unlock e)
  191.        (setq m (1+ m))
  192.      )
  193.     )
  194.   )
  195.   (command "_.undo" "e")
  196.   (setvar "cmdecho" 1)
  197. )

  198. ;;;全部解锁
  199. (defun ull ()
  200.   (laytab)
  201.   (setvar "cmdecho" 0)
  202.   (command "_.undo" "be")
  203.   (unall)
  204.   (command "_.undo" "e")
  205.   (setvar "cmdecho" 1)
  206. )
  207. ;;;单选解锁反锁
  208. (defun lul ()
  209.   (setvar "cmdecho" 0)
  210.   (command "_.undo" "be")
  211.   (if (setq e (car (entsel "\n选择需要编辑的图层上的对象:")))
  212.     (progn
  213.       (laytab)
  214.       (unall)
  215.       (locks e)
  216.     )          ;必须要先全部解开,不能只解开选定层,否则无法保存其他层的颜色信息
  217.   )
  218.   (command "_.undo" "e")
  219.   (setvar "cmdecho" 1)
  220. )
  221. ;;;;;定义操作
  222. (defun c:lay (/ code layname laycolor layltype laylst)
  223.   (initget "S L U UU")
  224.   (setq  code
  225.    (getkword
  226.      "\n单选反锁(S)<默认>/锁定指定层(L)/单独解锁一层(U)/全部解锁(UU)"
  227.    )
  228.   )
  229.   (cond  ((= code "L") (LL))
  230.   ((= code "U") (UL))
  231.   ((= code "UU") (ULL))
  232.   ((= code "S") (LUL))
  233.   ((LUL))
  234.   )
  235.   (princ)
  236. )

  237. ;;;程序结束

评分

参与人数 1明经币 +2 收起 理由
Gu_xl + 2 赞一个!

查看全部评分

本帖被以下淘专辑推荐:

  • · 学习|主题: 95, 订阅: 7
  • · 收集|主题: 58, 订阅: 4
发表于 2014-3-7 08:18 | 显示全部楼层
支持楼主
可在程序中加入“(command "_.regen")”一行
发表于 2014-3-7 08:54 | 显示全部楼层
本帖最后由 lz123456 于 2014-3-7 09:04 编辑

单选反锁,  单独解锁一层(U),
这个最好是搞成框选反锁,解锁,点选效率不高
发表于 2014-3-7 09:30 | 显示全部楼层
楼主有几个问题
1.就那选择锁定指定层后,全部解锁不能恢复颜色,必须每个单独解锁才能恢复颜色
2.那默认的反锁,把图中原来关闭的层自动打开了,
 楼主| 发表于 2014-3-7 09:55 | 显示全部楼层
yzr2002626 发表于 2014-3-7 09:30
楼主有几个问题
1.就那选择锁定指定层后,全部解锁不能恢复颜色,必须每个单独解锁才能恢复颜色
2.那默认 ...

试了一下,好像不存在你说的问题呀。锁定和解锁功能是正常的,另外程序不涉及开关图层,关闭的图层不会受影响
 楼主| 发表于 2014-3-7 10:02 | 显示全部楼层
lz123456 发表于 2014-3-7 08:54
单选反锁,  单独解锁一层(U),
这个最好是搞成框选反锁,解锁,点选效率不高

呵呵,这个我是根据我工作需要来的,框选的话,需要多按一次键盘
发表于 2014-3-7 10:06 | 显示全部楼层
用的是你最初的那程序,现在的没问题。只是解锁的时候最好是能多选。有时候框选锁定要多选几次才行(选择的东西包含块,线,字的时候)
 楼主| 发表于 2014-3-10 17:45 | 显示全部楼层
yzr2002626 发表于 2014-3-7 10:06
用的是你最初的那程序,现在的没问题。只是解锁的时候最好是能多选。有时候框选锁定要多选几次才行(选择的 ...

修改了1楼的程序全文。
现在解锁的时候也可以多选了。
另外,原来单选反锁之后,再选择锁定,会因为图层已锁不能修改而报错,现在增加了判断语句,不会报错了。

现在,单选反锁的时候,只修改层颜色,由于没有遍历所有对象,不能把颜色为不随层的对象也改成灰色,比如标注中的文字。
发表于 2014-3-10 20:46 | 显示全部楼层
本帖最后由 llsheng_73 于 2014-3-10 21:22 编辑

图层也可以直接用ENTMOD来修改的
(setq la(entget(tblobjname "layer" "0")))
(entmod(subst(cons 70 (+(cdr(assoc 70 la))4))(assoc 70 la)la))如果图层0本来是锁定的,它会开锁,反之进行锁定
这个比较奇怪,它不需要逆运算

 楼主| 发表于 2014-3-13 15:44 | 显示全部楼层
llsheng_73 发表于 2014-3-10 20:46
图层也可以直接用ENTMOD来修改的
(setq la(entget(tblobjname "layer" "0")))
(entmod(subst(cons 70 (+( ...

请问,有没有类似的针对层对象的命令,即vla命令
我程序里面都是转成层对象操作的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-5-2 03:12 , Processed in 0.262660 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表