AutoCAD数据库简介

AutoCAD数据库简介_第1张图片

AutoCAD图形是存储在数据库中对象的集合。符号表和字典是用来存储数据库对象的容器对象,这两种容器对象都可以将一个符号名映射到一个数据库对象。

符号表举例:层表AcDbLayerTable   块表AcDbBlockTable  线性表

块表记录AcDbBlockTableRecord   块表引用AcDbBlockTableReference

字典提供了一个比符号表更加通用的容器对象来存储。一个字典可以包含任何AcDbObject类和子类对象。

acdbHostApplicationServices()->workingDatabase()  获取当前图形的数据库

AutoCAD中对象ID与句柄的区别:

对象的ID是在编辑过程中用来识别不同对象(概念上对象包含实体),而在最终存储至数据库中时,采用句柄来标示相应的对象。

即从数据库中提取或存储对象时,才会使用或产生句柄。而在AutoCAD程序中操作对象时,使用的大多为对象ID。

所以,对象ID在一个应用程序中是唯一标示一个实体,而在应用程序连接的数据库中,不同的实体分别存储到不同数据库中时,可能会用到相同句柄。

AutoCAD数据库简介_第2张图片

获取对象ID的方法:

1. 可在创建对象实体并写入数据库的过程中获取对象ID

2. 可以用迭代器遍历容器和对象列表获取对象IDAcDbDictionaryIteratorAcDbObjectIterator.

3个块表记录:模型空间记录(MODEL_SPACE)和两种图形空间记录(PARER_SPACEPARER_SPACE0)。层表最初只包含一个记录:0层记录。线性表最初记录:CONTINUOUS记录

1.命名对象字典:组词典(GROUP DICTIONARY)、多线样式词典(MLINE style dictionary)、布局辞典(layout dictionary)和打印样式词典(plot style dictionary)

2.AcDbDatabase类构造函数中,buildDefaultDrawingkTrue时,可以再新的AutoCAD数据库中构造以上对象,打开DWGDXF文件时应该设置为kFalse

获取当前图形数据库的块表:acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pBlockTable,AcDb::kForRead);

                                                  acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable, AcDb::kForRead);  //获取可读的块表对象

3. 打开模型空间的块表记录:

pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord, AcDb::kForWrite);

成功返回Acad::eOk

4.将实体加入到块表记录:

Acad::ErrorStatus es = pBlockTableRecord->appendAcDbEntity(entId,pEnt);

5.创建新层:

AcDbLayerTable *pLayerTable;

acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLaterTable,AcDB::kForWrite);

AcDbLayerTableRecord *pLayerTableRecord = newAcDbLayerTableRecord;

pLayerTableRecord->setName(“MYNEWLAYER”);

AcDbObjectId pLayerId;

pLayerTable->add(pLayerId,pLayerTableRecord);pLayerTable->close();

pLayerTableRecord->close();

6. 创建新层
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLaterTable,AcDB::kForWrite);
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
pLayerTableRecord->setName(“MYNEWLAYER”);
AcDbObjectId pLayerId;
pLayerTable->add(pLayerId,pLayerTableRecord);
pLayerTable->close();
pLayerTableRecord->close();
return pLayerId;
7. 打开ObjectARX对象:acdbOpenObject(AcDbObject*& pObject, AcDbObjectId, AcDb::OpenMode)
8. AcDbDatabase::getAcDbObjectId(AcDbObjectId&retId,Adesk::Boolean createIfNotFound,const AcDbHandle& objHandle, Adesk::UInt32 xRefId=0);
9. AcDbObject的成员函数void getAcDbHandle(AcDbHandle& handle) const ,若对象没有加入数据库则没有句柄,可以用AcDbHandle::isNull来检查
10. 对象在加入数据库之前,随时可以用delete()函数删除。但是加入之后需要用erase将对象表示为擦除,但是数据库中仍存在。但在存盘时会被析构。
Erase(Ktrue)删除对象 erase(Kfalse) 恢复对象。但是数据库对象被删除后无法通过该方式恢复,需要重新setAt。若为实体对象,则可以恢复。
ads_name数据类型相当于AcdbObjectId.
AcDb库提供以下函数进行相互之间的转换:
extern Acad::ErrorStatus acdbGetAdsName(ads_name& objName,AcDbObjectId objId);
extern Acad::ErrorStatus acdbGetObjectId(AcDbObjectId& objId,const ads_name objName);
通过对象句柄来获得ads_name:
Int acdbHandEnt(const char* handle, ads_name entres);

11. 加入新组
createNewGroup(AcDbObjectIdArray& objIds, char* pGroupName, AcDbObjectId pLayerID)
{
AcDbGroup *pGroup = new AcDbGroup(pGroupName);
For(int I = 0; I < objIds.length();I++)
{
pGroup->append(objIds[I]);
}
AcDbDictionary *pGroupDict;
acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict,AcDb::kForWrite);
AcDbObjectId pGroupId;
pGroupDict->setAt(pGroupName,pGroup,pGroupId);
pGroup->setLayer(pLayerId);
pGroupDict->close();
pGroup->close();
}
return pLayerId;

对象ID于句柄之间的转换

AcDbDatabase::getAcDbObjectId(AcDbObjectId&retId,Adesk::BooleancreateIfNotFound,const AcDbHandle& objHandle, Adesk::UInt32 xRefId=0);

打开ObjectARX对象:acdbOpenObject(AcDbObject*& pObject, AcDbObjectId,AcDb::OpenMode)

AcDbObject的成员函数voidgetAcDbHandle(AcDbHandle& handle) const ,若对象没有加入数据库则没有句柄,可以用AcDbHandle::isNull来检查

对象在加入数据库之前,随时可以用delete()函数删除。但是加入之后需要用erase将对象表示为擦除,但是数据库中仍存在。但在存盘时会被析构。

Erase(Ktrue)删除对象 erase(Kfalse)恢复对象。但是数据库对象被删除后无法通过该方式恢复,需要重新setAt。若为实体对象,则可以恢复

ads_name数据类型相当于AcdbObjectId.

AcDb库提供以下函数进行相互之间的转换:

extern Acad::ErrorStatus acdbGetAdsName(ads_name&objName,AcDbObjectId objId);

extern Acad::ErrorStatus acdbGetObjectId(AcDbObjectId&objId,const ads_name objName);

通过对象句柄来获得ads_name

Int acdbHandEnt(const char* handle, ads_name entres);

加入新组

createNewGroupAcDbObjectIdArray&objIds, char* pGroupName, AcDbObjectId pLayerID

{

AcDbGroup *pGroup = new AcDbGroup(pGroupName);

For(int I = 0; I < objIds.length();I++)

{

          pGroup->append(objIds[I]);

}

AcDbDictionary *pGroupDict;

acdbHostApplicationServices()->workingDatabase()->getGroupDictionary(pGroupDict,AcDb::kForWrite);

AcDbObjectId pGroupId;

pGroupDict->setAt(pGroupName,pGroup,pGroupId);

pGroup->setLayer(pLayerId);

pGroupDict->close();

pGroup->close();

}

如果实体对象创建失败,返回值为NULL,return Acad::eOutOfMemory

当前数据库块表打开失败,返回值非Acad::eOk,关闭相应数据库表,并记录Acad::ErrorStatus es2对象,acrx_abort(“XXX”,acadErrorStatusText(es2))报出错误,删除相应对象。


如何辨析AutoCAD中数据库不同表之间的关系?

首先我们要明确的是AutoCAD数据库中不同表之间,甚至表与记录之间的关系都是平等的。并不是从表面上看到的包含关系。

初学者往往由于先要从当前主数据库中获取块表,然后通过块表来获得块记录,然后在块记录中存入或取出实体,认为这是包含关系。

但是事实上类似于块记录拥有一个存储多个实体对象ID的数组,块表与表记录之间大多都类似于这种关联关系。

所以,为了避免忘记,常常可以找到表记录时,就可以将不需要使用的表关闭。


 

 



你可能感兴趣的:(ObjectArx开发)