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 / break_obj cmd get_interpts intpts list->3pair lst masterlist onlockedlayer ss ssget->vla-list ssobjs)
    6. ;; ss2brk selection set to break
    7. ;; ss2brkwith selection set to use as break points
    8. ;; self when true will allow an object to break itself
    9. ;; note that plined will break at each vertex
    10. (vl-load-com)
    11. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    12. ;; S U B F U N C T I O N S
    13. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    14. (defun onlockedlayer (ename / entlst)
    15. (setq entlst (tblsearch "LAYER" (cdr (assoc 8 (entget ename)))))
    16. (= 4 (logand 4 (cdr (assoc 70 entlst))))
    17. )
    18. (defun ssget->vla-list (ss / i ename lst)
    19. (setq i -1)
    20. (while (setq ename (ssname ss (setq i (1+ i))))
    21. (setq lst (cons (vlax-ename->vla-object ename) lst))
    22. )
    23. lst
    24. )
    25. (defun list->3pair (old / new)
    26. (while (setq new (cons (list (car old) (cadr old) (caddr old)) new) old (cdddr old)))
    27. (reverse new)
    28. )
    29. ;;==============================================================
    30. ;; return a list of intersect points
    31. ;;==============================================================
    32. (defun get_interpts (obj1 obj2 / iplist)
    33. (if (not
    34. (vl-catch-all-error-p
    35. (setq
    36. iplist
    37. (vl-catch-all-apply
    38. 'vlax-safearray->list
    39. (list
    40. (vlax-variant-value
    41. (vla-intersectwith obj1 obj2 acextendnone)
    42. )
    43. )
    44. )
    45. )
    46. )
    47. )
    48. iplist
    49. )
    50. )
    51. ;;==============================================================
    52. ;; Break entity at break points in list
    53. ;;==============================================================
    54. (defun break_obj (ent brkptlst / brkobjlst closedobj en enttype maxparam minparam obj obj2break p1param p2 p2param)
    55. (setq obj2break ent brkobjlst (list ent) enttype (cdr (assoc 0 (entget ent))))
    56. (foreach brkpt brkptlst ; get last entity created via break
    57. ; in case multiple breaks
    58. (if brkobjlst
    59. (progn ; if pt not on object x, switch
    60. ; objects
    61. (if (not (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint (list obj2break brkpt))))
    62. (foreach obj brkobjlst ; find the one that pt is on
    63. (if (numberp (vl-catch-all-apply 'vlax-curve-getdistatpoint (list obj brkpt)))
    64. (setq obj2break obj) ; switch objects
    65. )
    66. )
    67. )
    68. )
    69. ) ; handle any objects that can not
    70. ; be used with the break command
    71. ; using one point, gap of 0.000001
    72. ; is used
    73. (cond
    74. ((and
    75. (= "SPLINE" enttype) ; only closed splines
    76. (vlax-curve-isclosed obj2break)
    77. )
    78. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
    79. p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001))
    80. )
    81. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
    82. (trans p2 0 1)
    83. )
    84. )
    85. ((= "CIRCLE" enttype) ; break the circle
    86. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
    87. p2 (vlax-curve-getpointatparam obj2break (+ p1param 0.000001))
    88. )
    89. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
    90. (trans p2 0 1)
    91. )
    92. (setq enttype "ARC")
    93. )
    94. ((and
    95. (= "ELLIPSE" enttype) ; only closed ellipse
    96. (vlax-curve-isclosed obj2break)
    97. ) ; break the ellipse, code borrowed
    98. ; from joe burke 6/6/2005
    99. (setq p1param (vlax-curve-getparamatpoint obj2break brkpt)
    100. p2param (+ p1param 0.000001)
    101. minparam (min
    102. p1param
    103. p2param
    104. )
    105. maxparam (max
    106. p1param
    107. p2param
    108. )
    109. obj (vlax-ename->vla-object obj2break)
    110. )
    111. (vlax-put obj 'startparameter maxparam)
    112. (vlax-put obj 'endparameter (+ minparam (* pi 2)))
    113. ) ; ==================================
    114. (t ; objects that can be broken
    115. (setq closedobj (vlax-curve-isclosed obj2break))
    116. (command "._break" obj2break "_non" (trans brkpt 0 1) "_non"
    117. (trans brkpt 0 1)
    118. )
    119. (if (not closedobj) ; new object was created
    120. (setq brkobjlst (cons (entlast) brkobjlst))
    121. )
    122. )
    123. )
    124. )
    125. )
    126. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    127. ;; S T A R T H E R E
    128. ;;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    129. (if (and ss2brk ss2brkwith)
    130. (progn
    131. ;; CREATE a list of entity & it's break points
    132. (foreach obj (ssget->vla-list ss2brk) ; check each object in ss2brk
    133. (if (not (onlockedlayer (vlax-vla-object->ename obj)))
    134. (progn
    135. (setq lst nil)
    136. ;; check for break pts with other objects in ss2brkwith
    137. (foreach intobj (ssget->vla-list ss2brkwith)
    138. (if (and (or self (not (equal obj intobj)))
    139. (setq intpts (get_interpts obj intobj))
    140. )
    141. (setq lst (append (list->3pair intpts) lst)) ; entity w/ break points
    142. )
    143. )
    144. (if lst
    145. (setq masterlist (cons (cons (vlax-vla-object->ename obj) lst) masterlist))
    146. )
    147. )
    148. )
    149. )
    150. ;; masterlist = ((ent brkpts)(ent brkpts)...)
    151. (if masterlist
    152. (foreach obj2brk masterlist
    153. (break_obj (car obj2brk) (cdr obj2brk))
    154. )
    155. )
    156. )
    157. )
    158. ;;==============================================================
    159. )
    160. (princ)
    161. ;;==========================================
    162. ;; Break all objects selected
    163. ;;==========================================
    164. (defun c:breakall (/ cmd ss)
    165. (command ".undo" "begin")
    166. (setq cmd (getvar "CMDECHO"))
    167. (setvar "CMDECHO" 0)
    168. ;; get objects to break
    169. (prompt "\nSelect All objects to break & press enter: ")
    170. (if (setq ss (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    171. (Break_with ss ss nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    172. )
    173. (setvar "CMDECHO" cmd)
    174. (command ".undo" "end")
    175. (princ)
    176. )
    177. ;;==========================================
    178. ;; Break a single object with many objects
    179. ;;==========================================
    180. (defun c:BreakObject (/ cmd ss1 ss2)
    181. (command ".undo" "begin")
    182. (setq cmd (getvar "CMDECHO"))
    183. (setvar "CMDECHO" 0)
    184. ;; get objects to break
    185. (prompt "\nSelect single object to break: ")
    186. (if (and (setq ss1 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    187. (not (redraw (ssname ss1 0) 3))
    188. (not (prompt "\n*** Select object(s) to break with & press enter: ***"))
    189. (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    190. (not (redraw (ssname ss1 0) 4)))
    191. (Break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    192. )
    193. (setvar "CMDECHO" cmd)
    194. (command ".undo" "end")
    195. (princ)
    196. )
    197. ;;==========================================
    198. ;; Break many objects with a single object
    199. ;;==========================================
    200. (defun c:breakwobjects (/ cmd ss1 ss2 ssredraw)
    201. (defun ssredraw (ss mode / i num)
    202. (setq i -1)
    203. (while (setq ename (ssname ss (setq i (1+ i))))
    204. (redraw (ssname ss i) mode)
    205. )
    206. )
    207. (command ".undo" "begin")
    208. (setq cmd (getvar "CMDECHO"))
    209. (setvar "CMDECHO" 0)
    210. ;; get objects to break
    211. (prompt "\nSelect object(s) to break & press enter: ")
    212. (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    213. (not (ssredraw ss1 3))
    214. (not (prompt "\n*** Select single object to break with: ***"))
    215. (setq ss2 (ssget "+.:E:S" '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    216. (not (ssredraw ss1 4))
    217. )
    218. (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    219. )
    220. (setvar "CMDECHO" cmd)
    221. (command ".undo" "end")
    222. (princ)
    223. )
    224. ;;==========================================
    225. ;; Break many objects with many object
    226. ;;==========================================
    227. (defun c:BreakWith (/ cmd ss1 ss2 ssredraw)
    228. (defun ssredraw (ss mode / i num)
    229. (setq i -1)
    230. (while (setq ename (ssname ss (setq i (1+ i))))
    231. (redraw (ssname ss i) mode)
    232. )
    233. )
    234. (command ".undo" "begin")
    235. (setq cmd (getvar "CMDECHO"))
    236. (setvar "CMDECHO" 0)
    237. ;; get objects to break
    238. (prompt "\nSelect object(s) to break & press enter: ")
    239. (if (and (setq ss1 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    240. (not (ssredraw ss1 3))
    241. (not (prompt "\n*** Select object(s) to break with & press enter: ***"))
    242. (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    243. (not (ssredraw ss1 4))
    244. )
    245. (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    246. )
    247. (setvar "CMDECHO" cmd)
    248. (command ".undo" "end")
    249. (princ)
    250. )
    251. ;;=============================================
    252. ;; Break many objects with a selected objects
    253. ;; Selected Objects create ss to be broken
    254. ;;=============================================
    255. (defun c:BreakTouching (/ cmd gettouching ss1 ss2)
    256. ;; get all objects touching entities in the sscross
    257. ;; limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
    258. (defun gettouching (sscros / ss lst lstb lstc objl)
    259. (and
    260. (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros))) objl (mapcar 'vlax-ename->vla-object lstb))
    261. (setq ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE") (cons 410 (getvar "ctab")))))
    262. (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    263. (setq lst (mapcar 'vlax-ename->vla-object lst))
    264. (mapcar
    265. '(lambda (x)
    266. (mapcar
    267. '(lambda (y)
    268. (if (not
    269. (vl-catch-all-error-p
    270. (vl-catch-all-apply
    271. '(lambda ()
    272. (vlax-safearray->list
    273. (vlax-variant-value
    274. (vla-intersectwith y x acextendnone)
    275. )
    276. )
    277. )
    278. )
    279. )
    280. )
    281. (setq lstc (cons (vlax-vla-object->ename x) lstc))
    282. )
    283. )
    284. objl
    285. )
    286. )
    287. lst
    288. )
    289. )
    290. lstc
    291. )
    292. (command ".undo" "begin")
    293. (setq cmd (getvar "CMDECHO"))
    294. (setvar "CMDECHO" 0)
    295. (setq ss1 (ssadd))
    296. ;; get objects to break
    297. (if (and (not (prompt "\nSelect object(s) to break with & press enter: "))
    298. (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    299. (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2))
    300. )
    301. (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    302. )
    303. (setvar "CMDECHO" cmd)
    304. (command ".undo" "end")
    305. (princ)
    306. )
    307. ;;==========================================================
    308. ;; Break selected objects with any objects that touch it
    309. ;;==========================================================
    310. (defun c:BreakSelected (/ cmd gettouching ss1 ss2)
    311. ;; get all objects touching entities in the sscross
    312. ;; limited obj types to "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"
    313. (defun gettouching (sscros / ss lst lstb lstc objl)
    314. (and
    315. (setq lstb (vl-remove-if 'listp (mapcar 'cadr (ssnamex sscros))) objl (mapcar 'vlax-ename->vla-object lstb))
    316. (setq ss (ssget "_A" (list (cons 0 "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE") (cons 410 (getvar "ctab")))))
    317. (setq lst (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss))))
    318. (setq lst (mapcar 'vlax-ename->vla-object lst))
    319. (mapcar
    320. '(lambda (x)
    321. (mapcar
    322. '(lambda (y)
    323. (if (not
    324. (vl-catch-all-error-p
    325. (vl-catch-all-apply
    326. '(lambda ()
    327. (vlax-safearray->list
    328. (vlax-variant-value
    329. (vla-intersectwith y x acextendnone)
    330. )
    331. )
    332. )
    333. )
    334. )
    335. )
    336. (setq lstc (cons (vlax-vla-object->ename x) lstc))
    337. )
    338. )
    339. objl
    340. )
    341. )
    342. lst
    343. )
    344. )
    345. lstc
    346. )
    347. (command ".undo" "begin")
    348. (setq cmd (getvar "CMDECHO"))
    349. (setvar "CMDECHO" 0)
    350. (setq ss1 (ssadd))
    351. ;; get objects to break
    352. (if (and (not (prompt "\nSelect object(s) to break with & press enter: "))
    353. (setq ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE"))))
    354. (mapcar '(lambda (x) (ssadd x ss1)) (gettouching ss2))
    355. )
    356. (break_with ss2 ss1 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    357. )
    358. (setvar "CMDECHO" cmd)
    359. (command ".undo" "end")
    360. (princ)
    361. )
    362. ;;;对原程序243-266行代码进行了改进:
    363. ;;==========================================
    364. ;; Break many objects with many object
    365. ;;==========================================
    366. ;(defun c:BreakWith (/ cmd ss1 ss2)
    367. ; (defun ssredraw (ss mode / i num)
    368. ; (setq i -1)
    369. ; (while (setq ename (ssname ss (setq i (1+ i))))
    370. ; (redraw (ssname ss i) mode)
    371. ; )
    372. ; )
    373. ; (command ".undo" "begin")
    374. ; (setq cmd (getvar "CMDECHO"))
    375. ; (setvar "CMDECHO" 0)
    376. ; (setq xuanz nil)
    377. ; ;; get objects to break
    378. ; (prompt "\n选择要打断的直线或多线段,按回车确定: ")
    379. ; (if (and
    380. ; (setq ss1
    381. ; (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))
    382. ; xuanz (ssget "P" '((0 . "LWPOLYLINE") (70 . 1)));取出选中的闭合多段线,一般为矩形或多边形命令创建
    383. ; flag1 (if (/= ss1 nil) T);判断选择集ss1是否非空
    384. ; )
    385. ; (not (ssredraw ss1 3))
    386. ; (not
    387. ; (prompt
    388. ; "\n*** 选择作为打断线的直线或多线段,按回车确定: ***"
    389. ; )
    390. ; )
    391. ; (setq
    392. ; ss2 (ssget '((0 . "LINE,ARC,SPLINE,LWPOLYLINE,POLYLINE,CIRCLE,ELLIPSE")))
    393. ; ssd (ssredraw ss1 4);新增
    394. ; flag2 (if (/= ss2 nil) T);判断选择集ss2是否非空
    395. ; )
    396. ; ;(not (ssredraw ss1 4))把该语句放在上面的setq语句群里,避免ss2nil时本句不被执行的意外情况
    397. ; )
    398. ; (progn
    399. ; (if(/= xuanz nil)
    400. ; (progn
    401. ; (setq snum -1)
    402. ; (repeat (SSLENGTH xuanz)
    403. ; (setq a (entget (ssname xuanz (setq snum (+ 1 snum)))));取出xuanz中的每个闭合多线段
    404. ; (setq num (cdr (assoc 90 a))) ;多线段顶点数量
    405. ; (setq pnum (- (length a) (length (member (assoc 10 a) a))))
    406. ; ;pnum为多线段第一个顶点坐标子列表所在项数(组码10
    407. ; (setq qdlst (PARTLIST1 pnum (+ pnum 4) a))
    408. ; ;第一个端点列表
    409. ; (setq tou (PartList1 0 (- (length a) 2) a))
    410. ; ;原列表去掉最后一个元素后的新列表
    411. ; (setq zhong (append tou qdlst))
    412. ; ;新列表插入第一个端点坐标
    413. ; (setq wei (nth (- (length a) 1) a))
    414. ; ;保存原列表最后一个元素
    415. ; (setq a (append zhong (list wei)))
    416. ; ;加入原列表最后一个元素
    417. ; (setq a (subst (cons 70 0) (assoc 70 a) a))
    418. ; ;将闭合多线段改为非闭合多线段
    419. ; (setq a (subst (cons 90 (+ num 1)) (assoc 90 a) a))
    420. ; ;修改多线段顶点个数
    421. ; (entmod a)
    422. ; )
    423. ; )
    424. ; )
    425. ; (break_with ss1 ss2 nil) ; ss2break ss2breakwith (flag nil = not to break with self)
    426. ; )
    427. ; )
    428. ;
    429. ; (setvar "CMDECHO" cmd)
    430. ; (command ".undo" "end")
    431. ; (princ)
    432. ;)
    433. ;
    434. ;;截取部分列表子函数
    435. ;(defun PartList1 (from to lst / I L)
    436. ; (setq i -1)
    437. ; (foreach x lst
    438. ; (setq i (1+ i))
    439. ; (cond ((and (>= i from) (<= i to)) (setq l (cons x l))))
    440. ; )
    441. ; (REVERSE l)
    442. ;)