当前位置:文档之家› AutoCAD图块实体几何信息的提取

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

AutoCAD图块实体几何信息的提取刘贤喜中国农业大学(100083)摘要本文介绍了在不“炸开(EXPLODE)”AutoCAD图块的前提下,利用ADS和C语言直接访问AutoCAD图形数据库的结果缓冲器,提取或处理图块内部所含全部子实体几何信息的方法。

关键词 AutoCAD图块几何信息提取 ADS接口 DXF码1 问题的提出AutoCAD是优秀的计算机辅助设计软件,不但具有友好的交互绘图功能,而且提供了强大的二次开发工具,如ADS、ARX等。

但在AutoCAD交互绘图环境中,对插入其中的图形块只作为一个整体来处理,仅直接提供其插入点的坐标值、比例因子和旋转角度等有限的几何信息,而不能直接提供图形块内部所有子实体的几何信息;若要对图块进行编辑修改,首先要用“EXPLODE”命令将图块分解为若干相互独立的几何实体。

我们在开发“饲料加工工艺设计专家系统(FPES)”时,用图块来表示饲料加工设备图形符号,为了让计算机能够在AutoCAD环境下自动生成饲料加工工艺流程图,不仅要识别图块所表示的加工设备,还要处理图块的外轮廓,以便于自动确定设备位置。

如果用“EXPLODE”命令将设备图块炸开,则就不再具有设备图形符号的含义了,计算机也就无法对设备进行智能处理。

为此我们利用ADS开发了一个智能模块,能够在不炸开图块的前提下,自动获取图块内部所含全部子实体几何信息的,提高 AutoCAD对图块的智能处理能力。

2 实现原理DXF(Drawing Exchang File)码是CAD领域的工业标准之一,在计算机内存中,可以把DXF看成是AutoCAD将当前图形数据库的ASCII码映像。

在AutoCAD图形数据库中实体类型(Entity)是预先定义的图形元素,如点(POINT)、直线(LINE)、圆(CIRCLE)、插入的块(INSERT)等。

实体名(Entity Name)用一个长整数表示,实际上是指向AutoCAD当前图形数据库的指针,通过这个指针,可以找到该实体在当前图形数据库中的记录。

结果缓冲器是ADS支撑环境的核心概念之一。

一个结果缓冲器被用来代表AutoCAD的实体和各种表(BLOCK、LTYPE、VIEW、LAYER、STYLE等)的数据信息,这些数据信息在结果缓冲器中都被映象为DXF组码与组值。

结果缓冲器在ADS中是这样定义的:union ads_u_val { //不同数据类型的联合ads_real rreal;ads_real rpoint[3];short rint;char *rstring;long rlname[2];long rlong;struct ads_binary rbinary;};struct rebuf { //结果缓冲器的结构struct rebuf *rbnext;short restype;union ads_u_val resval;};在AutoCAD当前数据库中,首先获取一个实体,并该得到实体的结果缓冲器,当DXF 组码为0时,其组值为实体类型,即:LINE、CIRCLE、ARC、PLINE、INSERT等;当DXF 组码为2时,其组值为图块名称;当DXF组码为10时,其组值根据实体类型的不同而表示不同的含义,可以是LINE的起点坐标,或是CIRCLE或ARC的中心坐标等。

当不同内容的结果缓冲器链接成一个链表时,它们就可以用来表示AutoCAD的图形实体和表记录了。

如:一个锤片粉碎机图形符号的块名为“CF”,其插入块的结果缓冲器表的结构如图1所示:由于所有图块的定义信息(包括几何信息)都以DXF组码与组值的形式存放在一个“BLOCK”符号表中,所以在AutoCAD的“BLOCK”符号表中检索指定的图块名,就可得到该图块全部定义信息的存储首地址,并将其作为一个结果缓冲器链表。

在循环遍历该结果缓冲器链表的过程中,通过DXF组码与组值,来判别块内子实体的类型,并提取有关几何信息。

3 程序流程图流程图如图2所示。

要获得一个图块的全部几何信息,首先要在AutoCAD当前图形数据库中确定一个实体(可以人为指定或程序自动获取),接下来,根据其DXF组码与组值,判断该实体是否为插入图块,当DXF码为0时,若DXF组值不是“INSERT”,该实体则不是图块,程序返回;若DXF组值为“INSERT”,则是图块,程序继续进行,当DXF组码为2时,其组值便为该图块的块名。

然后,在AutoCAD的“BLOCK”符号表中检索该块名,从而获得该图块信息链表的头指针,并遍历该链表,再根据链表中的不同DXF组码与组值确定块内子实体的不同类型,并提取的相关几何信息,如:起点、终点、圆心、半径、多义线的顶点、圆弧的起角、终角等等。

注意,由于块内的坐标值都是相对于块实体自身的实体坐标系(ECS)的值,所以,求得有关几何信息后,还要根据AutoCAD当前绘图环境中的坐标系、插入图块的插入点、X、Y方向的比例以及旋转角度等,对块内几何信息进行相关的平移变换、比例变换或旋转变换等坐标变换,直到该链表的标尾。

这样,便达到了不“炸开”图块就可获取其内部全部几何信息的目的。

程序是用C语言和ADS函数在Windows环境下编写的(源程序从略)。

4 结论利用上述方法开发的图形智能化处理模块,在“饲料加工工艺流程设计专家系统(FPES)”中收到较好的效果。

FPES在利用知识库中的知识和规则进行饲料加工工艺设计的同时,调用模块对设备图形符号进行智能处理,并自动生成设备布局合理的、符合有关标准的饲料加工工艺流程图。

参考文献1.刘贤喜.面向对象的饲料加工工艺设计专家系统的研究:[学位论文].北京:中国农业大学,19982.刘贤喜,陈忠良,李晓民.饲料加工工艺设计专家系统的设计.中国农业大学学报, 1998,3(4):47~503.方铁.AutoCADC语言高级编程.北京:清华大学出版社,1995年1月.通讯地址:北京中国农业大学东区213信箱,邮编:100083,联系人:刘贤喜电话:623928593.8 在AutoCAD中选择实体1. ads_name[在AutoCAD 2000中仍为此名]、acdbNameSet()[ads_name_set()]、acdbNameEqual()[ads_name_equal()]、acdbNameClear()[ads_name_clear()]、acdbNameNil()[ads_name_nil()]在ADS、ADSRX或ObjectARX中,选择实体的方法没有变化,但在ObjectARX 2000中改变了一些函数名(其他函数名没有改变,对于第6章讨论的数据类型和DCL对话框也基本是这样的)。

我们介绍一种新的数据类型:ads_name。

这种类型数据用来保存成功选择实体的结果。

通常,选择实体是为了用户能获得并修改实体特性。

这里是老式的ADS和现代的API ObjectARX 完全不同的地方。

在讨论ADS和ObjectARX在获得实体数据方面的差别之前,先来看一看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_name对象是否相等,可以用acdbNameEqual()宏。

要把一个空值(NULL)赋给一个ads_name对象,可以用acdbNameClear()宏。

要测试一个ads_name对象的值是否有效,可以用acdbNameNil()宏。

下面为一段代码实例:2. acedEntSel()[ads_entsel()]、acdbEntGet()[ads_entget()]、acdbEntMod()[ads_entmod()]、acdbEntUpd()[ads_entupd()]请牢记选择集也是ads_name对象(我知道这可能引起不小的混淆)。

我们很快就会讨论选择集。

前文谈到ADS和ObjectARX在获得和更改实体数据的方法上是完全不同的,在后面的章节中我们将讨论ObjectARX的方法。

在ADSRX中,使用acdbEntGet()函数获得实体数据,使用acdbEntMod()和acdbEntUpd()函数修改和更新实体。

下面是这些函数的定义:用acedEntSel()函数选择的实体将和ads_name对象相关联。

在详细讨论acedEntSel()函数之前,先要谈一下acdbEntGet()、acdbEntMod()和acdbEntUpd()函数。

acdbEntGet()函数返回一个结果缓冲区的单链表。

使用resbuf对象的rbnext字段可以遍历和检测结果缓冲区链表。

若rb为一个res buf结果缓冲区,则语法如下:之后还可以改变某些结果缓冲区中的值,当最终完成后调用acdbEntMod()函数修改实体的内部数据。

正如所见,该函数要求一个resbuf 对象。

如果正在处理一个如块或多段线一样的复杂对象,可以使用acdbEntUpd()函数来观察由各个acdbEntMod()函数调用所做的修改效果。

从本质上讲,使用ADSRX就是处理结果缓冲区链表。

ObjectARX的方法与此是完全不同的,且差别巨大。

对于有大量旧数据的用户,由于有ADSRX,这些函数在ObjectARX中仍然可以使用(Autodesk公司的人把ADS放进了ObjectARX)。

由于本书是讨论ObjectARX,因此,关于acdbEntGet()、acdbEntMod()和acdbEntUpd()函数的讨论就到此为止。

现在回到acedEntSel()函数,因为该函数在ObjectARX中仍然得到广泛应用。

再一次把acedEntSel()函数的定义说明如下:acedEntSel()函数暂停运行等待用户输入,并在entres中返回实体名,在ptres中返回选择实体使用的点。

参数str指定acedEntSel()函数暂停前显示的字符串。

参数str是可选的,如果是NULL,AutoCAD显示缺省提示“Select objects:”。

当用户指定一个复杂实体响应acedEntSel()函数时,则返回多段线或块的标题。

如果acedEntSel()函数调用成功,则返回RTNORM,失败则返回RTERROR,如果用户取消(按Esc键)则返回RTCAN。

相关主题