AutoLISP-自动更改图层

问题描述 投票:1回答:1

我想创建一个简单的AutoLISP例程,在该例程中,我在"0"层中绘制线,然后再更改回原始层。

使用下面的代码,我可以画一条线,但是它将保留在当前层中。如果我放出最后一条代码行,则会在"0"层中绘制该行,但是此后没有任何更改可返回到原始层。

(defun c:testfunction (/ OLD)
  (setq OLD (getvar 'clayer))
  (setvar 'clayer "0")
  (command "line")
  (setvar 'clayer OLD)
)

代码概念

首先将当前图层存储在OLD变量中,然后将图层更改为"0"。在LINE命令之后,我改回到OLD层。

先谢谢您。

lisp autocad autocad-plugin autolisp
1个回答
0
投票

暂停输入

由于AutoCAD LINE命令可以向用户发出任意数量的提示(取决于他们希望绘制的线条数),因此,您需要在代码中包括一个循环以允许任意数量的提示。用户输入,然后重置当前层。

您当前的代码将计算表达式LINE 之前用户已经提供了第一行点,因为用户输入没有暂停。

对于从AutoLISP程序或工具栏宏调用的AutoCAD命令中的(setvar 'clayer OLD),请使用反斜杠pause for user input

但是,由于反斜杠是AutoLISP中的\,因此您需要在其前面加上另一个反斜杠,以便将literal反斜杠输出到命令,例如escape character

此外:\\符号也计算为反斜杠,但是由于该符号不受保护并且可以重新定义,因此我始终建议您使用文字反斜杠。

所以我们可以使用:

pause

但是,这仅在单个输入时暂停,并且AutoCAD pause命令将接受任意数量的输入,因此我们需要一种构造循环并确定用户何时完成该命令的方法。

为此,我们可以使用(command "line" "\\") 系统变量,它是指示当前命令状态的位编码系统变量-LINE位代码指示命令处于活动状态。

[要测试是否设置了位代码LINE,我们可以使用AutoLISP CMDACTIVE函数,该函数返回两个提供的整数的按位CMDACTIVE,例如:

1

将其与1系统变量结合在一起:

logand

如果命令处于活动状态,它将返回logand,否则返回AND

因此我们循环的测试表达式可以是:

AND

现在只剩下构造循环本身了,为此,我们可以使用AutoLISP (logand 1 3) => 1 (logand 1 2) => 0 函数:

CMDACTIVE

当命令处于活动状态时,以上内容将继续暂停以供用户输入。

全部放在一起

将所有内容放在一起,我们有:

CMDACTIVE

但是,我们在这里还可以进行其他一些增强...

其他增强功能

  • 我们可以在函数定义的末尾添加(logand 1 (getvar 'cmdactive)) 表达式,以抑制最后一个求值表达式返回的值。按照编写,当前函数将返回1函数返回的值,它将是原始图层的名称。

    我们可以在定义的末尾使用0代替向命令行返回空符号,从而干净地退出程序:

    (= 1 (logand 1 (getvar 'cmdactive)))
    
  • 我们可以在AutoCAD while命令的调用前加上下划线,以说明AutoCAD的本地化版本(在其中while命令可能被称为其他名称:]

    (while (= 1 (logand 1 (getvar 'cmdactive)))
        (command "\\")
    )
    

    使用下划线命令前缀可确保我们正在调用非本地化的英语(defun c:testfunction ( / old ) (setq old (getvar 'clayer)) (setvar 'clayer "0") (command "line") (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\") ) (setvar 'clayer old) ) 命令。

  • 我们可以在AutoCAD (princ)命令的调用前加上句号,以说明可能重新定义的AutoCAD (princ)命令的版本:

    setvar

    由于可以重新定义AutoCAD命令,因此使用句点命令前缀可确保我们正在调用未重新定义的标准setvar命令。

  • 如果用户按下Esc退出程序,我们可以添加本地错误处理程序以将当前层自动重置为原始层:

    (princ)

    有关本地错误处理程序如何运行的更多信息,您可能希望参考我在(princ)上的AutoLISP教程。

  • [[我们还可以进行测试以确保在尝试将层(defun c:testfunction ( / old ) (setq old (getvar 'clayer)) (setvar 'clayer "0") (command "line") (while (= 1 (logand 1 (getvar 'cmdactive))) (command "\\") ) (setvar 'clayer old) (princ) ) 设置为当前层之前未冻结,但这超出了该初学者程序的范围。

扩展想法

通过上述方法,我们定义了自己的自定义函数来存储当前层,设置新的当前层,调用LINE命令,然后重置原始的当前层。

但是这意味着用户必须记住调用我们的自定义版本的LINE命令,而不是标准的LINE命令。

如果调用

standard AutoCAD命令时,有一种方法可以<>设置并重置当前图层怎么办?好吧,通过使用Visual LISP Reactor,可以实现。在我的开源LINE应用程序中,我演示了如何在调用标准AutoCAD命令时使用Command Reactors和LISP Reactors自动创建,设置和重置当前层:

(command "_line")
© www.soinside.com 2019 - 2024. All rights reserved.