;;;=======================[ BreakObjects.lsp ]==============================;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++;; M A I N S U B R O U T I N E ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++(defun break_with (ss2brk ss2brkwith self / break_obj cmd get_interpts intpts list->3pair lst masterlist onlockedlayer ss ssget->vla-list ssobjs) ;; ss2brk selection set to break ;; ss2brkwith selection set to use as break points ;; self when true will allow an object to break itself ;; note that plined will break at each vertex (vl-load-com) ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; S U B F U N C T I O N S ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ (defun onlockedlayer (ename / entlst) (setq entlst (tblsearch "LAYER" (cdr (assoc 8 (entget ename))))) (= 4 (logand 4 (cdr (assoc 70 entlst)))) ) (defun ssget->vla-list (ss / i ename lst) (setq i -1) (while (setq ename (ssname ss (setq i (1+ i)))) (setq lst (cons (vlax-ename->vla-object ename) lst)) ) lst ) (defun list->3pair (old / new) (while (setq new (cons (list (car old) (cadr old) (caddr old)) new) old (cdddr old))) (reverse new) ) ;;============================================================== ;; return a list of intersect points ;;============================================================== (defun get_interpts (obj1 obj2 / iplist) (if (not (vl-catch-all-error-p (setq iplist (vl-catch-all-apply 'vlax-safearray->list (list (vlax-variant-value (vla-intersectwith obj1 obj2 acextendnone) ) ) ) ) ) ) iplist ) ) ;;============================================================== ;; Break entity at break points in list ;;============================================================== (defun break_obj (ent brkptlst / brkobjlst closedobj en enttype maxparam minparam obj obj2break p1param p2 p2param) (setq obj2break ent brkobjlst (list ent) enttype (cdr (assoc 0 (entget ent)))) (foreach brkpt brkptlst ; get last entity created via break ; in case multiple breaks (if brkobjlst (progn ; if pt not on object x, switch ; objects (if (not (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint (list obj2break brkpt)))) (foreach obj brkobjlst ; find the one that pt is on (if (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint (list obj brkpt))) (setq obj2break obj) ; switch objects ) ) ) ) ) ; handle any objects that can not ; be used with the break command ; using one point, gap of 0.000001 ; is used (cond ((and (= "SPLINE" enttype) ; only closed splines (vlax-curve-isclosed obj2break) ) (setq p1param (vlax-curve-getparamatpoint obj2break brkpt) p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001)) ) (command "._break" obj2break "_non" (trans brkpt 0 1) "_non" (trans p2 0 1) ) ) ((= "CIRCLE" enttype) ; break the circle (setq p1param (vlax-curve-getparamatpoint obj2break brkpt) p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001)) ) (command "._break" obj2break "_non" (trans brkpt 0 1) "_non" (trans p2 0 1) ) (setq enttype "ARC") ) ((and (= "ELLIPSE" enttype) ; only closed ellipse (vlax-curve-isclosed obj2break) ) ; break the ellipse, code borrowed ; from joe burke 6/6/2005 (setq p1param (vlax-curve-getparamatpoint obj2break brkpt) p2param (+ p1param 0.000001) minparam (min p1param p2param ) maxparam (max p1param p2param ) obj (vlax-ename->vla-object obj2break) ) (vlax-put obj 'startparameter maxparam) (vlax-put obj 'endparameter (+ minparam (* pi 2))) ) ; ================================== (t ; objects that can be broken (setq closedobj (vlax-curve-isclosed obj2break)) (command "._break" obj2break "_non" (trans brkpt 0 1) "_non" (trans brkpt 0 1) ) (if (not closedobj) ; new object was created (setq brkobjlst (cons (entlast) brkobjlst)) ) ) ) ) ) ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ;; S T A R T H E R E ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ (if (and ss2brk ss2brkwith) (progn ;; CREATE a list of entity & it's break points (foreach obj (ssget->vla-list ss2brk) ; check each object in ss2brk (if (not (onlockedlayer (vlax-vla-object->ename obj))) (progn (setq lst nil) ;; check for break pts with other objects in ss2brkwith (foreach intobj (ssget->vla-list ss2brkwith) (if (and (or self (not (equal obj intobj))) (setq intpts (get_interpts obj intobj)) ) (setq lst (append (list->3pair intpts) lst)) ; entity w/ break points ) ) (if lst (setq masterlist (cons (cons (vlax-vla-object->ename obj) lst) masterlist)) ) ) ) ) ;; masterlist = ((ent brkpts)(ent brkpts)...) (if masterlist (foreach obj2brk masterlist (break_obj (car obj2brk) (cdr obj2brk)) ) ) ) ) ;;==============================================================)(princ);;==========================================;; Break all objects selected ;;==========================================(defun c:breakall (/ cmd ss) (command ".undo" "begin") (setq cmd (getvar "CMDECHO")) (setvar "CMDECHO" 0) ;; get objects to break (prompt "\nSelect All objects to break & press enter: ") (if (setq ss (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (Break_with ss ss nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;==========================================;; Break a single object with many objects ;;==========================================(defun c:BreakObject (/ cmd ss1 ss2) (command ".undo" "begin") (setq cmd (getvar "CMDECHO")) (setvar "CMDECHO" 0) ;; get objects to break (prompt "\nSelect single object to break: ") (if (and (setq ss1 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (redraw (ssname ss1 0) 3)) (not (prompt "\n*** Select object(s) to break with & press enter: ***")) (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (redraw (ssname ss1 0) 4))) (Break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;==========================================;; Break many objects with a single object ;;==========================================(defun c:breakwobjects (/ cmd ss1 ss2 ssredraw) (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) ;; get objects to break (prompt "\nSelect object(s) to break & press enter: ") (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (ssredraw ss1 3)) (not (prompt "\n*** Select single object to break with: ***")) (setq ss2 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (ssredraw ss1 4)) ) (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;==========================================;; Break many objects with many object ;;==========================================(defun c:BreakWith (/ cmd ss1 ss2 ssredraw) (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) ;; get objects to break (prompt "\nSelect object(s) to break & press enter: ") (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (ssredraw ss1 3)) (not (prompt "\n*** Select object(s) to break with & press enter: ***")) (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (not (ssredraw ss1 4)) ) (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;=============================================;; Break many objects with a selected objects ;; Selected Objects create ss to be broken ;;=============================================(defun c:BreakTouching (/ cmd gettouching ss1 ss2) ;; get all objects touching entities in the sscross ;; limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE" (defun gettouching (sscros / ss lst lstb lstc objl) (and (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros))) objl (mapcar 'vlax-ename->vla-object lstb)) (setq ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE") (cons 410 (getvar "ctab"))))) (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))) (setq lst (mapcar 'vlax-ename->vla-object lst)) (mapcar '(lambda (x) (mapcar '(lambda (y) (if (not (vl-catch-all-error-p (vl-catch-all-apply '(lambda () (vlax-safearray->list (vlax-variant-value (vla-intersectwith y x acextendnone) ) ) ) ) ) ) (setq lstc (cons (vlax-vla-object->ename x) lstc)) ) ) objl ) ) lst ) ) lstc ) (command ".undo" "begin") (setq cmd (getvar "CMDECHO")) (setvar "CMDECHO" 0) (setq ss1 (ssadd)) ;; get objects to break (if (and (not (prompt "\nSelect object(s) to break with & press enter: ")) (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2)) ) (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;==========================================================;; Break selected objects with any objects that touch it ;;==========================================================(defun c:BreakSelected (/ cmd gettouching ss1 ss2) ;; get all objects touching entities in the sscross ;; limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE" (defun gettouching (sscros / ss lst lstb lstc objl) (and (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros))) objl (mapcar 'vlax-ename->vla-object lstb)) (setq ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE") (cons 410 (getvar "ctab"))))) (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))) (setq lst (mapcar 'vlax-ename->vla-object lst)) (mapcar '(lambda (x) (mapcar '(lambda (y) (if (not (vl-catch-all-error-p (vl-catch-all-apply '(lambda () (vlax-safearray->list (vlax-variant-value (vla-intersectwith y x acextendnone) ) ) ) ) ) ) (setq lstc (cons (vlax-vla-object->ename x) lstc)) ) ) objl ) ) lst ) ) lstc ) (command ".undo" "begin") (setq cmd (getvar "CMDECHO")) (setvar "CMDECHO" 0) (setq ss1 (ssadd)) ;; get objects to break (if (and (not (prompt "\nSelect object(s) to break with & press enter: ")) (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))) (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2)) ) (break_with ss2 ss1 nil) ; ss2break ss2breakwith (flag nil = not to break with self) ) (setvar "CMDECHO" cmd) (command ".undo" "end") (princ));;;对原程序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);)