第9章访问和修改图形数据库9.1获取图元的名字AutoCAD的图形是由多个图形对象组成的,最基本的图形对象称作图元。图元之间是以链表的形式存储的。每个图元都有一个用16进制表示的唯一的名字。entnext函数可以获取图形库第一个图元的名字或指定图元的下一个图元的名字。entlast函数可以获取图形库最后一个,即最新生成的图元的名字。通过entnext函数,可以访问到图形库的每一个图元。假定本作业依次绘制了一条直线、一个圆和一个圆弧。(setqe1(entnext));返回图形库第一个图元即这条直线的图元名Entityname:7ef6ce88,并将其赋给了变量e1。(setqe2(entnexte1));返回图形库e1的下一个图元即这个圆的图元名Entityname:7ef6ce90,并将其赋给了变量e2。(setqe3(entnexte2));返回图形库e2的下一个图元即即这个图弧的图元名Entityname:7ef6ce98,并将其赋给了变量e3。(setqe4(entlast));返回图形库最后一个图元即这个图弧的图元名Entityname:7ef6ce98,并将其赋给了变量e1。因为圆弧既是第3个图元,也是最后一个图元,所以e3和e4记录的是同一图元的名字。【例9-1】绘制下图所示的4个带有中心线的螺纹孔。要求首先获取中心线的螺纹孔的图元名,然后复制这些指定名字的图元。以下表达式首先生成了两条中心线和1个螺纹孔。在生成这些图元的同时获取并保存了这些图元的名字为e1、e2、e3和e4。(commandlayermzhongxinlcenter)(commandline-5,05,0)(setqe1(entlast))(commandline0,-50,5)(setqe2(entlast))(commandlayermcuxianlw0.3)(commandcircle0,03)(setqe3(entlast))(commandlayermxixian)(commandarc-3.5,00,3.50,-3.5)(setqe4(entlast))以下表达式调用AutoCAD的copy命令,复制3个带有中心线的螺纹孔。(commandcopye1e2e3e4m0,012,024,036,0)[例9-2]定义绘制图b所示图形的命令。插入点p0、直径d、宽度b和h作为绘制该图形时交互输入的参数。该例的主要目的是示范如何利用图元名实现AutoCAD的图形编辑和填充剖面线。ab(defunc:keyway()(setqpc(getpoint输入定位点:))(setqd(getdistpc输入轴的直径:))(setqb(getdistpc输入键槽的宽度:))(setqw(getdistpc输入键槽的深度:))(setqr(*0.5d))(commandcirclepcr);绘制圆(setqe1(entlast));将entlast返回的该圆的图元名赋给e1(setqp0(polarpc0r));p0是圆上一点,将用于修剪该圆(setqp1(list(carpc)(+(cadrpc)(*0.5b))))(setqp2(list(+(carpc)(*1.2r))(cadrp1)))(commandlinep1p2)(setqe2(entlast));将entlast返回的该直线的图元名赋给e2(setqp3(list(carpc)(-(cadrpc)(*0.5b))))(setqp4(list(carp2)(cadrp3)))(commandlinep3p4)(setqe3(entlast));将entlast返回的该直线的图元名赋给e3(setqp5(list(+(carpc)(-rw))(+(cadrpc)(*0.5b))))(setqp6(list(+(carpc)(-rw))(-(cadrpc)(*0.5b))))(commandlinep5p6)(setqe4(entlast));将entlast返回的该直线的图元名赋给e4;e1、e2等作为剪切边,p0、p1等点确定被剪边和剪去哪一段(commandtrime1e2e3e4p0p1p2p3p4);e1、e2等作为剖面域的边界绘制剖面线(commandhatchansi3120e1e2e3e4);)9.2图元表图元表记录着图元的名字、类型、几何数据、图层、颜色等信息。通过修改或创建图元表,可以实现编辑或生成图元。9.2.1获取图元表例如输入下面3个表达式:(commandtext10,2050ABCDE);书写文本(setqe(entlast));获取文本的图元名,将图元的名字赋给变量e。(setqelist(entgete));获取图元名字为e的图元表。在Command:提示下键入!elist或在控制台_$提示下键入elist,即可得到以下该图元的图元表。((-1.Entityname:7ef69500);图元名(0.TEXT);图元种类(330.Entityname:7ef67d00);软指针句柄(5.19F);图元描述字(100.AcDbEntity);AutoCAD图元(67.0);模型空间(410.Model);模型空间标识(8.0);所在图层名(100.AcDbText);AutoCAD文本(1010.020.00.0);定位点坐标(40.5.0);文本字高(1.ABCDE);文本内容(50.0.0);文本的旋转角度(41.1.0);文字的宽度因子(51.0.0);文字的倾斜角度(7.STANDARD);字样的名字(71.0);正常文本(非左右或上下镜像的文本)(72.0);左下角点对齐方式(110.00.00.0);辅助的定位点坐标(2100.00.01.0);厚度方向(100.AcDbText);AutoCAD文本(73.0);不垂直书写)对图元表的补充说明:(1)图元表的每个元素还是表,子表的第一个元素是具有一定含义的整数,其含义与图元在DXF(图形交换文件)中实体代码的含义相同(详见AutoCAD有关DXF文件的介绍)。(2)多数的子表采用了点对结构,这样既节省存储空间,也可以简化运算,详见第2.4节数据的存储结构。(3)其他种类图元的图元表的非几何信息部份基本相同,几何信息部份有些差异。9.2.2对图元表的操作假定elist是某图元的图元表。利用AutoLISP有关表处理的函数可以修改图元表。(1)了解图元的种类(cdr(assoc0elist))该表达式的内层表达式中,用0作为关键字,在elist表中寻找相关的子表,返回有关图元种类的子表(0.图元种类),由于此表为点对,所以cdr函数返回它的第2个元素图元种类。若此图元为直线,则返回LINE,若此图元为单行文本,则返回TEXT。(2)了解图元所在图层的名字(cdr(assoc8elist))该表达式的内层表达式中,用8作为关键字,返回elist表中有关图层名字的子表(8.图层名),由于此表为点对,所以cdr函数返回它的第2个元素图层名。(3)了解圆、圆弧的半径或单行文本的字高(cdr(assoc40elist))该表达式的内层表达式中,用40作为关键字,返回elist表中有关圆、圆弧的半径或单行文本的字高的子表(40.数值),由于此表为点对,所以cdr函数返回它的第2个元素具体的数值。(4)了解直线的起点、圆、圆弧的中心或单行文本的定位点(cdr(assoc10elist))该表达式的内层表达式中,用10作为关键字,返回elist表中有关直线的起点、圆、圆弧的中心或单行文本的定位点的子表(10数值数值数值),注意此表不再是点对,所以cdr函数返回去掉它的第1个元素之后的子表,即点的XYZ坐标。(5)用圆、圆弧的半径或单行文本的新值取代其老值(setqelist(subst(cons40h)(assoc40elist)elist))(cons40h)构造一个新的点对子表,例如(40.3.5)。(assoc40elist)返回elist表内的点对子表,例如(40.5.0)。subst函数用新子表,例如(40.3.5),替换elist表内的老子表(40.5.0)。最外层的setq函数将替换后的赋给了变量elist。(6)更新图形库的图元表(entmodelist)entmod函数的功能是更新图形库的指定图元表的图元,即更新了实际图形对象。例如单行文本的字高由5.0改变为3.5。9.2.3举例【例9-3】定义将本作业所有的单行文本改变为指定高度的命令。右图所示为修改图形数据库内单行文本字高的程序流程图,其中e1是用于存放图元名的变量。单行文本的图元种类是TEXT,用MTEXT书写的是段落文本,它的图元种类是MTEXT。因此本程序不能修改用MTEXT书写的文本。开始输入新的字高h得到第一个图元的名字e1e1的类型是TEXT?用新的字高更新e1的图元表e1的名字为nil?令e1为e1的下一个图元名结束否否是是以下是定义改变本作业所有单行文本为指定的高度命令的程序代码:(defunc:cth(/heel)(setqh(getdist\n输入文本新的字高:))(setqe(entnext));得到第一个图元的名字(whilee;当e有定义时做以下运算(setqel(entgete));得到第一个图元的图元表(if(=TEXT(cdr(assoc0el)))(progn;如果图元的类型为TEXT时做以下运算(setqel(subst(cons40h)(assoc40el)el));新字高替换图元表的原字高(if(=3(cdr(assoc72el)));如果文本为Align方式对齐(setqel(subst(cons720)(assoc72el)el));忽略第二个定位点)(entmodel);更新图形数据库的el图元表))(setqe(entnexte));令e等于e的下一个图元名)(princ);静默退出)9.3选择集选择集是有名字的一些图元名的集合,常用于编辑或修改图形对象的命令。9.3.1常用的有关选择集的函数(1)(ssget[选择方法][点1[点2]][点表][过滤表])创建一个选择集。有以下一些选择方法。•C(Crossing):与点1、点2所确定的窗口相交的那些对象被选中。•CP(Cpolygon):与点表所确定的多边形相交的那些对象被选中。•F(Fence):与点表所确定的折线相交的那些对象被选中。•I(Implied):处于夹取(Grips)状态的那些对象被选中•L(Last):最新的、最后绘制的那个图元被选中。由于在多文档环境下最后绘制的对象并不一定是可见的,例如,这个绘图窗口被最小化或未放置在顶层,这时使用该选项将返回nil。•P(Previous):上一次创建的选择集。•W(Window):整体在点1、点2所确定的窗口之内的那些对象被选中。•WP(Wpolygon):整体在点表所确定的多边形之内的那些对象被选中。•X:整个数据库,包括被关闭、被冻结图层上的对象和屏幕之外的那些对象被选中。•:E:通过光标拾取框的那些对象被选中。•:N:在该函数的执行过程中,为选定对象调用ssnamex函数获得容器块和转换矩阵的附加信息。只有通过W、C和点拾取选择方法时,才可以使用这一附加信息。•:S:只允许单一选择集。•点1、点2、点表和过滤表是与选择方法配合使用的。•过滤表的功能是根据过滤表描述的条件对所选的对象进行筛选,只保留满足过滤条件的对象。过滤表是entget函数返回的图元表中的点对,例如(0.LINE)、(8.LAYER1)、(6.center)、(62.1),点对的第1个元素是图形交换文件中的组码,详见AutoCAD有关DXF文件的介绍。如果仅提供了一个点,该函数认为用户通过这个点来选择单个的对象。如果省略所有的参数,在调用该函数时将出现Selectobjects:提示,这用户以交互方式选择对象。在这种情况下,亮显被选取的对象。该函数忽略当前设置的对象捕捉模式。由