Установка и сброс системных переменных - AutoCAD LISP - PullRequest
2 голосов
/ 09 июля 2019

Я пытаюсь сделать рисование монтажных схем в AutoCAD чрезвычайно простым, не нажимая кнопки, кроме моих предварительно запрограммированных.

Один включает в себя LISP, который не очень хорошо настраивает системные переменные, а затем сбрасывает их на прежние значения. Программа, кажется, выполняет намеченную функцию, но не с намеченными результатами.

Как только моя команда PLINE запускается, переменные сбрасываются. Мне нужно PLINE, чтобы начать, закончить, и , а затем , чтобы получить переменные.

Я пытался установить OrthoMode и SnapMode внутри команды в LISP, а также с помощью команд (setvar (getvar ...)).

(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 Ответ

3 голосов
/ 09 июля 2019

Проблема с вашим кодом заключается в том, что вы делаете паузу только для одного пользовательского ввода, прежде чем пытаться сбросить системные переменные и завершить оценку программы.

Вместо этого вам нужно будет использовать цикл для непрерывногосделайте паузу для ввода данных пользователем, прежде чем продолжить оценку программы.

Например:

;; 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

Несколько замечаний:

  • Всегда указывайте свой местныйпеременные, чтобы избежать столкновения с переменными с одинаковыми именами в пространстве имен документа.См. Мое руководство здесь для получения дополнительной информации о том, как и почему вы это делаете.

  • Используйте getkword вместо getstring для контроля и проверки ввода пользователя.

  • Используйте "\\" вместо символа pause, так как символ pause является незащищенной глобальной переменной иможет быть непреднамеренно переопределен за пределами вашей программы, что приведет к ее разрыву.Поскольку символ pause оценивается как "\\", вы также можете использовать буквальную обратную косую черту.

В качестве расширения вы можете также рассмотреть возможность реализации локального обработчика ошибок для обработки, когдапользователь неизбежно нажимает Esc во время оценки программы (в этом случае системные переменные не будут сброшены).Я описываю, как это сделать, в моем уроке здесь .

Вот базовый пример, демонстрирующий включение локального обработчика ошибок:

;; 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
...