CAD平台开发分为两大部分。一是底层开发,即CAD数据库的开发(底层类和结构),二是上层开发,界面和功能实现。本人目前在一个开发CAD平台的公司工作,目前主要接触的是上层开发这一部分,没有底层开发的部分的代码,只有编号的底层数据库的DLL。所以在此我要好先准备一下CAD数据库和实体结构,虽说没有源码,但是可以根据AUTOCAD来熟悉掌握。因为两者大体相同。 一、符号表 一副CAD图形就是一个包含有多个表的数据库,它规定了9个符号表(见下表),用户不能再增加新的符号表。 具体符号表的数据结构我只能看到头文件,但是大体可以猜出一个细节。
AcDbDatabase数据组成
AcDbDatabase数据库 二、用ObjectARX创建对象
AcDbBlockTable AcDbBlockTableRecord 可以有多个数据库,但是只能打开一个数据库 获取当前打开的数据库acdbHostApplicationServices()->workingDatabase()或是acdbCurDwg() 打开当前的对象(由AcDbObject派生的) 使用acdbOpenObject inline Acad::ErrorStatus acdbOpenObject( AcDbEntity
*& pEnt, AcDbObjectId id,
AcDb::OpenMode mode ); AcDbObject类的函数可以通过帮助查到 看看以下的例子 //给当前数据库中添加一条直线 AcDbObjectId createLine() {
AcGePoint3d startPt(4.0, 2.0, 0.0);
AcGePoint3d endPt(10.0, 7.0, 0.0);
AcDbLine *pLine = new AcDbLine(startPt, endPt);// AcDbLine类
AcDbBlockTable *pBlockTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pBlockTable, AcDb::kForRead);//获得当前的AcDbBlockTable块
AcDbBlockTableRecord *pBlockTableRecord;
pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
AcDb::kForWrite);
pBlockTable->close(); // 获得ACDB_MODEL_SPACE的块记录
AcDbObjectId lineId;
pBlockTableRecord->appendAcDbEntity(lineId, pLine);//添加AcDbLine到BlockRecord
pBlockTableRecord->close();
pLine->close();
return lineId; } 注:添加道CAD数据库中的所有实体均获得一个对象ID。 //给当前数据库中添加一层 Void createNewLayer() {
AcDbLayerTable *pLayerTable;
acdbHostApplicationServices()->workingDatabase()
->getSymbolTable(pLayerTable, AcDb::kForWrite); //获得当前的AcDbLayerTable块
AcDbLayerTableRecord *pLayerTableRecord = new AcDbLayerTableRecord;
pLayerTableRecord->setName(_T("ASDK_MYLAYER"));// AcDbLayerTableRecord类 //
Defaults are used for other properties of //
the layer if they are not otherwise specified. pLayerTable->add(pLayerTableRecord);
//添加TableRecord到LayerTable
pLayerTable->close();
pLayerTableRecord->close(); } 注意:我们打开线性表进行读操作,获得 CONTINUOUS 线性。记住:线性 //建一个组,把objIds加入组中。 Void createGroup(AcDbObjectIdArray& objIds, TCHAR*
pGroupName) {
AcDbGroup *pGroup = new AcDbGroup(pGroupName);//新的组 //
Put the group in the group dictionary which resides
// in the named object dictionary.
//
AcDbDictionary *pGroupDict;
acdbHostApplicationServices()->workingDatabase()
->getGroupDictionary(pGroupDict, AcDb::kForWrite);//组字典
AcDbObjectId pGroupId;
pGroupDict->setAt(pGroupName, pGroup, pGroupId);//加入组
pGroupDict->close();
// Now that the group has been added, it has an ObjectID. //
This is important since the group will become a persistent //
reactor for the added entities... for (int i = 0;
i < objIds.length(); i++) {
pGroup->append(objIds[i]);// objIds加入组 } pGroup->close(); } //改变实体的颜色 Acad::ErrorStatus changeColor(AcDbObjectId entId,
Adesk::UInt16 newColor) {
AcDbEntity *pEntity;
acdbOpenObject(pEntity, entId,
AcDb::kForWrite);
pEntity->setColorIndex(newColor);
pEntity->close();
return Acad::eOk; } Void
runIt() // 将一种综合起来,就是一种操作 {
createNewLayer();
AcDbObjectIdArray idArr;
// create a line and circle and add them to the objectId
// array
//
idArr.append(createLine());
idArr.append(createCircle());
// change circle color to red
// changeColor(idArr.last(), 1);
// put the line and circle in a group named
// "ASDK_TEST_GROUP"
//
createGroup(idArr, _T("ASDK_TEST_GROUP")); } 在此声明一下。每个系统函数都要判断返回值,保证系统出现异常时能及时发现 返回值一种是 enum ErrorStatus{ eOk = 0, eNotImplementedYet =
1, ………………一直到eStringNotAllowedInExpression。非常多。几乎涵盖所有错误。可以用 acdbErrorStatusText(ErrorStatus)来返回错误的说明 另一种是int ,即不是RTNORM,则有误 通过以上代码,我们可以总结出一下把实体放入CAD数据库时所需的步骤。如下: 三、AutoCAD的数据库结构 所有的数据库有表和记录,AutoCAD把图形结构看作一个数据库。一幅图形具有如下的结构: 四、数据库常驻对象 为了能使用符号表和符号表记录,在应用程序中比寻包含头文件 dbsymtb.h,即:#include<dbsymtb.h> 符号表的查询函数如下: 符号表的编辑函数如下: 注:用适当的符号表名代替上面的###字符。 层表记录的查询函数如下: 五、常用返回码 两个最常用的返回码如下: 六、浏览器常用函数 void inblk() 特别说明:使用 upgradeOpen() 函数可以把 AcDb###Table 转换为写操作模式。 当前模式为: 改为写模式的写法: pBlkTable->upgradeOpen(); 用户通过readDwgFile和SaveAs来打开保存数据库 void ArxApp::cmd_createDwg(void) { AcDbDatabase
*pDataBase = new AcDbDatabase;//新建一个Database AcDbBlockTable* pBtbl; pDataBase->getBlockTable(pBtbl,AcDb::kForRead); AcDbBlockTableRecord
*pBtblRecord; pBtbl->getAt(ACDB_MODEL_SPACE,pBtblRecord,AcDb::kForWrite); pBtbl->close(); AcGePoint3d
startPt(0,0,0);//起点 AcGePoint3d
endPt(200,100,0);//终点 AcDbLine *pLine = new
AcDbLine(startPt,endPt); AcDbObjectId lineId =
AcDbObjectId::kNull; pBtblRecord->appendAcDbEntity(lineId,pLine); pLine->close(); pBtblRecord->close(); pDataBase->saveAs(_T("test1.dwg"));//保存DataBase为test1.dwg delete pDataBase; } void ArxApp::cmd_readDwg(void) { AcDbDatabase
*pDataBase = new AcDbDatabase; pDataBase->readDwgFile(_T("test1.dwg"));
//读取test1.dwg AcDbBlockTable* pBtbl; pDataBase->getBlockTable(pBtbl,AcDb::kForRead); AcDbBlockTableRecord
*pBtblRecord; pBtbl->getAt(ACDB_MODEL_SPACE,pBtblRecord,AcDb::kForRead); pBtbl->close(); AcDbBlockTableRecordIterator
*pBlkTblRdItr; pBtblRecord->newIterator(pBlkTblRdItr); AcDbEntity *pEnt; //遍历所有实体 for(pBlkTblRdItr->start();!pBlkTblRdItr->done();pBlkTblRdItr->step()) { pBlkTblRdItr->getEntity(pEnt,AcDb::kForRead); acutPrintf(_T("class
is: %s\n"),
pEnt->isA()->name()); pEnt->close(); } pBtblRecord->close(); delete pBlkTblRdItr; delete pDataBase; ads_tblnext } 使用SetCeColor,
SetCeltype,setClayer等设置数据库的值,具体的参考帮助文档 字典相互拷贝 字典相互拷贝使用AcDbDatabase::wblock (AcDbDatabase*& newDb) ,newDb中没有引用的符号在新数据库中略去,对象不被复制,用户要使用AcEditorReactor将数据传到新数据库中。 AcDbDatabase::wblock (AcDbDatabase*& newDb, AcDbObjectId recordId) 元Db中recordId的块表中的实体全部被复制过去 AcDbDatabase::wblock (AcDbDatabase*& newDb, AcDbObjectIdArray&idArray, AcGePoint3d& point) 元Db中idArray的实体放到新的DB中,point就是新的DB中世界坐标系原点 一个对象(实体,符号表记录,字典)有三种方式被引用 1. AcDbObjectId; 2. AcDbHandle; 3. ads_name; 三者相互转化 Acad::ErrorStatus getAcDbObjectId(
AcDbObjectId& retId, bool createIfNotFound,
const AcDbHandle& objHandle, Adesk::UInt32 xRefId = 0 );通过retId获取objHandle Acad::ErrorStatus acdbGetAdsName( ads_name& objName, AcDbObjectId objId );通过objId返回objName Acad::ErrorStatus acdbGetObjectId(
AcDbObjectId& objId, const ads_name objName ); 通过objName返回objId 上图就是数据库的具体显示 AcDbObject数据扩展 ? 扩展数据 ? Resbuf(组码) ? xData
(获取XData) ? setXData(修改,添加,删除1000-107扩展数据,包含在Resbuf中) ? acdbRegApp(加入到Resbuf中) ? acutRelRb(析构Resbuf) ? 扩展词典 ? createExtensionDictionary ? extensionDictionary setFromRbChain(Resbuf);加入扩展字典
rbChain(&Resbuf) 获取扩展字典扩展词典一种跟Obj(DXF (102 .
"{ACAD_XDICTIONARY")
(360 . <图元名:
7ee03008>) (102 . "}")
),一种放入字典。
有例子xdata,xrecord,xtsndict |
|