创建和编辑基本图形对象.ppt

上传人:牧羊曲112 文档编号:6040983 上传时间:2023-09-17 格式:PPT 页数:49 大小:225KB
返回 下载 相关 举报
创建和编辑基本图形对象.ppt_第1页
第1页 / 共49页
创建和编辑基本图形对象.ppt_第2页
第2页 / 共49页
创建和编辑基本图形对象.ppt_第3页
第3页 / 共49页
创建和编辑基本图形对象.ppt_第4页
第4页 / 共49页
创建和编辑基本图形对象.ppt_第5页
第5页 / 共49页
点击查看更多>>
资源描述

《创建和编辑基本图形对象.ppt》由会员分享,可在线阅读,更多相关《创建和编辑基本图形对象.ppt(49页珍藏版)》请在三一办公上搜索。

1、第三章 创建和编辑基本图形对象,在学习ObjectARX的时候,大多数曾经试图直接去学习数据库的操作、几何类等概念,结果并不理想。经过一段时间的摸索,将创建和编辑基本图形对象作为突破口,逐步深入,在学习过程中成就感很强。,3.1.1 说明本实例运行的结果是在AutoCAD 2008中,创建一条直线,该直线的起点是(0,0,0),终点是(100,100,0)。除此之外,不准备再做更多的事情。麻雀虽小,五脏俱全。通过这个程序,你将要开始了解AutoCAD数据库的基本结构,3.1 创建直线,3.1.2 思路首先来看看,在AutoCAD中,使用LINE命令创建一条直线,需要哪些东西:命令:_line

2、指定第一点:0,0 指定下一点或 放弃(U):100,100 指定下一点或 放弃(U):从上面的命令提示可以看出,创建一条直线,需要用户指定起点和终点。,在继续之前,必须给大家介绍一点数据库最基础的几个名词:表:表是数据库的组成单位,一个数据库至少包含一个表。记录:记录是表的组成单位,一个表可能包含多条记录,也可能不包含任何记录。,上图用来描述AutoCAD数据库的基本结构再好不过了。从图中来看,实体包含在块表记录中,因此要创建一个图形对象,需要遵循下面的基本步骤:(1)确定要创建对象的图形数据库;(2)获得图形数据库的块表;(3)获得一个存储实体的块表记录,所有模型空间的实体都存储在模型空间

3、的特定记录中。(4)创建实体类的一个对象,将该对象附加到特定的块表记录中。,3.1.3 步骤(1)使用向导创建一个命令(名称为MyLine)。,(2)函数中,添加创建直线对象(在ObjectARX中,AcDbLine类代表直线)的代码:/在内存上创建一个新的AcDbLine对象AcGePoint3d ptStart(0,0,0);AcGePoint3d ptEnd(100,100,0);AcDbLine*pLine=new AcDbLine(ptStart,ptEnd);注意,基于AutoCAD内部的实现机制,必须在堆上创建对象,而不能用下面的语句创建直线的对象:AcDbLine line(p

4、tStart,ptEnd);此时,直线对象仅被在内存上创建,并没有添加到图形数据库中,因此不可能会显示在图形窗口中。,(3)在函数中,添加获得指向块表的指针的相关代码:/获得指向块表的指针AcDbBlockTable*pBlockTable;acdbHostApplicationServices()-workingDatabase()-getBlockTable(pBlockTable,AcDb:kForRead);acdbHostApplicationServices()-workingDatabase()能够获得一个指向当前活动的图形数据库的指针,这在后面还要经常遇到。,getBlockT

5、able是AcDbDatabase类的一个成员函数,用于获得指向图形数据库的块表的指针,其定义为:inline Acad:ErrorStatus getBlockTable(AcDbBlockTable*该函数的返回值Acad:ErrorStatus是ObjectARX中定义的一个枚举类型,主要用于判断函数的返回状态,如果函数成功执行会返回Acad:eOk。第一个参数pTable返回指向块表的指针;第二个参数同样是一个枚举类型的变量,其类型AcDb:OpenMode包含了AcDb:kForRead、AcDb:kForWrite和AcDb:kForNotify三个可取的值,创建直线的时候不需要更

6、改块表,因此这里打开的模式为AcDb:kForRead。,(4)在函数中,添加获得指向特定块表记录的指针的相关代码:/获得指向特定的块表记录(模型空间)的指针AcDbBlockTableRecord*pBlockTableRecord;pBlockTable-getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb:kForWrite);getAt函数是AcDbBlockTable类的一个成员函数,用于获得块表中特定的记录,其定义为Acad:ErrorStatus getAt(const char*entryName,AcDbBlockTableRecord*

7、,第一个参数用于指定块表记录的名称,ACDB_MODEL_SPACE是ObjectARX中定义的一个常量,其内容是“*Model_Space”;第二个参数用于返回指向块表记录的指针;第三个参数指定了块表记录打开的模式,下一步要向块表记录中添加实体,所以就用写的模式(AcDb:kForWrite)打开;第四个参数指定是否查找已经被删除的记录,这里暂时不深入介绍,后面在合适的地方我会谈到它,一般使用默认的参数值。,(5)在函数中,添加向块表记录中附加实体的代码:/将AcDbLine类的对象添加到块表记录中AcDbObjectId lineId;pBlockTableRecord-appendAcD

8、bEntity(lineId,pLine);appendAcDbEntity是AcDbBlockTableRecord类的成员函数,用于将pEntity指向的实体添加到块表记录和图形数据库中,其定义为:Acad:ErrorStatus appendAcDbEntity(AcDbObjectId 第一个参数返回图形数据库为添加的实体分配的ID号;第二个参数指定了所要添加的实体。,(6)在函数中,添加关闭图形数据库各种对象的代码:/关闭图形数据库的各种对象pBlockTable-close();pBlockTableRecord-close();pLine-close();在操作图形数据库的各种对

9、象时,必须遵守AutoCAD的打开和关闭对象的协议。该协议确保当对象被访问时在物理内存中,而未被访问时可以被分页存储在磁盘中。创建和打开数据库的对象之后,必须在不用的时候关闭它。,(7)最后,来看一下完整的代码:void ZffCHAP2CreateLine()/在内存上创建一个新的AcDbLine对象AcGePoint3d ptStart(0,0,0);AcGePoint3d ptEnd(100,100,0);AcDbLine*pLine=new AcDbLine(ptStart,ptEnd);/获得指向块表的指针 AcDbBlockTable*pBlockTable;acdbHostApp

10、licationServices()-workingDatabase()-getBlockTable(pBlockTable,AcDb:kForRead);/获得指向特定的块表记录(模型空间)的指针 AcDbBlockTableRecord*pBlockTableRecord;pBlockTable-getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb:kForWrite);/将AcDbLine类的对象添加到块表记录中 AcDbObjectId lineId;pBlockTableRecord-appendAcDbEntity(lineId,pLine);

11、/关闭图形数据库的各种对象 pBlockTable-close();pBlockTableRecord-close();pLine-close();,3.2 修改图形对象的属性3.2.1 说明上一节的学习,你已经能创建一条直线了,本节介绍的例子则会改变直线的颜色。所要实现的效果非常简单:创建一条直线之后,将它的颜色变为红色。,3.2.2 思路如果是在创建时修改直线的颜色,就可以直接在上节函数中加入下面的代码(放在关闭图形数据库各种对象之前):pLine-setColorIndex(1);运行程序中注册的命令,创建的直线颜色变为红色。在实际编程中,并不是每一次都可以在创建对象时将其特性设置到合适

12、的状态,相反,更多的时候可能在创建对象之后才修改其特性,本节正要解决这个问题。,1打开和关闭图形数据库的对象访问图形数据库中对象的特性,必须在该对象被打开(对象创建时也会被打开)的状态下,用对象的指针进行访问,并且在访问结束后要及时关闭该对象,不然就会引起AutoCAD的错误终止。创建一个对象,必须在创建之后关闭该对象,那么如何在某个时候再访问该对象?这就要用到上面介绍的AcDbObjectId,也就是对象的ID号。在创建对象时,可以将图形数据库分配给该对象的ID保存起来,在需要访问该对象时,根据这个ID从数据库中获得指向该对象的指针,就可以修改或者查询该对象的特性。,AcDbBlockTab

13、leRecord类的appendAcDbEntity函数能够将一个实体添加到图形数据库中;全局函数acdbOpenAcDbEntity用于从实体的ID号获得指向图形数据库中实体的指针,其定义为:Acad:ErrorStatus acdbOpenAcDbEntity(AcDbEntity*,第一个参数返回指向图形数据库实体的指针;第二个参数输入了要获得的实体的ID号;第三个参数指定了打开该实体的方式,如果仅是查询该实体的特性用“读”模式打开即可,要修改实体的特性就必须用“写”模式打开;第四个参数指定是否允许访问一个已经被删除的实体。,ObjectARX提供了另外两个全局函数acdbOpenAcD

14、bObject和acdbOpenObject来实现类似的功能,这三个函数的区别在与适用范围:acdbOpenAcDbEntity:适用于打开继承于AcDbEntity的数据库常驻对象,这类对象一般都能在图形窗口中显示,如直线、圆等。acdbOpenAcDbObject:适用于打开未继承于AcDbEntity的数据库常驻对象,这类对象不能在图形窗口中显示,如层表、线型表等。acdbOpenObject:如何不知道要打开的对象是否继承于AcDbEntity类,可以使用这个函数。打开某个对象之后,使用close函数就可以将其关闭。,对象标识开发者使用ObjectARX API开发时,通常需要标识所处

15、理的对象,同一个数据库对象根据所处的阶段不同可以用不同的标识符加以标识,不同的阶段可以是在dwg 文件中或者是当前图形数据库(内存中),以及选择集中,通常可以通过以下方式标识一个实体。AcDbHandleDWG 文件中的每一个实体都有一个唯一的标识符,称为句柄,用AcDbHandle表示。实体的句柄可以随DWG 文件保存,所以即使DWG 文件没有被AutoCAD 打开,也可以根据句柄搜索DWG 文件获取对象信息,句柄的唯一性仅限于其所在的DWG 文件。,AcDbObjectId当DWG 图形被打开后,数据库中的实体对象都会在内存中对应一个唯一的对象ID(AcDbObjectId),对象ID 也

16、是与实体对象相关联的唯一的标识符,与句柄不同,对象ID仅存在于其所在的数据库从内存中产生到数据库被删除之间,并且如果操作多个数据库,对象ID 在多个数据库之间都是唯一的。,AcDbObject对象指针当一个对象被打开后,AutoCAD 会返回指向AcDbObject或其派生类型的一个C+指针,开发者就可以采用标准C+类对象的方式对实体进行操作。显然,这是ObjectARX操作实体的主要方式。,ads_nameads_name 是AutoCAD 定义的一个数据类型,这个数据类型在AutoCAD 发展到ADS开发阶段被引入,并作为ADSRX 的一部分保留在ObjectARX 开发方式下。ads_n

17、ame 一般用来保存用户交互过程中成功选择实体的结果,通常,选择实体是为了用户能获得并修改实体的属性,ObjectARX提供了ads_name与对象ID的转换函数,从而可以按ObjectARX的方式修改实体属性。,对象标识符的相互转换ObjectARX 提供了丰富的实体标识符转换函数,保证开发者采用合适的开发方式获取或修改实体的属性,如图所示:,具体来说,ID、指针、句柄和ads_name之间具有下面的转换关系(不完转换并未提及):从ID到对象指针:通过打开数据库对象的三个函数acdbOpenAcDbEntitu、cdbOpenAcDbObject和acdbOpenObject中的任何一个。从

18、对象指针到ID:所有的数据库常驻对象都继承自AcDbOject,而AcDbObject类包含的objectId函数能获得所指向对象的ID。,从句柄到ID:使用AcDbDatabase:getAcDbObje函数。从ID到句柄:使用AcDbObjectId:handle函数。从指针到句柄:使用AcDbObject:getAcDbHandle函数。从ads_name到ID:使用全局函数acdbGetObjectId。从ID到ads_name:使用全局函数acdbGetAdsName。,调用全局函数acdbOpenObject()传入AcDbObjectId将打开对象,得到对象指针。调用AcDbOb

19、ject:getAcDbHandle()可以获取对象的句柄AcDbHandle,通过AcDbDatabase:getAcDbObjectId()可以将对象句柄AcDbHandle映射为AcDbObjectId对象;反之,AcDbObjectId:handle()函数用于返回AcDbObjectId所关联的对象句柄AcDbHandle。调用acdbGetObjectId()可以ads_name 转化为AcDbObjectId;反之,调用acdbGetAdsName()则将AcDbObjectId转化为ads_name。,例:/选择对象,返回ads_nameads_name en;ads_poin

20、t pt;acedEntSel(_T(n选择对象:),en,pt);/通过对象标识转换函数得到对象IDAcDbObjectId eId;acdbGetObjectId(eId,en);/打开实体,得到AcDbEntity指针AcDbEntity*pEnt;acdbOpenObject(pEnt,eId,AcDb:kForRead);,3.3 创建圆,在ObjectARX中,AcDbCircle类用来表示圆。该类有两个构造函数,其形式分别为:AcDbCircle();AcDbCircle(const AcGePoint3d 两个构造函数的名称相同,接受不同的参数,这是C+中函数的重载。重载是C+

21、提供的一个很有用的特性,相同功能的函数采用同样的名称,大大减少了程序员的记忆量。第一个构造函数不接受任何参数,创建一个圆心为(0,0,0)、半径为0的圆,其所在平面法向量为(0,0,1);第二个构造函数则接受了圆心、圆所在平面法向量和半径三个参数。一般来说,我习惯于在创建实体时直接将其初始化,很少用第一个构造函数。,AcGePoint3d ptCenter(0,0,0);AcGeVector3d vec(0,0,1)double radius=10AcDbCircle*pCircle=new AcDbCircle(ptCenter,vec,radius);/将实体添加到图形数据库 AcDbOb

22、jectId circleId;,3.3 对象的类型判断由于所有实体都是从AcDbEntity 派生的,所以当打开一个AcDbEntity 对象时,开发者经常需要进一步判断其类型,如判断是一条线还是一个圆等。在实际的开发中,对ObjectARX 对象进行类型判断需要使用ObjectARX 提供的类型判断机制。,我们可以通过AcRxObject:desc()静态函数返回AcRxClass 类型的指针,然后调用AcRxObject:isA()或者AcRxObject:isKindOf()来进行类型判断,其中AcRxObject:isA()用于判断对象是否是所需要的对象类型,而AcRxObject:

23、isKindOf()可用于判断对象是否是所需要的类型或者其派生类类型。,假定AcDbEntity*pEnt,判断实体是否正好是一条线段可用以下代码:if(pEnt-isA()=AcDbLine:desc()如果要判断实体是否是线段或者线段的派生对象,可用以下代码来实现:if(pEnt-isKindOf(AcDbLine:desc()AcDbLine*pLine=AcDbLine:cast(pEnt);通过上述方法完成了对象的类型判断以后,如果需要进行类型转换,通常调用静态函数AcRxObject:cast()来完成,该函数将传入的对象指针转化为指定的对象类型指针,如上述代码中将实体pEnt 转

24、化为AcDbLine对象指针。,3.4 实体操作前面介绍了通过API创建新实体对象,除此之外,开发者还可以通过API来对实体进行打开、编辑、删除等操作,当然对于复杂实体在处理的时候需要多做一些工作。,3.4.1 实体操作方式ObjectARX 中对实体的操作一般有两种方式,一种为open/close 方式,另一种为通过事务的方式。open/close方式在 open/close 方式中,通常调用全局函数acdbOpenObject()来打开实体对象,需要传入数据库对象ID,返回数据库对象的指针。另外还可以通过acdbOpenAcDbEntity()打开从AcDbEntity派生的实体对象,或者

25、调用acdbOpenAcDbObjec()打开从AcDbObject派生的数据库常驻对象。,这三个函数的用法一样,下面以acdbOpenObject()为例说明函数的使用,acdbOpenObject函数原型为:Acad:ErrorStatus acdbOpenObject(AcDbObject*,在通过 acdbOpenObject函数打开对象的时候,需要指定对象的打开模式AcDb:OpenMode,打开模式有AcDb:kForRead,AcDb:kForWrite和AcDb:kForNotify三种,各种模式的说明如下:打开模式 说明AcDb:kForRead以读的模式打开对象。一个对象最

26、多可以同时被以读模式打开256次,此时不能再以读或通知模式打开AcDb:kForWrite以写模式打开。如果已经打开,则以写模式打开对象将失败。一个对象同时只能以写的模式打开一次。AcDb:kForNotify以通知模式打开。当对象已经被读或写模式打开时,可以通知模式打开。,当以AcDb:kForRead打开对象的时候,只能访问数据库对象的数据,不能进行修改操作,如果要进行修改,需要调用AcDbObject:upgradeOpen()将打开模式升级为写,可以调用AcDbObject:downgradeOpen将对象打开模式降低为读。实体对象打开后,就可以通过实体的对象指针操作实体,当操作结束后

27、,切记关闭实体对象,否则会造成AutoCAD 异常,关闭实体调用的是实体的close()成员函数。,/选择对象ads_name en;ads_point pt;acedEntSel(_T(n选择实体:),en,pt);AcDbObjectId id;/转化ads_name 为AcDbObjectIdacdbGetObjectId(id,en);AcDbEntity*pEnt;/打开对象acdbOpenObject(pEnt,id,AcDb:kForRead);/将打开的对象转化为AcDbLine对象指针if(pEnt-isKindOf(AcDbLine:desc()/编辑对象AcDbLine*

28、pLine=AcDbLine:cast(pEnt);pLine-upgradeOpen();pLine-setColorIndex(1);/关闭对象pEnt-close();,实体的删除如果新创建的实体没有通过AcDbBlockTableRecord:appendAcDbEntity()加入到块表记录的时候,它只是一个普通的C+对象指针,开发者可以使用delete将其删除。一旦实体被添加加进数据库,则不能通过delete 进行删除,否则会造成AutoCAD 崩溃。删除已经在数据库中的实体必须通过AcDbObject:erase(),该函数有一个bool 型的参量,所以它既可以删除实体,也可以将

29、删除的实体恢复。实际上,erase 函数只是将实体做了是否删除的标记,实体仍然在数据库中,只有执行了文件保存操作的时候,它才会从数据库中消失。,3.5 实体属性不论是AutoCAD 自带的实体还是开发者开发的自定义实体,所有实体都是从AcDbEntiy派生的,它们都具有一些共同的属性,并且拥有共同的存取属性的函数。这些属性包括颜色、线型、线型比例、可见性、图层等。当添加一个实体到块表记录的时候,如果没有明确的设置这些属性,AutoCAD 会自动调用AcDbEntity:setDatabaseDefaults()函数,将这些属性设置为默认值。,实体颜色实体颜色可以用0256 的颜色索引值表示,也

30、可以用AcCmColor 类来表示,通过AcCmColor:colorIndex()成员函数可以得到颜色的索引值。颜色索引值17 用于标准颜色,8255 的颜色取决于显示设备。17 的颜色如下表,可以通过AcDbEntity:colorIndex()来获取实体颜色索引值,也可以通过AcDbEntity:setColorIndex(Adesk:UInt16 color)来设置实体的颜色,下面代码通过输入颜色索引来改变实体的颜色。Acad:ErrorStatuschangeColor(AcDbObjectId entId,Adesk:UInt16 newColor)AcDbEntity*pEnti

31、ty;acdbOpenObject(pEntity,entId,AcDb:kForWrite);pEntity-setColorIndex(newColor);pEntity-close();return Acad:eOk;,实体线型线型就是定义了一系列的点和短线的组合,用来绘制不同样式的线段,在ObjectARX中线型对象对应线型表中的一条线型记录,通过AcDbLinetypeTableRecord来表示,通过API 可以根据线型记录的名称来获取指定的线型表记录,如下代码所示:,/首先获取线型表AcDbLinetypeTable*pLinetypeTbl;es=acdbHostApplica

32、tionServices()-workingDatabase()-getSymbolTable(pLinetypeTbl,AcDb:kForRead);if(es!=Acad:eOk)return;/获取指定的线型表记录AcDbObjectId ltypeObjId;es=pLinetypeTbl-getAt(_T(CONTINUOUS),ltypeObjId);if(es!=Acad:eOk)es=pLinetypeTbl-close();return;,当一个实体对象被创建时,其线型被初始化为NULL,然后用户可以通过调用AcDbEntity:setLinetype()传入线型名或线型的对

33、象ID 来设置实体的线型,同样也可以AcDbEntity:linetype()或AcDbEntity:linetypeId()来返回实体线型名或线型的对象ID。,可以通过以下代码来设置实体的线型:ads_name en;ads_point pt;acedEntSel(_T(n选择实体:),en,pt);AcDbObjectId entId;acdbGetObjectId(entId,en);AcDbEntity*pEntity;acdbOpenAcDbEntity(pEntity,entId,AcDb:kForWrite);pEntity-setLinetype(_T(HIDDEN);pEntity-close();,如果实体对象添加到数据库时没有显式地调用以上函数进行设置,则实体将采用数据库的当前线型值,此值存在CELTYPE 系统变量中。AutoCAD 中提供一些特殊的线型,具体说明如下表:,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号