- 积分
- 4400
- 明经币
- 个
- 注册时间
- 2015-1-16
- 在线时间
- 小时
- 威望
-
- 金钱
- 个
- 贡献
-
- 激情
-
|
本帖最后由 qq1254582201 于 2024-9-5 17:18 编辑
摘要
本文详细介绍了AutoCAD开发中扩展数据XData、扩展记录XRecord以及有名对象字典NameDict的使用。XData用于向实体添加用户数据,但有限;XRecord存储能力更强,常用于替代XData;而NameDict作为图形数据库的一部分,用于保存与实体无关的设计参数。文章涵盖如何添加、查看和删除这些数据,并提供了源码地址供进一步研究。
1、实体-扩展数据XData
扩展数据能被添加到任何实体上,由一个结果缓冲区链表组成,并且随AutoCAD图形一起保存(AutoCAD不会使用扩展数据)。在许多情况下,扩展数据是向实体追加用户数据的一个有效途径,但是每个实体上所附加的扩展数据不能超过16K。
1)添加扩展数据
- static void ZYMyGroupAddXData()
- {
- // Put your command code here
- // 提示用户选择所要添加扩展数据的图形对象
- AcDbEntity *pEnt = nullptr;
- AcGePoint3d pickPoint;
- if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要添加扩展数据的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
- {
- CString appName = TEXT("CustomXDataApp");
- // 注册应用程序名称
- acdbRegApp(appName);
- // 创建结果缓冲区链表
- struct resbuf* rb = acutBuildList(AcDb::kDxfRegAppName, appName, // 应用程序名称
- AcDb::kDxfXdAsciiString, TEXT("扩展数据字符串"), // 字符串
- AcDb::kDxfXdInteger32, 2, // 整数
- AcDb::kDxfXdReal, 3.14, // 实数
- AcDb::kDxfXdWorldXCoord, asDblArray(pickPoint), // 点坐标值
- RTNONE);
- // 为选择的实体添加扩展数据
- pEnt->setXData(rb);
- acutRelRb(rb);
- acutPrintf(TEXT("\n成功为实体添加了扩展数据!"));
- pEnt->close();
- }
- }
复制代码 2)查看扩展数据
- static void ZYMyGroupViewXData()
- {
- // 提示用户选择所要查看扩展数据的图形对象
- AcDbEntity *pEnt = NULL;
- AcGePoint3d pickPoint;
- if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要查看扩展数据的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
- {
- CString appName = TEXT("CustomXDataApp");
- // 获取实体的扩展数据
- struct resbuf *pRb = pEnt->xData(appName);
- if (pRb != NULL)
- {
- // 在命令行显示所有的扩展数据
- struct resbuf *pTemp = pRb; // 使用临时的结果缓冲区指针进行遍历,pRb不修改便于释放
- // 首先要跳过应用程序的名称这一项
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n字符串类型的扩展数据是: %s"), pTemp->resval.rstring);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n整数类型的扩展数据是: %d"), pTemp->resval.rint);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n实数类型的扩展数据是: %.2f"), pTemp->resval.rreal);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n点坐标类型的扩展数据是: (%.2f, %.2f, %.2f)"),
- pTemp->resval.rpoint[X], pTemp->resval.rpoint[Y],
- pTemp->resval.rpoint[Z]);
- acutRelRb(pRb);
- }
- else
- {
- acutPrintf(TEXT("\n所选择的实体不包含任何的扩展数据!"));
- }
- pEnt->close();
- }
- }
复制代码 3)删除扩展数据
- static void ZYMyGroupDeleteXData()
- {
- // 提示用户选择所要删除扩展数据的图形对象
- AcDbEntity *pEnt = NULL;
- AcGePoint3d pickPoint;
- if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要删除扩展数据的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
- {
- CString appName = TEXT("CustomXDataApp");
- // 注册应用程序名称
- acdbRegApp(appName);
- // 创建结果缓冲区链表
- struct resbuf* rb = acutBuildList(AcDb::kDxfRegAppName, appName,RTNONE);
- // 设置内容为空的结果缓冲区链表就是删除扩展数据
- pEnt->setXData(rb);
- acutRelRb(rb);
- acutPrintf(TEXT("\n成功为实体删除了扩展数据!"));
- pEnt->close();
- }
- }
复制代码 2、实体–扩展记录Data
扩展记录与扩展数据类似,但是其数据存储量和能够存储的数据类型都要多于扩展数据。扩展记录可以保存在实体的扩展字典中。扩展字典隶属于特定的实体,每个实体只能包含一个扩展字典,它为实体保存自定义数据提供了一种途径,实际上, Autodesk 也建议开发者用扩展字典和扩展记录来代替传统的扩展数据。有名对象字典直接保存在图形数据库中,不与特定的实体有关,因此可用于保存与实体无关的设计参数。字典与符号表类似,其中包含一个惟一的字符串关键字索引和对象 ID 号,通过关键字来访问字典中保存的内容。
1)添加扩展记录
- static void ZYMyGroupAddXRecord()
- {
- // 提示用户选择所要添加扩展记录的图形对象
- AcDbEntity *pEnt = NULL;
- AcGePoint3d pickPoint;
- if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要添加扩展记录的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
- {
- // 向实体中添加扩展字典
- pEnt->createExtensionDictionary();
- AcDbObjectId dictObjId = pEnt->extensionDictionary();
- pEnt->close();
- // 创建扩展记录
- AcDbXrecord *pXrec = new AcDbXrecord;
- // 向扩展字典中添加一条记录
- AcDbObjectId xRecObjId;
- AcDbDictionary *pDict = NULL;
- if (acdbOpenObject(pDict, dictObjId, AcDb::kForWrite) == Acad::eOk)
- {
- pDict->setAt(TEXT("XRecord"), pXrec, xRecObjId);
- pDict->close();
- }
- // 设置扩展记录的内容
- struct resbuf* pRb = acutBuildList(AcDb::kDxfText, TEXT("测试字符串数据"),
- AcDb::kDxfInt32, 12,
- AcDb::kDxfReal, 3.14,
- AcDb::kDxfXCoord, asDblArray(pickPoint),
- RTNONE);
- pXrec->setFromRbChain(*pRb); // 扩展数据内容填充扩展记录对象
- pXrec->close();
- acutRelRb(pRb);
- }
- }
复制代码 2)查看扩展记录
- static void ZYMyGroupViewXRecord()
- {
- // 提示用户选择所要查看扩展记录的图形对象
- AcDbEntity *pEnt = NULL;
- AcGePoint3d pickPoint;
- if (CSelectUtil::PromptSelectEntity(TEXT("\n选择所要查看扩展记录的实体:"), AcDbEntity::desc(), pEnt, pickPoint))
- {
- // 获得实体的扩展字典
- AcDbObjectId dictObjId = pEnt->extensionDictionary();
- pEnt->close();
- if (dictObjId.isNull())
- {
- acutPrintf(TEXT("\n所选择的实体不包含扩展字典!"));
- return;
- }
- // 打开扩展字典,获得与关键字"XRecord"关联的扩展记录
- AcDbDictionary *pDict = NULL;
- AcDbXrecord *pXrec = NULL;
- struct resbuf *pRb = NULL;
- if (acdbOpenObject(pDict, dictObjId, AcDb::kForRead) == Acad::eOk)
- {
- pDict->getAt(TEXT("XRecord"), (AcDbObject*&)pXrec, AcDb::kForRead);
- // 获得扩展记录的数据链表并关闭扩展数据对象
- pXrec->rbChain(&pRb);
- pXrec->close();
- pDict->close();
- }
- if (pRb != NULL)
- {
- // 在命令行显示扩展记录内容
- struct resbuf *pTemp = pRb;
- acutPrintf(TEXT("\n字符串类型的扩展数据是:%s"), pTemp->resval.rstring);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n整数类型的扩展数据是:%d"), pTemp->resval.rint);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n实数类型的扩展数据是:%.2f"), pTemp->resval.rreal);
- pTemp = pTemp->rbnext;
- acutPrintf(TEXT("\n点坐标类型的扩展数据是:(%.2f, %.2f, %.2f)"),
- pTemp->resval.rpoint[X], pTemp->resval.rpoint[Y],
- pTemp->resval.rpoint[Z]);
- acutRelRb(pRb);
- }
- }
- }
复制代码 3)删除扩展记录
3、图形数据库–有名对象字典
AutoCAD 每个图形数据库中都包含一个有名对象字典,默认情况下该字典中包含了组、多线样式、布局和打印等信息。例如,用户在 AutoCAD 创建一个组,就会有一个代表改组的元素被添加到组字典中。如果需要在有名对象字典中保存自己的数据,一般可以在有名对象字典中添加一个根字典,然后再向根字典中添加新的字典,进而在新字典中保存数据。这样的好处是不会与有名对象字典的基本字典相混淆。使用 AcDbDatabase 对象的 getNamedObjectsDictionary 函数可以获得图形的有名对象字典(根字典),可以通过 setAt 函数向根字典添加一个字典,或者通过 getAt 函数获得其中的一个字典。获得字典之后,向字典中保存数据的方法与扩展字典完全一致。
1)添加有名对象字典
- static void ZYMyGroupAddNameDict()
- {
- // 获得有名对象字典,向其中添加指定的字典项
- AcDbDictionary *pNameObjDict = NULL;//,
- acdbHostApplicationServices()->workingDatabase()
- ->getNamedObjectsDictionary(pNameObjDict, AcDb::kForWrite);
- // 检查所要添加的字典项是否已经存在
- AcDbObjectId dictObjId;
- AcDbDictionary *pDict = NULL;
- if (pNameObjDict->getAt(TEXT("MyDict"), (AcDbObject*&)pDict, AcDb::kForWrite) == Acad::eKeyNotFound)
- {
- pDict = new AcDbDictionary;
- pNameObjDict->setAt(TEXT("MyDict"), pDict, dictObjId);
- pDict->close();
- }
- pNameObjDict->close();
- // 向新建的字典中添加一个块记录对象
- if (acdbOpenObject(pDict, dictObjId, AcDb::kForWrite) == Acad::eOk)
- {
- CString sLinkName = _T("linkFilePath");
- CString sLinkPath = _T("C:\\Users\\zhangly-e\\Desktop\ggf.dwg");
- AcDbBlockTableRecord* pBlockRecord = new AcDbBlockTableRecord();
- pBlockRecord->setName(sLinkName);
- pBlockRecord->setPathName(sLinkPath);
- AcDbObjectId objectId;
- Acad::ErrorStatus es = pDict->setAt(TEXT("BlockKey"), pBlockRecord, objectId);
- pBlockRecord->close();
- pDict->close();
- }
- }
复制代码 2)查看有名对象字典
- static void ZYMyGroupViewNameDict()
- {
- // 获得对象有名字典中指定的字典项
- AcDbDictionary *pNameObjDict = NULL;
- Acad::ErrorStatus es;
- acdbHostApplicationServices()->workingDatabase()
- ->getNamedObjectsDictionary(pNameObjDict, AcDb::kForRead);
- AcDbDictionary *pDict = NULL;
- es = pNameObjDict->getAt(TEXT("MyDict"), (AcDbObject*&)pDict, AcDb::kForRead);
- pNameObjDict->close();
- // 如果不存在指定的字典项,退出程序
- if (es == Acad::eKeyNotFound)
- {
- acutPrintf(TEXT("\n不存在字典项MyDict."));
- return;
- }
- // 获得指定的对象字典中的对象
- AcDbBlockTableRecord *pBlockRecord = NULL;
- if (pDict->getAt(TEXT("BlockKey"), (AcDbObject*&)pBlockRecord, AcDb::kForRead) == Acad::eOk)
- {
- CString sName;
- ACHAR* chName = new ACHAR;
- pBlockRecord->pathName(chName);
- pBlockRecord->close();
- acutPrintf(TEXT("\n当前文件链接的文件为: %s"), chName);
- if (chName)
- {
- delete chName;
- chName = nullptr;
- }
- }
- pDict->close();
- }
复制代码 4、源码地址
下载地址
转载自<四>objectARX开发:扩展数据XData、扩展记录XRecord和有名对象字典NameDict_arx2017开发输入命令输出xdata-CSDN博客
|
评分
-
查看全部评分
|