英語比較爛,藉着翻譯幫助文檔,一邊學習英語,一邊增強專業知識,有翻譯的不妥的地方,歡迎評論區指正,謝謝各位看官賞臉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