broncos15 发表于 2022-7-5 17:13:38

冻融层

我有一个快速的问题,关于如何最有效地编写我正在开发的层冻结程序。该例程的重点是冻结所有不是结构的实用程序层。我要做的就是
例如,然后用-STRC或类似的东西解冻任何东西。我这样做是因为通配符方法似乎总是比在所有层上迭代快得多。我唯一的问题是,我不想解冻一个已经冻结的层,例如,如果C-STRM-STRC被冻结。编写这部分代码的最快方法是什么?我不想做一个单独的检查,因为我们的模板文件中有数千层。我需要在开始时用wcmatch做些什么,并存储所有符合特定标准的冻结层吗?

rlx 发表于 2022-7-5 17:20:16

我发现:http://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/trying-to-freeze-layers-by-using-wildcard-layer-name/td-p/4941568
 
 



(defun c:fREV ();; to freeze
(vl-load-com)
(vlax-for layer(vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
   (if (and (wcmatch (strcase (vla-get-name layer)) "*REV*")
   (not (wcmatch (vla-get-name layer) "*|*"))
   (not (wcmatch (strcase (vla-get-name layer)) (strcase (getvar 'CLAYER))))
      )
      (vla-put-freeze layer :vlax-true)
   )
)
(princ)
)

(defun c:tREV ();; to thaw
(vl-load-com)
(vlax-for layer(vla-get-layers (vla-get-activedocument (vlax-get-acad-object)))
   (if (and (wcmatch (strcase (vla-get-name layer)) "*REV*")
   (not (wcmatch (vla-get-name layer) "*|*"))
      )
      (vla-put-freeze layer :vlax-false)
   )
)
(princ)
)



 
 
 
 
gr.Rlx

Grrr 发表于 2022-7-5 17:20:44

你好
这是一项有趣的任务。。。我的尝试是:
(while (setq LayEnx (tblnext "LAYER" (null LayEnx)))
(if (= 1 (logand 1 (cdr (assoc 70 LayEnx)))) ; layer is frozen
        (setq LstFrozenLayers (cons LayEnx LstFrozenLayers))
        (setq LstThawedLayers (cons LayEnx LstThawedLayers))
)
)

(setq match "*|C-CATV*")
(mapcar 'entupd
(mapcar
        (function
                (lambda (x)
                        (if (wcmatch (cdr (assoc 2 x)) match)
                                (cond ; I don't know how to subst the layer's elist with (logand)
                                        ((member x LstFrozenLayers)
                                                (subst (assoc 70 x) (cons 70 0) x)
                                        )
                                        ((member x LstThawedLayers)
                                                (subst (assoc 70 x) (cons 70 1) x)
                                        )
                                )
                        )
                )
        )
        (list LstFrozenLayers LstThawedLayers)
)
)
上述片段将是任务的理想情况(仅使用Vanilla LISP)。。尽管只有一个问题:
我不知道如何将层的elist与(logand)函数组合起来。
如果您不理解代码中发生了什么,让我解释一下:
1.它通过图层表进行迭代,并将图层分为两组(列表):冻结和解冻
2.然后使用lambda,我们检查每个层的匹配名称,以及它所属的组/列表(冻结或解冻)。。通过替换x层的elist,我们可以切换其冻结/解冻状态。
 
下面是我的替代建议(使用VLAX):
(while (setq ld (tblnext "LAYER" (null ld)))
(setq LayersEnxs (cons ld LayersEnxs))
)

(setq match "*|C-CATV*")
(mapcar
(function
        (lambda (x / o )
                (if (wcmatch (cdr (assoc 2 x)) match)
                        (progn ; I use VLA, because I don't know how to subst a layer's elist with (logand)
                                (vlax-put (setq o (vlax-ename->vla-object (tblobjname "LAYER" (cdr (assoc 2 x))))) 'Freeze :vlax-false)
                                (vla-update o)
                        )
                )
        )
)
(vl-remove-if-not (function (lambda (x) (= 1 (logand 1 (cdr (assoc 70 x)))))) LayersEnxs); frozen layers's elists
)
(vla-Regen (vla-get-ActiveDocument (vlax-get-acad-object)) acActiveViewport)

它用这个名字解冻冷冻层(但这种VLA方法应该比香草冰淇淋慢)。
HTH公司
顺便说一句,我喜欢在回答的同时问问题
 
编辑:这是另一个。。。
(setq match "*|C-CATV*")
(vlax-map-collection (vla-get-Layers (vla-get-ActiveDocument (vlax-get-acad-object)))
(function
        (lambda (x)
                (if
                        (and
                                (wcmatch (vla-get-name x) match)
                                (eq (vla-get-Freeze x) :vlax-true)
                        )
                        (vla-update (vlax-put x 'Freeze :vlax-false))
                )
        )
)
)
我想你明白了。。。但我真的认为,如果不迭代所有层,就无法实现它。

rlx 发表于 2022-7-5 17:25:20

我不知道当你谈论数千层时,迭代所有层需要多少时间,但是如果你在几秒钟内谈论呢。。。
 
认为c:tRev只需要额外检查一次层状态
 
但是你真的做了功课
 
gr.Rlx

Grrr 发表于 2022-7-5 17:27:05

谢谢,但像broncos15一样,我也很好奇。。。如果有人能提出基准测试,哪种迭代方法最快,因为有很多方法可以通过使用(mapcar+lambda)/(foreach)/(vlax map collection)/(vlax for)来实现。
直接访问LAYERS表/集合并在那里执行更改会更快吗,还是先创建一个包含层的列表,然后迭代该列表以执行这些更改。

rlx 发表于 2022-7-5 17:31:42

这可能会帮助您实现以下目标:http://www.cadtutor.net/forum/showthread.php?59993-帮助-操作-测试-功能速度
 
即使是我的耐心也有局限性,但如果成功了,它也会成功,而且。。。下一次,你的老板认为你能以超快的速度做任何事情,所以速度并不总是一件好事;-)
 
gr.Rlx
 
下面是另一个讨论:https://www.theswamp.org/index.php?topic=45954.0

rlx 发表于 2022-7-5 17:34:53

检查速度的简单方法可以通过vl-times完成
 
参见此示例http://www.cadtutor.net/forum/showthread.php?95337-使用来自块attribute的信息批量重命名(&highlight=RlxReadTitleBlock)
 
在函数开始时,输入以下内容:

(defun bladiebla ()
(setq start (car(_vl-times)))
;do your stuff
;;;for testing
(princ (strcat "\n\nProcessed" (itoa (length filelist)) " drawings in "
         (rtos (/ (- (car (_VL-TIMES)) start) 1000.) 2 4) " secs."))



 
Gr.Rlx

BIGAL 发表于 2022-7-5 17:38:43

如果你在看秒,然后你在看错误的任务来提高,我做了一些事情,其他人花了大约10分钟来画,Lisp程序替换2秒,可惜我从来没有得到它的付款。
 
Rlx我同意“如果可行,就可行”。

Roy_043 发表于 2022-7-5 17:42:18

@broncos15:
在某些情况下,一个聪明的wcmatch字符串可以做到这一点。
这将解冻名称以“NewLayer”开头的所有层,但以“NewLayer2”开头的层除外(匹配不区分大小写)。

Lee Mac 发表于 2022-7-5 17:46:30

FWIW,这里有另一种使用香草的方法:
(defun c:myfreeze ( / cla dxf enx lay )
   (setq cla (getvar 'clayer))
   (while (setq lay (tblnext "layer" (not lay)))
       (setq lay (cdr (assoc 2 lay)))
       (and (wcmatch lay "*|C-CATV*")
            (wcmatch lay "~*-STRC")
            (/= cla lay)
            (setq enx (entget (tblobjname "layer" lay))
                  dxf (assoc 70 enx)
            )
            (entmod (subst (cons 70 (boole 7 1 (cdr dxf))) dxf enx))
       )
   )
   (princ)
)
页: [1] 2
查看完整版本: 冻融层