1. ;;;While 循环:共处理4970单元格;耗时: 67.844
    2. ;;;Mapcar 循环:共处理4970单元格;耗时: 67.66
    3. ;;;Foreach循环:共处理4970单元格;耗时: 67.134 秒-----------------------------------
    4. ;;说明:2021.1.2 10:41完善多行文字的处理效果
    5. (defun c:tt(/ ang by cell cellex celley cells cellsx cellsy cept cl coldislst coltopent colvlst crossrl cspt cylst ent entisinrectang entss getccrossr getptdis getptx getpty getrcrossc hlst interwithpt lshlst lsvlst lx n ptmid remhlst remore remvlst rept rl rowlst rspt rx rxlst sortline ss time1 time2 ty vlst xdislst ydislst)
    6. (progn
    7. ;;说明:判断图元是中心点是否在两点构成的矩形框内
    8. ;;参数:ent:图元图元名
    9. ;;参数:pt1:矩形框第一点
    10. ;;参数:pt2:矩形框第一点
    11. ;;返回:如果图元中心点在两点构成的矩形框内,则返回【图元的中心点】,否则返回【nil
    12. (defun EntIsInRectang(ent pt1 pt2 / box isptinrectang pt tmp)
    13. ;;;判断p点是否在P1P2构成的矩形框内
    14. ;;;(IsPtInRectang (getpoint) (getpoint) (getpoint))
    15. (defun IsPtInRectang(p p1 p2) (vl-every '>= (mapcar '* (mapcar '- p p1) (mapcar '- p2 p)) '(0 0)))
    16. (defun box(e / getmtextbox ll ur)
    17. (defun getMTextBox (en / b enx h j l n o r w)
    18. (setq
    19. enx (entget en)
    20. n (cdr (assoc 210 enx))
    21. b (trans (cdr (assoc 10 enx)) 0 n)
    22. r (angle '(0.0 0.0 0.0) (trans (cdr (assoc 11 enx)) 0 n))
    23. w (cdr (assoc 42 enx))
    24. h (cdr (assoc 43 enx))
    25. j (cdr (assoc 71 enx))
    26. o (list
    27. (cond
    28. ((member j '(2 5 8)) (/ w -2.0))
    29. ((member j '(3 6 9)) (- w))
    30. (0.0)
    31. )
    32. (cond
    33. ((member j '(1 2 3)) (- h))
    34. ((member j '(4 5 6)) (/ h -2.0))
    35. (0.0)
    36. )
    37. )
    38. l (list
    39. (list (car o) (cadr o))
    40. (list (+ (car o) w) (cadr o))
    41. (list (+ (car o) w) (+ (cadr o) h))
    42. (list (car o) (+ (cadr o) h))
    43. )
    44. )
    45. (setq l
    46. (
    47. (lambda (m)
    48. (mapcar
    49. '(lambda (p)
    50. (mapcar '+(mapcar '(lambda (r) (apply '+ (mapcar '* r p))) m) b)
    51. )
    52. l
    53. )
    54. )
    55. (list
    56. (list (cos r) (sin (- r)) 0.0)
    57. (list (sin r) (cos r) 0.0)
    58. '(0.0 0.0 1.0)
    59. )
    60. )
    61. )
    62. (setq l (mapcar '(lambda (x) (trans x n 0)) l))
    63. (list (car l) (caddr l))
    64. )
    65. (if (= "MTEXT" (cdr (assoc 0 (entget e))))
    66. (getMTextBox e)
    67. (progn
    68. (vla-getboundingbox (vlax-ename->vla-object e) 'll 'ur)
    69. (mapcar 'vlax-safearray->list (list ll ur))
    70. )
    71. )
    72. )
    73. (setq tmp (box ent) pt (mapcar '* (mapcar '+ (car tmp) (cadr tmp)) '(0.5 0.5 0.5)))
    74. (if (IsPtInRectang pt pt1 pt2)
    75. pt
    76. nil
    77. )
    78. )
    79. ;;说明:消除合并重复直线程序(***消除合并重复线条yad_undup*** YAD建筑")
    80. ;;参数:ss:需要消重的选择集
    81. ;;返回:消重后的选择集
    82. (defun remore(sss / chg_ent dxf on_ent os pmt sdel tang undup)
    83. (defun dxf(ent i)
    84. (cdr (assoc i (entget ent)))
    85. )
    86. (defun tang(ang sty)
    87. (rem (+ (* 2 pi) ang) sty)
    88. )
    89. (defun chg_ent(ent i pt / en)
    90. (setq en (entget ent) en (subst (cons i pt) (assoc i en) en))
    91. (entmod en)
    92. )
    93. (defun on_ent(a a1 a2)
    94. (equal (+ (distance a1 a) (distance a a2)) (distance a1 a2) 0.01)
    95. )
    96. (defun undup(s / c ent ent1 ent2 ept1 ept2 m n nm sdels spt1 spt2 ss)
    97. (setq n -1 nm 0 sdels s)
    98. (while (setq ent1 (ssname s (setq n (1+ n))))
    99. (if (entget ent1)
    100. (progn
    101. (setq spt1 (dxf ent1 10) ept1 (dxf ent1 11))
    102. (if (setq ss (ssget "cp" (list (polar spt1 (angle ept1 spt1) 0.1)
    103. (polar ept1 (- (angle spt1 ept1) (/ pi 4)) 0.15)
    104. (polar ept1 (+ (angle spt1 ept1) (/ pi 4)) 0.15)
    105. ) '((0 . "line"))
    106. )
    107. )
    108. (progn
    109. (ssdel ent1 ss)
    110. (setq m -1 c (sslength ss))
    111. (repeat c
    112. (setq ent (ssname ss (setq m (1+ m))))
    113. (if (not (ssmemb ent s))
    114. (progn
    115. (ssdel ent ss)
    116. (setq m (1- m))
    117. )
    118. )
    119. )
    120. (setq m -1 c (sslength ss))
    121. (repeat c
    122. (setq ent2 (ssname ss (setq m (1+ m))))
    123. (setq spt2 (dxf ent2 10) ept2 (dxf ent2 11))
    124. (cond
    125. ((and (on_ent spt2 spt1 ept1) (on_ent ept2 spt1 ept1))
    126. (entdel ent2)
    127. (if (ssmemb ent2 sdels) (ssdel ent2 sdels))
    128. )
    129. ((and (on_ent spt1 spt2 ept2) (on_ent ept1 spt2 ept2))
    130. (entdel ent1)
    131. (if (ssmemb ent1 sdels) (ssdel ent1 sdels))
    132. (setq ent1 ent2 spt1 spt2 ept1 ept2)
    133. )
    134. ((and (equal (tang (angle spt1 ept1) pi) (tang (angle spt2 ept2) pi) 0.001)
    135. (or (on_ent spt2 spt1 ept1) (on_ent ept2 spt1 ept1))
    136. )
    137. (entdel ent2)
    138. (if (ssmemb ent2 sdels) (ssdel ent2 sdels))
    139. (progn
    140. (if (on_ent spt2 spt1 ept1)
    141. (setq spt2 ept2)
    142. )
    143. (if (> (distance spt1 spt2) (distance ept1 spt2))
    144. (progn (chg_ent ent1 11 spt2) (setq ept1 spt2))
    145. (progn (chg_ent ent1 10 spt2) (setq spt1 spt2))
    146. )
    147. )
    148. )
    149. (T (setq nm (1- nm)))
    150. )
    151. (setq nm (1+ nm))
    152. )
    153. )
    154. )
    155. )
    156. )
    157. )
    158. sdels
    159. )
    160. (command "_.undo" "_be")
    161. (command "_.ucs" "")
    162. (setq os (getvar "osmode") sdel (ssadd))
    163. (setvar "cmdecho" 0)
    164. (setvar "osmode" 0)
    165. (if (> (sslength sss) 1) (progn (setq sdel (undup sss)) (setq pmt T)) (setq sdel sss))
    166. (if (and sss (not pmt)) sss)
    167. (setvar "osmode" os)
    168. (command "_.undo" "_e")
    169. sdel
    170. )
    171. ;;说明:获取两个对象交点
    172. ;;参数:ent1:图元1
    173. ;;参数:ent2:图元2
    174. ;;返回:有交点则返回交点列表,没有交点则返回nil
    175. (defun InterWithPt(ent1 ent2 / bf-list-split-3d var)
    176. ;;;name:BF-list-split-3d
    177. ;;;desc:列表按顺序切分为3元素表组成的表,不足部分用nil表示
    178. ;;;arg:lst:列表
    179. ;;;return:((x x x )(x x x)...)
    180. ;;;example:(BF-list-split-3d '(1 2 3 4))
    181. (defun BF-list-split-3d (lst)
    182. (if lst
    183. (cons
    184. (list
    185. (car lst)
    186. (cadr lst)
    187. (caddr lst)
    188. )
    189. (BF-list-split-3d (cdddr lst))
    190. )
    191. )
    192. )
    193. (if (>
    194. (vlax-safearray-get-u-bound
    195. (setq
    196. var (vlax-variant-value
    197. (vla-IntersectWith (vlax-ename->vla-object ent1) (vlax-ename->vla-object ent2) acExtendNone)
    198. )
    199. )
    200. 1
    201. )
    202. 1
    203. )
    204. (BF-list-split-3d (vlax-safearray->list var))
    205. nil
    206. )
    207. )
    208. (defun getptx(ent) (cadr (assoc 10 (entget ent))))
    209. (defun getpty(ent) (caddr (assoc 10 (entget ent))))
    210. ;;说明:获取图元间距离表
    211. ;;参数:entlst:图元表
    212. ;;返回:返回图元间距离表
    213. (defun GetPtDis(entlst isx)
    214. (if isx
    215. (mapcar (function (lambda (x y) (abs (- (getptx x) (getptx y))))) (cdr entlst) (reverse (cdr (reverse entlst))))
    216. (mapcar (function (lambda (x y) (abs (- (getpty x) (getpty y))))) (cdr entlst) (reverse (cdr (reverse entlst))))
    217. )
    218. )
    219. (defun GetRCrossC(ent lst)
    220. (setq xlst nil clst nil)
    221. (foreach e lst
    222. (if (setq pt (InterWithPt ent e))
    223. (setq xlst (cons (caar pt) xlst) clst (cons e clst))
    224. )
    225. )
    226. (list (reverse xlst) (vl-sort clst (function (lambda (x y) (< (getptx x) (getptx y))))))
    227. )
    228. (defun GetCCrossR(ent lst)
    229. (setq ylst nil)
    230. (foreach e lst
    231. (if (setq pt (InterWithPt ent e))
    232. (setq ylst (cons (cadar pt) ylst))
    233. )
    234. )
    235. (reverse ylst)
    236. )
    237. ;;说明:直线根据坐标排序
    238. ;;参数:lst:直线图元表
    239. ;;参数:Symbol:升降序:<、>
    240. ;;参数:Isx:T:对X轴排序,nil:对Y轴排序
    241. ;;返回:排序后的图元表
    242. (defun SortLine(lst Symbol Isx)
    243. (if isx
    244. (vl-sort lst (function (lambda (x y) (Symbol (getptx x) (getptx y)))))
    245. (vl-sort lst (function (lambda (x y) (Symbol (getpty x) (getpty y)))))
    246. )
    247. )
    248. )
    249. (setvar "CMDECHO" 0)
    250. (princ "\n请选择网格线:")
    251. (setq time1 (getvar "date")) ;;计时1
    252. (if (setq ss (remore (ssget '((0 . "LINE")))))
    253. (progn
    254. (setq n -1 lshlst nil remhlst nil lsvlst nil remvlst nil hlst nil vlst nil)
    255. (while (setq ent (ssname ss (setq n (1+ n))))
    256. (setq ang (vla-get-Angle (vlax-ename->vla-object ent)))
    257. (cond
    258. ((or (equal 0 ang 1e-5) (equal pi ang 1e-5) (equal (* 2 pi) ang 1e-5))
    259. (setq lshlst (cons ent lshlst))
    260. (if (vl-member-if (function (lambda (x) (= (getpty ent) (getpty x)))) remhlst)
    261. ()
    262. (setq remhlst (cons ent remhlst))
    263. )
    264. ;(setq lshlst (cons ent lshlst))
    265. )
    266. ((or (equal (* 0.5 pi) ang 1e-5) (equal (* 1.5 pi) ang 1e-5))
    267. (setq lsvlst (cons ent lsvlst))
    268. (if (vl-member-if (function (lambda (x) (= (getptx ent) (getptx x)))) remvlst)
    269. ()
    270. (setq remvlst (cons ent remvlst))
    271. )
    272. )
    273. )
    274. )
    275. (setq hlst (SortLine remhlst > nil))
    276. (setq vlst (SortLine remvlst < T))
    277. (setq rowlst (GetPtDis hlst nil))
    278. (setq
    279. cells nil cell nil rxlst nil cylst nil
    280. lx (getptx (car vlst)) rx (getptx (last vlst))
    281. ty (getpty (car hlst)) by (getpty (last hlst))
    282. );;(setq cells nil)
    283. (foreach RowTopEnt hlst
    284. (if (not (equal RowTopEnt (last hlst)))
    285. (progn
    286. (setq
    287. rspt (list lx (- (getpty RowTopEnt) (* 0.5 (car rowlst))))
    288. rept (list rx (- (getpty RowTopEnt) (* 0.5 (car rowlst))))
    289. rowlst (cdr rowlst)
    290. rl (entmakex (list '(0 . "LINE") (cons 10 rspt) (cons 11 rept)))
    291. rxlst (car (setq CrossRl (GetRCrossC rl (SortLine lsvlst < T))))
    292. colvlst (cadr CrossRl)
    293. coldislst (GetPtDis colvlst T)
    294. )
    295. (entdel rl)
    296. (foreach cwid coldislst
    297. (setq
    298. ColTopEnt (car colvlst) colvlst (cdr colvlst)
    299. cellsx (car rxlst) xdislst (cdr rxlst)
    300. cspt (list (+ (getptx ColTopEnt) (* 0.5 cwid)) ty)
    301. cept (list (+ (getptx ColTopEnt) (* 0.5 cwid)) by)
    302. cl (entmakex (list '(0 . "LINE") (cons 10 cspt) (cons 11 cept)))
    303. cylst (GetCCrossR cl (SortLine lshlst > nil))
    304. cellsy (car cylst)
    305. ydislst (cdr cylst)
    306. )
    307. (entdel cl)
    308. (while (< (setq cellex (car xdislst)) (car cspt)) (setq cellsx cellex xdislst (cdr xdislst)))
    309. (while (> (setq celley (car ydislst)) (cadr rspt)) (setq cellsy celley ydislst (cdr ydislst)))
    310. (setq
    311. cell
    312. (list
    313. (list cellsx cellsy)
    314. (list cellex celley)
    315. )
    316. )
    317. ;;(entmake (list '(0 . "LINE") (cons 10 (car cell)) (cons 11 (cadr cell)) (cons 62 1)))
    318. (if (vl-member-if (function (lambda (x) (and (equal (car x) (car cell)) (equal (cadr x) (cadr cell))))) cells);;(vl-position cell cells)
    319. ()
    320. (setq cells (cons cell cells))
    321. )
    322. )
    323. )
    324. )
    325. )
    326. (command "undo" "be")
    327. (foreach x cells
    328. (setq entss (ssget "C" (car x) (cadr x)) n -1)
    329. (while (setq ent (ssname entss (setq n (1+ n))))
    330. (if (not (ssmemb ent ss))
    331. (if (setq ptmid (EntIsInRectang ent (car x) (cadr x)))
    332. (command "move" ent "" "non" ptmid "non" (mapcar '* (mapcar '+ (car x) (cadr x)) '(0.5 0.5 0.5)))
    333. )
    334. )
    335. )
    336. )
    337. (command "undo" "e")
    338. (setq time2 (getvar "date")) ;;计时2
    339. (princ (strcat "\n共处理" (rtos (length cells)) "单元格;耗时: " (rtos (* 86400 (- time2 time1)) 2 4) " 秒"))
    340. )
    341. )
    342. (prin1)
    343. )