4/29/2016

AutoLISP 开发者指南

1 引言

  • LISP: LISt Processing language
  • AutoCAD支持AutoLISP,但不支持许多Visual LISP functions 或 Microsoft ActiveX Automation interface
  • 没有一个集成开发环境
  • Application Programming Interface (API)

使用AutoLISP语言

AutoLISP基础

  • 能够使用 number, string and list-handing functions 来自定义AutoCAD
  • AutoLISP不需要编译,能够在命令行直接输入代码,并立即看到结果

AutoLISP表达式

  • 表达式的格式:
(function  
arguments
)
(fun1 (fun2
arguments) (fun3
arguments)
)

示例:

(* 2 27)

54
(* 2 (+ 5 10))

30
AutoLISP 函数语法
  • 约定俗成的语法:
(foo string [number ...])

foo: 函数名
string: 必要参数
number: 可选参数

AutoLISP 数据类型

  • Integers: 整数

    • 32位有符号数字:+2,147,483,647 ~ -2,147,483,648(note: getint函数只接受16位整数(+32767 ~ -32768))
2147483647

2147483647
2147483648

2.14748e+009
(+ 2147483646 3)

-2147483647
(+ 2147483648 2)

2.14748e+009
-2147483647

-2147483647
-2147483648

-2.14748e+009
(- -2147483648 1)

-2.14748e+009
  • Reals: 实数

    • -1 ~ 1之间的实数必须包含前导0
    • 实数以双精度浮点数格式存储
    • 可用科学计数法表示
  • Strings: 字符串

"\nEnter first point:"
  • Lists: 列表
(1.0 1.0 0.0)

("this" "that" "the other")

(1 "ONE")
  • Selection Sets: 选择集

    • 选择集是包含一个或多个对象(或实体)的集合,你能够交互地向选择集中增加对象,或从选择集中删除对象
    • 下面的例子用ssget函数返回一个drawing中所有对象的选择集
(ssget "X")

<Selection set: 6>
  • Entity Names: 实体名(图元名)

    • 一个实体名是指派给某个drawing对象的数字标签
    • 它实际上是某个AutoCAD文件中的指针,并且能被用来找到对象的数据库记录和它的向量
    • 该标签能够被AutoLISP函数引用以进行各种处理
    • AutoCAD内部引用对象作为实体
    • 下面的例子使用entlast函数得到输入drawing中的最后一个对象
(entlast)

<图元名: -16bbe0>

图元名指的是drawing中仅在当前编辑会话期间有效的对象
  • File Descriptors: 文件描述符

    • _文件描述符_是一个指向AutoLISP open 函数打开的文件的指针
    • open 函数以字母数字标签的形式返回该指针
    • 其他AutoLISP函数可以应用该指针读或写所指向的文件
(setq file1(open "test.dwg" "r"))

#<file "test.dwg">
------
(close file1)

nil
  • Symbols and Variables: 象征符号与变量

    • AutoLISP使用象征符号指代数据
    • 象征符号名大小写敏感,可以包含任意顺序的字母数字和符号(除了以下的限制符号
    • 象征符号名不能仅包含数字字符
Notation characters descriptions
( (Open Parenthesis)
) (Close Parenthesis)
. (Period)
(Apostrophe)
" (Quote Symbol)
; (Semicolon)
(setq str1 "this is a string")

"this is a string"

AutoLISP 程序文件

  • AutoLISP 源代码文件的扩展名为 .lsp
空格
  • 变量名、常量、函数名之间的多个空格被视作一个空格;行尾被视作一个空格
(setq test1 123 test2 456)

(setq
    test1 123
	test2 456
)

两者结果相同
注释
  • 注释符号为分号 ;, ;| ... |;,注释可用来做以下事情:
    • 给出题目、作者和创建日期
    • 提供使用说明
    • 做解释性的备注
    • 在调试过程中做备注
; This entire line is a comment
(setq area (* pi r r)) ; Compute area of circle
; 行内注释
(setq tmode ;|some note here|; (getvar "tilemode"))
; 多行注释
(setvar "orthomode" 1) ;|comment starts here
and continues to this line,
but ends way down here|; (princ "\nORTHOMODE set On.")
变量
  • setq 函数将值赋给变量
(setq
	variable_name1 value1 [variable_name2 value2 ...]
)
(set val 3 abc 3.875)

3.875
(setq layr "EXTERIOR-WALLS")

"EXTERIOR-WALLS"
  • 显示变量的值,用 !
!abc

3.875
  • nil 变量
    • 没有被赋值的变量;不同于空(blank),也不同于0,前者是一个字符串,后者是一个数字
    • 设置一个变量为Nil将释放掉该变量值所占据的内存空间
(setq val nil)

nil
  • 预定义变量
    • PAUSE: 包含\\的一个字符串,该变量配合command函数来暂停用户输入
    • PI: 一个常量,近似等于3.14159
    • T: 一个常量,被用作一个non-nil
    • 注意:这些预定义变量的值可以使用setq函数来修改,但不建议这样做

数字处理

(* 2.5 13)

32.5
(/ 12 5)

2
(/ 12.0 5)

2.4

字符串处理

  • strcase 函数用来转换字母大小写,包含两个参数:一个字符串,一个可选参数
(strcase "This is a TEST.")

"THIS IS A TEST."
(strcase "This is a TEST." T)

"this is a test."
  • strcat 函数将多个字符串合并为一个字符串
(setq str "BIG")(setq bigstr (strcat "This is a " str " test."))

"This is a BIG test."
  • strlen 函数返回字符串长度
(strlen bigstr)

19
  • substr 函数返回一个字符串的子串,包含2个必要参数和一个可选参数:字符串、第一个字母的位置(从1开)和字母的数量

    • 定义一个文件名,获取子串
(setq filnam "bigfile.txt")

"bigfile.txt"
(setq newlen (- (strlen filnam) 4))

7
------
(substr filnam 1 newlen)

"bigfile"

或者,合并为一行代码:

(substr filnam 1 (- (strlen filnam) 4))

"bigfile"

基本输出函数

文本输出
  • 主要的文本输出函数包括:
prin1
princ
print
prompt
  • princ: 输出无引号封闭的字符串
  • prinl: 输出有引号封闭的字符串
  • print: 输出有引号封闭的字符串,但在表达式前放一个空行,其后放一个空格
(setq str "The \"allowable\" tolerance is 1\/4")

"The \"allowable\" tolerance is 1/4"

(prompt str)

The "allowable" tolerance is 1/4nil

(princ str)

The "allowable" tolerance is 1/4"The \"allowable\" tolerance is 1/4"

(prin1 str)

"The \"allowable\" tolerance is 1/4""The \"allowable\" tolerance is 1/4"

(print str)

"The \"allowable\" tolerance is 1/4" "The \"allowable\" tolerance is 1/4"
  • 安静退出:使用一个不带参数的 princ 函数
控制字符串中的字母
Code Description
\ \
" "
\e Escape character
\n Newline character
\r Return character
\t Tab character
\nnn 八进制编码nnn的字符
  • promptprinc 扩展了这些控制字符
(princ "The \"filename\" is: /ACAD/TEST.TXT.")

The "filename" is: /ACAD/TEST.TXT."The \"filename\" is: /ACAD/TEST.TXT."
(prompt "An example of the \nnewline character.")

An example of the
newline character.nil
通配符匹配
  • 通配符(wild-card)与其它语言的正则表达式(regular expressions)类似
  • wcmatch 函数能够用来进行字符串和通配符的比较
(setq matchme "this is a string - test1 test2 the end")

"this is a string - test1 test2 the end"

(wcmatch matchme "this*")

T

; 如果包含 "test4", "test5", "test6" or "test9",将返回 T
(wcmatch matchme "*test[4-69]*")

nil

(wcmatch matchme "*test[4-61]*")

T

(wcmatch matchme "ABC,XYZ*,*end")

T

等式和条件

  • AutoLISP 在某些情况下会自动将象征表名转化为大写,此时进行比较时可能需要用到 strcase 函数

列表处理

  • 列表中的项不需要数据类型相同
(setq lst1 (list 1.0 "One" 1))

(1.0 "One" 1)
  • nth 函数检索列表中的某一项,包含两个参数:起始序号(从0开始),列表本身
(nth 1 lst1)

"One"
  • cdr 函数返回除第一个元素外的所有元素
(cdr lst1)

("One" 1)
  • append 函数向列表尾增加一个新项,并返回一个新列表;并且其所有参数必须是列表
; 注意:quote函数(or ')很容易将一个字符串添加进一个列表
(setq lst2 (append lst1 '("One")))

(1.0 "One" 1 "One")
  • cons函数向列表头增加一个新项,并返回一个新列表
(setq lst3 (cons "Ones" lst2))

("Ones" 1.0 "One" 1 "One")
  • subst函数用新项替换掉原列表中所有出现的老项,并返回一个新列表
(setq lst4 (subst "one" "One" lst3))

("Ones" 1.0 "one" 1 "one")
点列表
(list 3.875 1.23)

(3.875 1.23)

(list 88.0 14.77 3.14)
(setq pt1 (list 3.875 1.23))

(3.875 1.23)

(setq pt2 (list 88.0 14.77 3.14))

(88.0 14.77 3.14)

(setq abc 3.45)

3.45

(setq pt3 (list abc 1.23))

(3.45 1.23)
  • 当列表的所有项均为常数时,可使用 quote 函数
(setq pt1 (quote (4.5 7.5)))

(4.5 7.5)

; 功能同上
(setq pt1 '(4.5 7.5))

(4.5 7.5)
(setq pt '(1.5 3.2 2.0))

(1.5 3.2 2.0)
  • car 函数返回列表的第一项
(setq x_val (car pt))

1.5
  • cadr 函数返回列表的第二项
(setq y_val (cadr pt))

3.2
  • caddr 函数返回列表的第三项
(setq z_val (caddr pt))

2.0
; 定义矩形的左下角和右上角坐标
(setq pt1 '(1.0 2.0) pt2 '(3.0 4.0))

(3.0 4.0)

; 定义坐标的左上角坐标
(setq pt3 (list (car pt1) (cadr pt2)))

(1.0 4.0)
  • AutoLISP 支持 carcdr 最深4层的串联
(caar x)	; 等同于 (car (car x))

(cdar x)	; 等同于 (cdr (car x))

(cadar x)	; 等同于 (car (cdr (car x)))
点对(dotted pairs)
  • 点对列表必须总是包含2项
  • 大多数列表处理函数不接受点对作为一个参数
  • car, cdr, assoc 函数可以处理点对
(setq sublist (cons 'lyr "WALLS"))

(LYR . "WALLS")
(setq wallinfo (list sublist (cons 'len 240.0) (cons 'hgt 96.0)))

((LYR . "WALLS") (LEN . 240.0) (HGT . 96.0))
(assoc 'len wallinfo)

(LEN . 240.0)

(cdr (assoc 'lyr wallinfo))

"WALLS"

(nth 1 wallinfo)

(LEN . 240.0)

(car (nth 1 wallinfo))

LEN

符号和函数处理

defun 定义一个函数
  • defun 函数要求至少三个参数:函数名、参数列表和表达式
(defun symbol_name (args / local_variables) expressions)
(defun DONE () (prompt "\nbye!"))

DONE
(prompt "The value is 127.")(DONE)

The value is 127.
bye!nil
------
(prompt "The value is 127.")(DONE)(princ)

The value is 127.
bye!
C:XXX 函数
  • 可以用此函数定义新的命令或重定义已有的命令
  • 必须服从以下规则:
    • 函数名必须为C:XXXC:xxx形式:C: 部分必须存在;XXX 为你定义的命令名
    • 不能带参数(除了 local variables)
(defun C:HELLO () (princ "Hello world. \n")(princ))

C:HELLO
  • 重定义AutoCAD命令
(defun C:LINE () (princ "Shouldn't you be using PLINE?\n") (command ".LINE")(princ))

C:LINE

(command "undefine" "line")
; 禁止输出重复信息
(defun C:LINE (/ cmdsave) (setq cmdsave (getvar "cmdecho")) (setvar "cmdecho" 0) (princ "Shouldn't you be using PLINE?\n") (command ".LINE") (setvar "cmdecho" cmdsave) (princ))

C:LINE
  • 重定义命令后,要使用原内置命令,可以使用.前缀命令,如.line
函数中的局部变量 local variables
  • 声明全局变量:*default-layer*
; 定义带局部变量的函数
(defun LOCAL (/ aaa bbb)
(setq aaa "A" bbb "B")
(princ (strcat "\naaa has the value " aaa))
(princ (strcat "\nbbb has the value " bbb))
(princ))

LOCAL
(setq aaa 1 bbb 2)

2
(local)

aaa has the value A
bbb has the value B
带参函数
  • 用户自定义函数不能包含_可选参数_
; 注意:这里不能使用 princ 函数抑制程序返回值
(defun ARGTEST (arg1 arg2 / ccc)
(setq ccc "Constant string")
(strcat ccc ", " arg1 ", " arg2))

ARGTEST
(setq newstr (ARGTEST "String 1" "String 2"))

"Constant string, String 1, String 2"

; 程序执行完成,局部变量`ccc`所占用的内存空间就被释放了
!ccc

nil
  • 特殊形式
and
command
cond
defun
defun-q
foreach
function
if
lambda
or
progn
quote
repeat
setq
trace
untrace
vlax-for
while

AutoLISP 中的错误处理

*error* 函数
vl-catch-all-apply 函数

(alert "File not found")

; 将弹出一个警告框

使用AutoLISP与AutoCAD进行交流

访问命令与服务

命令提交

(command "circle" "0,0" "3,3")
(command "thickness" 1)
(setq p1 '(1.0 1.0 3.0))
(setq rad 4.5)
(command "circle" p1 rad)
  • 外国语支持

  • 暂停用户输入

没有评论:

发表评论

Cloudflare R2 + WebP Cloud + uPic 免费图床方案

搭建免费全球可访问的图床方案:Cloudflare R2 + WebP Cloud + uPic