明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 1088|回复: 5

[讨论] lisp批量选择文本然后设置一个距离阈值将符合条件的每一个、两个或多个文本生成一...

  [复制链接]
发表于 2024-4-29 00:06:03 | 显示全部楼层 |阅读模式
本帖最后由 h2295 于 2024-4-30 09:07 编辑

lisp批量选择文本然后设置一个距离阈值将符合条件的每一个、两个或多个文本生成一个属性块怎么实现啊?
例如你选择了10个文本,其中有一组3个和一组2个之间的距离在阈值内,则这3个text和2个text分别成为一个属性块的3、2个属性,而其它的则单独成块。
 楼主| 发表于 2024-5-7 21:54:47 | 显示全部楼层
这是参考吧内其它网友的代码修改整合的,目前只实现根据距离阈值两两成块,没能实现不定数量成块,可能存在不足之处,现发布一下,有需要或有兴趣的可以完善完善
  1. ;;; 批量文本转属性定义 txtat Define the top-level function for the command "txtatt"
  2. (defun listToSelectionSet (entityList / ss)
  3.   (setq ss (ssadd))
  4.   (foreach ent entityList
  5.     (ssadd ent ss)
  6.   )
  7.   ss
  8. )
  9. (defun txtatt4 (ss1 c1 layer-name / ent66)
  10.   (setq attlist '()) ; 创建一个空列表用于存储属性定义实体
  11.   (setq curTime (rtos (* (getvar "cdate") 1e8)))
  12.   (setq blkname curTime) ; Specify the block name where you want to insert the ATTDEF
  13.   (setq ss111 (listToSelectionSet ss1))
  14.   (if ss111
  15.     (progn
  16.       (princ ss111)
  17.       (setq ii 0)
  18.       (repeat (sslength ss111)
  19.         (setq ent66 (ssname ss111 ii))
  20.         (princ ent66)
  21.         (setq tnewdxfem (txt2att4 ent66 ii blkname layer-name))
  22.         (setq ii (1+ ii))
  23.         (if (/= tnewdxfem nil)
  24.           (setq attlist (cons tnewdxfem attlist)) ; 将属性定义实体添加到列表中
  25.         )
  26.       )
  27.       (ZG_MakeBlock attlist c1)
  28.     )
  29.     (if (setq ent (entsel "\nSelect text entity: "))
  30.       (txt2att4 (car ent) ii blkname layer-name)
  31.       (prompt "No entity was selected.")
  32.     )
  33.   )
  34.   (princ)
  35. )
  36. ;;; Define the core function that converts a text entity to an attribute definition
  37. (defun txt2att4 (ent2 id blkname layer-name / entdxf newdxf malst tem)

  38.   (setq entdxf (entget ent2)
  39.         newdxf '((0 . "ATTDEF"))
  40.         newdxf (append
  41.                  newdxf
  42.                  (list
  43.                    (cons 1 (cdr (assoc 1 entdxf)))
  44.                    (cons 2 (rtos id))
  45.                    (cons 3 (cdr (assoc 1 entdxf)))
  46.                    (cons 70 0)
  47.                    (cons 8 layer-name)
  48.                  )
  49.                )
  50.         malst  (list 7 10 11 39 40 41 50 51 62 71 72 73)
  51.   )
  52.   (foreach mai malst
  53.     (setq tem (assoc mai entdxf))
  54.     (if (/= tem nil)
  55.       (setq newdxf (append newdxf (list tem)))
  56.     )
  57.   )
  58.   ; (entdel ent)
  59.   (entmake newdxf)
  60.   ; 可以使用(entlast)函数获取最后一次创建的实体的句柄,然后再使用ssget函数选中这个实体
  61.   (setq entd (entlast))
  62.   ; (princ entd)
  63.   ; (setq ssd (ssget "X" (list (cons 0 (cdr (assoc 0 (entget entd)))))))
  64.   (eval entd)
  65. )

  66. (defun emkblk (ss blkname pt / i)
  67.   (princ ss)
  68.   (entmake (list '(0 . "block") (cons 2 blkname) '(70 . 0) (cons 10 pt)))
  69.   ; (entmake (cdr (entget ss)))
  70.   (entmake ss)
  71.   ; (repeat (setq i (sslength ss))
  72.   ;   (entmake (cdr (entget (ssname ss (setq i (1- i))))))
  73.   ; )
  74.   (entmake '((0 . "ENDBLK")))
  75.   (command "_.erase" ss "")
  76.   (entmake (list '(0 . "INSERT") (cons 2 blkname) (cons 10 pt)))
  77. )
  78. (defun random (site / date random)  ;@site作为随机数位数,定义为1,2,3分别对应0-9,0-99,0-999

  79.   (setq date (* 100000000 (getvar "cdate"))) ;获取当前时间并去掉小数点赋值到@date
  80.   (setq remValue 1) ;赋值除数为1
  81.   (repeat site
  82.     (setq remValue (* 10 remValue))
  83.   ) ;循环次数等于保留位数,如果三次则@remValue等于1000,两次100,一次10
  84.   (setq random (rem date remValue)) ;将@date保留最后若干位,赋值到@random
  85. )
  86. ;快速创建块
  87. ;块名为当前时间(如"2012101620161699"),块基点为选择集中心点
  88. ;命令:ZG_MakeBlock
  89. (defun ZG_MakeBlock (ss44 c2 / zg-GetSSBoundingbox blipmode_bak ss44 blkname ssbox1
  90.                      basept inspt
  91.                     )
  92.   ;功能:返回选择集包围盒
  93.   ;参数: ss--选择集
  94.   ;返回值:选择集所有实体做为整体的包围盒
  95.   ;(setq ssbox (zg-GetSSBoundingbox (setq ss (ssget))))
  96.   (defun zg-GetSSBoundingbox (ss2 / iii ssn ll rr box ptlist ssbox)
  97.     (if ss2
  98.       (progn
  99.         (setq iii -1)
  100.         (repeat (sslength ss2)
  101.           (setq ssn (ssname ss2 (setq iii (1+ iii))))
  102.           (vla-GetBoundingBox (vlax-ename->vla-object ssn) 'll 'rr) ;得到对象的包围盒
  103.           (setq box (list (vlax-safearray->list ll) (vlax-safearray->list rr)))
  104.           (setq ptlist (append box ptlist))
  105.         )
  106.         (setq ssbox (mapcar '(lambda (x) (apply 'mapcar (cons x ptlist)))
  107.                             (list 'min 'max)
  108.                     )
  109.         )
  110.       )
  111.     )
  112.   )
  113.   (vl-load-com)
  114.   ; (setq ss (cadr (ssgetfirst)))
  115.   (setvar "cmdecho" 0)
  116.   (command "_undo" "be")
  117.   (princ "\n选择快速创建块的对象: ")
  118.   ; (if (or ss (setq ss (ssget)))
  119.   (setq ss444 (listToSelectionSet ss44))
  120.   (if (or ss444)
  121.     (progn
  122.       (setq randomNum (random 3))
  123.       (setq blkname (rtos (* (getvar "cdate") 1e8)))
  124.       (setq blkname (strcat blkname (rtos c2)))
  125.       (setq ssbox1 (zg-GetSSBoundingbox ss444))
  126.       (setq basept (apply 'mapcar
  127.                           (cons (function (lambda (a b) (/ (+ a b) 2))) ssbox1)
  128.                    )
  129.       )
  130.       (command "block" blkname "non" basept ss444 "") ;创建块并删除创建块的对象
  131.       (setq inspt basept)
  132.       ; 设置为0:粘贴时不提示“输入属性”
  133.       ; 设置为1:粘贴时提示“输入属性”
  134.       (command "attreq" "0")
  135.       (command "_.insert" blkname "x" 1 "y" 1 "z" 1 "r" 0 "non" inspt "") ;插入块
  136.       (command "attreq" "1")
  137.     )
  138.   )
  139.   (command "_undo" "e")
  140.   (setvar "cmdecho" 1)
  141.   (princ)
  142. )


  143. (defun get-midpoint (ent22)  ;返回对象外包框的中点坐标BY:Dea25
  144.   (vl-load-com)
  145.   (if (= (type ent22) 'ENAME)
  146.     (mapcar '*
  147.             '(0.5 0.5 0.5)
  148.             (apply '(lambda (x1 x2) (mapcar '+ x1 x2))
  149.                    (acet-ent-geomextents ent22)
  150.             )
  151.     )
  152.     nil
  153.   )
  154. )


  155. (defun calculate-distance (midpoint1 midpoint2)
  156.   ; 计算两个中点之间的距离
  157.   (distance midpoint1 midpoint2)
  158. )

  159. (defun process-distance (distance1)
  160.   ; 处理距离,如果距离小于1返回距离值,否则返回nil
  161.   (if (< distance1 1.5)
  162.     distance1
  163.     nil
  164.   )
  165. )


  166. (defun create-sequence (length start step)
  167.   (setq sequence '())
  168.   (repeat length
  169.     (setq sequence (cons start sequence))
  170.     (setq start (+ start step))
  171.   )
  172.   (reverse sequence)
  173. )

  174. (defun permutations (numbers / result i j)
  175.   ; (setq numbers '(1 2 3))
  176.   (setq result '())
  177.   (setq i (getvar 'cmdactive))
  178.   (repeat (length numbers)

  179.     (setq j (+ i 1))
  180.     (repeat (- (length numbers) (+ 1 i))

  181.       (setq result (cons (list (nth i numbers) (nth j numbers)) result))
  182.       ; (setq result (list (nth i numbers) (nth j numbers)))
  183.       (princ result)
  184.       (setq j (+ j 1))
  185.     )
  186.     (setq i (+ i 1))
  187.   )
  188.   (princ "\nPermutations: ")
  189.   (foreach pair result
  190.     (princ (strcat "(" (itoa (car pair)) " " (itoa (cadr pair)) ") "))
  191.     ; (princ (strcat "(" (itoa pair) " " (itoa pair) ") "))
  192.   )
  193.   (princ)
  194.   (reverse result)
  195. )

  196. ; (princ "\nType PERMUTATIONS to run the command.")

  197. (defun create-sequence1 ()


  198.   (setq sequence1 (create-sequence 3 1 1))
  199.   (setq result (permutations sequence1))
  200.   (princ "\nPermutations: ")
  201.   (foreach pair result
  202.     (princ (strcat "(" (itoa (car pair)) " " (itoa (cadr pair)) ") "))
  203.     ; (princ (strcat "(" (itoa pair) " " (itoa pair) ") "))
  204.   )
  205.   (princ)
  206. )

  207. (defun delay-1s ()
  208.   (setq start-time (getvar 'DATE))
  209.   (setq end-time (+ start-time 1.0))
  210.   (while (<= (getvar 'DATE) end-time)
  211.     (command "_.redraw")
  212.   )
  213. )
  214. (defun c:get-selected-texts ()
  215.   ; 获取用户选择的文本对象


  216.   ; 获取用户选择的文本对象
  217.   ; (setq ss (ssget '((0 . "TEXT"))))
  218.   (setq ss1 (ssget "_:L" '((0 . "TEXT,MTEXT"))))
  219.   ; 循环计算选择集中两两对象之间的距离
  220.   (setq n (sslength ss1))
  221.   (setq start 0)
  222.   (setq step 1)

  223.   (princ n)
  224.   (setq tempi -1)
  225.   (setq tempj -1)
  226.   (setq i 0)
  227.   (while (< i n)
  228.     (setq j (+ i 1))
  229.     (while (< j n)
  230.       (if (and (/= tempi i) (/= tempj j))
  231.         (progn
  232.           (princ i)
  233.           (princ j)
  234.           (princ tempi)
  235.           (princ tempj)
  236.           (setq ent1 (ssname ss1 i))
  237.           (setq ent2 (ssname ss1 j))
  238.           (setq midpoint1 (get-midpoint ent1))
  239.           (setq midpoint2 (get-midpoint ent2))
  240.           (princ midpoint1)
  241.           (setq distance1 (distance midpoint1 midpoint2))
  242.           (setq result (process-distance distance1))
  243.           (if result
  244.             (progn
  245.               (setq layer-name "图块图层")
  246.               (command "-layer" "n" layer-name "")

  247.               (command "-layer" "m" layer-name "")
  248.               (setq attlist '())
  249.               (setq ssd1 (ssget "X" (list (cons 0 (cdr (assoc 0 (entget ent1)))))))
  250.               (setq ssd2 (ssget "X" (list (cons 0 (cdr (assoc 0 (entget ent2)))))))
  251.               (setq attlist (cons ent1 attlist))
  252.               (setq attlist (cons ent2 attlist))
  253.               (txtatt4 attlist i layer-name)
  254.               (princ
  255.                 (strcat "Distance between object "
  256.                         (itoa i)
  257.                         " and object "
  258.                         (itoa j)
  259.                         ": "
  260.                         (rtos distance1)
  261.                         "\n"
  262.                 )
  263.               )
  264.               (setq tempi i)
  265.               (setq tempj j)
  266.               (princ
  267.                 (strcat "Distance between object1 "
  268.                         (itoa tempi)
  269.                         " and object1 "
  270.                         (itoa tempj)
  271.                         ": "
  272.                         (rtos distance1)
  273.                         "\n"
  274.                 )
  275.               )
  276.             )
  277.           )
  278.         )
  279.       )
  280.       (setq j (+ j 1))
  281.     )
  282.     (setq i (+ i 1))
  283.   )

  284.   (princ "Calculation completed.")
  285. )

 楼主| 发表于 2024-5-7 22:01:59 | 显示全部楼层
你有种再说一遍 发表于 2024-4-29 05:32
构建邻接表,不会就集合里面一一比较

大佬,我上传了一段代码只简单实现了两两成块,你看看能不能优化优化
发表于 2024-4-29 05:32:47 | 显示全部楼层
本帖最后由 你有种再说一遍 于 2024-4-29 05:35 编辑

构建邻接表,不会就集合里面一一比较
发表于 2024-4-29 07:45:49 | 显示全部楼层
感觉问题都没咋描述清楚
 楼主| 发表于 2024-4-30 09:08:31 | 显示全部楼层
guosheyang 发表于 2024-4-29 07:45
感觉问题都没咋描述清楚

例如你选择了10个文本,其中有一组3个和一组2个之间的距离在阈值内,则这3个text和2个text分别成为一个属性块的3、2个属性,而其它的则单独成块。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

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

GMT+8, 2024-11-25 18:38 , Processed in 0.252561 second(s), 27 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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