收藏 分享(赏)

AutoCAD图块实体几何信息的提取.doc

上传人:eukav 文档编号:4386940 上传时间:2018-12-26 格式:DOC 页数:21 大小:57KB
下载 相关 举报
AutoCAD图块实体几何信息的提取.doc_第1页
第1页 / 共21页
AutoCAD图块实体几何信息的提取.doc_第2页
第2页 / 共21页
AutoCAD图块实体几何信息的提取.doc_第3页
第3页 / 共21页
AutoCAD图块实体几何信息的提取.doc_第4页
第4页 / 共21页
AutoCAD图块实体几何信息的提取.doc_第5页
第5页 / 共21页
点击查看更多>>
资源描述

1、AutoCAD 图块实体几何信息的提取刘贤喜中国农业大学(100083)摘 要本文介绍了在不“炸开(EXPLODE) ”AutoCAD 图块的前提下,利用 ADS 和 C 语言直接访问 AutoCAD 图形数据库的结果缓冲器,提取或处理图块内部所含全部子实体几何信息的方法。关键词 AutoCAD 图块 几何信息提取 ADS 接口 DXF 码1 问题的提出AutoCAD 是优秀的计算机辅助设计软件,不但具有友好的交互绘图功能,而且提供了强大的二次开发工具,如 ADS、ARX 等。但在 AutoCAD 交互绘图环境中,对插入其中的图形块只作为一个整体来处理,仅直接提供其插入点的坐标值、比例因子和旋

2、转角度等有限的几何信息,而不能直接提供图形块内部所有子实体的几何信息;若要对图块进行编辑修改,首先要用“EXPLODE” 命令将图块分解为若干相互独立的几何实体。我们在开发“饲料加工工艺设计专家系统(FPES) ”时,用图块来表示饲料加工设备图形符号,为了让计算机能够在 AutoCAD 环境下自动生成饲料加工工艺流程图,不仅要识别图块所表示的加工设备,还要处理图块的外轮廓,以便于自动确定设备位置。如果用“EXPLODE”命令将设备图块炸开,则就不再具有设备图形符号的含义了,计算机也就无法对设备进行智能处理。为此我们利用 ADS 开发了一个智能模块,能够在不炸开图块的前提下,自动获取图块内部所含

3、全部子实体几何信息的,提高 AutoCAD 对图块的智能处理能力。2 实现原理DXF(Drawing Exchang File)码是 CAD 领域的工业标准之一,在计算机内存中,可以把 DXF 看成是 AutoCAD 将当前图形数据库的 ASCII 码映像。在 AutoCAD图形数据库中实体类型(Entity)是预先定义的图形元素,如点(POINT) 、直线(LINE) 、圆(CIRCLE)、插入的块(INSERT)等。实体 名(Entity Name)用一个长整数表示,实际上是指向 AutoCAD 当前图形数据库的指针,通过这个指针,可以找到该实体在当前图形数据库中的记录。结果缓冲器是 AD

4、S 支撑环境的核心概念之一。一个结果缓冲器被用来代表 AutoCAD 的实体和各种表(BLOCK、LTYPE 、VIEW、LAYER、STYLE 等)的数据信息,这些数据信息在结果缓冲器中都被映象为 DXF 组码与组值。结果缓冲器在 ADS 中是这样定义的:union ads_u_val /不同数据类型的联合ads_real rreal;ads_real rpoint3;short rint;char *rstring;long rlname2;long rlong;struct ads_binary rbinary;struct rebuf /结果缓冲器的结构struct rebuf *rb

5、next;short restype;union ads_u_val resval;在 AutoCAD 当前数据库中,首先获取一个实体,并该得到实体的结果缓冲器,当 DXF组码为 0时,其组值为实体类型,即:LINE、CIRCLE、ARC、PLINE、INSERT 等;当 DXF组码为 2 时,其组值为图块名称;当 DXF 组码为 10 时,其组值根据实体类型的不同而表示不同的含义,可以是LINE 的起点坐标,或是 CIRCLE 或 ARC 的中心坐标等。当不同内容的结果缓冲器链接成一个链表时,它们就可以用来表示 AutoCAD 的图形实体和表记录了。如:一个锤片粉碎机图形符号的块名为“CF”

6、 ,其插入块的结果缓冲器表的结构如图1所示:由于所有图块的定义信息(包括几何信息)都以 DXF 组码与组值的形式存放在一个“BLOCK”符号表中,所以在 AutoCAD 的“BLOCK”符号表中检索指定的图块名,就可得到该图块全部定义信息的存储首地址,并将其作为一个结果缓冲器链表。在循环遍历该结果缓冲器链表的过程中,通过 DXF 组码与组值,来判别块内子实体的类型,并提取有关几何信息。3 程序流程图流程图如图 2 所示。要获得一个图块的全部几何信息,首先要在 AutoCAD 当前图形数据库中确定一个实体(可以人为指定或程序自动获取) ,接下来,根据其 DXF 组码与组值,判断该实体是否为插入图

7、块,当 DXF 码为 0 时,若 DXF 组值不是“INSERT” ,该实体则不是图块,程序返回;若 DXF 组值为“INSERT” ,则是图块,程序继续进行,当 DXF 组码为 2 时,其组值便为该图块的块名。然后,在 AutoCAD 的“BLOCK”符号表中检索该块名,从而获得该图块信息链表的头指针,并遍历该链表,再根据链表中的不同 DXF 组码与组值确定块内子实体的不同类型,并提取的相关几何信息,如:起点、终点、圆心、半径、多义线的顶点、圆弧的起角、终角等等。注意,由于块内的坐标值都是相对于块实体自身的实体坐标系(ECS)的值,所以,求得有关几何信息后,还要根据 AutoCAD 当前绘图

8、环境中的坐标系、插入图块的插入点、X、Y 方向的比例以及旋转角度等,对块内几何信息进行相关的平移变换、比例变换或旋转变换等坐标变换,直到该链表的标尾。这样,便达到了不“炸开”图块就可获取其内部全部几何信息的目的。程序是用 C 语言和 ADS 函数在 Windows 环境下编写的(源程序从略) 。4 结论利用上述方法开发的图形智能化处理模块,在“饲料加工工艺流程设计专家系统(FPES) ”中收到较好的效果。FPES 在利用知识库中的知识和规则进行饲料加工工艺设计的同时,调用模块对设备图形符号进行智能处理,并自动生成设备布局合理的、符合有关标准的饲料加工工艺流程图。参 考 文献1.刘贤喜面向对象的

9、饲料加工工艺设计专家系统的研究:学位论文北京:中国农业大学, 1998 2.刘贤喜,陈忠良,李晓民饲料加工工艺设计专家系统的设计中国农业大学学报,1998,3(4) :4750 3.方铁AutoCADC 语言高级编程北京:清华大学出版社, 1995 年 1 月 通讯地址:北京中国农业大学东区 213 信箱,邮编: 100083,联系人:刘贤喜电 话:623928593.8 在 AutoCAD 中选择实体1. ads_name在 AutoCAD 2000 中仍为此名、acdbNameSet()ads_name_set()、acdbNameEqual()ads_name_equal()、acdbN

10、ameClear()ads_name_clear()、acdbNameNil()ads_name_nil()在 ADS、ADSRX 或 ObjectARX 中,选择实体的方法没有变化,但在ObjectARX 2000 中改变了一些函数名(其他函数名没有改变,对于第 6 章讨论的数据类型和 DCL 对话框也基本是这样的)。我们介绍一种新的数据类型:ads_name。这种类型数据用来保存成功选择实体的结果。通常,选择实体是为了用户能获得并修改实体特性。这里是老式的 ADS 和现代的 API ObjectARX完全不同的地方。在讨论 ADS 和 ObjectARX 在获得实体数据方面的差别之前,先来

11、看一看 ads_name 的定义。ads_name 数据类型是一个具有两个 long 型元素的数组,因此不能使用赋值操作符使一个 ads_name 对象等于另一个 ads_name 对象。这种情形类似于前文的 ads_point 数据类型。正如 ads_point 数据类型一样,AutoCAD 提供了一个名为 acdbNameSet()的宏,用来使一个 ads_name 对象等于另一个 ads_name对象。ADS/ADSRX 提供了许多宏来处理 ads_name 对象。要使一个 ads_name对象等于另一个 ads_name 对象,可以用 acdbNameSet()宏。要判断两个ads_n

12、ame 对象是否相等,可以用 acdbNameEqual()宏。要把一个空值(NULL)赋给一个 ads_name 对象,可以用 acdbNameClear()宏。要测试一个 ads_name对象的值是否有效,可以用 acdbNameNil()宏。下面为一段代码实例:2. acedEntSel()ads_entsel()、acdbEntGet()ads_entget() 、acdbEntMod()ads_entmod()、acdbEntUpd()ads_entupd()请牢记选择集也是 ads_name 对象(我知道这可能引起不小的混淆)。我们很快就会讨论选择集。前文谈到 ADS 和 Obje

13、ctARX 在获得和更改实体数据的方法上是完全不同的,在后面的章节中我们将讨论 ObjectARX 的方法。在 ADSRX 中,使用 acdbEntGet()函数获得实体数据,使用 acdbEntMod()和 acdbEntUpd()函数修改和更新实体。下面是这些函数的定义:用 acedEntSel()函数选择的实体将和 ads_name 对象相关联。在详细讨论acedEntSel()函数之前,先要谈一下 acdbEntGet()、acdbEntMod()和acdbEntUpd()函数。acdbEntGet()函数返回一个结果缓冲区的单链表。使用resbuf 对象的 rbnext 字段可以遍历

14、和检测结果缓冲区链表。若 rb 为一个 resbuf 结果缓冲区,则语法如下:之后还可以改变某些结果缓冲区中的值,当最终完成后调用 acdbEntMod()函数修改实体的内部数据。正如所见,该函数要求一个 resbuf 对象。如果正在处理一个如 块或多段线一样的复杂对象,可以使用 acdbEntUpd()函数来观察由各个 acdbEntMod()函数调用所做的修改效果。从本质上讲,使用 ADSRX 就是处理结果缓冲区链表。ObjectARX 的方法与此是完全不同的,且差别巨大。对于有大量旧数据的用户,由于有 ADSRX,这些函数在 ObjectARX 中仍然可以使用(Autodesk 公司的人

15、把 ADS 放进了 ObjectARX)。由于本书是讨论ObjectARX,因此,关于 acdbEntGet()、acdbEntMod()和acdbEntUpd()函数的讨论就到此为止。现在回到 acedEntSel()函数,因为该函数在 ObjectARX 中仍然得到广泛应用。再一次把 acedEntSel()函数的定义说明如下:acedEntSel()函数暂停运行等待用户输入,并在 entres 中返回实体名,在ptres 中返回选择实体使用的点。参数 str 指定 acedEntSel()函数暂停前显示的字符串。参数 str 是可选的,如果是 NULL,AutoCAD 显示缺省提示“Se

16、lect objects:”。当用户指定一个复杂实体响应 acedEntSel()函数时,则返回多段线或块的标题。如果 acedEntSel()函数调用成功,则返回RTNORM,失败则返回 RTERROR,如果用户取消(按 Esc 键)则返回RTCAN。acedEntSel() 函数可以和 acedInitGet()函数结合使用,如前面实例代码段所示。acedEntSel()函数在 ObjectARX 中是怎样使用的呢?AutoCAD 把图形作为数据库来处理。在每个打开的 AutoCAD 图形中的每一个实体都有一个唯一的AutoCAD 数据库对象 ID 与之关联。通过其对象的 ID 号我们可以

17、打开AutoCAD 实体,确定要处理什么类型的实体。然后我们可以使用实体的获得和设置方法(函数)来操作实体。一旦有了一个 ads_name 对象,我们就能得到关联的AutoCAD 数据库对象 ID(数据类型为 AcDbObjectId)。下面就是得到一个AutoCAD 数据库对象 ID 的函数定义:ads_name 对象是使用 acedEntSel()函数选择实体成功的结果。下面是一段使用 acedEntSel()函数的 ObjectARX 代码:该函数用 pEnt 返回 AcDbEntity 指针,注意是怎样用 acedEntSel()函数选择AutoCAD 实体的。3. acdbEntLa

18、st()ads_entlast()、acedNEntSel()ads_nentsel() 、acedNEntSelP()ads_nentselp()在 ADS 中还有几个其他的实体选择函数:acdbEntLast()、acedNEntSel()和acedNEntSelP()。先看一下 acdbEntLast()函数。AutoCAD 始终知道最近生成的一个实体,该实体可以通过 acdbEntLast()函数找到。acdbEntLast() 函数的定义如下:acdbEntLast()函数在图形中找出最近的实体,并把图形数据库中最近的(未删除的)主实体名存入 result。即使最近的实体在屏幕之外或

19、在冻结的层上也能选到。最近的实体是指最近创建的实体,所以 acdbEntLast()函数可用于获得刚加进AutoCAD 数据库中实体的实体名。如果 acdbEntLast()函数调用成功,返回 RTNORM,否则返回 RTERROR。对于块和多段线复杂实体,ADS 函数 acedNEntSel()和 acedNEntSelP()(代表嵌套的实体选择)将选择属性(假定选择了块实体,且块的属性已定义)和顶点信息(假定选择了多段线) 。与 acedNEntSel()函数相比,Autodesk 推荐使用acedNEntSelP()函数。acedNEntSelP()函数比 acedNEntSel()函数

20、增加了更新的内容,所以我们只讨论 acedNEntSelP()函数。下面是acedNEntSelP()函数的定义:这是一个带有许多参数的复杂函数。acedNEntSelP()函数暂停运行等待用户输入,并传回一个实体名(存入 entres)和一个用于选择实体的点(存入 ptres)。参数pickflag 的值为 FALSE 或 TRUE,用于指定 acedNEntSelP()函数是否可以人机交互(即允许用户选择与输入点对应的点)。如果 pickflag 的值为 FALSE,acedNEntSelP()函数提示用户指定实体,参数 ptres 的初始值被忽略了。如果 pickflag 的值为 TRU

21、E,ptres 的初始值被用于选择实体。我几乎未使用过 pickflag 为 TRUE。如果需要其他参数的说明,请参阅 ADSRX文档。如果 str 为 NULL,AutoCAD 就用标准的“Select objects:|”提示。我最感兴趣的参数是 entres,其中存放一个顶点或一个属性。3.9 应用程序实例 CH3_1 要点的进一步分析在应用程序实例 CH3_1.ARX 中,就在创建第一个圆之后使用了 acedGetXXX()类函数。现在再来看一看这些函数。在 while 循环中,我们询问用户是否需要再画一个圆。只要用户不回答“No”,就会不断地要求用户画圆。让我们来观察一下 while

22、 循环的前两行:acedInitGet()函数中的关键字表是 “Yes No”,第一个参数是 NULL,所以我们能够接受空输入。我们本可以使用 RSG_NONULL 迫使用户打入“Y”或“N”。在一般情况下,AutoCAD 的缺省选项用尖括号表示,这里是 。如果用户输入“Y”,字符串 kw 的值将为“Yes”。如果用户输入“N”,kw 的值将为“No”。然而,如果用户只按 Enter 键,kw 将为一空串。这种情形由 switch 语句的 RTNONE case 处理,把“Yes”复制到 kw 缓冲区。记住acedInitGet()函数只适用于紧跟其后的 acedGetXXX()类函数。再次运

23、行该应用程序时,试着输入一些不是“Y”或“N”的字母,看看会发生什么。你会重复地得到提示直至按下 Y、N 或 Enter 键。如果用户要再画圆,程序就进入 if 语句的 else 分支,并要求用户选择圆心,如下面的代码所示:这里,我们使用 RSG_NONULL 调用 acedInitGet()函数,因为我们要用户选择一个圆心。在下一句的 acedGetPoint()函数调用中,注意第一个参数是NULL。记住在 acedGetPoint()函数中,第一个参数可以用作选点的参考点。这是第一个点,所以我们使用 NULL。当要求选择圆心时试着按 Enter键,会重新提示选择圆心。当输入圆半径时,我们使

24、用 acedGetDist 函数替代 acedGetPoint()函数,因为acedGetDist 函数的响应允许我们选择一个点或从键盘输入一个距离值。下面是使用 acedGetDist()函数的代码:注意我们怎样用 RSG_NONULL、RSG_NOZERO 和 RSG_NONEG 的组合来调用 acedInitGet()函数。这是因为我们要使用跟在 acedInitGet()函数设置之后的 acedGetDist()函数。acedGetDist()函数中的第一个参数是 cp,这是我们前面选定的点。从点 cp 开始会画出一条橡皮筋线。当用户选定第二点后,从点 cp 到第二点之间的距离被存入变

25、量 rad,这是一个 ads_real 数据类型的变量。然而,用户还可用键盘敲入数值。我们不允许零和负数输入,这就是为什么在调用 acedInitGet()函数时还包括 RSG_NOZERO 和 RSG_NONEG 的原因。在用户定义的带有一个 ads_name 类型参数的 printEntInfo()函数中,我们调用acdbEntGet()函数检索结果缓冲区链表。如果调用成功,结果缓冲区链表会包含实体的数据结构,如下列代码段所示:我们使用 rbEnt-rbnext 字段来遍历链表,并检测 rbEnt-restype 字段的值,这一字段表示存储在 rbEnt-resval 字段中的数据类型。3

26、.10 选择集一个选择集就是 AutoCAD 当前图形中的一组实体,通过名字加以引用,在这里是一个 ads_name 对象。选择集非常类似于 AutoCAD 实体的“组(group)” 。一旦拥有一个选择集,就可以确定组成选择集的实体数量(也称为选择集长度引用)。既然我们知道了选择集的长度,我们就可以使用循环机制遍历选择集中的每个实体,并 读取和修改实体。一个实体在一个选择集中只能表示一次,然而一个实体可以属于多个选择集。如果我们有一个选择集 ss1,并希望向选择集中添加一条直线实体,我们可以手工选择直线实体。按规则我们可以多次选择直线实体,但在选择集中多次选择的实体只表示一次。假定我们现在创

27、建第二个选择集 ss2,并选择同一条直线实体,那么该实体就被加到第二个选择集中。现在直线实体出现在 ss1 和 ss2 两个选择集中,但在每一个选择集中直线实体只表达一次。选择集是实体的有名集合,选择集中的实体由 AutoCAD 用户手工选择或依据实体特性加入。依据特性选择实体,如选择“parts” 层上半径小于 0.25 的所有圆,这允许我们把它们的半径改为 0.375。选择集甚至可以选择被冻结的图层上的实体。选择集也可以是空的它只是存放 AutoCAD 实体的一个容器,就像放糖果的纸袋一样,如果你没有在里面放糖果或者你已把它们全部吃光,纸袋就空了。表 3-6 列出了处理选择集的 ADS 函

28、数。表 3-6 ADS 的选择集函数选择集函数 说 明 等效的 AutoLISP 函数acedSSGet() 选择要加到选择集中的实体 ssgetacedSSLength() 返回指定选择集的长度 sslengthacedSSAdd() 添加实体到已有选择集或新建一空选择集 ssaddacedSSDel() 从已有选择集中删除实体 ssdelacedSSName() 在选择集中检索出实体的 ads_name ssnameacedSSMemb() 测试某实体是否为选择集的成员 ssmembacedSSFree() 释放选择集 1. acedSSGet()ads_ssget()选择集是 ads_n

29、ame 对象,为了把实体加入到指定的选择集,必须使用acedSSGet()函数选择实体,或者假如预先知道实体名,则可使用 acedSSAdd()函数。下面是 acedSSGet()函数的定义:acedSSGet()函数返回一个选择集,当指定了一种 AutoCAD 选取模式时就获得该选择集,选取模式可以通过 AutoCAD 用户的提示或过滤图形数据库指定。使用 acedSSGet()函数有多种方式。首先我们将说明函数中的各个参数,然后阐述使用 acedSSGet()函数的各种方式。参数 str 是指定实体选取模式的可选字符串。参数 pt1 和 pt2 指定若干选取模式的可选点。对于 polygo

30、n(多边形)或 fence(栏选)选取模式选项,参数 pt1 还可以是一个含有多个点的结果缓冲区链表。参数 filter 是一个可选的结果缓冲区链表,能使 acedSSGet()函数过滤图形以选择具有某种类型与(或)具有某种特性的实体。无论你使用哪一种模式来获得选择集,都用参数ss 来标识选择集的名称。参数 str 指定要使用哪一种选取模式,它可以是表 3-7所列字符串之一。从表 3-7 可以看出有多种选择集的选取模式,如果想探讨所有的选项,可参阅帮助文档。一般我只做两件事:让用户选择实体(NULL 选项)或根据特性选择实体(“X” 选项) 。下面是一些有代表性的调用 acedSSGet()函

31、数的程序代码。如 acutBuildList()函数调用示例那样,对于多边形选项 CP 和 WP(但不包括 F)会自动封闭列出的点,不必把终点指定为起点。表 3-7 acedSSGet()函数的选取模式选项:参数 str 的值值(选取模式 ) 说 明NULL 单点选择(指定 pt1)或用户选择(pt1 也是 NULL)“I” 指定 PICKFIRST 实体集“C” Crossing 选取模式“CP” Crossing polygon 选取模式“F” Fence(或 open polygon)选取模式“L” Last 选取模式,选择最近生成的实体“P” Previous 选取模式,选择上一个选择

32、集“W” Window 选取模式“WP” Window Polygon 选取模式“X” 只用于过滤选取模式“G” Groups 选取模式“:$” Prompts supplied 选取模式“:?” “Other” callbacks 选取模式“:D” Duplicates allowed 选取模式“:E” Everything in aperture 选取模式“:K” Keyword callbacks 选取模式“:N” Nested 选取模式“:S” 单一对象选取模式“.” 用户选取模式“#” 非几何选取模式(all、last、previous)“A” All 选取模式“B” BOX 选取模

33、式“M” Multiple 选取模式3.10.1 选择集的过滤为了使用选择集过滤模式,参数 str 必须指定为“X” 。选择集过滤模式允许依据特性选择实体。过滤参数是一个结果缓冲区表,在这里给 acedSSGet()函数详细说明了要使用的实体种类和特性种类。如果过滤参数是 NULL,并且参数 str为“X”,则选择集 ss 将包含当前 AutoCAD 图形中的每一个实体,而不考虑实体是否在冻结的层上。函数调用如下:现在选择集 ss 将包含当前 AutoCAD 图形中的每一个实体。那么我们怎样选择数据库中所有的圆实体呢?为了有效地使用选择集,必须知道 DXF 组码。首先我们必须构造一个结果缓冲区

34、,但因为我们只寻找一种实体,所以我们可以使用 acutNewRb()函数来创建该结果缓冲区。下面是一段代码实例:下面的程序代码实例生成由某一图层上所有的实体组成的选择集。图层的 DXF组码是 8。好了,下面我们举一个稍微复杂一点的例子,假定我们要选择“parts” 层上的所有圆。这是一个利用 acutBuildList()函数构造结果缓冲区表后再传给acedSSGet()函数的实例。3.10.2 选择集的关系过滤在选择集中可以使用关系运算符。例如:我们要选取“parts” 图层上半径大于等于 2.0 的所有圆。在缺省情况下,acedSSGet() 函数选取满足过滤表中所有条件的实体。过滤时每两

35、个项之间的隐含关系是“相等(equals)” 。对于数值型组码(整数、实数、点和向量) ,借助在结果缓冲区中包含一个说明关系运算符的特殊组码“-4”可以指定其他的关系运算。该运算符应用于紧跟其后的结果缓冲区项。关系运算符由字符串指定。表 3-8 列出了所有的关系运算符。关系运算符可以用实例来很好地说明,继续我们所举的例子:选取“parts” 图层上半径大于等于 2.0 的所有圆。其程序代码如下:表 3-8 选择集过滤表的关系运算符关系运算符 说 明“*” 任意(始终为真)“=” 等于“!=” 不等于(C/C+)“/=” 不等于(AutoLISP)“=” 大于或等于“&” 按位 “与”( 只用于

36、整数组码)“&=” 按位等于(只用于整数组码)3.10.3 选择集的条件过滤除关系测试外,我们还可以使用条件运算符。表 3-9 列出了所有的选择集条件运算符。表 3-9 选择集过滤表的条件运算符起始运算符 中间内容 终止运算符“”“”“”“”选择集的条件运算符允许我们执行像选择图形中半径为 1.0 的所有圆和“parts”图层上的所有直线这一类的选择集操作。编程后代码如下:本例有助于掌握选择集的关系过滤和条件过滤。3.10.4 选择集的扩展实体数据过滤从 R11 版本起,AutoCAD 就有了一个为实体添加数据的机制,称为扩展实体数据(xdata)。我不准备深入讨论扩展实体数据,因为从 Aut

37、oCAD R13 c4a 起,在 AutoCAD R14 和以后的版本中引入了一种新的机制称为 XRecords,这在后面的章节中将会加以讨论。扩展实体数据通常是由外部应用程序附加到一个对象上的文本串、数值、3D 点、距离、层名或其他数据。扩展数据的大小是每个实体 16KB。注意 XRecords 是不附加于任何实体的,因此XRecords 的存在并不需要实体的存在。借助在过滤表中使用-3 组码标记指定应用程序名,就可以检索扩展数据。acedSSGet() 函数返回登记有特定名称的扩展数据的实体集合,acedSSGet() 函数并不检索单个扩展数据项 (组码范围为 10002000)。下面为选

38、择所有实体的代码段,所有实体均有以其应用程序 ID 号为“APPNAME”注册的扩展数据:在 ADSRX 文档中,有关扩展实体数据的信息还有很多,但由于 AutoCAD R14和以后的版本使用 XRecords,因此,在后面的章节中我们将详细讨论XRecords。3.10.5 转换矩阵和选择集acedXformSS()ads_xformss()借助 acedXformSS()函数,选择集可以使用转换矩阵。利用转换矩阵,可以变比、移动、旋转或镜像选择集中的实体。这可以用适当的矩阵元素设置调用acedXformSS()函数来实现,而不是循环整个选择集并执行 acedCommand()/acedCm

39、d()函数来变比、移动、旋转或镜像每一个实体。在这里我不想完整地讨论矩阵代数学。ObjectARX 已经定义了处理矩阵代数的数值函数(见 AcGeMatrix2d 和 AcGeMatrix3d 矩阵操作类) 。前面讲过转换矩阵是一个具有 ads_real 数据类型的 44 阶数组。矩阵的前三列确定比例和旋转,第四列是一个平移向量。矩阵的最后一行其值规定为0 0 0 1,传递 ads_matrix 型参数的函数忽略了此值。ADSRX 为平移操作定义符号 T,如下所示:acedXformSS()函数的定义如下:acedXformSS()函数将一个转换矩阵 genmat 应用于由 ssname 指定

40、的选择集。参数 genmat 是一个 44 阶矩阵。如果 genmat 没有均匀变比, acedXformSS()函数返回 RTERROR。把转换矩阵应用于选择集是不使用 acedCommand()、acedCmd()或 acdbEntMod()函数即在选择集中变比、旋转或移动实体的一种方法。如果 acedXformSS()函数调用成功返回 RTNORM,否则返回RTERROR。下面是一段初始化矩阵的程序代码:在上面的函数中,我们使用嵌套的 for 循环初始化了 ads_matrix 类型的参数id(各元素的值为 0),然后再用一个 for 循环初始化了元素 0,0 1,1 2,2 和 3,3

41、 使其值为 1。现在矩阵被初始化为恒等矩阵。观察如下由 Tx、Ty 和 Tz 决定的平移矩阵:改变第四列中的前三个元素的值并应用 acedXformSS()函数,选择集中的所有实体将沿 X、Y 和 Z 方向移动适当的距离。注意,如果只需要在 X 方向移动,那么只需改变矩阵中的 Tx 值。当处理选择集和 acedXformSS()函数时,所有的比例系数必须相等,即Sx=Sy=Sz。还有像旋转矩阵之类的其他 2D 和 3D 操作(参阅 ADSRX 和ObjectARX 文档)。现在让我们来看一个用于选择集操作的转换矩阵实例。这是要对选择集实施变换的矩阵,X、Y 和 Z 方向的缩放系数是 0.5,选

42、择集的移动距离是(20.0,5.0) 。下面是程序代码:3.10.6 选择集的操作既然我们已经看到有各种方法创建选择集,现在就让我们来看看操作这些选择集的函数。也许我们要知道的第一件事是有多少实体组成了该选择集。1. acedSSLength()ads_sslength()acedSSLength()函数返回组成选择集的实体个数。其定义如下:acedSSLength()函数返回一个长整数 len,表示选择集 sname 中含有的实体个数。结果是特定实体的个数,不管选择集是怎样选取的,选择集不包含重复的实体。如果 acedSSLength()函数调用成功,返回 RTNORM,否则返回一个错误码。

43、acedSSLength()函数通常和 for 循环连用,如下例程序代码所示:2. acedSSName()ads_ssname()在上述代码中,如果 acedSSLength()函数返回的变量 len 的值大于 0,那么我们就能够得到一个由长整型变量 i 表示在选择集中位置的特定实体。为得到在选择集特定位置上的实体,可以使用 acedSSName()函数。表示实体在选择集中位置的序号从 0 开始,第一个实体的序号是 0。下面是 acedSSName()函数的定义:acedSSName()函数选取选择集 ss 中位置序号为 i 的实体,并在 entres 中返回实体名。实体从 0 开始编号,所

44、以 i 必须是非负的且不大于选择集中最后一个实体的序号(acedSSLength(ss)-1)。在用 acedSSGet()函数获得的选择集中的实体名总是主实体名。acedSSName() 函数不能获得 子实体名(例如块的属性和多段线的顶点)。如果 acedSSName()函数调用成功,返回RTNORM,否则返回一个错误码。在过去,就 ADS 和选择集而言,函数 acedSSLength()返回选择集的长度。一旦有了选择集的长度,就能够使用 for 循环通过选择集,并使用 acedSSName()函数获得实体名。一旦有了实体名,就能使用 acdbEntGet()函数获得实体数据,该函数返回结果

45、缓冲区链表形式的实体数据。然后可以修改结果缓冲区表,调用 acdbEntMod()函数改变实体数据库,如有必要可以调用acdbEntUpd()函数更新实体的表达。正如前文所述,ObjectARX 处理实体数据库有更好的机制,其中一些在上面的代码段中已有暗示。现在趋向于不再使用acdbEntGet()、acdbEntMod()和 acdbEntUpd()函数。然而,我们仍然使用选择集。3. acedSSFree()ads_ssfree()在上述代码段的最后一行,调用了 acedSSFree()函数。当处理选择集时,在操作完成后释放选择集是很重要的,因为 AutoCAD 只能同时打开有限的选择集个

46、数(最大为 128)。下面是 acedSSFree()函数的定义:acedSSFree()函数释放由 sname 指定的选择集。该选择集必须预先通过调用acedSSGet()或 acedSSAdd()函数获得。稍后我们将讨论 acedSSAdd()和acedSSDel()函数。ADSRX 应用程序不能同时打开多于 128 个的选择集。如果达到了此极限,AutoCAD 拒绝创建更多的选择集。同时,我们不推荐使用大量的选择集。而应该保持一个合理的选择集数目,并尽可能调用 acedSSFree()函数释放无用的选择集。如果 acedSSFree()函数调用成功,返回 RTNORM,否则返回一个错误码

47、。4. acedSSAdd()ads_ssadd()acedSSAdd()函数创建一个新的选择集或把一个实体添加到一个已存在的选择集中。acedSSAdd()函数的定义如下:参数 ename 指定一个实体, sname 指定一个选择集。如果 ename 和 sname 均为空指针(NULL),acedSSAdd()函数创建一个没有实体的新选择集(以后可以添加实体的空选择集),其名由 result 设置。如果 ename 为一有效实体,但 sname是 NULL,则 acedSSAdd()函数创建一个新的选择集,其中包含一个实体 ename,选择集名为 result。如果 ename 指定了一有

48、效实体,sname 指定了一已有的选择集,acedSSAdd()函数把实体 ename 添加到由 sname 指定了的选择集中。在所有情形下,acedSSAdd()函数把 result 设置为新建的或更新的选择集名。如果由 ename 指定的实体已经在 sname 指定的选择集中,acedSSAdd()函数就不考虑这种请求,也不报告错误。参数 sname 和 result可以指定同一个选择集。这是添加实体 ename 到一个已有的选择集中去的最直观的方法。调用 acedSSAdd()函数且 sname 参数为 NULL 创建的每一个选择集,以后必须调用 acedSSFree()函数来释放。这一

49、点也适用于空选择集(当 ename 也是 NULL 时)。如果 acedSSAdd()函数返回一错误码,就不创建新的选择集。如果 acedSSAdd()函数调用成功,返回 RTNORM,否则返回一个错误码。5. acedSSDel()ads_ssdel()用 acedSSDel()函数从一个已有的选择集中删除实体。acedSSDel()函数的定义如下:acedSSDel()函数从选择集 ss 中删除由 ename 指定的实体。实体名和选择集名必须对当前图形有效。6. acedSSMemb()ads_ssmemb()最后,使用 acedSSMemb()函数可以检验一个实体是否在一个已有的选择集中。acedSSMemb()函数的定义如下:acedSSMemb()函数测试实体 ename 是否是选择集 ss 的一员。实体名和选择集名必须对当前图形有效。如果 acedSSMemb()函数找到 ename,返回RTNORM,如果没有找到,则返回 RTERROR。3.11 数据类型转换函数有时会要求转换数据类型,特别是当使用 acutPrintf()函数在命令行提示用户时。表 3-10 列出了 ADS 转换函数

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中等教育 > 职业教育

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报