timmy521 发表于 2024-7-24 20:56:12

如何快速获取选择集图层列表

现在做法是,获取选择集,然后判断选择集中每一个对象的图层,形成图层名称列表,然后再去掉重复图层,最终形成选择集图层列表。 选择集中其实有好多对象全是同一层的,如果每个都判断一下,就太慢了。各位大神有没有好方法,一下能获取选择集对象 的图层列表?

自贡黄明儒 发表于 2024-7-25 09:03:48

这是另一办法,也许行

(defun LayerList1 (/ L)
(while (setq d (tblnext "layer" (null d)))
    (setq L (cons (cdr (assoc 2 d)) L))
)
)
(defun wmg-ssgetp1 (ss filter)
(vl-cmdf "_.select" ss "")
(ssget "p" filter)
)

(defun C:t1 (/ L SS)
(setq ss (ssget))
(foreach layer (LayerList1)
    (if        (wmg-ssgetp1 ss (list (cons 8 layer)))
      (setq L (cons layer L))
    )
)
L
)

liuhe 发表于 2024-7-25 08:25:22

本帖最后由 liuhe 于 2024-7-25 08:39 编辑

你应该直接上代码和图纸,而不是简单描述,大概率是你写法问题,即使你思路是正确的



(DEFUN C:FOO (/ SS I LST E LAY )
(SETQ SS (SSGET "X"))
(IF (NOT SS)
    (VL-EXIT-WITH-VALUE 0)
)
(SETQ      I   0
      LST NIL
)
(REPEAT (SSLENGTH SS)
    (SETQ E   (SSNAME SS I)
          LAY (CDR (ASSOC 8 (ENTGET E)))
          LST (VL-REMOVE LAY LST)
          LST (CONS LAY LST)
          I   (1+ i)
    )
)
(PRINC )
)

5W个图形仍然很快,176w个图形感觉会有点卡

你有种再说一遍 发表于 2024-7-24 21:06:16

本帖最后由 你有种再说一遍 于 2024-7-25 02:07 编辑

并不是每个都判断一下很慢,而是判断的方式问题,
写lisp的人没有注意到,
很多时候写了双for去比较数据,或者调用remove-if,
你怎么知道这个remove-if是双for还是排序后剔除,还是词典呢?它的时间复杂度...


然后这个循环还不能中断,
在其他语言则不是,其他语言的优点:
1,数组array能够通过index,这是CPU寻址速度,嘎嘎快.
2,循环可以break.
3,数据结构可以O(1)速度.
4,处理图元不是每个都启动事务,能够更快的进行数据路由.


消重不应该是全部加入集合再剔除,而是加入时候剔除,
例如使用数据结构:词典或者红黑树就天然可以剔除重复项,
lisp针对第三点,可以调用vb词典:
和尚777这里就用了dictionary词典来减少时间复杂度
http://bbs.mjtd.com/thread-186202-1-1.html


词典的原理就是利用数组寻址速度,
1,计算字符串的hashcode,
2,hashcode取模,获取数组索引下标:
int index=array.length%hashcode
3,key是array获取,因为hash冲突,所以索引相同不一定内容相同,接着内部会通过equals比较.
4,如果相同的,就取出value内容,你的value是计数器int,然后++.


这也就是,lisp的终点是调用vb...vb的终点的换到c#或c++

kozmosovia 发表于 2024-7-24 22:07:55

图元数量非常大的话,可以先弄到dbx中再遍历读取图层。

timmy521 发表于 2024-7-24 22:32:42

没有学过这个东西

kozmosovia 发表于 2024-7-24 22:37:12

timmy521 发表于 2024-7-24 22:32
没有学过这个东西

找资料学一下,把图元vla-CopyObjects进dbx,然后读取DBX的图层表获取层名就行了。不需要遍历图元。顶多不确定0层是否有被包含

shirker 发表于 2024-7-25 07:40:27

学习了,支持一下
页: [1]
查看完整版本: 如何快速获取选择集图层列表