找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 2446|回复: 4

[分享] ObjectARX AutoCAD的数据库和实体结构

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2019-1-15 18:00:03 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×

一、符号表

一副CAD图形就是一个包含有多个表的数据库,它规定了9个符号表(见下表),用户不能再增加新的符号表


符号表名
符号表功能
AcDbViewTable

(视图表)      

适用于 AcDbViewTableRecord 类,表示在数据库中存储的视图。
视图与CAD的"VIEW"命令相关联
AcDbViewportTable

(视口表)

适用于 AcDbViewportTableRecord 类,表示在CAD中当前系统变
量TILEMODE的值为1时的视口设置。视口配置由CAD的 VPORTS
命令创建。不要和 MVIEW 命令混淆,当系统变量 TILEMODE 的
值为0是,该命令创建视口实体。
AcDbLinetypeTable

(线性表)

适用于 AcDbLinetypeTableRecord 类,表示图形数据库中的线性。
AcDbLayerTable

(层表)

适用于 AcDbLayerTableRecord类,表示图层。
AcDbTextStyleTable

(文字样式表)

适用于 AcDbTextStyleTable 类,表示文字样式。
AcDbUCSTable

(用户坐标系表)

适用于 AcDbUCSTableRecord 类,表示图形数据库中的存储的用户
坐标系。
AcDbRegAppTable

(应用程序名注册表)

适用于 AcDbRegAppTableRecord 类,表示为图形数据库中对象的扩
展实体数据而注册的应用程序名。
AcDbDimStyleTable

(尺寸标注样式表)

适用于 AcDbDimStyleTableRecord 类,表示图形数据库中的尺寸标注
样式。
AcDbBlockTable

(块表)

适用于 AcDbDimStyleTableRecord 类,表示图形数据库中定义的块。
此表含有两个非常重要的记录:模型空间和图纸空间。所有的实体(可
见对象)均防御块表AcDbBlockTable中。



二、用ObjectARX创建对象

(1)创建直线



[C++] 纯文本查看 复制代码
AcDbObjectId createLine()
{
     AcDbBlockTable *pBlkTable;
     AcDbBlockTableRecord *pBlkTableRecord;
      AcDbLine *pLine;
      AcDbObjectId lineId;
      AcGePoint3d startPt(100.0, 100.0, 0.0);
      AcGePoint3d endPt(500.0, 500.0, 0.0);
      //  创建线段
      pLine = new AcDbLine(startPt, endPt);
      //  以读方式打开块表
      acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTable, AcDb::kForRead);
      //  以写方式打开块表记录,并在其中查找 ACDB_MODEL_SPACE 或 ACDB_PAPER_SPACE 或一个布局
      pBlkTable->getAt(ACDB_MODEL_SPACE, pBlkTableRecord, AcDb::kForWrite);
      //  关闭块表
      pBlkTable->close();
      //  把实体添加到块表记录
     lineId = pBlkTableRecord->appendAcDbEntity(lineId, pLine);
      //  关闭块表记录
      pBlkTableRecord->close();
      //  关闭实体对象
      pLine->close();
      //  返回对象ID
      return lineId;
}




注:添加道CAD数据库中的所有实体均获得一个对象ID。


(2)创建图层



[C++] 纯文本查看 复制代码
void createNewLayer()
{
      AcDbDatabase *pCurDb;
      AcDbLayerTable *pLayerTable;
      pCurDb = acdbHostApplicationServices()->workingDatabase();
      pCurDb->getLayerTable(pLayerTable, AcDb::kForRead);
      AcDbLayerTableRecord *pLayerTalbeRecord = new AcDbLayerTableRecord;
      //  设置层名
      pLayerTalbeRecord->setName("ARX");
      //  设置线性
      AcDbLinetypeTable *pLinetypeTbl;
      pCurDb->getLinetypeTable(pLinetypeTbl, AcDb::kForRead);
      //  创建图层
      AcDbObjectId layerId;
      pLinetypeTbl->getAt("CONTINUOUS", layerId);
      pLayerTalbeRecord->setLinetypeObjectId(layerId);
      pLayerTable->add(pLayerTalbeRecord);
      //  释放内存
     pLinetypeTbl->close();
      pLayerTable->close();
      pLayerTalbeRecord->close();
}

注意:我们打开线性表进行读操作,获得 CONTINUOUS 线性。记住:线性  CONTINUOUS 始终存在。最后,我们把新的层表记录加进层表中,接着关闭层表和层表记录。这和创建实体并非完全相同。

通过以上代码,我们可以总结出一下把实体放入CAD数据库时所需的步骤。如下:



    • 创建一个新实体。
    • 以读方式打开块表。
    • 以写方式打开块表记录,并在其中查找 ACDB_MODEL_SPACE 或 ACDB_PAPER_SPACE 或一个布局。
    • 关闭块表。
    • 把实体添加到块表记录。
    • 关闭块表记录。
    • 关闭实体对象。



三、AutoCAD的数据库结构

所有的数据库有表和记录,AutoCAD把图形结构看作一个数据库。一幅图形具有如下的结构:



    • 层表和层表记录——AcDbLayerTable, AcDbLayerTableRecord。
    • 块表和块表记录——AcDbBlockTable, AcDbBlockTableRecord。AutoCAD中的所有实体(可见实体)均属于块表记录。块表中包含有两天特殊的记录:*MODEL_SPACE(模型空间)和*PAPER_SPACE(图纸空间)。所有的AutoCAD实体均属于这两个记录。
    • 符号表和各种类型的符号表记录,见上面的符号表表格。
    • 有名对象字典,其中有“组字典”和“多线样式字典”。




四、数据库常驻对象


数据库常驻对象中的每一个对象都使用AcDb前缀。这些对象可分为下列几大类型:符号表、符号表记录、实体、基本类和光栅类。所有的数据库常驻对象均有AcDbObject类派生,而AcDbObject类是由AcRxObject类派生,AcRxObject是基类。

为了能使用符号表和符号表记录,在应用程序中比寻包含头文件 dbsymtb.h,即:#include<dbsymtb.h>

符号表的查询函数如下:


  • AcDb###Table::getAt()----------->  获得指定符号表记录的指针或ID号。
  • AcDb###Table::has()------------->  确定符号表中指定的符号表记录是否存在。
  • AcDb###Table::newIterator()----->  创建遍历符号表的浏览器。

符号表的编辑函数如下:


  • AcDb###Table::add()---->  在符号表中加入一条符号表记录。

注:用适当的符号表名代替上面的###字符。

层表记录的查询函数如下:


  • AcDbLayerTableRecord::color()            图层是什么颜色?
  • AcDbLayerTableRecord::ifFrozen()         图层是否冻结?
  • AcDbLayerTableRecord::isLocked()         图层是否锁住?
  • AcDbLayerTableRecord::isOff()            图层是否关闭?
  • AcDbLayerTableRecord::linetypeObjectId() 图层的线性是什么?
  • AcDbLayerTableRecord::VPDFLT()           视口中层的可见性缺省值?

层表记录的编辑函数如下:


  • AcDbLayerTableRecord::setColor()     改变图层颜色。
  • AcDbLayerTableRecord::setIsFrozen()  解冻/冻结。
  • AcDbLayerTableRecord::setIsLocked()  锁住/解锁。
  • AcDbLayerTableRecord::setIsOff()     打开/关闭。
  • AcDbLayerTableRecord::setLinetypeObjectId()  改变图层的线性。
  • AcDbLayerTableRecord::setVPDFLT()    改变图层的可见性缺省值。


五、常用返回码

两个最常用的返回码如下:


  • Acad::ErrorStatus  在头文件 acadstr.h 中定义。
  • Adesk::Boolean     在 adesk.h 中定义。


六、浏览器常用函数


浏览器函数说明
AcDbSymbolTableIterator::done()如果浏览器到达表尾,函数返回 Adesk::kTrue,否则返回 Adesk::kFalse
AcDbSymbolTableIterator::getRecord()以 openMode 模式打开浏览器所在位置的记录,使 pRecord指向打开的
记录。此函数也在由 AcDbSymbolTable 派生出的类中定义,并常被该
类应用
AcDbSymbolTableIterator::getRecordId()返回浏览器所在位置对象的 AcDbObjectId
AcDbSymbolTableIterator::seek()用于定位浏览器,使浏览器处于由 AcDbObjectId 指定的记录处
AcDbSymbolTableIterator::start()用于初始化浏览器的位置,使其处于表的开头或表的结尾
AcDbSymbolTableIterator::step()移动浏览器,使其再表中下移(或上移)一条记录


例:利用浏览器显示数据库中所有线型

void inblk()

{

//  首先以读模式打开获得一条记录,接着获得先姓名,关闭记录,然后打印先姓名。

//  最后删除浏览器

AcDbDatabase *pCurDb;

AcDbLinetypeTable *pLineTypeTable;

AcDbLinetypeTableRecord *pLineTypeTableRecord;

AcDbLinetypeTableIterator *pLineTypeTableIter;

char * pName;

pCurDb = acdbHostApplicationServices()->workingDatabase();

//  获得线性表

pCurDb->getLinetypeTable(pLineTypeTable, AcDb::kForRead);

//  定义浏览器

pLineTypeTable->newIterator(pLineTypeTableIter);

//  遍历浏览器

for (; !pLineTypeTableIter->done(); pLineTypeTableIter->step())

{

  pLineTypeTableIter->getRecord(pLineTypeTableRecord, AcDb::kForRead);

  pLineTypeTableRecord->getName(pName);

  pLineTypeTableRecord->close();

  acutPrintf("\n线性名:%s", pName);

  //  释放资源

  free(pName);

}

//  释放浏览器

delete pLineTypeTableIter;

pLineTypeTable->close();

}

特别说明:使用 upgradeOpen() 函数可以把 AcDb###Table 转换为写操作模式。

当前模式为:  pCurDb->getBlockTable(pBlkTable, AcDb::kforread);

改为写模式的写法: pBlkTable->upgradeOpen();


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 28个

财富等级: 恭喜发财

发表于 2019-1-15 23:42:35 来自手机 | 显示全部楼层
什么时候讲讲acgi库和acgs的一些类呗
来自: 微社区
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 3904个

财富等级: 富可敌国

发表于 2019-1-16 09:08:18 | 显示全部楼层
做一个热心并受欢迎的人
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2个

财富等级: 恭喜发财

发表于 2020-9-24 10:22:50 | 显示全部楼层
非常感谢大佬的启蒙贴!赞!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2020-9-25 18:52:01 | 显示全部楼层
沙发我来坐,看看是什么。
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-4-26 22:06 , Processed in 0.352842 second(s), 35 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表