




已阅读5页,还剩16页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
AutoCAD图块实体几何信息的提取刘贤喜中国农业大学(100083)摘要本文介绍了在不“炸开(EXPLODE)”AutoCAD图块的前提下,利用ADS和C语言直接访问AutoCAD图形数据库的结果缓冲器,提取或处理图块内部所含全部子实体几何信息的方法。关键词AutoCAD图块几何信息提取ADS接口DXF码1问题的提出AutoCAD是优秀的计算机辅助设计软件,不但具有友好的交互绘图功能,而且提供了强大的二次开发工具,如ADS、ARX等。但在AutoCAD交互绘图环境中,对插入其中的图形块只作为一个整体来处理,仅直接提供其插入点的坐标值、比例因子和旋转角度等有限的几何信息,而不能直接提供图形块内部所有子实体的几何信息;若要对图块进行编辑修改,首先要用“EXPLODE”命令将图块分解为若干相互独立的几何实体。我们在开发“饲料加工工艺设计专家系统(FPES)”时,用图块来表示饲料加工设备图形符号,为了让计算机能够在AutoCAD环境下自动生成饲料加工工艺流程图,不仅要识别图块所表示的加工设备,还要处理图块的外轮廓,以便于自动确定设备位置。如果用“EXPLODE”命令将设备图块炸开,则就不再具有设备图形符号的含义了,计算机也就无法对设备进行智能处理。为此我们利用ADS开发了一个智能模块,能够在不炸开图块的前提下,自动获取图块内部所含全部子实体几何信息的,提高AutoCAD对图块的智能处理能力。2实现原理DXF(DrawingExchang File)码是CAD领域的工业标准之一,在计算机内存中,可以把DXF看成是AutoCAD将当前图形数据库的ASCII码映像。在AutoCAD图形数据库中实体类型(Entity)是预先定义的图形元素,如点(POINT)、直线(LINE)、圆(CIRCLE)、插入的块(INSERT)等。实体名(Entity Name)用一个长整数表示,实际上是指向AutoCAD当前图形数据库的指针,通过这个指针,可以找到该实体在当前图形数据库中的记录。结果缓冲器是ADS支撑环境的核心概念之一。一个结果缓冲器被用来代表AutoCAD的实体和各种表(BLOCK、LTYPE、VIEW、LAYER、STYLE等)的数据信息,这些数据信息在结果缓冲器中都被映象为DXF组码与组值。结果缓冲器在ADS中是这样定义的:unionads_u_val/不同数据类型的联合ads_realrreal;ads_realrpoint3;shortrint;char*rstring;longrlname2;longrlong;structads_binaryrbinary;structrebuf/结果缓冲器的结构structrebuf*rbnext;shortrestype;unionads_u_valresval;在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):47503.方铁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为一个resbuf结果缓冲区,则语法如下: 之后还可以改变某些结果缓冲区中的值,当最终完成后调用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。acedEntSel()函数可以和acedInitGet()函数结合使用,如前面实例代码段所示。acedEntSel()函数在ObjectARX中是怎样使用的呢?AutoCAD把图形作为数据库来处理。在每个打开的AutoCAD图形中的每一个实体都有一个唯一的AutoCAD数据库对象ID与之关联。通过其对象的ID号我们可以打开AutoCAD实体,确定要处理什么类型的实体。然后我们可以使用实体的获得和设置方法(函数)来操作实体。一旦有了一个ads_name对象,我们就能得到关联的AutoCAD数据库对象ID(数据类型为AcDbObjectId)。下面就是得到一个AutoCAD数据库对象ID的函数定义:ads_name对象是使用acedEntSel()函数选择实体成功的结果。下面是一段使用acedEntSel()函数的ObjectARX代码:该函数用pEnt返回AcDbEntity指针,注意是怎样用acedEntSel()函数选择AutoCAD实体的。3. acdbEntLast()ads_entlast()、acedNEntSel()ads_nentsel()、acedNEntSelP()ads_nentselp()在ADS中还有几个其他的实体选择函数:acdbEntLast()、acedNEntSel()和acedNEntSelP()。先看一下acdbEntLast()函数。AutoCAD始终知道最近生成的一个实体,该实体可以通过acdbEntLast()函数找到。acdbEntLast()函数的定义如下:acdbEntLast()函数在图形中找出最近的实体,并把图形数据库中最近的(未删除的)主实体名存入result。即使最近的实体在屏幕之外或在冻结的层上也能选到。最近的实体是指最近创建的实体,所以acdbEntLast()函数可用于获得刚加进AutoCAD数据库中实体的实体名。如果acdbEntLast()函数调用成功,返回RTNORM,否则返回RTERROR。对于块和多段线复杂实体,ADS函数acedNEntSel()和acedNEntSelP()(代表嵌套的实体选择)将选择属性(假定选择了块实体,且块的属性已定义)和顶点信息(假定选择了多段线)。与acedNEntSel()函数相比,Autodesk推荐使用acedNEntSelP()函数。acedNEntSelP()函数比acedNEntSel()函数增加了更新的内容,所以我们只讨论acedNEntSelP()函数。下面是acedNEntSelP()函数的定义:这是一个带有许多参数的复杂函数。acedNEntSelP()函数暂停运行等待用户输入,并传回一个实体名(存入entres)和一个用于选择实体的点(存入ptres)。参数pickflag的值为FALSE或TRUE,用于指定acedNEntSelP()函数是否可以人机交互(即允许用户选择与输入点对应的点)。如果pickflag的值为FALSE,acedNEntSelP()函数提示用户指定实体,参数ptres的初始值被忽略了。如果pickflag的值为TRUE,ptres的初始值被用于选择实体。我几乎未使用过pickflag为TRUE。如果需要其他参数的说明,请参阅ADSRX文档。如果str为NULL,AutoCAD就用标准的“Select objects:|”提示。我最感兴趣的参数是entres,其中存放一个顶点或一个属性。3.9 应用程序实例CH3_1要点的进一步分析在应用程序实例CH3_1.ARX中,就在创建第一个圆之后使用了acedGetXXX()类函数。现在再来看一看这些函数。在while循环中,我们询问用户是否需要再画一个圆。只要用户不回答“No”,就会不断地要求用户画圆。让我们来观察一下while循环的前两行:acedInitGet()函数中的关键字表是“Yes No”,第一个参数是NULL,所以我们能够接受空输入。我们本可以使用RSG_NONULL迫使用户打入“Y”或“N”。在一般情况下,AutoCAD的缺省选项用尖括号表示,这里是。如果用户输入“Y”,字符串kw的值将为“Yes”。如果用户输入“N”,kw的值将为“No”。然而,如果用户只按Enter键,kw将为一空串。这种情形由switch语句的RTNONE case处理,把“Yes”复制到kw缓冲区。记住acedInitGet()函数只适用于紧跟其后的acedGetXXX()类函数。再次运行该应用程序时,试着输入一些不是“Y”或“N”的字母,看看会发生什么。你会重复地得到提示直至按下Y、N或Enter键。如果用户要再画圆,程序就进入if语句的else分支,并要求用户选择圆心,如下面的代码所示:这里,我们使用RSG_NONULL调用acedInitGet()函数,因为我们要用户选择一个圆心。在下一句的acedGetPoint()函数调用中,注意第一个参数是NULL。记住在acedGetPoint()函数中,第一个参数可以用作选点的参考点。这是第一个点,所以我们使用NULL。当要求选择圆心时试着按Enter键,会重新提示选择圆心。当输入圆半径时,我们使用acedGetDist函数替代acedGetPoint()函数,因为acedGetDist函数的响应允许我们选择一个点或从键盘输入一个距离值。下面是使用acedGetDist()函数的代码:注意我们怎样用RSG_NONULL、RSG_NOZERO和RSG_NONEG的组合来调用acedInitGet()函数。这是因为我们要使用跟在acedInitGet()函数设置之后的acedGetDist()函数。acedGetDist()函数中的第一个参数是cp,这是我们前面选定的点。从点cp开始会画出一条橡皮筋线。当用户选定第二点后,从点cp到第二点之间的距离被存入变量rad,这是一个ads_real数据类型的变量。然而,用户还可用键盘敲入数值。我们不允许零和负数输入,这就是为什么在调用acedInitGet()函数时还包括RSG_NOZERO和RSG_NONEG的原因。在用户定义的带有一个ads_name类型参数的printEntInfo()函数中,我们调用acdbEntGet()函数检索结果缓冲区链表。如果调用成功,结果缓冲区链表会包含实体的数据结构,如下列代码段所示:我们使用rbEnt-rbnext字段来遍历链表,并检测rbEnt-restype字段的值,这一字段表示存储在rbEnt-resval字段中的数据类型。3.10 选择集一个选择集就是AutoCAD当前图形中的一组实体,通过名字加以引用,在这里是一个ads_name对象。选择集非常类似于AutoCAD实体的“组(group)”。一旦拥有一个选择集,就可以确定组成选择集的实体数量(也称为选择集长度引用)。既然我们知道了选择集的长度,我们就可以使用循环机制遍历选择集中的每个实体,并读取和修改实体。一个实体在一个选择集中只能表示一次,然而一个实体可以属于多个选择集。如果我们有一个选择集ss1,并希望向选择集中添加一条直线实体,我们可以手工选择直线实体。按规则我们可以多次选择直线实体,但在选择集中多次选择的实体只表示一次。假定我们现在创建第二个选择集ss2,并选择同一条直线实体,那么该实体就被加到第二个选择集中。现在直线实体出现在ss1和ss2两个选择集中,但在每一个选择集中直线实体只表达一次。选择集是实体的有名集合,选择集中的实体由AutoCAD用户手工选择或依据实体特性加入。依据特性选择实体,如选择“parts”层上半径小于0.25的所有圆,这允许我们把它们的半径改为0.375。选择集甚至可以选择被冻结的图层上的实体。选择集也可以是空的它只是存放AutoCAD实体的一个容器,就像放糖果的纸袋一样,如果你没有在里面放糖果或者你已把它们全部吃光,纸袋就空了。表3-6列出了处理选择集的ADS函数。表3-6 ADS的选择集函数选择集函数 说 明 等效的AutoLISP函数acedSSGet() 选择要加到选择集中的实体 ssgetacedSSLength() 返回指定选择集的长度 sslengthacedSSAdd() 添加实体到已有选择集或新建一空选择集 ssaddacedSSDel() 从已有选择集中删除实体 ssdelacedSSName() 在选择集中检索出实体的ads_name ssnameacedSSMemb() 测试某实体是否为选择集的成员 ssmembacedSSFree() 释放选择集 1. acedSSGet()ads_ssget()选择集是ads_name对象,为了把实体加入到指定的选择集,必须使用acedSSGet()函数选择实体,或者假如预先知道实体名,则可使用acedSSAdd()函数。下面是acedSSGet()函数的定义:acedSSGet()函数返回一个选择集,当指定了一种AutoCAD选取模式时就获得该选择集,选取模式可以通过AutoCAD用户的提示或过滤图形数据库指定。使用acedSSGet()函数有多种方式。首先我们将说明函数中的各个参数,然后阐述使用acedSSGet()函数的各种方式。参数str是指定实体选取模式的可选字符串。参数pt1和pt2指定若干选取模式的可选点。对于polygon(多边形)或fence(栏选)选取模式选项,参数pt1还可以是一个含有多个点的结果缓冲区链表。参数filter是一个可选的结果缓冲区链表,能使acedSSGet()函数过滤图形以选择具有某种类型与(或)具有某种特性的实体。无论你使用哪一种模式来获得选择集,都用参数ss来标识选择集的名称。参数str指定要使用哪一种选取模式,它可以是表3-7所列字符串之一。从表3-7可以看出有多种选择集的选取模式,如果想探讨所有的选项,可参阅帮助文档。一般我只做两件事:让用户选择实体(NULL选项)或根据特性选择实体(“X”选项)。下面是一些有代表性的调用acedSSGet()函数的程序代码。如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选取模式,选择上一个选择集“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选取模式“M” Multiple选取模式3.10.1 选择集的过滤为了使用选择集过滤模式,参数str必须指定为“X”。选择集过滤模式允许依据特性选择实体。过滤参数是一个结果缓冲区表,在这里给acedSSGet()函数详细说明了要使用的实体种类和特性种类。如果过滤参数是NULL,并且参数str为“X”,则选择集ss将包含当前AutoCAD图形中的每一个实体,而不考虑实体是否在冻结的层上。函数调用如下:现在选择集ss将包含当前AutoCAD图形中的每一个实体。那么我们怎样选择数据库中所有的圆实体呢?为了有效地使用选择集,必须知道DXF组码。首先我们必须构造一个结果缓冲区,但因为我们只寻找一种实体,所以我们可以使用acutNewRb()函数来创建该结果缓冲区。下面是一段代码实例:下面的程序代码实例生成由某一图层上所有的实体组成的选择集。图层的DXF组码是8。好了,下面我们举一个稍微复杂一点的例子,假定我们要选择“parts”层上的所有圆。这是一个利用acutBuildList()函数构造结果缓冲区表后再传给acedSSGet()函数的实例。3.10.2 选择集的关系过滤在选择集中可以使用关系运算符。例如:我们要选取“parts”图层上半径大于等于2.0的所有圆。在缺省情况下,acedSSGet()函数选取满足过滤表中所有条件的实体。过滤时每两个项之间的隐含关系是“相等(equals)”。对于数值型组码(整数、实数、点和向量),借助在结果缓冲区中包含一个说明关系运算符的特殊组码“-4”可以指定其他的关系运算。该运算符应用于紧跟其后的结果缓冲区项。关系运算符由字符串指定。表3-8列出了所有的关系运算符。关系运算符可以用实例来很好地说明,继续我们所举的例子:选取“parts”图层上半径大于等于2.0的所有圆。其程序代码如下:表3-8 选择集过滤表的关系运算符关系运算符 说 明“*” 任意(始终为真)“=” 等于“!=” 不等于(C/C+)“/=” 不等于(AutoLISP)“” 不等于“” 小于“” 大于“=” 大于或等于“&” 按位“与”(只用于整数组码)“&=” 按位等于(只用于整数组码)3.10.3 选择集的条件过滤除关系测试外,我们还可以使用条件运算符。表3-9列出了所有的选择集条件运算符。表3-9 选择集过滤表的条件运算符起始运算符 中间内容 终止运算符“”“”“”“”选择集的条件运算符允许我们执行像选择图形中半径为1.0的所有圆和“parts”图层上的所有直线这一类的选择集操作。编程后代码如下:本例有助于掌握选择集的关系过滤和条件过滤。3.10.4 选择集的扩展实体数据过滤从R11版本起,AutoCAD就有了一个为实体添加数据的机制,称为扩展实体数据(xdata)。我不准备深入讨论扩展实体数据,因为从AutoCAD R13 c4a起,在AutoCAD R14和以后的版本中引入了一种新的机制称为XRecords,这在后面的章节中将会加以讨论。扩展实体数据通常是由外部应用程序附加到一个对象上的文本串、数值、3D点、距离、层名或其他数据。扩展数据的大小是每个实体16KB。注意XRecords是不附加于任何实体的,因此XRecords的存在并不需要实体的存在。借助在过滤表中使用-3组码标记指定应用程序名,就可以检索扩展数据。acedSSGet()函数返回登记有特定名称的扩展数据的实体集合,acedSSGet()函数并不检索单个扩展数据项(组码范围为10002000)。下面为选择所有实体的代码段,所有实体均有以其应用程序ID号为“APPNAME”注册的扩展数据:在ADSRX文档中,有关扩展实体数据的信息还有很多,但由于AutoCAD R14和以后的版本使用XRecords,因此,在后面的章节中我们将详细讨论XRecords。3.10.5 转换矩阵和选择集acedXformSS()ads_xformss()借助acedXformSS()函数,选择集可以使用转换矩阵。利用转换矩阵,可以变比、移动、旋转或镜像选择集中的实体。这可以用适当的矩阵元素设置调用acedXformSS()函数来实现,而不是循环整个选择集并执行acedCommand()/acedCmd()函数来变比、移动、旋转或镜像每一个实体。在这里我不想完整地讨论矩阵代数学。ObjectARX已经定义了处理矩阵代数的数值函数(见AcGeMatrix2d和AcGeMatrix3d矩阵操作类)。前面讲过转换矩阵是一个具有ads_real数据类型的44阶数组。矩阵的前三列确定比例和旋转,第四列是一个平移向量。矩阵的最后一行其值规定为0 0 0 1,传递ads_matrix型参数的函数忽略了此值。ADSRX为平移操作定义符号T,如下所示:acedXformSS()函数的定义如下:acedXformSS()函数将一个转换矩阵genmat应用于由ssname指定的选择集。参数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使其值为1。现在矩阵被初始化为恒等矩阵。观察如下由Tx、Ty和Tz决定的平移矩阵:改变第四列中的前三个元素的值并应用acedXformSS()函数,选择集中的所有实体将沿X、Y和Z方向移动适当的距离。注意,如果只需要在X方向移动,那么只需改变矩阵中的Tx值。当处理选择集和acedXformSS()函数时,所有的比例系数必须相等,即Sx=Sy=Sz。还有像旋转矩阵之类的其他2D和3D操作(参阅ADSRX和ObjectARX文档)。现在让我们来看一个用于选择集操作的转换矩阵实例。这是要对选择集实施变换的矩阵,X、Y和Z方向的缩放系数是0.5,选择集的移动距离是(20.0,5.0)。下面是程序代码:3.10.6 选择集的操作既然我们已经看到有各种方法创建选择集,现在就让我们来看看操作这些选择集的函数。也许我们要知道的第一件事是有多少实体组成了该选择集。1. acedSSLength()ads_sslength()acedSSLength()函数返回组成选择集的实体个数。其定义如下:acedSSLength()函数返回一个长整数len,表示选择集sname中含有的实体个数。结果是特定实体的个数,不管选择集是怎样选取的,选择集不包含重复的实体。如果acedSSLength()函数调用成功,返回RTNORM,否则返回一个错误码。acedSSLength()函数通常和for循环连用,如下例程序代码所示:2. acedSSName()ads_ssname()在上述代码中,如果acedSSLength()函数返回的变量len的值大于0,那么我们就能够得到一个由长整型变量i表示在选择集中位置的特定实体。为得到在选择集特定位置上的实体,可以使用acedSSName()函数。表示实体在选择集中位置的序号从0开始,第一个实体的序号是0。下面是acedSSName()函数的定义:acedSSName()函数选取选择集ss中位置序号为i的实体,并在entres中返回实体名。实体从0开始编号,所以i必须是非负的且不大于选择集中最后一个实体的序号(acedSSLength(ss)-1)。在用acedSSGet()函数获得的选择集中的实体名总是主实体名。acedSSName()函数不能获得子实体名(例如块的属性和多段线的顶点)。如果acedSSName()函数调用成功,返回RTNORM,否则返回一个错误码。在过去,就ADS和选择集而言,函数acedSSLength()返回选择集的长度。一旦有了选择集的长度,就能够使用for循环通过选择集,并使用acedSSName()函数获得实体名。一旦有了实体名,就能使用acdbEntGet()函数获得实体数据,该函数返回结果缓冲区链表形式的实体数据。然后可以修改结果缓冲区表,调用acdbEntMod()函数改变实体数据库,如有必要可以调用acdbEntUpd()函数更新实体的表达。正如前文所述,ObjectARX处理实体数据库有更好的机制,其中一些在上面的代码段中已有暗示。现在趋向于不再使用acdbEntGet()、acdbEntMod()和acdbEntUpd()函数。然而,我们仍然使用选择集。3. acedSSFree()ads_ssfree()在上述代码段的最后一行,调用了acedSSFree()函数。当处理选择集时,在操作完成后释放选择集是很重要的,因为AutoCAD只能同时打开有限的选择集个数(最大为128)。下面是acedSSFree()函数的定义:acedSSFree()函数释放由sname指定的选择集。该选择集必须预先通过调用acedSSGet()或acedSSAdd()函数获得。稍后我们将讨论acedSSAdd()和acedSSDel()函数。ADSRX应用程序不能同时打开多于128个的选择集。如果达到了此极限,AutoCAD拒绝创建更多的选择集。同时,我们不推荐使用大量的选择集。而应该保持一个合理的选择集数目,并尽可能调用acedSSFree()函数释放无用的选择集。如果acedSSFree()函数调用成功,返回RTNORM,否则返回一个错误码。4. acedSSAdd()ads_ssadd()acedSSAdd()函数创建一个新的选择集或把一个实体添加到一个已存在的选择集中。acedSSAdd()函数的定义如下:参数ename指定一个实体,sname指定一个选择集。如果ename和sname均为空指针(NULL),acedSSAdd()函数创建一个没有实体的新选择集(以后可以添加实体的空选择集),其名由result设置。如果ename为一有效实体,但sname是NULL,则acedSSAdd()函数创建一个新的选择集,其中包含一个实体ename,选择集名为result。如果ename指定了一有效实体,sname指定了一已有的选择集,acedSSAdd()函数把实体ename添加到由sname指定了的选择集中。在所有情形下,acedSSAdd()函数把result设置为新建的或更新的选择集名。如果由ename指定的实体已经在sname指定的选择集中,acedSSAdd()函数就不考虑这种请求,也不报告错误。参数sname和result可以指定同一个选择集。这是添加实体ename到一个已有的选择集中去的最直观的方法。调用acedSSAdd()函数且sname参数为NULL创建的每一个选择集,以后必须调用acedSSFree()函数来释放。这一点也适用于空选择集(当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转换函数。表3-10 常用的ADS转换函数函 数 说 明acdbRToS() 转换ads_real类型的数值为字符串acdbAngToS() 按格式转换角度为字符串acutToUpper() 把字符转换为大写acutToLower() 把字符转换为小写acedTrans() 把点或位移从一个坐标系转换到另一个坐标系1. acdbRToS()ads_rtos()acdbRToS()函数的定义如下:acdbRToS()函数按照unit和prec(精度)设置的格式把val转换为字符串,结果放入str,str必须指向足以容纳格式化字符串的一块缓冲区。参数unit选取转换后字符串的单位制,其值应符合AutoCAD系统变量LUNITS允许的取值范围(15,参阅AutoCAD在线帮助中的“系统变量”)。如果unit的值为-1,acdbRToS()函数使用LUNITS的当前值。参数prec选取字符串中包含的小数位数。如果prec的值为-1,acdbRToS()函数使用AutoCAD系统变量LUPREC的当前值。AutoCAD尺寸标注变量DIMZIN的当前值控制acdbRToS()函数是否把前导零和结尾零写入str。如果acdbRToS()函数调用成功,返回RTNORM,否则返回一个错误码。2. acdbAngToS()ads_angtos()acdbAngToS()函数的定义如下:acdbAngToS()函数按照unit和prec(精度)设置的格式把v转换为字符串,参数v以弧度为单位,结果放入str,str必须指向足以容纳格式化字符串的一块缓冲区。字符串的大小取决于请求模式和精度,通常15字节就足够了。参数unit选取角度转换后的单位制,其值应符合AutoCAD系统变量AUNITS允许的取值范围。此外,如果设置unit的值为-1,acdbAngToS()函数使用AUNITS的当前值。参数prec选取字符串中包含的小数位数。如果prec的值设置为-1,acdbAngToS()函数使用AutoCAD系统变量AUPREC的当前值。AutoCAD尺寸标注变量DIMZIN的当前值控制acdbAngToS()函数是否把前导零和结尾零写入str。AutoCAD用户指南说明了DIMZIN如何取值。如果acdbAngToS()函数调用成功,返回RTNORM,否则返回一个错误码。3. acutToUpper()ads_toupper()和acutToLower()ads_tolower()acutToUpper()和acutToLower()函数的定义如下:这两个函数分别把字符参数(ASCII码整数值)转换为大写或小写字符。4. acedTrans()ads_trans()acedTrans()函数的定义如下:acedTrans()函数把坐标点或位移量从一个坐标系统转换到另一个坐标系统。参数pt既可解释为一个三维点,也可解释为一个三维位移矢量。参数from指定pt所在的坐标系统,参数to指定转换后的坐标系统。如果参数disp不等于0,则pt被看作是一个位移矢量,否则pt是一个点。说明acedTrans()函数最好的方法是通过例子。AutoCAD使用的坐标系统代码为:1表示WCS(世界坐标系统),2表示当前的UCS(用户坐标系统)。AutoCAD还定义了2和3,这些值我很少使用,你可以查阅有关文档。下面是一段从UCS转换到WCS的程序代码:这是第一段没有使用结果缓冲区指针的程序代码。在函数中声明结果缓冲区类型的变量为局部变量,在函数退出时会自动清除,无需调用acutRelRb()函数。然而,请注意必须在resbuf 变量的前面放上&运算符,因为acedTrans()函数需要一个指向 resbuf 结构的指针(或地址)。3.12 应用程序实例CH3_2在本应用程序中,我们再次示范了acedGetXXX()类函数的使用,还示范了选择集函数的使用。当循环通过选择集时,还示范了怎样利用结果缓冲区链表改变选择集中实体的特性。在一个纯粹的ObjectARX应用程序中,改变实体的特性是由相应实体类中的get和set函数完成的。我们先来观察应用程序实例CH3_2的程序代码,然后讨论其要点。CH3_2.CPP文件内容如下:用户定义命令CEL的CH3_2Commands.cpp
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026届西藏林芝第一中学高二化学第一学期期中教学质量检测模拟试题含解析
- 2025年注册验船师资格考试(B级船舶检验专业基础安全)综合练习题及答案一
- 2025年老龄化社会与养老服务研究项目考试及答案
- 2025年篮球试卷考试题及答案
- 海安银行考试题目及答案
- 2025年建筑设计师求职面试技巧解析与答案版
- 2025年电子商务运营专家中级面试题及解析
- 2025年电力行业专业技术岗位招聘考试预测题集
- 2025年机关物业电梯岗位应聘面试题详解与攻略
- 2025年注册会计师考试CPA核心考点梳理与试题预测
- 2025江苏南京农业大学新校区建设指挥部、基本建设处人员招聘10人笔试备考试题及答案解析
- VTE的预防及护理
- 《如何做好研究生》课件
- 高等数学期末试卷及答案
- 从0开始跨境电商-第三章-阿里巴巴国际站入门-OK
- 新能源电站远程监控系统建设方案
- 《紫藤萝瀑布》《丁香结》《好一朵木槿花》
- 河流地貌的发育 - 侵蚀地貌
- 离网光伏发电系统详解
- 广告文案写作(第二版)全套教学课件
- 《国家电网公司电力安全工作规程(配电部分)》
评论
0/150
提交评论