明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 12359|回复: 33

批量交点打断 支持多段线 <转帖>

    [复制链接]
发表于 2012-5-23 11:17 | 显示全部楼层 |阅读模式
  1. ;;;=======================[ BreakObjects.lsp ]==============================
  2. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3. ;;               M A I N   S U B R O U T I N E                  
  4. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  5. (defun break_with (ss2brk ss2brkwith self / cmd intpts lst masterlist ss ssobjs
  6.                    onlockedlayer ssget->vla-list list->3pair
  7.                    get_interpts break_obj
  8.                   )
  9.   ;; ss2brk     selection set to break
  10.   ;; ss2brkwith selection set to use as break points
  11.   ;; self       when true will allow an object to break itself
  12.   ;;            note that plined will break at each vertex
  13.   (vl-load-com)

  14. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  15. ;;                S U B   F U N C T I O N S                     
  16. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  17.   (defun onlockedlayer (ename / entlst)
  18.     (setq entlst (tblsearch "LAYER" (cdr (assoc 8 (entget ename)))))
  19.     (= 4 (logand 4 (cdr (assoc 70 entlst))))
  20.   )
  21.   
  22.   (defun ssget->vla-list (ss / i ename lst)
  23.     (setq i -1)
  24.     (while (setq ename (ssname ss (setq i (1+ i))))
  25.       (setq lst (cons (vlax-ename->vla-object ename) lst))
  26.     )
  27.     lst
  28.   )
  29.   (defun list->3pair (old / new)
  30.     (while (setq new (cons (list (car old) (cadr old) (caddr old)) new)
  31.                  old (cdddr old))
  32.     )
  33.     (reverse new)
  34.   )
  35.   
  36. ;;==============================================================
  37. ;;  return a list of intersect points
  38. ;;==============================================================
  39. (defun get_interpts (obj1 obj2 / iplist)
  40.   (if (not (vl-catch-all-error-p
  41.              (setq iplist (vl-catch-all-apply
  42.                             'vlax-safearray->list
  43.                             (list
  44.                               (vlax-variant-value
  45.                                 (vla-intersectwith obj1 obj2 acextendnone)
  46.                               ))))))
  47.     iplist
  48.   )
  49. )

  50. ;;==============================================================
  51. ;;  Break entity at break points in list
  52. ;;==============================================================
  53. (defun break_obj (ent brkptlst / brkobjlst en enttype maxparam closedobj
  54.         minparam obj obj2break p1param p2 p2param
  55.    )
  56.   (setq obj2break ent
  57. brkobjlst (list ent)
  58. enttype (cdr (assoc 0 (entget ent)))
  59.   )
  60.   (foreach brkpt brkptlst        ;  get last entity created via break
  61.            ; in case multiple breaks
  62.     (if brkobjlst
  63.       (progn          ;  if pt not on object x, switch
  64.            ; objects
  65. (if (not (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint
  66.            (list obj2break brkpt)
  67.      )
  68.    )
  69.      )
  70.    (foreach obj brkobjlst       ; find the one that pt is on
  71.      (if (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint
  72.           (list obj brkpt)
  73.     )
  74.   )
  75.        (setq obj2break obj)     ; switch objects
  76.      )
  77.    )
  78. )
  79.       )
  80.     )           ;  handle any objects that can not
  81.            ; be used with the break command
  82.            ;  using one point, gap of 0.000001
  83.            ; is used
  84.     (cond
  85.       ((and
  86.   (= "SPLINE" enttype)        ; only closed splines
  87.   (vlax-curve-isclosed obj2break)
  88.        )
  89. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
  90.        p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001))
  91. )
  92. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
  93.    (trans p2 0 1)
  94. )
  95.       )
  96.       ((= "CIRCLE" enttype)        ; break the circle
  97. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
  98.        p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001))
  99. )
  100. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
  101.    (trans p2 0 1)
  102. )
  103. (setq enttype "ARC")
  104.       )
  105.       ((and
  106.   (= "ELLIPSE" enttype)        ; only closed ellipse
  107.   (vlax-curve-isclosed obj2break)
  108.        )          ;  break the ellipse, code borrowed
  109.            ; from joe burke  6/6/2005
  110. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
  111.        p2param (+ p1param 0.000001)
  112.        minparam (min
  113.     p1param
  114.     p2param
  115.          )
  116.        maxparam (max
  117.     p1param
  118.     p2param
  119.          )
  120.        obj (vlax-ename->vla-object obj2break)
  121. )
  122. (vlax-put obj 'startparameter maxparam)
  123. (vlax-put obj 'endparameter (+ minparam (* pi 2)))
  124.       )           ; ==================================
  125.       (t          ;   objects that can be broken
  126. (setq closedobj (vlax-curve-isclosed obj2break))
  127. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
  128.    (trans brkpt 0 1)
  129. )
  130. (if (not closedobj)        ; new object was created
  131.    (setq brkobjlst (cons (entlast) brkobjlst))
  132. )
  133.       )
  134.     )
  135.   )
  136. )
  137.   
  138.   ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  139.   ;;                   S T A R T   H E R E                        
  140.   ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  141.     (if (and ss2brk ss2brkwith)
  142.     (progn
  143.       ;;  CREATE a list of entity & it's break points
  144.       (foreach obj (ssget->vla-list ss2brk) ; check each object in ss2brk
  145.         (if (not (onlockedlayer (vlax-vla-object->ename obj)))
  146.           (progn
  147.             (setq lst nil)
  148.             ;; check for break pts with other objects in ss2brkwith
  149.             (foreach intobj (ssget->vla-list ss2brkwith)
  150.               (if (and (or self (not (equal obj intobj)))
  151.                        (setq intpts (get_interpts obj intobj))
  152.                   )
  153.                 (setq lst (append (list->3pair intpts) lst)) ; entity w/ break points
  154.               )
  155.             )
  156.             (if lst
  157.               (setq masterlist (cons (cons (vlax-vla-object->ename obj) lst) masterlist))
  158.             )
  159.           )
  160.         )
  161.       )
  162.       ;;  masterlist = ((ent brkpts)(ent brkpts)...)
  163.       (if masterlist
  164.         (foreach obj2brk masterlist
  165.           (break_obj (car obj2brk) (cdr obj2brk))
  166.         )
  167.       )
  168.       )
  169.   )
  170. ;;==============================================================
  171. )
  172. (princ)

  173. ;;==========================================
  174. ;;        Break all objects selected        
  175. ;;==========================================
  176. (defun c:breakall (/ cmd ss)
  177.   (command ".undo" "begin")
  178.   (setq cmd (getvar "CMDECHO"))
  179.   (setvar "CMDECHO" 0)
  180.   ;;  get objects to break
  181.   (prompt "\nSelect All objects to break & press enter: ")
  182.   (if (setq ss (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  183.      (Break_with ss ss nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  184.   )
  185.   (setvar "CMDECHO" cmd)
  186.   (command ".undo" "end")
  187.   (princ)
  188. )

  189. ;;==========================================
  190. ;;  Break a single object with many objects
  191. ;;==========================================
  192. (defun c:BreakObject (/ cmd ss1 ss2)
  193.   (command ".undo" "begin")
  194.   (setq cmd (getvar "CMDECHO"))
  195.   (setvar "CMDECHO" 0)
  196.   ;;  get objects to break
  197.   (prompt "\nSelect single object to break: ")
  198.   (if (and (setq ss1 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  199.            (not (redraw (ssname ss1 0) 3))
  200.            (not (prompt "\n***  Select object(s) to break with & press enter:  ***"))
  201.            (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  202.            (not (redraw (ssname ss1 0) 4)))
  203.      (Break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  204.   )
  205.   (setvar "CMDECHO" cmd)
  206.   (command ".undo" "end")
  207.   (princ)
  208. )
  209. ;;==========================================
  210. ;;  Break many objects with a single object
  211. ;;==========================================
  212. (defun c:breakwobjects (/ cmd ss1 ss2)
  213.   (defun ssredraw (ss mode / i num)
  214.     (setq i -1)
  215.     (while (setq ename (ssname ss (setq i (1+ i))))
  216.       (redraw (ssname ss i) mode)
  217.     )
  218.   )
  219.   (command ".undo" "begin")
  220.   (setq cmd (getvar "CMDECHO"))
  221.   (setvar "CMDECHO" 0)
  222.   ;;  get objects to break
  223.   (prompt "\nSelect object(s) to break & press enter: ")
  224.   (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  225.            (not (ssredraw ss1 3))
  226.            (not (prompt "\n***  Select single object to break with:  ***"))
  227.            (setq ss2 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  228.            (not (ssredraw ss1 4))
  229.       )
  230.     (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  231.   )
  232.   (setvar "CMDECHO" cmd)
  233.   (command ".undo" "end")
  234.   (princ)
  235. )
  236. ;;==========================================
  237. ;;  Break many objects with many object     
  238. ;;==========================================
  239. (defun c:BreakWith (/ cmd ss1 ss2)
  240.   (defun ssredraw (ss mode / i num)
  241.     (setq i -1)
  242.     (while (setq ename (ssname ss (setq i (1+ i))))
  243.       (redraw (ssname ss i) mode)
  244.     )
  245.   )
  246.   (command ".undo" "begin")
  247.   (setq cmd (getvar "CMDECHO"))
  248.   (setvar "CMDECHO" 0)
  249.   ;;  get objects to break
  250.   (prompt "\nSelect object(s) to break & press enter: ")
  251.   (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  252.            (not (ssredraw ss1 3))
  253.            (not (prompt "\n***  Select object(s) to break with & press enter:  ***"))
  254.            (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  255.            (not (ssredraw ss1 4))
  256.       )
  257.     (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  258.   )
  259.   (setvar "CMDECHO" cmd)
  260.   (command ".undo" "end")
  261.   (princ)
  262. )

  263. ;;=============================================
  264. ;;  Break many objects with a selected objects
  265. ;;  Selected Objects create ss to be broken   
  266. ;;=============================================
  267. (defun c:BreakTouching (/ cmd ss1 ss2)
  268.   
  269.   ;;  get all objects touching entities in the sscross
  270.   ;;  limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
  271.   (defun gettouching (sscros / ss lst lstb lstc objl)
  272.     (and
  273.       (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros)))
  274.             objl (mapcar 'vlax-ename->vla-object lstb)
  275.       )
  276.       (setq
  277.         ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")
  278.                              (cons 410 (getvar "ctab"))))
  279.       )
  280.       (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
  281.       (setq lst (mapcar 'vlax-ename->vla-object lst))
  282.       (mapcar
  283.         '(lambda (x)
  284.            (mapcar
  285.              '(lambda (y)
  286.                 (if (not
  287.                       (vl-catch-all-error-p
  288.                         (vl-catch-all-apply
  289.                           '(lambda ()
  290.                              (vlax-safearray->list
  291.                                (vlax-variant-value
  292.                                  (vla-intersectwith y x acextendnone)
  293.                                ))))))
  294.                   (setq lstc (cons (vlax-vla-object->ename x) lstc))
  295.                 )
  296.               ) objl)
  297.          ) lst)
  298.     )
  299.     lstc
  300.   )
  301.   (command ".undo" "begin")
  302.   (setq cmd (getvar "CMDECHO"))
  303.   (setvar "CMDECHO" 0)
  304.   (setq ss1 (ssadd))
  305.   ;;  get objects to break
  306.   (if (and (not (prompt "\nSelect object(s) to break with & press enter: "))
  307.            (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  308.            (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2))
  309.       )
  310.     (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  311.   )
  312.   (setvar "CMDECHO" cmd)
  313.   (command ".undo" "end")
  314.   (princ)
  315. )

  316. ;;==========================================================
  317. ;;  Break selected objects with any objects that touch it  
  318. ;;==========================================================

  319. (defun c:BreakSelected (/ cmd ss1 ss2)
  320.   
  321.   ;;  get all objects touching entities in the sscross
  322.   ;;  limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
  323.   (defun gettouching (sscros / ss lst lstb lstc objl)
  324.     (and
  325.       (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros)))
  326.             objl (mapcar 'vlax-ename->vla-object lstb)
  327.       )
  328.       (setq
  329.         ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")
  330.                              (cons 410 (getvar "ctab"))))
  331.       )
  332.       (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
  333.       (setq lst (mapcar 'vlax-ename->vla-object lst))
  334.       (mapcar
  335.         '(lambda (x)
  336.            (mapcar
  337.              '(lambda (y)
  338.                 (if (not
  339.                       (vl-catch-all-error-p
  340.                         (vl-catch-all-apply
  341.                           '(lambda ()
  342.                              (vlax-safearray->list
  343.                                (vlax-variant-value
  344.                                  (vla-intersectwith y x acextendnone)
  345.                                ))))))
  346.                   (setq lstc (cons (vlax-vla-object->ename x) lstc))
  347.                 )
  348.               ) objl)
  349.          ) lst)
  350.     )
  351.     lstc
  352.   )
  353.   (command ".undo" "begin")
  354.   (setq cmd (getvar "CMDECHO"))
  355.   (setvar "CMDECHO" 0)
  356.   (setq ss1 (ssadd))
  357.   ;;  get objects to break
  358.   (if (and (not (prompt "\nSelect object(s) to break with & press enter: "))
  359.            (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
  360.            (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2))
  361.       )
  362.     (break_with ss2 ss1 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
  363.   )
  364.   (setvar "CMDECHO" cmd)
  365.   (command ".undo" "end")
  366.   (princ)
  367. )



发表于 2015-10-30 10:54 | 显示全部楼层
本帖最后由 布朗运动 于 2015-10-30 10:55 编辑
lilq_78 发表于 2014-2-19 15:46
顶,但是矩形与矩形相交打断不行

对原程序243-266行代码进行了改进:      
;;==========================================
;;  Break many objects with many object     
;;==========================================
(defun c:BreakWith (/ cmd ss1 ss2)
  (defun ssredraw (ss mode / i num)
    (setq i -1)
    (while (setq ename (ssname ss (setq i (1+ i))))
      (redraw (ssname ss i) mode)
    )
  )
  (command ".undo" "begin")
  (setq cmd (getvar "CMDECHO"))
  (setvar "CMDECHO" 0)
  (setq xuanz nil)
  ;;  get objects to break
  (prompt "\n选择要打断的直线或多线段,按回车确定: ")
  (if (and  (setq ss1
                      (ssget
                        '((0
                           .
                           "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
                          )
                         )
                      )
                  xuanz (ssget "P" '((0 . "LWPOLYLINE") (70 . 1)));取出选中的闭合多段线,一般为矩形或多边形命令创建
                  flag1 (if (/= ss1 nil) T);判断选择集ss1是否非空
               )
               
           
         (not (ssredraw ss1 3))
           (not
             (prompt
               "\n***  选择作为打断线的直线或多线段,按回车确定:  ***"
             )
           )
           (setq
             ss2 (ssget
                   '((0
                      .
                      "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
                     )
                    )
                 )
             ssd  (ssredraw ss1 4);新增
             flag2 (if (/= ss2 nil) T);判断选择集ss2是否非空
           )
           ;(not (ssredraw ss1 4))把该语句放在上面的setq语句群里,避免ss2为nil时本句不被执行的意外情况
      )
    (progn
      (if(/= xuanz nil)
        (progn
      (setq snum -1)
      (repeat (SSLENGTH xuanz)
        (setq a (entget (ssname xuanz (setq snum (+ 1 snum)))));取出xuanz中的每个闭合多线段
        (setq num (cdr (assoc 90 a)))        ;多线段顶点数量
        (setq pnum (- (length a) (length (member (assoc 10 a) a))))
                                        ;pnum为多线段第一个顶点坐标子列表所在项数(组码10)




        (setq qdlst (PARTLIST1 pnum (+ pnum 4) a))
        ;第一个端点列表
        (setq tou (PartList1 0 (- (length a) 2) a))
        ;原列表去掉最后一个元素后的新列表
        (setq zhong (append tou qdlst))
        ;新列表插入第一个端点坐标
        (setq wei (nth (- (length a) 1) a))
        ;保存原列表最后一个元素
        (setq a (append zhong (list wei)))
        ;加入原列表最后一个元素
        (setq a (subst (cons 70 0) (assoc 70 a) a))
        ;将闭合多线段改为非闭合多线段
        (setq a (subst (cons 90 (+ num 1)) (assoc 90 a) a))
        ;修改多线段顶点个数
        (entmod a)
      )
      )
    )
    (break_with ss1 ss2 nil)                ; ss2break ss2breakwith (flag nil = not to break with self)
      )
  )

  (setvar "CMDECHO" cmd)
  (command ".undo" "end")
  (princ)
)

其中用到了自贡黄明儒老师发表的函数:
;截取部分列表子函数
(defun PartList1 (from to lst / I L)
  (setq i -1)
  (foreach x lst
    (setq i (1+ i))
    (cond ((and (>= i from) (<= i to)) (setq l (cons x l))))
  )
  (REVERSE l)
)

评分

参与人数 1明经币 +1 收起 理由
guosheyang + 1 赞一个!

查看全部评分

回复 支持 1 反对 0

使用道具 举报

发表于 2021-12-16 09:43 | 显示全部楼层
布朗运动 发表于 2015-10-30 10:54
对原程序243-266行代码进行了改进:      
;;==========================================
;;  Break  ...

涉及到矩形打断的时候    矩形的左上角点会被强制断开  这点能改下的话 就很好了
发表于 2020-2-29 18:56 | 显示全部楼层
非常好的功能,谢谢
 楼主| 发表于 2012-5-23 11:21 | 显示全部楼层
c:\\1.gif
 楼主| 发表于 2012-5-23 11:24 | 显示全部楼层
类似这个 图谱的功能
看到 论坛有了 就不在录制了

本帖子中包含更多资源

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

x
发表于 2012-5-23 17:07 | 显示全部楼层
很好的程序,多谢分享!
发表于 2012-7-1 11:19 | 显示全部楼层
看看,学习一下
发表于 2012-7-14 23:58 | 显示全部楼层
niu
tai niu le
发表于 2012-7-16 20:27 | 显示全部楼层
很给力,谢分享
发表于 2012-7-16 21:38 | 显示全部楼层
已经收下!
发表于 2012-7-17 14:44 | 显示全部楼层
很好的程序,多谢分享
发表于 2012-8-17 17:16 | 显示全部楼层
确实不错。主要是交点比较多的话,稍微有点慢。
十分感谢。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2024-4-19 01:53 , Processed in 0.234159 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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