设置和重置系统变量-AutoCAD LISP

时间:2019-07-09 14:21:57

标签: lisp autocad autocad-plugin autolisp

我正在尝试使AutoCAD中的接线图非常容易,除了我预先编程的按钮外,没有其他按钮可以按下。

涉及一个LISP,该LISP不能很好地设置系统变量,然后将其重置为以前的状态。该程序似乎执行了预期的功能,但未达到预期的结果。

一旦我的PLINE命令启动,变量将被重置。我需要PLINE才能开始,完成操作,然后然后重置变量。

我尝试在LISP中的命令中以及通过(setvar (getvar ...))命令来设置OrthoMode和SnapMode。

(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)
)

(princ)

(defun C:wire ()
(progn
(varget)
(setq prevlayer (getvar "clayer"))
(setq P (getstring "Audio(A)/Video(V)/Comm(CO)/Coax(R)/Control(C)/(N)etwork/(P)ower:"))
(IF (= P "V")(command "-LAYER" "M" "VIDEO" "C" "150" "" "" "PLINE" PAUSE))
(IF (= P "A")(command "-LAYER" "M" "AUDIO" "C" "94" "" "" "PLINE" PAUSE))
(IF (= P "CO")(command "-LAYER" "M" "COMM" "C" "206" "" "" "PLINE" PAUSE))
(IF (= P "R")(command "-LAYER" "M" "COAX" "C" "44" "" "" "PLINE" PAUSE))
(IF (= P "C")(command "-LAYER" "M" "CONTROL" "C" "10" "" "" "PLINE" PAUSE))
(IF (= P "N")(command "-LAYER" "M" "NETWORK" "C" "210" "" "" "PLINE" PAUSE))
(IF (= P "P")(command "-LAYER" "M" "POWER" "C" "7" "" "" "PLINE" PAUSE))
(setvar "clayer" prevlayer)
(varset)
(princ)
);Progn
);defun

无错误消息。

我希望在执行PLINE命令后在 之后将变量重置。

1 个答案:

答案 0 :(得分:3)

代码的问题在于,在尝试重设系统变量并完成程序评估之前,您仅暂停单个用户输入即可。

相反,在继续进行程序评估之前,您将需要使用循环来连续暂停用户输入。

例如:

;; Define function, declare local symbols
(defun c:wire ( / col lay opt val var )

    ;; System variables to be modified within the program
    (setq var '(clayer orthomode snapmode cmdecho)
    ;; Retrieve current sys var values
          val  (mapcar 'getvar var)                
    ) ;; end setq

    ;; Predefine the getkword options
    (initget "Audio Video COmm R Control Network Power")
    ;; Prompt the user for input, default to "Audio" on null input
    (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))

    ;; Define the layer & colour based on the option returned
    (cond
        (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
        (   (= opt "Video")   (setq lay "VIDEO"    col 150))
        (   (= opt "COmm")    (setq lay "COMM"     col 206))
        (   (= opt "R")       (setq lay "COAX"     col  44))
        (   (= opt "Control") (setq lay "CONTROL"  col  10))
        (   (= opt "Network") (setq lay "NETWORK"  col 210))
        (   (= opt "Power")   (setq lay "POWER"    col   7))
    ) ;; end cond

    ;; Suppress command-line output for the -LAYER command
    (setvar 'cmdecho 0)
    ;; Create & set the layer & layer colour
    (command "_.-layer" "_M" lay "_C" col "" "")

    ;; Set everything except the first sys var
    (mapcar 'setvar (cdr var) '(1 1 1))
    ;; Initiate the PLINE command
    (command "_.pline")
    ;; Continuously pause for user input
    (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))

    ;; Reset system variables
    (mapcar 'setvar var val)

    ;; Suppress the value returned by the last evaluated expression
    (princ) 
) ;; end defun

需要注意的几点:

  • 始终声明局部变量,以避免与文档命名空间中名称相同的变量发生冲突。有关如何以及为什么执行此操作的更多信息,请参见我的教程here

  • 使用getkword代替getstring来控制和验证用户的输入。

  • 使用"\\"代替pause符号,因为pause符号是不受保护的全局变量,很容易在程序外部无意中被重新定义,从而导致程序打破。由于pause符号的计算结果为"\\",因此您也可以使用文字反斜杠。

作为扩展,您可能还想考虑实现一个本地错误处理程序,以在用户在程序评估期间不可避免地按下 Esc 时进行处理(否则,在这种情况下不会重置系统变量) )。我将在教程here中介绍如何执行此操作。

这是一个基本示例,演示了包含本地错误处理程序的情况:

;; Define function, declare local symbols
(defun c:wire ( / *error* col lay opt val var )

    ;; Define local error handler
    (defun *error* ( msg )
        ;; Reset system variables
        (mapcar 'setvar var val)
        ;; Suppress the output of standard cancellation messages
        (if (not (wcmatch (strcase msg t) "*break,*cancel*,*exit*"))
            ;; Print critical errors
            (princ (strcat "\nError: " msg))
        ) ;; end if
        (princ) ;; Suppress the value returned by the last evaluated expression
    ) ;; end defun

    ;; System variables to be modified within the program
    (setq var '(clayer orthomode snapmode cmdecho)
    ;; Retrieve current sys var values
          val  (mapcar 'getvar var)                
    ) ;; end setq

    ;; Predefine the getkword options
    (initget "Audio Video COmm R Control Network Power")
    ;; Prompt the user for input, default to "Audio" on null input
    (setq opt (cond ((getkword "\n[Audio/Video/COmm/Coax(R)/Control/Network/Power] <Audio>: ")) ("Audio")))

    ;; Define the layer & colour based on the option returned
    (cond
        (   (= opt "Audio")   (setq lay "AUDIO"    col  94))
        (   (= opt "Video")   (setq lay "VIDEO"    col 150))
        (   (= opt "COmm")    (setq lay "COMM"     col 206))
        (   (= opt "R")       (setq lay "COAX"     col  44))
        (   (= opt "Control") (setq lay "CONTROL"  col  10))
        (   (= opt "Network") (setq lay "NETWORK"  col 210))
        (   (= opt "Power")   (setq lay "POWER"    col   7))
    ) ;; end cond

    ;; Suppress command-line output for the -LAYER command
    (setvar 'cmdecho 0)
    ;; Create & set the layer & layer colour
    (command "_.-layer" "_M" lay "_C" col "" "")

    ;; Set everything except the first sys var
    (mapcar 'setvar (cdr var) '(1 1 1))
    ;; Initiate the PLINE command
    (command "_.pline")
    ;; Continuously pause for user input
    (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\"))

    ;; Reset system variables
    (mapcar 'setvar var val)

    ;; Suppress the value returned by the last evaluated expression
    (princ) 
) ;; end defun