我想创建一个简单的AutoLISP例程,在该例程中,我在"0"
层中绘制线,然后再更改回原始层。
使用下面的代码,我可以画一条线,但是它将保留在当前层中。如果我放出最后一条代码行,则会在"0"
层中绘制该行,但是此后没有任何更改可返回到原始层。
(defun c:testfunction (/ OLD)
(setq OLD (getvar 'clayer))
(setvar 'clayer "0")
(command "line")
(setvar 'clayer OLD)
)
代码概念
首先将当前图层存储在OLD
变量中,然后将图层更改为"0"
。在LINE
命令之后,我改回到OLD
层。
先谢谢您。
由于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")