objectarx帮助文档的.net版本(第二章)
www.dimcax.com
objectarx帮助文档的.net版本(第二章)
第二章 autocad数据库入门
autocad数据库中存储了组成autocad图形的对象和实体。本章讨论数据库的关键元素:实体,符号表和命名对象字典。
这一章也会介绍对象id和打开数据库对象的接口。还会给出创建实体、层和组及向数据库加入对象的例子。
autocad数据库概览
autocad图形是存储在为数据库中的对象集合。数据库对象的基类是实体、符号表和字典。实体是autocad图形中具有图形界面的一种特殊的数据库对象。直线、圆、文本、solid、面域、椭圆等就是实体。换句话说,实体就是用户可以在屏幕上看到并且可以操作的东西。
符号表和字典是用来存储数据库对象的容器。这些容器对象把符号名(一个字符串)映射成一个数据库对象。每个autocad数据库都包括一系列固定的符号表,每个符号表包括一种特定类型的符号表记录的实例。你不能在数据库中加入新的符号表。符号表的例子包括:层表(layertable,包含层表记录),块表(blocktable,包括块表记录)。所有的autocad实体都属于块表记录。
字典提供了比符号表更通用的存储对象的容器。字典可以包含dbobject类(就是实体类的基类)或它的派生类的对象。当创建一个新的autocad图形时,autocad数据库会创建一个名为命名对象字典的字典。你可以在命名对象字典中创建新的字典,然后在创建的字典中加入新的数据库对象。
下图展示了autocad数据库中的主要元素。
此主题相关图片如下:
在autocad编辑的过程中,你可以通过调用语句来获取当前图形所在的数据库:
application.documentmanager.mdiactivedocument.database
或者hostapplicationservices.workingdatabase
多个数据库
在一个autocad进程中可以载入多个数据库。进程中的每个对象都有一个句柄和对象id。句柄唯一标识了一个数据库中的对象,对象id唯一标识了所有数据库中的对象。对象id只存在于一次编辑进程中,而句柄则和图形文件一起保存。和对象id不同的是,当多个数据库被载入到autocad进程中时,句柄不一定会唯一。
获得对象id
有了对象id,你可以对实际的数据库对象进行操作。
你可以通过不同的方法来获得对象id:
l 创建一个对象并加入到数据库中。数据库会给加入的对象分配一个id,你可以通过访问对象的ojectid属性来获得分配的id。
l 使用数据库接口来获得对象id,这些对象都是在数据库创建的时候被自动创建的(例如九个固定的符号表和命名对象字典)。
l 使用特定类的接口来获得对象id。特定类(如符号表和字典)定义的对象会包含其它的对象。这些类提供了获得包含的对象的id的接口。
l 查询一个选择集。用户选择后,可以通过查询选择集来获取选中的对象id列表。
基本的数据库对象
在autocad中创建的对象都会被加入到适合它们的容器对象中。实体被加入到块表的记录中。符号表记录被加入到对应的符号表。实体和符号表之外的其它对象被加入到命名对象字典、被其它对象拥有的对象(其实这些对象最终还是被命名对象字典所拥有)或扩展的字典中。
数据库必须至少拥有以下的对象才可用:
l 包括块表、层表和线型表在内的九个符号表。块表最初包含三个记录:model_space,两个图纸空间记录(paper_space,paper_space0)。这三个块表记录表示模型空间和两个系统预定义的图纸空间布局。层表最初只包含一个记录0层。线型表最初只包含continuous线型。
l 一个命名对象字典。当一个数据库创建后,这个字典就包含了以下四个数据库字典:组字典、多线样式字典、布局字典和打印样式命名字典。在多线样式字典中,standard样式总是存在的。
当你给database类的构造函数的builddefaultdrawing参数传递true时,上面介绍的这些对象会被自动创建。如果传递false,则会创建一个可以载入dwg或dxf文件的空数据库。
在autocad中创建对象
这一部分向大家介绍在autocad中创建直线、圆、层和组,并展示autocad是怎样把这些对象加入到数据库中的。首先,假定用户使用下列命令在模型空间中创建了一条直线:
line 4,2 10,7
在数据库中,autocad先创建了一个line类的实例,然后把它存储在模型空间块表记录中,如下图所示:
此主题相关图片如下:
当你首次启动autocad时,数据库处于缺省状态,实体被加入到模型空间,它是autocad的主空间,被用于模型几何体和图形。图纸空间是用来支持“文档”几何体和图形的。生成实体的命令(line,对应于这个例子)把实体加入到当前的数据库中,并把它加入到模型空间块中。你可以查询实体所属的数据库和块。
接下来,假定用户用下面的命令创建了一个圆:
circle 9,3 2
同样地,autocad创建了对应实体(这次是circle)的实例,然后把它加入到模型空间块表记录中。
此主题相关图片如下:
接下来,用户创建了一个新层:
layer _make mylayer
autocad创建了一个新的层表记录来表示这个层,然后把这个记录加入到层表中。
最后,用户把所有的实体组合在一起。
group 3,2 9,3
autocad创建一个新的组对象,然后把它加入到组字典中,组字典包含在命名对象字典中。这个新的组包括组成这个组的对象的id。
此主题相关图片如下:
在objectarx中创建对象
这部分的objectarx代码示例向你演示如何创建一些autocad实体(直线和圆)、创建一个新层、改变直线的颜色、加入一个组到组字典中。
创建实体
下面的createline()函数创建一条直线并把它加入到模型空间块表记录中:
public void createline()
{
point3d startpoint=new point3d(4,2,0);
point3d endpoint=new point3d(10,7,0);
lines line=new lines(startpoint,endpoint);
database db= application.documentmanager.mdiactivedocument.database;
objectid btid=db.blocktableid;
blocktable bt=(blocktable)btid.open(openmode.forread);
objectid btrid=bt[blocktablerecord.modelspace];
blocktablerecord btr=(blocktablerecord)btrid.open(openmode.forwrite);
bt.close();
btr.appendentity(line);
btr.close();
line.close();
}
createline()首先获取当前图形的块表,然后打开模型空间块表记录用于写入。关闭块表后,向块表记录中加入实体,最后关闭块表记录和实体。
注意:当你使用完objectarx对象后,你必须尽快地显式关闭它们。呵呵,就好像要大家节约用水一样,用完水以后要记得关上水龙头。不过你可能注意到在你编译这个程序的时候,visual studio.net提示你最好用transaction来代替open()和close()函数。使用transaction的好处是你不用再手动编写关闭objectarx对象的代码,因为系统已经自动帮你做好了(呵呵,这就好像可以自动关闭的水龙头)。
下面是使用transaction的例子。
public void createline()
{
point3d startpoint=new point3d(4,2,0);
point3d endpoint=new point3d(10,7,0);
line line=new line(startpoint,endpoint);
database db= application.documentmanager.mdiactivedocument.database;
dbtransman tm=db.transactionmanager;
using(transaction trans=tm.starttransaction())
{
blocktable bt=(blocktable)tm.getobject(db.blocktableid,openmode::forread,true);
blocktablerecord btr=(blocktablerecord) tm.getobject(bt[blocktablerecord.modelspace],openmode::forwrite,true);
btr.appendentity(line);
tm.addnewlycreateddbobject(line,true);
trans.commit();
}
}
在以后的例子,我都会用transaction来写相关的代码。
下面的createcircle()函数创建一个圆并把它加入到模型空间块表记录中:
public void createcircle()
{
point3d center=new point3d(9.0,3.0,0.0);
vector3d normal=new vector3d(0.0,0.0,1.0);
circle circle=new circle(center,normal,2.0);
database db= application.documentmanager.mdiactivedocument.database;
dbtransman tm=db.transactionmanager;
using(transaction trans=tm.starttransaction())
{
blocktable bt=(blocktable)tm.getobject(db.blocktableid,openmode::forread,true);
blocktablerecord btr=(blocktablerecord) tm.getobject(bt[blocktablerecord.modelspace],openmode::forwrite,true);
btr.appendentity(circle);
tm.addnewlycreateddbobject(circle,true);
trans.commit();
}
}
下面的代码演示了如何从数据库中获得层表,创建一个新的层表记录,命名这个记录(asdk_mylayer)。层表记录最后被加入到层表中。
public void createnewlayer()
{
database db= application.documentmanager.mdiactivedocument.database;
dbtransman tm=db.transactionmanager;
using(transaction trans=tm.starttransaction())
{
layertable lt=( layertable)tm.getobject(db.layertableid,openmode::forwrite,true);
layertablerecord ltr=new layertablerecord();
ltr.name="asdk_mylayer";
lt.add(ltr);
tm.addnewlycreateddbobject(ltr,true);
trans.commit();
}
}
打开objectarx对象
这部分的代码向你讲述当你处理数据库驻留对象时,你必须遵守的打开和关闭对象的规则。这个规则会保证当需要访问对象时它们会在内存中,当不需要它们的时候则被记录到磁盘。在你修改一个对象之前,你必须像下面的例子一样打开它:
tm.getobject(objid,openmode::forwrite,true);
openmode是一个枚举类型,它表示你打开对象是用来读(forread)、写(forwrite)或通知(fornotify)。如果打开对象是用来写的话,那么你可以修改它。
一个新生成的对象实例被认为是打开用来写的。一个对象只有被加入到数据库后才能关闭。你可以在对象被加入到数据库之前自由地删除它。但如果对象已被加入到数据库后,你就不能直接删除它。你可以调用dbobject的erase()函数来擦除它。被擦除的对象仍然会保留在数据库中直到数据库被销毁为止,但当autocad图形被保存时,它不会被保存。
警告!如果直接删除已加入到数据库中的对象,那么会导致autocad终止。
在组字典中加入一个组
下面的代码使用createline()函数和createcircle()函数创建的直线和圆来创建一个组,然后把这个组加入到组字典中。直线和圆的id被当作参数传递到函数中。请注意组字典是如何打开用于写、修改。
public void creategroup(objectidcollection objids,string groupname)
{
group group=new group(groupname,true);
group.append(objids);
database db= application.documentmanager.mdiactivedocument.database;
dbtransman tm=db.transactionmanager;
using(transaction trans=tm.starttransaction())
{
dbdictionary groupdict =
(dbdictionary)tm.getobject(db.groupdictionaryid,openmode::forwrite,true);
groupdict.setat(groupname,group);
tm.addnewlycreateddbobject(groupp,true);
trans.commit();
}
}
c#最适合开发autocad,因为它拥有vb容易的特点,却具有vc++的强大功能。