英语比较烂,借着翻译帮助文档,一边学习英语,一边增强专业知识,有翻译的不妥的地方,欢迎评论区指正,谢谢各位看官赏脸html
arxdev.chm帮助文档:ObjectARX库为AutoCAD 2010提供的开发指南c++
第一章:ObjectARX 介绍性的概念数据库
第五节:数据库对象app
本章节描述的主题涉及全部的AutoCAD数据库对象,包括实体、符号表记录和字典项;主要概念包括打开/关闭对象、管理内存中的对象、对象权限和使用扩展数据或对象的扩展字典扩展一个对象。对象的其余常见操做,还讨论了移除和文件读取问题。函数
本小节内容:学习
1.打开关闭数据库对象测试
2.删除对象ui
3.数据库对象的全部权spa
4.添加特定的数据到对象翻译
5.移除对象
6.对象文件读取
7.嵌入和封装对象
(1)打开/关闭数据库对象
每一个AcDbObject对象能够用三种不一样的方式来用:
1.句柄
2.对象id
3.c++实例指针
当AutoCAD没有运行的时候,图像是存储在文件系统中的。DWG文件中包含的对象经过他们的句柄来标识。图像打开以后,能够经过AcDbDatabase 对象访问图像信息。每一个对象在数据库中都有一个对象id,该id在当前编辑的对话框中,从建立到删除都始终存在于该对象的AcDbDatabase中。open()函数将对象ID做为参数,并返回一个指向AcDbObject对象的指针。这个指针在对象关闭以前都是有效的,以下图所示:
1.你可使用全局函数acdbOpenObject() 打开一个对象
2.你可使用函数getAcDbObjectId()将句柄映射到对象id
3.你也能够打开一个对象,而后得到它的句柄
AcDbObject* pObject; AcDbHandle handle; pObject->getAcDbHandle(handle);
注:每当打开数据库对象时,应该尽早关闭它,用AcDbObject::close()函数关闭数据库对象。
ads_name等价于AcDbObjectId。AcDb库提供了两个独立的函数,容许你在AcDbObjectId和ads_name之间进行转换:
// 经过AcDbObjectId 返回一个ads_name acdbGetAdsName(ads_name& objName, AcDbObjectId objId); // 经过ads_name返回一个AcDbObjectId acdbGetObjectId(AcDbObjectId& objId, ads_name objName);
一般,你经过选择得到一个对象,而后它以ads_name形式返回,此时你须要把ads_name转换成AcDbObjectId,并打开AcDbObjectId。下面的函数演示了这个过程:
AcDbEntity*selectEntity(AcDbObjectId& eId, AcDb::OpenMode openMode) { ads_name en; ads_point pt; acedEntSel("\n请选择一个实体: ", en, pt); acdbGetObjectId(eId, en); AcDbEntity * pEnt; acdbOpenObject(pEnt, eId, openMode); return pEnt; }
你能够在如下三种权限中打开一个对象:
1.kForRead:只要对象尚未通知以写的权限被打开,就能够被多达256个读者打开一个对象。
2.kForWrite:若是对象还没有打开,则能够打开该对象。不然,打开失败。
3.kForNotify:当对象关闭、 以读的权限打开或以写的权限打开时,能够通知打开一个对象,但当该对象已经通知被打开时则不能打开。请参见Notification (第四章:第二节:通知),它不多须要通知打开一个对象并通知发送。
下表显示了一个对象已经打开后,在尝试以不一样权限打开对象时所返回的错误信息:
若是你试图以写的权限打开一个对象,而后获得一个错误eWasOpenForRead,只有一个读者时,可使用upgradeOpen()来升级打开状态,也可使用downgradeOpen()来下降其读取的状态。同理,若是你通知打开对象,例如,当您接收通知,您想要以写的权限打开时,您可使用upgradeFromNotify()来升级它的打开状态。或者使用downgradeToNotify()下降其状态。
有关如何管理打开和关闭对象的复杂顺序的更多信息,请参见Transaction Manager(第四章:第四节:事务管理器)
(2)删除对象
当你建立一个用于将 AcDbObject对象添加到数据库的实例时,使用AcDbObject::new()函数。当一个对象首先被建立而且尚未被添加到数据库时,你能够删除他,然而,一旦一个对象被加到数据库,你就不能删除他;AutoCAD管理删除全部数据库内的对象。
(3)数据库对象全部者
根对象:一个由数据库隐式拥有的对象(而不是另外一个数据库对象)。数据库包含10个根对象:九个符号表和命名的对象字典。全部的文件读取操做都是经过对数据库的根对象进行文件读取来开始的。看Object Filing(对象文件读取)
除了根对象外,数据库中的每一个对象都必须有一个全部者,而且只能有一个全部者。数据库建立的对象像一个有层次结构的树。下面的调用将对象添加到数据库,并为其分配一个ID,可是该对象尚未全部者:
db->addAcDbObject(...);
一般,您可使用一个成员函数AcDbBlockTableRecord::appendAcDbEntity()将对象添加到它的全部者,同时将其添加到数据库中,他同时执行俩个任务。
AutoCAD的全部权关系以下:
1.块表记录本身的实体
2.符号表记录每一个特定类型的符号
3.AcDbDictionary对象能够拥有任何AcDbObject对象
4.任何AcDbObject对象均可以有一个扩展字典;
另外,应用程序能够创建本身的全部权链接。
(4) 添加特定的数据到对象
你能够任意使用四种机制来在应用程序中添加实例特定的数据:
1.扩展数据
2.扩展记录(看Container Objects:第一章:第七节:容器对象)
3.任何对象的扩展字典
4.自定义对象也能够保存实体
本小节内容:
1.扩展数据
2.扩展字典
(4.1)扩展数据
扩展数据是由应用程序用ObjectARX®或AutoLISP®编写的,能够添加到任何对象。应用程序使用由resbufs链表组成的扩展数据。(不是使用AutoCAD维护信息)。扩展数据的DXF组代码在1000到1071的范围内相关联。
此机制具备空间效率,可用于将轻量级数据添加到对象中。因此,扩展数据必须小于16K,或者是现有的DXF组代码和类型集。
有关扩展数据的详细描述,请参阅AutoCAD DXF引用。
使用AcDbObject::xData()函数,获取包含对象的扩展数据的resbuf链:
virtual resbuf* AcDbObject::xData(const char* regappName = NULL) const;
使用AcDbObject::setXData()函数来设置对象的扩展数据:
virtual Acad::ErrorStatus AcDbObject::setXData(const resbuf* xdata);
下面的例子使用xData()函数获取所选对象的扩展数据,并将扩展数据打印到屏幕上。而后向xdata添加一个字符串(testrun),并调用setXdata()函数来修改对象的xdata。这个示例也说明了upgradeOpen()和downgradeOpen()函数的用法。
// selectObject()函数容许用户选择一个对象,而后为对象增长扩展数据,而且用printList()函数发送列表的类型和resval值 void printXdata() { //选择而且打开一个对象 AcDbObject *pObj = selectObject(AcDb::kForRead); if (pObj == NULL) return; //获取扩展数据名称。 char appname[133]; if (acedGetString(NULL, "\n请输入所需扩展数据的扩展数据名称: ",appname) != RTNORM) return; // 获取扩展数据名称的扩展数据。 struct resbuf *pRb = NULL; pRb = pObj->xData(appname); if (pRb != NULL) { //若是有扩展数据的话,打印扩展数据。 // Notice that there is no -3 group, as there is in // LISP. This is ONLY the xdata, so // the -3 xdata-start marker isn't needed. // printList(pRb); acutRelRb(pRb); } else { acutPrintf("\n这个扩展数据名称没有扩展数据"); } pObj->close(); } void addXdata() { AcDbObject* pObj = selectObject(AcDb::kForRead); if (!pObj) { acutPrintf("选择对象错误!\n"); return; } // 获取扩展数据名称,而且添加扩展数据 char appName[132], resString[200]; appName[0] = resString[0] = '\0'; acedGetString(NULL, "请输入扩展数据名称: ",appName); acedGetString(NULL, "请输入要添加的字符串: ",resString); struct resbuf *pRb, *pTemp; pRb = pObj->xData(appName); if (pRb != NULL) { // 若是存在扩展数据,则找到列表最后。 for (pTemp = pRb; pTemp->rbnext != NULL; pTemp = pTemp->rbnext) { ; } } else { // 若是没有扩展数据, 注册扩展数据名称而且在resbuf 链表的开头添加扩展数据名称 // Notice that there is no -3 group as there is in // AutoLISP. This is ONLY the xdata so // the -3 xdata-start marker isn't needed. acdbRegApp(appName); pRb = acutNewRb(AcDb::kDxfRegAppName); pTemp = pRb; pTemp->resval.rstring = (char*) malloc(strlen(appName) + 1); strcpy(pTemp->resval.rstring, appName); } // 添加用户指定字符串到扩展数据 pTemp->rbnext = acutNewRb(AcDb::kDxfXdAsciiString); pTemp = pTemp->rbnext; pTemp->resval.rstring = (char*) malloc(strlen(resString) + 1); strcpy(pTemp->resval.rstring, resString); //下面的代码显示了upgradeOpen()函数将实体由读改成写 pObj->upgradeOpen(); pObj->setXData(pRb); pObj->close(); acutRelRb(pRb); }
(4.2)扩展字典
每一个对象均可以有一个扩展字典,能够包含任意一组AcDbObject对象。使用这种机制, 多个应用程序能够将数据附加到同一个对象。 扩展字典比扩展数据须要更多的开销,但它也为添加数据提供了一种更灵活,更高效的机制。
例如,使用扩展字典将任意字符串附加到任何AcDbObject,查看ObjectARX示例\数据库\ dataxtsn目录中的edinvent 程序。
本小节内容:
1.ObjectARX扩展字典示例
2.全局函数扩展字典示例
(4.2.1)ObjectARX扩展字典示例
下面这个例子演示,实例化一个扩展记录,而且将它添加到命名对象字典中的扩展字典:
void createXrecord() { AcDbXrecord *pXrec = new AcDbXrecord; AcDbObject *pObj = NULL; AcDbObjectId dictObjId, xrecObjId; AcDbDictionary* pDict = NULL; pObj = selectObject(AcDb::kForWrite); if (pObj == NULL) return; // 建立一个对象的扩展字典时,若是扩展字典已经存在时,将是一个空操做 pObj->createExtensionDictionary(); // 经过扩展字典获得当前选择对象的对象id dictObjId = pObj->extensionDictionary(); pObj->close(); // 打开扩展字典,而且添加一个扩展记录 acdbOpenObject(pDict, dictObjId, AcDb::kForWrite); pDict->setAt("ASDK_XREC1", pXrec, xrecObjId); pDict->close(); //建立一个resbuf列表,而且把扩展记录加进去 struct resbuf* head = NULL; ads_point testpt = {1.0, 2.0, 0.0}; head = acutBuildList(AcDb::kDxfText,"测试字符串", AcDb::kDxfXCoord, testpt, AcDb::kDxfReal, 3.14159, AcDb::kDxfAngle, 3.14159, AcDb::kDxfColor, 1, AcDb::kDxfInt16, 180, 0); //添加数据到扩展记录.通知成员函数引用resbuf而不是指针,因此在发送以前先释放指针 pXrec->setFromRbChain(*head); pXrec->close(); acutRelRb(head); } //listXrecord()函数得到扩展记录与key值ASDK_XREC1的记录,而且经过resbuf向printList()列出了内容 void listXrecord() { AcDbObject *pObj = NULL; AcDbXrecord *pXrec = NULL; AcDbObjectId dictObjId; AcDbDictionary *pDict = NULL; pObj = selectObject(AcDb::kForRead); if (pObj == NULL) return; //经过对象字典得到对象id dictObjId = pObj->extensionDictionary(); pObj->close(); //打开对象字典,而且得到key值为 ASDK_XREC1的扩展记录 acdbOpenObject(pDict, dictObjId, AcDb::kForRead); pDict->getAt("ASDK_XREC1", (AcDbObject*&)pXrec, AcDb::kForRead); pDict->close(); //获得扩展记录的数据,而且关闭扩展记录 struct resbuf *pRbList = NULL; pXrec->rbChain(&pRbList); pXrec->close(); printList(pRbList); acutRelRb(pRbList); }
(4.2.2)全局函数扩展字典示例
下面这个例子,用ObjectARX全局函数建立扩展记录,而且将其添加到key值为ASDK_REC相关联的字典中。
int createXrecord() { struct resbuf *pXrec, *pEnt, *pDict, *pTemp, *pTemp2; ads_point dummy, testpt = {1.0, 2.0, 0.0}; ads_name xrecname, ename, extDict = {0L, 0L}; // 让用户选择一个实体。而后获得数据。 if (acedEntSel("\n选择实体: ", ename, dummy) != RTNORM) { acutPrintf("\n没有选中"); acedRetVoid(); return RTNORM; } pEnt = acdbEntGet(ename); // 检查实体是否有扩展字典 for (pTemp = pEnt; pTemp->rbnext != NULL; pTemp = pTemp->rbnext) { if (pTemp->restype == 102) { if (!strcmp("{ACAD_XDICTIONARY",pTemp->resval.rstring)) { ads_name_set(pTemp->rbnext->resval.rlname, extDict); break; } } } // 若是没有扩展字典,添加一个 if (extDict[0] == 0L) { pDict = acutBuildList(RTDXF0, "DICTIONARY", 100,"AcDbDictionary", 0); acdbEntMakeX(pDict, extDict); acutRelRb(pDict); pDict = acutBuildList(102, "{ACAD_XDICTIONARY", 360,extDict, 102, "}", 0); for (pTemp = pEnt; pTemp->rbnext->restype != 100; pTemp = pTemp->rbnext) { ; } for (pTemp2 = pDict; pTemp2->rbnext != NULL;pTemp2 = pTemp2->rbnext) { ; } pTemp2->rbnext = pTemp->rbnext; pTemp->rbnext = pDict; acdbEntMod(pEnt); acutRelRb(pEnt); } // 有扩展字典后,建立resbuf 的扩展记录的实体信息和数据 pXrec = acutBuildList(RTDXF0, "XRECORD", 100, "AcDbXrecord", 1, "测试字符串", //AcDb::kDxfText 10, testpt, //AcDb::kDxfXCoord 40, 3.14159, //AcDb::kDxfReal 50, 3.14159, //AcDb::kDxfAngle 60, 1, //AcDb::kDxfColor 70, 180, //AcDb::kDxfInt16 0); //建立没有全部者的扩展记录.扩展记录的新名称将被放入xrecname acdbEntMakeX (pXrec, xrecname); acutRelRb (pXrec); //设置扩展记录的全部者为扩展字典 acdbDictAdd(extDict, "ASDK_XRECADS", xrecname); acedRetVoid(); return RTNORM; } //访问用户选择实体的扩展字典里,key值为ASDK_XRECADS的扩展记录,用printList()函数列出扩展数据的内容 int listXrecord() { struct resbuf *pXrec, *pEnt, *pTemp; ads_point dummy; ads_name ename, extDict = {0L, 0L}; //用户选中实体,而后获得他的数据 if (acedEntSel("\n选择实体: ", ename, dummy) != RTNORM) { acutPrintf("\n没有选中"); acedRetVoid(); return RTNORM; } pEnt = acdbEntGet(ename); //获得扩展字典中实体的名称 for (pTemp = pEnt;pTemp->rbnext != NULL;pTemp = pTemp->rbnext) { if (pTemp->restype == 102) { if (!strcmp("{ACAD_XDICTIONARY", pTemp->resval.rstring)) { ads_name_set(pTemp->rbnext->resval.rlname, extDict); break; } } } if (extDict[0] == 0L) { acutPrintf("\n如今没有扩展字典."); return RTNORM; } pXrec = acdbDictSearch(extDict, "ASDK_XRECADS", 0); if(pXrec) { printList(pXrec); acutRelRb(pXrec); } acedRetVoid(); return RTNORM; }
(5)移除对象
数据库中的任何对象均可以用如下函数删除:
Acad::ErrorStatus AcDbObject::erase(Adesk::Boolean Erasing = true);
注:erase()函数对数据库对象和实体有不一样的结果,不清除他们的影响:
1.当数据库对象被清除时,与该对象相关的信息也被从字典中移除 ,若是该对象未被erase(kfalse)清除,他的信息不会从新引入,你必须使用setAt()函数从新将信息添加到字典中。
2.当一个实体被清除时,在块表记录中的标识被简单的移除。该实体能够被erase(kfalse)删除。
默认状况下,你不能用acdbOpenObject()函数打开一个已经被删除的对象,若是你试图这样作的话,他将返回一个eWasErased的错误。
extern Acad::ErrorStatus acdbOpenObject( AcDbObject*& obj,AcDbObjectId objId,AcDb::OpenMode openMode,Adesk::Boolean openErasedObject = Adesk::kFalse);
acdbOpenObject()函数的最后一个参数使用kTrue,打开一个已经被删除的对象。
好比多段线polylines和块表记录block table之类的容器对象一般在迭代它们的内容时提供跳过删除元素的选项。这就是跳过删除 默认行为原理。
删除的对象没有保存到DWG或DXF文件。
(6)对象文件读取
对象文件保存是指对象状态到单个数据序列之间的转换过程,用于将其存储在磁盘、复制或记录其状态以进行撤消操做。文件读取有时候也被叫作序列化。一个对象的文件保存是将一个序列数据返回到一个对象的过程,有时候也被称为反序列化。
在AutoCAD中,文件保存的的使用有几种状况:
1.编写和读取DWG文件(使用DWG格式)
2.编写和读取DXF文件(使用DXF格式)
3.在AutoCAD、AutoLISP和ObjectARX之间进行通讯(使用DXF格式)
4.还原和撤销(使用DWG格式)
5.复制操做,如INSERT、XREF和COPY(使用DWG格式)
6.分页(使用DWG格式)
AcDbObject有俩个函数用于文件读取:dwgOut()和dxfOut(),而且还有俩个函数用于文件保存dwgIn() 和dxfIn().这些成员函数主要由AutoCAD调用;使用数据库的应用程序几乎历来没有明确地控制对象归档。然而,若是你的应用程序执行了新的数据库对象类,您须要更深刻地了解对象归档。看Deriving from AcDbObject(第三章:第四节:AcDbObject的来源)
dwg -和dxf -前缀表示两种彻底不一样的数据格式,第一个一般用于写入DWG文件,第二个主要用于DXF文件和AutoLISP entget、entmake和entmod函数。这两种格式的主要区别是DWG 文件(将数据写入文件的对象),没有明确地标记数据。与此不一样,DXF文件是将数据组代码与每一个数据元素相关联的数据格式。看Deriving from AcDbObject(第三章:第四节:AcDbObject的来源)
(7) 嵌入和封装对象
有两种方法能够将对象嵌入到另外一个对象中:封装对象有一个数据成员,它实际是一个嵌入对象,或者封装对象有指向对象的指针(在这种状况下,对象被认为是嵌入的)。不论发生何种状况,封装对象负责分配和释放嵌入的对象。封装对象还必须将全部调用的方法转发给嵌入对象,由于AutoCAD不知道嵌入对象。为了显示嵌入对象,封装对象的subWorldDraw()必须调用嵌入对象的worldDraw()。
对于subGetGripPoints()和subGetStretchPoints(),你必须调用嵌入对象的getGripPoints()和getStretchPoints()方法,以使点的索引值高于封装实体的索引。此外,用subMoveGripPointsAt()和subMoveStretchPointsAt()时,若是所传递的指数超过封装实体的范围,你须要减去封装实体的最高索引值,并将结果传递到嵌入对象的moveGripPointsAt()或moveStretchPointsAt()中。例如,如下代码来自于更新jblob示例中的,具备嵌入式的AcDbCircle实体:
Acad::ErrorStatus Jblob::subGetGripPoints( AcGePoint3dArray& gripPoints, AcDbIntArray& osnapMasks, AcDbIntArray& geomIds) const { assertReadEnabled(); gripPoints.append(mp); gripPoints.append(mp + 0.5 * (mpblob - mp)); gripPoints.append(mpblob); AcGeVector3d xoff(mrblob, 0, 0); AcGeVector3d yoff(0, mrblob, 0); gripPoints.append(mpblob + xoff); gripPoints.append(mpblob + yoff); gripPoints.append(mpblob - xoff); gripPoints.append(mpblob - yoff); return circle.getGripPoints(gripPoints, osnapMasks, geomIds); } Acad::ErrorStatus Jblob::subMoveGripPointsAt( const AcDbIntArray& indices, const AcGeVector3d& offset) { AcGePoint3d oldquad, newquad; assertWriteEnabled(); AcDbIntArray circleIndices; for (int i = 0; i < indices.length(); i++) { int idx = indices[i]; switch(idx) { case 0: mp += offset; continue; // stretch begin point case 1: mp += offset; mpblob += offset; continue; // move case 2: mpblob += offset; continue; // stretch blob center // stretch blob radius: // case 3: oldquad = mpblob + AcGeVector3d(mrblob, 0, 0); break; case 4: oldquad = mpblob + AcGeVector3d(0, mrblob, 0); break; case 5: oldquad = mpblob - AcGeVector3d(mrblob, 0, 0); break; case 6: oldquad = mpblob - AcGeVector3d(0, mrblob, 0); break; default: if (idx > 6) circleIndices.append(idx - 7); continue; } newquad = oldquad + offset; mrblob = newquad.distanceTo(mpblob); } if (circleIndices.length() > 0) return circle.moveGripPointsAt(circleIndices, offset); else return Acad::eOk; }
对于目标文件保存,封装对象必须调用嵌入对象本身的这些方法dwgOutFields()、dwgInFields()、dxfOutFields()和dxfInFields()。
对于DWG文件,对嵌入对象的dwgOutFields()和dwgInFields()方法的调用能够在封装对象的对应方法的任何一点上发生(在调用基类的方法以后)。如下代码来自更新的jblob示例程序:
Acad::ErrorStatus Jblob::dwgInFields(AcDbDwgFiler* filer) { assertWriteEnabled(); AcDbEntity::dwgInFields(filer); filer->readItem(&mp); filer->readItem(&mpblob); filer->readItem(&mrblob); filer->readItem(&mnormal); return circle.dwgInFields(filer); } Acad::ErrorStatus Jblob::dwgOutFields(AcDbDwgFiler* filer) const { assertReadEnabled(); AcDbEntity::dwgOutFields(filer); filer->writeItem(mp); filer->writeItem(mpblob); filer->writeItem(mrblob); filer->writeItem(mnormal); return circle.dwgOutFields(filer); }
对于DXF文件,嵌入的对象必须在封装对象的全部数据已经被文件保存和文件保存以后进行文件保存;所以,对嵌入对象的dxfOutFields()和dxfInFields()方法的调用应该在封装对象的dxfOutFields()和dxfInFields()方法中最后完成。在封装对象的数据和随后的嵌入对象的数据之间须要一个分隔符。分隔符必须与组的 0或100相似,因此它必须使过滤器中止读取数据。不能使用普通的DXF组代码0,由于DXF代理使用它来肯定什么时候中止读取数据。组代码100能够被使用,可是当手动读取DXF文件时可能会引发混乱,而且须要区分何时嵌入的对象要被写出来以便作一些内部的记录。所以,引入了DXF组代码101。
DXF AcDb::DxfCode枚举值组代码101是AcDb::kDxfEmbeddedObjectStart。数据字符串嵌入对象是由过滤器为这个DXF组代码编写的。
在AcDbDxfFiler类中还添加了两个方法:
1.writeEmbeddedObjectStart()
2.atEmbeddedObjectStart()
下面的代码演示了如何在更新的jblob示例程序中使用这些方法:
Acad::ErrorStatus Jblob::dxfInFields(AcDbDxfFiler* filer) { assertWriteEnabled(); struct resbuf rb; Acad::ErrorStatus es = AcDbEntity::dxfInFields(filer); if (es != Acad::eOk) { return es; } if (!filer->atSubclassData(kClassName)) { return Acad::eBadDxfSequence; } mnormal = AcGeVector3d(0, 0, 1); // set default value: while (es == Acad::eOk) { if ((es = filer->readItem(&rb)) == Acad::eOk) { switch(rb.restype) { case AcDb::kDxfXCoord: mp.set(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); break; case AcDb::kDxfXCoord+1: mpblob.set(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); break; case AcDb::kDxfReal: mrblob = rb.resval.rreal; break; case AcDb::kDxfNormalX: mnormal.set(rb.resval.rpoint[X], rb.resval.rpoint[Y], rb.resval.rpoint[Z]); } } } if (filer->atEmbeddedObjectStart()) return circle.dxfInFields(filer); else { filer->setError(Acad::eMissingDxfField, "missing expected embeddedObject marker"); return filer->filerStatus(); } } Acad::ErrorStatus Jblob::dxfOutFields(AcDbDxfFiler* filer) const { assertReadEnabled(); AcDbEntity::dxfOutFields(filer); filer->writeItem(AcDb::kDxfSubclass, kClassName); filer->writeItem(AcDb::kDxfXCoord, mp); filer->writeItem(AcDb::kDxfXCoord + 1, mpblob); filer->writeItem(AcDb::kDxfReal, mrblob); if (filer->includesDefaultValues() || mnormal != AcGeVector3d(0,0,1)) { filer->writeItem(AcDb::kDxfNormalX, mnormal); } filer->writeEmbeddedObjectStart(); return circle.dxfOutFields(filer); }
下面的示例显示了DXF文件中的输出(与310组数据字符串缩短了可读性):
0 JBLOB 5 52 330 19 100 AcDbEntity 8 0 92 256 310 00010000040000003C0000000600000002000000... 310 000000000000000000000000000000F03F700000... 310 0000 100 Jblob 10 4.026791 20 3.172968 30 0.0 11 5.916743 21 5.299622 31 0.0 40 1.458724 101 Embedded Object 100 AcDbEntity 100 AcDbCircle 10 5.916743 20 5.299622 30 0.0 40 0.729362
https://wenku.baidu.com/view/ea48c94769eae009581bec40.html