非递归模式获取块中深度嵌套的图元
本帖最后由 dcl1214 于 2024-12-22 21:42 编辑块中块深度嵌套的时候,要想获取块中所有图元,很多同仁一开始就想到递归,其实我是比较抵触递归的,所以,随手写了一个非递归模式获取块中块图元的代码,哪位还有速度更快的(块中块深度嵌套很多),可以一起切磋一下
请下载vlx测试,速度极快
(defun $kuai-nei-tu-yuan$ (ENT-B lst / $kn-objs$ a blks e ents-all obj)
;非递归模式获取块内图元
(defun $kn-objs$ (ENT-B / a blk ents km obj)
(if
(= (TYPE ENT-B) 'ENAME)
(SETQ OBJ (vlax-ename->vla-object ENT-B))
)
(IF(and OBJ (= (type obj) 'VLA-object))
(if (vlax-property-available-p obj 'effectivename)
(setq km (vla-get-effectivename obj))
(if (vlax-property-available-p obj 'name)
(setq km (vla-get-name obj))
)
)
)
(setq blk (vl-catch-all-apply
'vla-item
(list (vla-get-blocks
(vla-get-activedocument
(vlax-get-acad-object)
)
)
km
)
)
)
(ifblk
(vlax-fora blk
(setq ents (cons a ents))
);遍历blk对象
)
ents
)
(setq ents-all nil)
(setq obj nil)
(setq blks ($kn-objs$ ENT-B));块中obj对象
(while (setq obj (car blks));循环第一个obj
(setq e nil)
(setq e (vlax-vla-object->ename obj));转换为图元
(if(= (vla-get-objectname obj) "AcDbBlockReference");如果是块对象
(setq blks (append blks ($kn-objs$ e)));获取块中obj对象,拼接到blks尾巴上
(setq ents-all (cons e ents-all));如果不是块对象就收集到ents-all里面,下面要返回给上一级
)
(setq blks (cdr blks));下一个obj对象
)
(setq ents-all (reverse ents-all));倒置
ents-all
)
;;; 示例
(setq ent-b (car (entsel)))
(setq ents ($kuai-nei-tu-yuan$ ent-b nil))
(mapcar(function
(lambda (a)
(vl-catch-all-apply
'vla-put-color
(list
(vl-catch-all-apply 'vlax-ename->vla-object (list a))
1
)
)
)
)
ents
)
本帖最后由 你有种再说一遍 于 2024-12-22 17:16 编辑
我也有一段时间跟你一样觉得,
既然递归会爆栈,那么全改循环不就好了,后来发现其实不然.
如果不喜欢递归,这通常对于编译器的信心不足引起的,
因为尾递归优化是可以消除新栈帧的,
而且存入堆容器再拿出来,比起开辟栈帧再拿出来效率更低,
所以其实建议是多写递归,尤其是尾递归,
毕竟有成千上万的人来实现编译器优化,就连Lisp内部也会做的. 这样获取出来的图元列表没有任何用途,块内定义的图形,其parent都是各自上层块定义,一堆父亲不一样的图元弄到一个列表里,你咋做下一步处理?有啥实际需求要做这种处理?同时,同名的图块如果嵌套在不同的层次,或者同一个层级有若干同名图块,会返回一堆图形重复,都混合在一个表里,这种垃圾数据表有存在的意义吗? 本帖最后由 wudechao 于 2024-12-22 13:10 编辑
有bug.但是速度很快,我用在关闭图块所有图层(建筑提资的图,很多块中块,比如想关闭某些块,这些块是块中块),先获取图块所有图元,取块中每个图元的图层,消重复图层,最后逐个关闭图层,速度非常快,比我原来用递归快一倍。反复执行这个函数,就出现错误,不知道是什么原因。 本帖最后由 ssyfeng 于 2024-12-22 13:56 编辑
你有种再说一遍 发表于 2024-12-21 23:05
我也有一段时间跟你一样觉得,
然后递归会爆栈,那么全改循环不就好了,
后来发现其实不然.
确实尾递归比其它递归要快一倍,比楼主的也稍微快一点 wudechao 发表于 2024-12-22 12:16
有bug.但是速度很快,我用在关闭图块所有图层(建筑提资的图,很多块中块,比如想关闭某些块,这些块是块中 ...
这种需求,直接用DBX比这种递归快n倍,尤其是大图。 kozmosovia 发表于 2024-12-22 11:30
这样获取出来的图元列表没有任何用途,块内定义的图形,其parent都是各自上层块定义,一堆父亲不一样的图元 ...
我编译成【独立空间】了,提速9000倍 ssyfeng 发表于 2024-12-22 13:31
确实尾递归比其它递归要快一倍,比楼主的也稍微快一点
下载我的vlx试试,我编译成【独立空间】了,提速9000倍 同一个图元重复处理无数次,有什么意义? 根本不存在快不快的概念,同一图元重复处理无数次,本身就是慢的方案,CAD数据库块里只有参照,不存在多层的概念,块参照就是一个图元,n个参照的图元数量就只有块内图元数量+n,而并不是块内图元数量*n
页:
[1]
2