找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 4374|回复: 29

[原创]:高效的合并直线程序,敬请使用。

[复制链接]
发表于 2004-5-25 10:52:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我在http://www.xdcad.net/forum/showthread.php?s=&postid=434934贴了一个关于合并直线的程序,它的功能是合并相互重叠或首尾相接的直线,后来在实际使用过程中发现,如果选中的实体过多时(500个以上),处理速度会很慢。近几天,我修改了处理方式,速度大幅度提升,一次50000个以上的实体,速度仍然能够接受。
另外还增加了两个功能,一是只能将相同图层的直线合并,二是增加了进度的显示。
欢迎各位使用,并提出宝贵意见,不收钱了。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
发表于 2004-5-25 12:00:53 | 显示全部楼层
这个函数ACET-UI-PROGRESS没有定义
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-5-25 13:03:25 | 显示全部楼层
需要安装ET工具
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-25 15:51:08 | 显示全部楼层
请问加载后如何调用。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-5-26 07:41:43 | 显示全部楼层
加载后有提示啊,用HBZHX调用
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-27 14:19:00 | 显示全部楼层
能否提供源碼交流,願交換自己開發的LISP
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-5-27 14:26:24 | 显示全部楼层
最初由 harrywang77 发布
[B]能否提供源碼交流,願交換自己開發的LISP [/B]

  1.   [FONT=courier new]
  2. (defun c:hbzhx (/ ss ss1 ss2 ss3 ss4 sslay item        p1 p2 xuhao zongshu
  3.                 ssbak step)
  4.   (cond
  5.     ((and
  6.        (setq ss (ssget (list (cons 0 "LINE"))))
  7.        (> (sslength ss) 1)
  8.      )
  9.      (setq ss (ss->list ss))
  10.      (setq zongshu (/ 100.0 (length ss)))
  11.      (setq xuhao 0
  12.            step        1
  13.      )
  14.      (acet-ui-progress "已经完成" 100)
  15.      (setq ssbak ss)
  16.      (while (> (length ss) 0)
  17.        (setq ss1 (car ss)
  18.              ss         (vl-remove ss1 ss)
  19.        )
  20.        (setq xuhao (+ xuhao zongshu))
  21.        (if (= (fix xuhao) step)
  22.          (progn
  23.            (acet-ui-progress -1)
  24.            (setq step (1+ step))
  25.          )
  26.        )
  27.        (vla-GetBoundingBox (vlax-ename->vla-object ss1) 'p1 'p2)
  28.        (setq p1        (vlax-safearray->list p1)
  29.              p2        (vlax-safearray->list p2)
  30.        )
  31.        (setq sslay (vla-get-layer (vlax-ename->vla-object ss1)))
  32.        (setq
  33.          ss3 (ssget "c" p1 p1 (list (cons 0 "LINE") (cons 8 sslay)))
  34.        )
  35.        (setq
  36.          ss4 (ssget "c" p2 p2 (list (cons 0 "LINE") (cons 8 sslay)))
  37.        )
  38.        (setq ss3 (ss->list ss3))
  39.        (setq ss3 (vl-remove ss1 ss3))
  40.        (setq ss4 (ss->list ss4))
  41.        (setq ss4 (vl-remove ss1 ss4))
  42.        (foreach        item ss4
  43.          (setq ss3 (cons item ss3))
  44.        )
  45.        (while (> (length ss3) 0)
  46.          (setq ss2 (car ss3)
  47.                ss3 (vl-remove ss2 ss3)
  48.          )
  49.          (if (and
  50.                (member ss2 ssBAK)
  51.                (hbline ss1 ss2)
  52.              )
  53.            (progn
  54.              (setq ss (vl-remove ss2 ss))
  55.              (setq xuhao (+ xuhao zongshu))
  56.              (if (= (fix xuhao) step)
  57.                (progn
  58.                  (acet-ui-progress -1)
  59.                  (setq step (1+ step))
  60.                )
  61.              )
  62.              (entdel ss2)
  63.            )
  64.          )
  65.        )
  66.      )
  67.      (acet-ui-progress)
  68.     )
  69.     (t nil)
  70.   )
  71.   (princ)
  72. )
  73. (defun ss->list        (ss / cs_i out)
  74.   (if (= (type ss) 'PICKSET)
  75.     (progn
  76.       (setq cs_i 0.0
  77.             out         '()
  78.       )
  79.       (repeat (sslength ss)
  80.         (setq out (cons (ssname ss cs_i) out))
  81.         (setq cs_i (1+ cs_i))
  82.       )
  83.       (setq out (reverse out))
  84.     )
  85.   )
  86. )
  87. (defun hbline (ent_line1         ent_line2           /            ent_data1
  88.                ent_data2         pt          p1           p2            p3
  89.                p4        dis1         dis2          dis3           dis4            dis
  90.               )
  91.   (setq        ent_data1 (entget ent_line1)
  92.         ent_data2 (entget ent_line2)
  93.         p1          (cdr (assoc 10 ent_data1))
  94.         p2          (cdr (assoc 11 ent_data1))
  95.         p3          (cdr (assoc 10 ent_data2))
  96.         p4          (cdr (assoc 11 ent_data2))
  97.         dis          (distance p1 p2)
  98.         dis1          (distance p1 p3)
  99.         dis2          (distance p2 p3)
  100.         dis3          (distance p1 p4)
  101.         dis4          (distance p2 p4)
  102.   )
  103.   (if (and
  104.         (equal (+ dis dis1 dis2)
  105.                (* 2.0 (max dis dis1 dis2))
  106.                0.000001
  107.         )
  108.         (equal (+ dis dis3 dis4)
  109.                (* 2.0 (max dis dis3 dis4))
  110.                0.000001
  111.         )
  112.       )
  113.     (progn
  114.       (if (or (equal 90.0 (rtod (angle p1 p2)) 20)
  115.               (equal 270 (rtod (angle p1 p2)) 20)
  116.           )
  117.         (setq pt
  118.                (vl-sort        (list p1 p2 p3 p4)
  119.                         (function (lambda (e1 e2) (< (cadr e1) (cadr e2))))
  120.                )
  121.         )
  122.         (setq pt
  123.                (vl-sort        (list p1 p2 p3 p4)
  124.                         (function (lambda (e1 e2) (< (car e1) (car e2))))
  125.                )
  126.         )
  127.       )
  128.       (setq p1              (cons 10 (car pt))
  129.             p2              (cons 11 (nth 3 pt))
  130.             ent_data1 (subst p1 (assoc 10 ent_data1) ent_data1)
  131.             ent_data1 (subst p2 (assoc 11 ent_data1) ent_data1)
  132.       )
  133.       (entmod ent_data1)
  134.     )
  135.   )
  136. )
  137. (defun rtod (dat /)
  138.   (* 180.0 (/ dat pi))
  139. )
  140. (princ "\n本程序由李蛟编写,功能是合并相同图层里的首尾相接或重叠的直线,用HBZHX调用。")
  141. (princ)
  142.   [/FONT]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-28 19:20:46 | 显示全部楼层

很好用啊

很好用啊
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-5-31 01:38:15 | 显示全部楼层
50000个实体可以接受?!
多少时间.

光50000下(vla-GetBoundingBox (vlax-ename->vla-object ss1)时间就多少?
还有10万次的ssget
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-5-31 07:45:27 | 显示全部楼层
不对,实际上没有那么多的次数,因为在处理过程中有很大一部分被合并了。
如果50000个实体全部是首尾相接,大约只有30000多次SSGET。
至于时间,可能有点夸张,因为我的机器配置比较高(图形工作站),速度还可以;另外,处理时间还与实体的位置关系有关。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2004-5-31 13:07:46 | 显示全部楼层
最初由 lijiao 发布
[B]不对,实际上没有那么多的次数,因为在处理过程中有很大一部分被合并了。
如果50000个实体全部是首尾相接,大约只有30000多次SSGET。
至于时间,可能有点夸张,因为我的机器配置比较高(图形工作站),速度还可以?.. [/B]

这样修改下
[php]
(defun isOn (pt e)
  (equal (vlax-curve-getclosestpointto e pt)
         pt
         1e-5
  )
)
(defun hbline (ln1 ln2 / tf p0 p00 p1 p2 p3 p4)
  (setq        p1   (vlax-curve-getstartpoint ln1)
        p2   (vlax-curve-getendpoint ln1)
        p3   (vlax-curve-getstartpoint ln2)
        p4   (vlax-curve-getendpoint ln2)
        elst (entget ln1)
  )
  (if (or (ison p3 ln1)
          (ison p4 ln1)
          (ison p1 ln2)
          (ison p2 ln2)
      )
    (progn
      (setq pl (vl-sort        (list p1 p2 p3 p4)
                        '(lambda (e1 e2)
                           (if (equal (car e1) (car e2) 1e-5)
                             (< (cadr e1) (cadr e2))
                             (< (car e1) (car e2))
                           )
                         )
               )
      )
      (setq elst (subst (cons 10 (car pl)) (assoc 10 elst) elst)
            elst (subst (cons 11 (last pl)) (assoc 11 elst) elst)
      )
      (entmod elst)
      (entdel ln2)
    )
  )
  (princ)
)
(defun c:hbzhx (/ a ang e e1 el ep oldlst sp ss ssl)
  (if (setq ss (ssget '((0 . "line"))))
    (progn
      (command ".undo" "g")
      (setq ssl (sslength ss))
      (while (> ssl 0)
        (setq e          (ssname ss (setq ssl (1- ssl)))
              sp  (vlax-curve-getstartpoint e)
              ep  (vlax-curve-getendpoint e)
              ang (angle sp ep)
        )
        (if (>= ang pi)
          (setq ang (read (rtos (- ang pi) 2 4)))
          (setq ang (read (rtos ang 2 4)))
        )
        (if (not el)
          (setq el (list (list ang e)))
          (if (setq oldlst (assoc ang el))
            (setq el (subst (append oldlst (list e))
                            oldlst
                            el
                     )
            )
            (setq el (append el (list (list ang e))))
          )
        )
      )
      ;;将直线按角度划分
      (foreach i (mapcar 'cdr el)
        (if (> (length i) 1)
          (progn
            (while i
              (setq e1 (car i))
              (setq i (cdr i))
              (mapcar '(lambda (a)
                         (if (and (not (vlax-erased-p e1))
                                  (not (vlax-erased-p a))
                             )
                           (hbline e1 a)
                         )
                       )
                      i
              )
            )
          )
        )
      )
      (command ".undo" "e")
    )
  )
  (princ)
)
(princ)

[/php]
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2004-5-31 13:25:51 | 显示全部楼层
不错,有点用
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-5-31 14:45:07 | 显示全部楼层
[QUOTE]最初由 eachy 发布
[B][QUOTE]
刚测试了一下版主的代码和我提供的代码,处理实体16000个水平直线,我的代码耗时89秒,版主的代码耗时350秒。
我觉得提高效率的关键是如何减少循环次数。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 593个

财富等级: 财运亨通

发表于 2004-5-31 14:48:51 | 显示全部楼层
最初由 lijiao 发布
[B][QUOTE]最初由 eachy 发布
[B][QUOTE]
刚测试了一下版主的代码和我提供的代码,处理实体16000个水平直线,我的代码耗时89秒,版主的代码耗时350秒。
我觉得提高效率的关键是如何减少循环次数。 [/B]

把你的测试图发上来看看,整 16000 个线也麻烦。

重新修改,比上次提高了很多。还可以在 合并部分优化,有的直接entdel,不用vl-sort。

  1. ;;点是否在曲线上
  2. (defun isOn (pt e)
  3.   (equal (vlax-curve-getclosestpointto e pt)
  4.          pt
  5.          1e-5
  6.   )
  7. )
  8. ;;合并两个直线,不考虑图层
  9. (defun hbline (ln1 ln2 / elst pl tf p0 p00 p1 p2 p3 p4)
  10.   (setq        p1   (vlax-curve-getstartpoint ln1)
  11.         p2   (vlax-curve-getendpoint ln1)
  12.         p3   (vlax-curve-getstartpoint ln2)
  13.         p4   (vlax-curve-getendpoint ln2)
  14.         elst (entget ln1)
  15.   )
  16.   (if (or (ison p3 ln1)
  17.           (ison p4 ln1)
  18.           (ison p1 ln2)
  19.           (ison p2 ln2)
  20.       )
  21.     (progn
  22.       (setq pl (vl-sort        (list p1 p2 p3 p4)
  23.                         '(lambda (e1 e2)
  24.                            (if (equal (car e1) (car e2) 1e-5)
  25.                              (< (cadr e1) (cadr e2))
  26.                              (< (car e1) (car e2))
  27.                            )
  28.                          )
  29.                )
  30.       )
  31.       (setq elst (subst (cons 10 (car pl)) (assoc 10 elst) elst)
  32.             elst (subst (cons 11 (last pl)) (assoc 11 elst) elst)
  33.       )
  34.       (entmod elst)
  35.       (entdel ln2)
  36.       ln2
  37.     )
  38.   )
  39. )
  40. (defun c:hbzhx (/ a ang e e1 el ep oldlst sp ss ssl l i1)
  41.   (if (setq ss (ssget '((0 . "line"))))
  42.     (progn
  43.       (command ".undo" "g")
  44.       ;;(command ".time" "r" "on" "d" "")
  45.       (setq ssl (sslength ss))
  46.       (while (> ssl 0)
  47.         (setq e          (ssname ss (setq ssl (1- ssl)))
  48.               sp  (vlax-curve-getstartpoint e)
  49.               ep  (vlax-curve-getendpoint e)
  50.               ang (angle sp ep)
  51.         )
  52.         (if (>= ang pi)
  53.           (setq ang (read (rtos (- ang pi) 2 4)))
  54.           (setq ang (read (rtos ang 2 4)))
  55.         );精度
  56.         (if (not el)
  57.           (setq el (list (list ang e)))
  58.           (if (setq oldlst (assoc ang el))
  59.             (setq el (subst (append oldlst (list e))
  60.                             oldlst
  61.                             el
  62.                      )
  63.             )
  64.             (setq el (append el (list (list ang e))))
  65.           )
  66.         )
  67.       )                                        ;将直线按角度划分
  68.       (setq el (mapcar 'cdr el))
  69.       (foreach i el
  70.         (if (> (length i) 1)
  71.           (progn
  72.             (while i
  73.               (setq e1 (car i))
  74.               (setq i  (cdr i)
  75.                     i1 i
  76.               )
  77.               (while i1
  78.                 (setq a         (car i1)
  79.                       i1 (cdr i1)
  80.                 )
  81.                 (if (and (not (vlax-erased-p e1))
  82.                          (not (vlax-erased-p a))
  83.                     );这个判断似乎可以省掉
  84.                   (if (setq l (hbline e1 a))
  85.                     (setq i (vl-remove l i)) ;减少第一次的循环
  86.                   )
  87.                 )
  88.               )
  89.             )
  90.           )
  91.         )
  92.       )
  93.       ;;(command ".time" "d" "")
  94.       (command ".undo" "e")
  95.     )
  96.   )
  97.   (princ)
  98. )
  99. (princ)
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 488个

财富等级: 日进斗金

发表于 2004-5-31 23:36:51 | 显示全部楼层
最初由 eachy 发布
[B][QUOTE]最初由 lijiao 发布
[B][QUOTE]最初由 eachy 发布
[B][QUOTE]
刚测试了一下版主的代码和我提供的代码,处理实体16000个水平直线,我的代码耗时89秒,版主的代码耗时350秒。
我觉得提高效率... [/B]



(if (>= ang pi)
          (setq ang (read (rtos (- ang pi) 2 4)))
          (setq ang (read (rtos ang 2 4)))
        );
我们对付float,一般是equal,你这样写其实是"精确"了
比如 1.22222 1.22225,不在一起.
   我曾经把1.22,用1.22 1.23 1.21三次assoc,速度不理想。
上面其实不要read, 字符用作索引更好.
  assoc 表长了也挺慢的,再subst ,其实找两遍.


(repeat  3(assoc "6" lst))  ;;lst中要没"6",不然"6"在开头就不好说了
  lst : 1000长的表(3遍,表中没这东东) 0.21秒
lst:  2000长的表 (3遍,表中没这东东) 0.8秒
次数多了,时间可观,表的长度是个关键.



还有合并两线,一重合就entmod,好象次数也多了,不过entmod速度很快.
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2025-9-28 07:00 , Processed in 0.371741 second(s), 61 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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