CAD-autolisp(一)——数据结构、函数、图元

一、概述

1.1 简介

  • 简介:cad 二次开发语言,后缀名*.lsp适用于编写小工具,不适用大量数据或者需要大量计算的场景,编译后后缀名为*.vlx
  • 优点:所有cad版本均通用,不像arx或者其他只针对固定版本
  • 缺点:不适合处理大量计算或图元场景,超过1000个单元即有轻微等待卡顿,软件加密困难

1.2 打开编辑器

  • cad命令行输入:vlisp
  • cad菜单:管理–>visual lisp 编辑器
  • cad菜单:工具–> auto lisp–>visual lisp 编辑器

1.3 调试页面

  • 主编辑窗口
    在这里插入图片描述
  • 跟踪变量值
    在这里插入图片描述

二、数据类型

  • 常量:数字、nil、t、null
  • 变量
    数据类型意义数据类型意义
    浮点型REAL整型INT
    字符串STRLIST
    文件描述符FILE符号SYM
    选择集PICKSET图元名ENAME
    内部LISP函数SUBR外部ads函数EXSUBR
  • 查看类型语句:(type item)

三、函数

  • 地位:lisp中万物皆函数,函数均用括号括起来
  • 返回值:默认返回函数内最后一个表达式的结果

3.1 用户函数

  • 代码示例
    ;不传参函数,cad命令行输入(demo1)运行
    (defun demo1 ()
    	;此处可以写语句
    )
    ;传参函数,cad命令行输入(demo2 3)运行
    (defun demo2 (a)
    	;此处可以写语句
    )
    ;传参函数,cad命令行输入demo3运行
    (defun c:demo3 ()
    	;可以直接调用当前源码文件中其他函数
    	(demo1)
    )
    ;定义了参数a和局部变量r(作用域仅函数内,用完即释放内存)
    (defun c:demo4 (a / r)
    	(demo2 3)	
    )
    

四、语句

4.1 常规语句

4.1.1 赋值语句

  • 代码
    ;赋值,必须以括号括起来每一个语句
    (setq a 1)
    (setq a 1.0)
    (setq a "1")
    ;连续赋值
    (setq a 1 b 2)
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;赋值表,list函数,返回(1 2 0),对每个表元素做类型检测
    (setq a (list 1 2 0))
    ;赋值表,英文单引号,返回值相同,不对每个表参数做类型检测
    (setq a '(1 2 0))
    ;获取表元素:(car a)返回1,(cadr a)返回2,(caddr a)返回0
    ;删除表首元素: (cdr a)返回(2 0),不修改a元素
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;交互式赋值:getreal、getint、getpoint
    (setq a (getreal "\n请输入一个实实数:"))
    (setq distance (getdist '(0 0 0) "两点直接距离为:"))
    

    cad命令行获取变量值:cad命令行输入!a,即可返回a的值

  • 设置系统变量
    (defun C:demo ()
      (print "start testing")
      ; 获取系统变量,设置系统变量,这里是获取设置对象捕捉
      (setq osmode_bak (getvar "osmode"))
      (setvar "osmode" 0)
      (print "do sth")
      ; 还原系统变量,可以注释这一条看效果
      (setvar "osmode" osmode_bak)
      (princ)
    )
    

4.1.2 命令行输出语句

  • 代码示例
    ;cad命令行输出:不分辨转义字符,先换行再打印,最后加一个空格
    ;常用于打印非字符串元素
    ;命令: DEMO1
    ;"\na"
    ;"\na"
    (defun c:demo1 ()
      (print "\na")
      (print "\na")
      (setq a "test")
      ;函数会返回最后一个表达式的返回值,
      ;此句让函数最后返回空
      (princ)
    )
    ;cad命令行输出:分辨转义字符,常用于打印字符串
    ;命令: DEMO2
    ;a
    ;a
    (defun c:demo2 ()
      (princ "\na")
      (princ "\na")
      (setq a "test")
      ;函数会返回最后一个表达式的返回值,
      ;此句让函数最后返回空
      (princ)
    )
    ;cad命令行输出:常用于跟文件打印连用
    ;命令: DEMO3
    ;"\na""\na"
    (defun c:demo3 ()
      (prin1 "\na")
      (prin1 "\na")
      (setq a "test")
      ;函数会返回最后一个表达式的返回值,
      ;此句让函数最后返回空
      (princ)
    )
    

    多语句拼接:(princ "\na的值是:") (princ a)

4.1.3 运算语句

  • 代码示例
    ;代表1>0,返回T,假的话返回nil
    ;还有< <= >= > = /=
    (> 1 0)
    ;代表1+0,返回1,还有+ - * / 
    (+ 1 0)
    ;特例,相当于(+ i 1),和(- i 1)
    (1+ i)
    (1- i)
    ;循环中i自加1
    (setq i (1+ i))
    

4.1.4 逻辑语句

  • 代码示例
    ;逻辑与语句
    (and (> a b) (< c d))
    ;逻辑或语句
    (or (> a b) (< c d))
    ;否定语句
    (not (= a 1))
    

4.1.5 直接调用cad原生命令

  • 代码示例
    (defun c:demo4 ()
      ;最后一个""是命令最后输入的enter
      (command "line" '(0 0) '(100 100) "")
      ;两点画圆
      (command "circle" "2p" '(0 0) '(100 100))
      ;屏幕点选画圆
      (setq	center (getpoint "\n请输入或选择圆心:"))
      (setq	radius (getdist center "\n请输入或选择半径:"))
      (command "circle" center radius)
      ;command函数正常执行返回值是nil
      ;删除最后一个生成的元素
      (command "erase" (entlast) "")
      (princ)
    )
    

4.2 流程控制语句

4.2.1 判断语句

  • 代码示例
    ;单语句判断,若第二个语句不写,则默认为nil
    (if (> a 1)
    	;常量可直接写
    	"如果为真,返回这句话"
    	"如果为假,返回这句话"
    )
    (if (> a 1)
    	;如果真返回第一个表达式,如果假返回第二个
    	(setq a 1)
    	(setq a 2)
    )
    ;多语句判断
    (setq a (getint "请输入一个整型:"))
    (if (> a 1)
      (progn (princ "a") (princ "b"))
      (progn (princ "c") (princ "d"))
    )
    

4.2.2 循环语句

  • while、repeat语句
    ;while语句:指定条件
    (defun c:demo1 ()
      (setq a 0)
      (while (< a 500)
      	;循环打印0~499
      	(print a)
        (setq a (1+ a))
      )
      (princ)
    )
    ;repeat语句:指定次数
    (defun c:demo1 ()
      (setq a 0)
      (repeat 3
      	;循环3次
      	(print a)
        (setq a (1+ a))
      )
      (princ)
    )
    
  • 针对数组遍历函数
    ;foreach语句:遍历表
    (defun c:demo1 ()
      (setq s '(1 2 3))
      (foreach temp s
      	(print temp)
      )
      (princ)
    )
    ;mapcar语句:遍历表,并配置遍历函数,
    ;           foreach的升级版,功能相同
    (defun c:demo2 ()
      ;匿名函数lambda:将每个元素传入temp,处理后返回
      (setq s_recal (mapcar '(lambda (temp) (1+ temp)) '(1 2 3)))
      (print s_recal)
      (princ)
    )
    ;mapcar语句:做更复杂的遍历操作	
    (defun c:demo3 ()
      (setq a (mapcar 'find_ele (entget (car (entsel)))))
      ;输出((-1 . <图元名: 7ff4650e9180>) nil nil nil nil nil nil 。。。)
      (print a)
      (princ)
    )
    
    (defun find_ele	(temp)
      ;函数返回值会被添加进a中
      (if (= -1 (car temp)) temp)
    )
    
    ;vl-remove-if函数:返回b的值为remove的元素
    ;                 即返回不满足函数判断式的元素
    ;vl-remove-if-not函数:返回b为符合函数判断式的元素
    (setq a (list 3 4 5 6 7))
    (setq b (vl-remove-if '(lambda (temp) (> temp 5)) a))
    
    

4.2.3 条件判断语句

  • 代码示例
    (defun C:demo ()
      (setq a (getint "输入一个整数:"))
      (cond
        (
         (= a 1)
           (alert "输入了1")
           (alert "结束1")
        )
        (
         (= a 2)
           (alert "输入了2")
           (alert "结束2")
        )
        (T
           (alert "输入了其他")
           (alert "结束其他")
        )
      )
      (princ)
    )
    

4.2.4 高频应用

  • 查找表中元素并替换
    (defun c:demo1 ()
    	(setq s '((1 2) (3 4) "12" "34"))
    	(setq i 0 new ())
    	(repeat (length s)
    		(if (= (nth i s) "12")
    			(setq new (append new (list "56")))
    			(setq new (append new (list (nth i s))))
    		)
    		(setq i (1+ i))
    	)
    	(print new)
    	(princ)
    )
    

五、图元操作

5.1 定义

  • 定义:每个可视cad元素均为一个图元,图元之间以链表形式互相连接,可以用(entsel “提示文字,选填”)命令选择,返回:(图元名,点选处的坐标)
  • 示例如下图
    在这里插入图片描述

5.2 图元选择

  • 常用语句
    ;以下命令在命令栏测试
    ;图中点选图形元素
    (setq e1 (entsel "请在途中选择图元:\n"))
    ;选择刚刚点选的下一个元素:因为是链表存储,所以按
    ;绘图顺序依次选取下一个
    (setq e2 (entnext (car e1)))
    ;选择第一个图元
    (setq e3 (entnext))
    ;选择最后一个(还未删除的)元素
    (setq e4 (entlast))
    

    命令栏返回:(<图元名:>(鼠标点选图元时的坐标,注意不是图元的夹点))
    显示验证:可以在命令行输入move命令,在选择对象处输入!e2,图中会虚线显示被选中图元,(type e2)返回enname

  • 命令行获取图元属性列表:(entget (car (entsel))),图中选择图元并返回图元属性列表

5.3 图元属性列表

5.3.1 分部每个函数意义

  • 获取图元属性点对列表
    ;以下命令在命令栏测试
    ;图中点选圆这个元素
    (setq e1 (entsel "请在图中选择图元"))
    ;获取图元名
    (setq e1_name (car e1))
    ;显示图元属性列表:元素为圆
    
  • 获取点对列表中的某一点对
    ;获取属性点对列表的所有项,以下是圆的 
    (setq ent_list (entget e1_name))
    ;!ent_list返回:((-1 . <图元名: 7ff425c06280>) (0 . "CIRCLE") 
    ;(330 . <图元名: 7ff425c039f0>) (5 . "2D8") (100 . "AcDbEntity") 
    ;(67 . 0) (410 . "Model") (8 . "0") (100 . "AcDbCircle") 
    ;(10 0.0 0.0 0.0) (40 . 1000.0) (210 0.0 0.0 1.0))
    
    ;获取属性列表的某一项,组码为40,返回:(40 . 1000.0)
    ;若组码填10,返回:(10 0.0 0.0 0.0)
    (setq old_r (assoc 40 ent_list))
    
  • 生成点对(注意跟表list的区别)
    ;数点对表的构建,下式返回:(40 . 500.0)
    (setq new_r (cons 40 500.0))
    
    ;坐标点对表的构建,下式返回:(10 1000 1000 0)
    ;(cons 10 '(1000 1000 0))或(cons 10 (list 1000 1000 0))
    
    ;字符点对表的构建,下式返回:(8 . "图层1")
    ;(cons 8 "图层1")
    
    ;不可用列表生成点对列表
    错误 (setq list1 (list (1 . 2) (2 . 3)))
    可以 (setq list1 '((1 . 2) (2 . 3)))
    
  • 替换原属性点对列表的一项
    ;subst函数:用新点对表更新旧点对表,并返回替换后的点对列表
    ;          此处用返回值直接重新赋值原属性表变量
    (setq ent_list (subst new_r old_r ent_list))
    
    ;如果是随层的、随块的,如颜色线性等,属性列表中是不显示的,需要新增
    ;生成(62 . 1),然后打开ent2_list,并将之前点对列表加进并覆盖ent2_list
    (setq ent2_list (cons (cons 62 1) ent2_list))
    
  • 刷新更新模型区图像
    ;entmod函数:返回更新后的图元属性列表,entmod更新图元,
    ;          并将更新后的图元属性列表重新赋值给ent_list
    (setq ent_list (entmod ent_list))
    

5.3.2 综合修改并更新图元

  • 选择并修改圆颜色
    ;获取图元属性列表
    (setq ent_list (entget (car (entsel))))
    ;因为随层,圆颜色点对表不存在,新增
    (setq ent_list (entmod (cons (cons 62 3) ent_list)))
    ;因刚已新增颜色项目,可以直接修改颜色项
    (setq ent_list (entmod (subst (cons 62 5) (assoc 62 ent_list) ent_list)))
    
  • 新建圆
    ;entmake函数:给出最少参数,图元类型,颜色,圆心,半径
    ;等同(command "circle" '(1000 0 0) 1)
    (entmake '((0 . "CIRCLE") (62 . 1) (10 1000.0 0.0 0.0) (40 . 1.0)))
    

返回目录

  • 25
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值