You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

AutoCAD LISP系统变量设置与重置异常:PLINE执行前变量提前恢复

问题分析

你的核心问题是AutoCAD LISP中command函数的执行逻辑导致的:当你在command里使用PAUSE时,LISP只会暂停等待用户的单次输入(比如PLINE的起点),一旦用户完成这个输入,LISP就会继续执行后续代码(也就是varset),但此时PLINE命令还处于交互状态(用户还在绘制线段、还没结束命令),所以系统变量提前被重置,不符合你的预期。

另外你的代码还有个隐性bug:lisvarvarget函数内的局部变量,varset函数无法正确访问它们,这可能导致变量重置不完全。

解决方案

我们分两步修复问题:

1. 修复变量作用域问题

把需要跨函数访问的变量设为全局变量(用星号前缀标识,这是AutoCAD LISP的惯例),确保varset能正确读取之前保存的系统变量值:

(defun varget () 
  (setq *lis* '("orthomode" "snapmode"))  ; 定义全局变量保存系统变量名称
  (setq *var* (mapcar 'getvar *lis*))     ; 保存原始系统变量值
  (setq var1 '(1 1)) 
  (setq no 0) 
  (repeat (length *lis*) 
    (setvar (nth no *lis*) (nth no var1)) 
    (setq no (1+ no)) 
  ) 
  (princ) 
) 

(defun varset () 
  (setq no 0) 
  (repeat (length *lis*) 
    (setvar (nth no *lis*) (nth no *var*)) 
    (setq no (1+ no)) 
  ) 
  (princ) 
) 

2. 等待PLINE命令完全结束后再重置变量

不要在command调用里直接带PAUSE,而是先启动PLINE命令,然后通过循环等待cmdactive系统变量变为0(表示当前没有活跃命令),确保用户完全结束PLINE操作后再执行后续代码。同时我们用cond替代多个IF,让代码更简洁:

(defun C:wire () 
  (progn 
    (varget) 
    (setq prevlayer (getvar "clayer")) 
    ; 转大写避免用户输入小写导致匹配失败,添加换行让提示更友好
    (setq P (strcase (getstring "\nAudio(A)/Video(V)/Comm(CO)/Coax(R)/Control(C)/(N)etwork/(P)ower:")))
    
    (cond
      ((= P "V")
        (command "-LAYER" "M" "VIDEO" "C" "150" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "A")
        (command "-LAYER" "M" "AUDIO" "C" "94" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "CO")
        (command "-LAYER" "M" "COMM" "C" "206" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "R")
        (command "-LAYER" "M" "COAX" "C" "44" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "C")
        (command "-LAYER" "M" "CONTROL" "C" "10" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "N")
        (command "-LAYER" "M" "NETWORK" "C" "210" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
      ((= P "P")
        (command "-LAYER" "M" "POWER" "C" "7" "" "")
        (command "PLINE")
        (while (not (zerop (getvar 'cmdactive)))
          (command pause)
        )
      )
    )
    
    (setvar "clayer" prevlayer) 
    (varset) 
    (princ) 
  )
)

额外优化说明

  • strcase处理用户输入,避免因大小写导致的匹配失败
  • cond替代多个独立IF,代码结构更清晰易维护
  • getstring添加换行符,让命令行提示更易读

这样修改后,当你执行wire命令选择线路类型后,PLINE会正常运行直到你手动结束(按回车/空格确认),之后LISP才会执行图层恢复和系统变量重置,完全符合你的预期。

内容的提问来源于stack exchange,提问作者Perry Chapman

火山引擎 最新活动