乐筑天下

搜索
欢迎各位开发者和用户入驻本平台 尊重版权,从我做起,拒绝盗版,拒绝倒卖 签到、发布资源、邀请好友注册,可以获得银币 请注意保管好自己的密码,避免账户资金被盗
查看: 53|回复: 5

[编程交流] 简化lisp,选择对象,

[复制链接]

76

主题

312

帖子

254

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
390
发表于 2022-7-5 16:02:09 | 显示全部楼层 |阅读模式
大家好,
我设法构建了一个lisp,它允许我选择外部参照的直线、多段线、圆弧或圆,并将该外部参照的图层的图层颜色更改为选定的颜色,可以是indexcolor、truecolor或colorbook颜色。。。
 
然而我认为这段代码可以简单得多。。。
有什么建议吗?
 
  1. (defun C:ChangeLayerColor ( / selectedobject selectedobjecttype selectedobjectlayer layercolor colorbook colorbookcolor)
  2. (setvar "cmdecho" 0)
  3. (command "UNDO" "BEGIN")
  4. (setq selectedobject (nentsel "\nSelect a line, polyline, circle or arc to change its layers color: "))
  5. (if (/= selectedobject nil)
  6.         (progn
  7.                 (if (/= (cdr (assoc 410 (entget (car selectedobject)))) nil)
  8.                         (progn
  9.                                 (setq selectedobject (entget (car selectedobject)))
  10.                                 (setq selectedobjecttype (cdr (assoc 0 selectedobject)))
  11.                         )
  12.                         (progn
  13.                                 (setq selectedobject (entget (car (nth 3 selectedobject))))
  14.                                 (setq selectedobjecttype (cdr (assoc 0 selectedobject)))
  15.                         )
  16.                 )
  17.                 (cond
  18.                         ((= selectedobjecttype (car (member selectedobjecttype (list "LINE" "LWPOLYLINE" "CIRCLE" "DIMENSION" "TEXT" "INSERT" "ARC"))))
  19.                                 (setq selectedobjectlayer (cdr (assoc 8 selectedobject)))
  20.                         )
  21.                         (t
  22.                                 (setq selectedobjectlayer nil)
  23.                         )               
  24.                 )
  25.                 (if (/= selectedobjectlayer nil)
  26.                         (progn
  27.                                 (setq layercolor (acad_truecolordlg 253 nil))
  28.                                 (if (/= layercolor nil)
  29.                                         (progn
  30.                                                 (if (/= (car (cddr layercolor)) nil)
  31.                                                         (progn
  32.                                                                 (setq layercolor (cdr (car (cddr layercolor))))
  33.                                                                 (setq colorbook (substr layercolor 1 (vl-string-position (ascii "$") layercolor 0 t)))
  34.                                                                 (setq colorbookcolor (substr layercolor (+ 2(vl-string-position (ascii "$") layercolor 0 t))))
  35.                                                                 (command-s "-Layer" "Color" "Colorbook" colorbook colorbookcolor selectedobjectlayer "")
  36.                                                                 (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " colorbookcolor "."))
  37.                                                         )
  38.                                                         (progn
  39.                                                                 (if (/= (car (cdr layercolor)) nil)
  40.                                                                         (progn
  41.                                                                                 (setq layercolor (OLEtoRGB_color (cdr (car (cdr layercolor)))))
  42.                                                                                 (setq layercolor (strcat (itoa (car layercolor))","(itoa (car (cdr layercolor)))","(itoa (car (cddr layercolor)))))
  43.                                                                                 (command-s "-Layer" "Color" "Truecolor" layercolor selectedobjectlayer "")
  44.                                                                                 (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " layercolor "."))
  45.                                                                         )
  46.                                                                         (progn
  47.                                                                                 (setq layercolor (cdr (car layercolor)))
  48.                                                                                 (command-s "-Layer" "Color" layercolor selectedobjectlayer "")
  49.                                                                                 (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " (itoa layercolor) "."))
  50.                                                                         )
  51.                                                                 )
  52.                                                         )
  53.                                                 )
  54.                                         )
  55.                                         (progn
  56.                                                 (princ "\nCancelled...")
  57.                                         )
  58.                                 )
  59.                         )
  60.                         (progn
  61.                                 (princ "\nInvalid selection.")
  62.                         )
  63.                 )
  64.         )
  65.         (progn
  66.                 (princ "\nCancelled...")
  67.         )
  68. )
  69. (command "UNDO" "END")
  70. (setvar "cmdecho" 1)
  71. (princ)
  72. )
  73. (defun OLEtoRGB_color (OLE_color / r g b)
  74. (setq r (lsh OLE_color -16))
  75. (setq g (lsh (lsh OLE_color 16) -24))
  76. (setq b (lsh (lsh OLE_color 24) -24))
  77. (list r g b)
  78. )
  79. (princ)
回复

使用道具 举报

28

主题

317

帖子

292

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
140
发表于 2022-7-5 16:26:02 | 显示全部楼层
Hi Aftertouch。这里有一些想法。
 
(if(/=selectedobject nil)可以替换为(if selectedobject)。更简洁易读。很少有地方使用相同的逻辑。
(if(/=(cdr(assoc 410(entget(car selectedobject)))nil)可以替换为(if(assoc 410(entget(car selectedobject)))。如果assoc 410 deosn不存在,它将返回nil并计算If的“else”部分。也就是说,如果不进行深入分析,我不确定为什么要检查410组代码是否存在,如果存在,则使用第n个3,但我注意到,由于selectedobjecttype在这两种情况下设置为相同,因此可以从if中删除该部分,而不是在if的两个条件和下复制。这样也可以移除2个尖头。
 
同样,对于cond,您只需要查看selectedobjecttype是否是列表的成员。如果是,则selectedobjecttype将始终等于成员返回的列表的car。还要注意的是,conditional的(t部分是无用的。如果它是列表的成员,则将设置selectedobjectlayer(cdr(assoc 8 selectedobject)),但如果它不是成员,则selectedobjectlayer不存在,因此无需将其设置为nil,因为它已经是nil。如果删除cond的(t)部分,则会得到一个具有单个条件的cond,因此可以将其替换为If语句。哦,由于列表不会变化,因此可以引用它,而不是使用(list)来构建它
 
(if(/=selectedobjectlayer nil)替换为(if selectedobjectlayer
(if(/=layercolor nil)替换为(if layercolor
基本上在剩下的部分中,我使用了cond而不是嵌套if,因为对于3个选项(配色系统/真彩色/索引),它更具可读性。我还将(cdr(car(cdr layercolor)))更改为(cdadr layercolor)。括号更少,可读性更强。我没有修改任何其他内容,因为它的执行似乎完美无瑕。
 
  1. (defun C:CLC ( / selectedobject selectedobjecttype selectedobjectlayer layercolor colorbook colorbookcolor OLDCMDECHO)
  2. (setq OLDCMDECHO (getvar "cmdecho"))
  3. (setvar "cmdecho" 0)
  4. (command "UNDO" "BEGIN")
  5. (setq selectedobject (nentsel "\nSelect a line, polyline, circle or arc to change its layers color: "))
  6. (if selectedobject
  7.         (progn
  8.                 (if (assoc 410 (entget (car selectedobject)))
  9.                     (setq selectedobject (entget (car selectedobject)))
  10.                     (setq selectedobject (entget (car (nth 3 selectedobject))))
  11.                 )
  12.                        (setq selectedobjecttype (cdr (assoc 0 selectedobject)))
  13.                 (if (member selectedobjecttype '("LINE" "LWPOLYLINE" "CIRCLE" "DIMENSION" "TEXT" "INSERT" "ARC"))
  14.                            (setq selectedobjectlayer (cdr (assoc 8 selectedobject)))
  15.                 )
  16.                 (if selectedobjectlayer
  17.                         (progn
  18.                                 (setq layercolor (acad_truecolordlg 253 nil))
  19.                                 (if layercolor
  20.                                                (cond ((cddr layercolor)
  21.                                                       (setq layercolor (cdaddr layercolor))
  22.                                                       (setq colorbook (substr layercolor 1 (vl-string-position (ascii "$") layercolor 0 t)))
  23.                                                       (setq colorbookcolor (substr layercolor (+ 2(vl-string-position (ascii "$") layercolor 0 t))))
  24.                                                       (command-s "-Layer" "Color" "Colorbook" colorbook colorbookcolor selectedobjectlayer "")
  25.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " colorbookcolor "."))
  26.                                                      )
  27.                                                      ((cdr layercolor)
  28.                                                       (setq layercolor (OLEtoRGB_color (cdadr layercolor)))
  29.                                                       (setq layercolor (strcat (itoa (car layercolor))","(itoa (cadr layercolor))","(itoa (caddr layercolor))))
  30.                                                       (command-s "-Layer" "Color" "Truecolor" layercolor selectedobjectlayer "")
  31.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " layercolor "."))
  32.                                                      )
  33.                                                      ((setq layercolor (cdr (car layercolor)))
  34.                                                       (command-s "-Layer" "Color" layercolor selectedobjectlayer "")
  35.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " (itoa layercolor) "."))
  36.                                                      )
  37.                                                )
  38.                                         (princ "\nCancelled...")
  39.                                 )
  40.                         )
  41.                         (princ "\nInvalid selection.")
  42.                 )
  43.         )
  44.         (princ "\nCancelled...")
  45. )
  46. (command "UNDO" "END")
  47. (setvar "cmdecho" OLDCMDECHO)
  48. (princ)
  49. )

 
旁注:最好避免多次使用(entget)。您可以使用selectedobject,但由于我不明白您在检查410的存在性时的目标是什么,因此我无法提供多次调用entget的替代方法。
不要随意更改变量(如cmdecho)。将变量OLDCMDECHO设置为原始值,并根据需要进行更改。最后,使用OLDCMDECHO将变量恢复为其原始值。
 
干杯
回复

使用道具 举报

76

主题

312

帖子

254

银币

后起之秀

Rank: 20Rank: 20Rank: 20Rank: 20

铜币
390
发表于 2022-7-5 16:30:31 | 显示全部楼层
嘿,杰夫,谢谢你的反馈。
关于assoc 410部分:
  1.                 (if (assoc 410 (entget (car selectedobject)))
  2.                     (setq selectedobject (entget (car selectedobject)))
  3.                     (setq selectedobject (entget (car (nth 3 selectedobject))))
  4.                 )

我在这里试图做的是,当选定的对象没有410属性(模型)时,那么它是块的一部分。
在这种情况下,使用选定对象的(第n个3),它是选定线的父块(它位于第0层的块中)。
回复

使用道具 举报

58

主题

3353

帖子

33

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1761
发表于 2022-7-5 16:41:21 | 显示全部楼层
您还可以检查nentsel列表的长度。。如果是嵌套的,则长度将大于2。
  1. (setq e (nentsel))
  2. (cond ((caddr e) (car (last e)))
  3.      ((car e))
  4. )

 
这里还有另一种构建代码的方法:
  1. (if (and (setq selectedobject
  2.         (nentsel "\nSelect a line, polyline, circle or arc to change its layer color: "
  3.         )
  4. )
  5. (setq selectedobject
  6.         (cond ((caddr selectedobject) (car (last selectedobject)))
  7.               ((car selectedobject))
  8.         )
  9. )
  10. ;; Why check object type?
  11. (vl-position
  12.    (cdr (assoc 0 (entget selectedobject)))
  13.    '("LINE" "LWPOLYLINE" "CIRCLE" "DIMENSION" "TEXT" "INSERT" "ARC")
  14. )
  15. (setq layercolor (acad_truecolordlg 253 nil))
  16.    )
  17. (cond        ((assoc 430 layercolor) "do your colorbook stuff")
  18. ((assoc 420 layercolor) "do your truecolor stuff")
  19. ("do your aci stuff")
  20. )
  21. )
回复

使用道具 举报

28

主题

317

帖子

292

银币

初露锋芒

Rank: 3Rank: 3Rank: 3

铜币
140
发表于 2022-7-5 16:50:32 | 显示全部楼层
啊。。。我懂了。2件事。进一步检查项目的性质是否是该列表的成员:(“LINE”“LWPOLYLINE”“CIRCLE”“DIMENSION”“TEXT”“INSERT”“ARC”),因此如果是块插入,则需要检查两次。我将通过使用entsel而不是entsel来摆脱第一个额外步骤。在这里使用entsel对所有实体都是相同的操作。(仅当需要nentsel时才使用nentsel)。
 
通过在if中移动setq,可以进一步减少代码的长度。
 
  1. (defun C:CLC ( / selectedobject selectedobjecttype selectedobjectlayer layercolor colorbook colorbookcolor OLDCMDECHO)
  2. (setq OLDCMDECHO (getvar "cmdecho"))
  3. (setvar "cmdecho" 0)
  4. (command "UNDO" "BEGIN")
  5. (if (setq selectedobject (entsel "\nSelect a line, polyline, circle or arc to change its layers color: "))
  6.         (progn
  7.                        (setq selectedobjecttype (cdr (assoc 0 (setq selectedobject (entget (car selectedobject))))))
  8.                 (if (member selectedobjecttype '("LINE" "LWPOLYLINE" "CIRCLE" "DIMENSION" "TEXT" "INSERT" "ARC"))
  9.                            (setq selectedobjectlayer (cdr (assoc 8 selectedobject)))
  10.                 )
  11.                 (if selectedobjectlayer
  12.                         (progn
  13.                                 (if     (setq layercolor (acad_truecolordlg 253 nil))
  14.                                                (cond ((cddr layercolor)
  15.                                                       (setq layercolor (cdaddr layercolor))
  16.                                                       (setq colorbook (substr layercolor 1 (vl-string-position (ascii "$") layercolor 0 t)))
  17.                                                       (setq colorbookcolor (substr layercolor (+ 2(vl-string-position (ascii "$") layercolor 0 t))))
  18.                                                       (command-s "-Layer" "Color" "Colorbook" colorbook colorbookcolor selectedobjectlayer "")
  19.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " colorbookcolor "."))
  20.                                                      )
  21.                                                      ((cdr layercolor)
  22.                                                       (setq layercolor (OLEtoRGB_color (cdadr layercolor)))
  23.                                                       (setq layercolor (strcat (itoa (car layercolor))","(itoa (cadr layercolor))","(itoa (caddr layercolor))))
  24.                                                       (command-s "-Layer" "Color" "Truecolor" layercolor selectedobjectlayer "")
  25.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " layercolor "."))
  26.                                                      )
  27.                                                      ((setq layercolor (cdr (car layercolor)))
  28.                                                       (command-s "-Layer" "Color" layercolor selectedobjectlayer "")
  29.                                                       (princ (strcat "\nLayer: " selectedobjectlayer " changed to color: " (itoa layercolor) "."))
  30.                                                      )
  31.                                                )
  32.                                         (princ "\nCancelled...")
  33.                                 )
  34.                         )
  35.                         (princ "\nInvalid selection.")
  36.                 )
  37.         )
  38.         (princ "\nCancelled...")
  39. )
  40. (command "UNDO" "END")
  41. (setvar "cmdecho" OLDCMDECHO)
  42. (princ)
  43. )

 
如果这是我的项目,我可能会做其他事情:制作OLEtoRGB_颜色的变体,直接返回您需要的颜色,即“99171207”,而不是需要进一步处理的(99171 207)。可能是一个接受任何颜色格式和图层作为参数的sub,以使颜色相应地改变。当诸如acad_truecolordlg(点对中的str或int((62.43)(420.13676676)(430。“RAL CLASSIC$RAL 1001”))之类的函数可以返回不同格式时,使用vl princ to string可以删除一堆代码。验证更少,处理方式独特。(vl princ将wathever串起来,而不必根据性质以不同的方式对其进行操作。(itoa/rtos/as is if str)
 
最后一点,当你有很多if时,遵循流程可能是一个挑战,代码可以跨越许多行。它们可以嵌套,也可以一个接一个地嵌套。
如果(…)比做一个
如果A大于B
如果B大于C
  1. [b]Nested if:[/b]
  2. (if (...)
  3. (if A
  4.    (if B
  5.      C)
  6. )
  7. )
  8. [b]Chain of if:[/b]
  9. (if (...)
  10. A
  11. )
  12. (if A
  13.    B
  14. )
  15. (if B
  16.    C
  17. )
  18. [b]And alternative:[/b]
  19. (and (...)
  20.        A
  21.        B
  22.        C
  23. )

And和Or函数可以极大地帮助使代码更加简洁易读。看看Ron的例子
@Ronjonp你有一个(列表缺失!
回复

使用道具 举报

58

主题

3353

帖子

33

银币

顶梁支柱

Rank: 50Rank: 50

铜币
1761
发表于 2022-7-5 17:07:18 | 显示全部楼层
好眼力。。固定的
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

  • 微信公众平台

  • 扫描访问手机版

  • 点击图片下载手机App

QQ|关于我们|小黑屋|乐筑天下 繁体中文

GMT+8, 2025-3-14 21:06 , Processed in 0.362539 second(s), 64 queries .

© 2020-2025 乐筑天下

联系客服 关注微信 帮助中心 下载APP 返回顶部 返回列表