kozmosovia 发表于 2024-10-3 12:05:22

两个vlax-for处理全图

本帖最后由 kozmosovia 于 2024-10-3 12:07 编辑

很多时候遇到需要处理全图,往往都是先ssget "_x"再循环选择集一一处理,遇到图块了,还要考虑块内是否有嵌套块,有的话还得递归进行处理,同时,如果同一个名字的图块有很多个参照,循环处理中如果不做标记,还会重复处理N多次,严重拉长程序执行时间。这样的代码写下来非常长,而且逻辑非常绕。
遇到这种需求的处理,可以参考DBX的方式,DBX中是没有选择的,直接遍历数据库,而且无论模型还是布局,自身都是一个特殊的块,因此,直接遍历块表内每一个图块定义记录即可实现更加快速的全图,而且完全不用考虑块内有嵌套这个让初学者十分烧脑的处理。
最精简的处理方式,直接
(vlax-for blk (vla-get-blocks(vla-get-activedocument (vlax-get-acad-object)))
(vlax-for vlo      blk
    图元处理代码,如果需要过滤,不如只处理某个名字的图块或者只处理某类实体,可以先添加判断再处理
)
)
两个嵌套的vlax-for就能快速架构处理全图的程序,不但不需要任何用户交互,而且VL代码执行速度很多时候比AL还快。

kozmosovia 发表于 2024-10-3 17:10:43

编程是一个整体综合的选择,如果要处理全图,有不想过多受到图块定义的影响。尤其是处理其他人画的图时,很难保证绘图习惯和规则能满足程序的一些基础要求。同时,考虑很多种的情况,也就意味着需要大量的编程以及调试时间,整体效率算下来,直接一股脑处理块表可能代码更简单,即便运行时可能须要更多时间,但是相比为编程、调试程序所花的时间,还是直接处理要更效率和简单。跟AI一样,当算力足够时,直接力大拍砖就行,不必花时间适配各种情况。

xj6019 发表于 2024-10-3 12:14:52

这样全图扫一遍,有需要过滤的时候不如ssget的过滤快,大批量处理的时候可能有优势,小批量处理,而且图很大的情况下,这个办法其实挺卡的

dcl1214 发表于 2024-10-3 14:46:58

不要用递归,递归很耗时的,双倍耗时

你有种再说一遍 发表于 2024-10-3 14:57:04

本帖最后由 你有种再说一遍 于 2024-10-17 02:24 编辑

两个for本质还是O(n^2).
其实遍历全图这种操作本身就是禁止的才对,
所谓的开发不规范,亲人两行泪...

获取同名块:
https://www.cnblogs.com/JJBox/p/16002267.html#_lab2_1_1

如果非要遍历全图,像是处理合并图层这类的任务,也会被分解在开图构造索引,然后通过索引进行合并.
那么多年来都没有人摸清楚acad索引构造,确实是力没有往同一个地方使.

DBX没有select是因为还没有制作索引.
1,反序列化数据库,DBX
2,构造索引(map,有序数组,二叉树,四叉树,八叉树)
3,通过索引进行选择(查)
4,绘图过程中就是维护索引(增删改)
5,序列化,通常序列化是有序的.
因为节省内存的操作是通过mmap不断读取和写入磁盘的数据块.这样读取可以不用排序,直接利用二分法查找.
不过dwg可能并非这样操作,我看开源dwg工程都是制作一系列map,map是无序的O(1).


gzcsun 发表于 2024-10-3 15:05:11

xj6019 发表于 2024-10-3 12:14
这样全图扫一遍,有需要过滤的时候不如ssget的过滤快,大批量处理的时候可能有优势,小批量处理,而且图很 ...

是的。
只是全选择是最快的,但只能一个一个的处理,是最慢的。
如果图很大,块不多,速度快。
如果图不大,块多,速度慢。

wzg356 发表于 2024-10-3 18:40:55

能用ssget就快了不少,我测试过许多种方式了
页: [1]
查看完整版本: 两个vlax-for处理全图