實體AcDbBlockReference :塊參照,塊引用數據庫
塊表AcDbBlockTable 數組
表記錄AcDbBlockTableRecord:塊定義,塊表記錄,app
(1)建立塊定義:全部的實體都保存在塊表記錄中,而塊表記錄則存儲在塊表中。定義塊至關於增長了一個塊表記錄,塊表記錄的名稱就是塊定義的名稱。函數
當前圖形的塊表中包含了五個記錄:*Model_Space(模型空間)、*Paper_Space(圖紙空間中的「佈局1」)、*Paper_Space0(圖紙空間中的「佈局2」)、 「圓形」和「矩形」 。佈局
void ZffCHAP3AddBlk() { // 得到當前圖形數據庫的塊表 AcDbBlockTable *pBlkTbl = NULL; acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite); // 建立新的塊表記錄 AcDbBlockTableRecord *pBlkTblRcd = new AcDbBlockTableRecord(); // 根據用戶的輸入設置塊表記錄的名稱 char blkName[40]; if (acedGetString(Adesk::kFalse, "\n輸入圖塊的名稱:", blkName) != RTNORM) { pBlkTbl->close(); delete pBlkTblRcd; return; } pBlkTblRcd->setName(blkName); // 將塊表記錄添加到塊表中 AcDbObjectId blkDefId; pBlkTbl->add(blkDefId, pBlkTblRcd); pBlkTbl->close(); // 向塊表記錄中添加實體 AcGePoint3d ptStart(-10, 0, 0), ptEnd(10, 0, 0); AcDbLine *pLine1 = new AcDbLine(ptStart, ptEnd); // 建立一條直線 ptStart.set(0, -10, 0); ptEnd.set(0, 10, 0); AcDbLine *pLine2 = new AcDbLine(ptStart, ptEnd); // 建立一條直線 AcGeVector3d vecNormal(0, 0, 1); AcDbCircle *pCircle = new AcDbCircle(AcGePoint3d::kOrigin,vecNormal, 6); AcDbObjectId entId; pBlkTblRcd->appendAcDbEntity(entId, pLine1); pBlkTblRcd->appendAcDbEntity(entId, pLine2); pBlkTblRcd->appendAcDbEntity(entId, pCircle); // 關閉實體和塊表記錄 pLine1->close(); pLine2->close(); pCircle->close(); pBlkTblRcd->close(); }
(2)插入塊參照:塊定義不是一個實體,而是一種對實體的描述,經過定義塊得到;塊參照則是一種實體,圖形窗口中顯示的「塊」都是塊參照,經過插入塊得到。this
void ZffCHAP3InsertBlk() { acDocManager->lockDocument(curDoc()); // 得到用戶輸入的塊定義名稱 char blkName[40]; if (acedGetString(Adesk::kFalse, "\n輸入圖塊的名稱:", blkName) !=RTNORM) return; // 得到當前數據庫的塊表 AcDbBlockTable *pBlkTbl = NULL; acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForWrite); // 查找用戶指定的塊定義是否存在 CString strBlkDef; strBlkDef.Format("%s", blkName); if (!pBlkTbl->has(strBlkDef)) { acutPrintf("\n當前圖形中未包含指定名稱的塊定義!"); pBlkTbl->close(); return; } // 得到用戶輸入的塊參照的插入點 ads_point pt; if (acedGetPoint(NULL, "\n輸入塊參照的插入點:", pt) != RTNORM) { pBlkTbl->close(); return; } AcGePoint3d ptInsert = asPnt3d(pt); // 得到用戶指定的塊表記錄 AcDbObjectId blkDefId; pBlkTbl->getAt(strBlkDef, blkDefId); // 建立塊參照對象 AcDbBlockReference *pBlkRef = new AcDbBlockReference(ptInsert,blkDefId); //pBlkRef->setPosition(basePoint); //設置插入點 //pBlkRef->setRotation(0.0); //設置旋轉角度 //pBlkRef->setNormal(normal);//設置法向量 // 將塊參照添加到模型空間 AcDbBlockTableRecord *pBlkTblRcd = NULL; pBlkTbl->getAt(ACDB_MODEL_SPACE, pBlkTblRcd,AcDb::kForWrite); AcDbObjectId entId; pBlkTblRcd->appendAcDbEntity(entId, pBlkRef); // 關閉數據庫的對象 pBlkRef->close(); pBlkTblRcd->close(); pBlkTbl->close(); acDocManager->lockDocument(curDoc()); }
(3)建立帶屬性的塊定義:AcDbAttributeDefinition 類: AcDbText 類的一個派生類,表示屬性定義對象,,屬性定義是 AutoCAD的一種圖形對象(對應於 AutoCAD 中的「屬性」 ) ,能夠直接建立該類的一個對象,而後將其添加到塊表記錄中。3d
// 建立一個屬性 輸入直徑 AcDbAttributeDefinition *pAttDef = new AcDbAttributeDefinition(ptEnd, "20", "直徑", "輸入直徑"); // 向塊表記錄中添加實體 pBlkTblRcd->appendAcDbEntity(entId, pAttDef);
(4)插入帶屬性的塊參照:包含塊參照和屬性兩個部分,屬性不能直接存在於圖形窗口中,而必須依附於塊參照存在。指針
插入一個普通的塊參照後,使用遍歷器遍歷塊參照對應的塊表記錄,若是找到一個屬性定義,就建立一個屬
性,而且附加到塊參照上。code
// 判斷指定的塊表記錄是否包含屬性定義 AcDbBlockTableRecord *pBlkDefRcd = NULL; acdbOpenObject(pBlkDefRcd, blkDefId, AcDb::kForRead); if (pBlkDefRcd->hasAttributeDefinitions()) { AcDbBlockTableRecordIterator *pItr = NULL; pBlkDefRcd->newIterator(pItr); AcDbEntity *pEnt = NULL; for (pItr->start(); !pItr->done(); pItr->step()) { pItr->getEntity(pEnt, AcDb::kForRead); // 檢查是不是屬性定義 AcDbAttributeDefinition *pAttDef = NULL; pAttDef = AcDbAttributeDefinition::cast(pEnt); if (pAttDef != NULL) { // 建立一個新的屬性對象 AcDbAttribute *pAtt = new AcDbAttribute(); // 從屬性定義得到屬性對象的圖層特性 pAtt->setPropertiesFrom(pAttDef); // 設置屬性對象的其餘特性 pAtt->setInvisible(pAttDef->isInvisible()); AcGePoint3d ptBase = pAttDef->position(); ptBase += pBlkRef->position().asVector(); pAtt->setPosition(ptBase); pAtt->setHeight(pAttDef->height()); pAtt->setRotation(pAttDef->rotation()); // 得到屬性對象的Tag、Prompt和TextString char *pStr = NULL; pStr = pAttDef->tag(); pAtt->setTag(pStr); free(pStr);//也可用全局函數 acutDelString 來代替 pStr = pAttDef->prompt(); acutPrintf("%s%s", "\n", pStr); free(pStr); pAtt->setFieldLength(30); pAtt->setTextString("40"); // 向塊參照追加屬性對象 pBlkRef->appendAttribute(pAtt); pAtt->close(); } pEnt->close(); } delete pItr; }
(5)查看塊定義的圖標orm
得到指定的塊表記錄的預覽圖像
HBITMAP CPreviewBlkDlg::BlockIconToBMP(const AcDbObjectId &blkId, HDC hdc) { Acad::ErrorStatus es; AcDbBlockTableRecord *pBlkTblRcd = NULL; // 塊表記錄的指針 AcArray<Adesk::UInt8> icon; // 保存預覽圖標的數組 // 得到保存塊表記錄的預覽圖標的數組 try { es = acdbOpenObject(pBlkTblRcd, blkId, AcDb::kForRead); if (es != Acad::eOk) throw 1; if (!pBlkTblRcd->hasPreviewIcon()) // 若是塊定義不包含預覽圖標 { pBlkTblRcd->close(); return NULL; } es = pBlkTblRcd->getPreviewIcon(icon); if (es != Acad::eOk) throw 2; es = pBlkTblRcd->close(); if (es != Acad::eOk) throw 3; } catch (...) { pBlkTblRcd->close(); return NULL; } // 由icon數組得到可顯示的位圖 BITMAPINFOHEADER ih; // 位圖信息頭 memcpy(&ih, icon.asArrayPtr(), sizeof(ih)); size_t memsize = sizeof(BITMAPINFOHEADER) + ((1<<ih.biBitCount)* sizeof(RGBQUAD)); LPBITMAPINFO bi = (LPBITMAPINFO)malloc(memsize); // 位圖信息 memcpy(bi, icon.asArrayPtr(), memsize); HBITMAP hbm = CreateDIBitmap(hdc, &ih, CBM_INIT,icon.asArrayPtr() + memsize, bi,DIB_RGB_COLORS); free(bi); return hbm; }
得到當前圖形中用戶定義的全部塊表記錄
// 得到當前圖形的塊表 AcDbBlockTable *pBlkTbl = NULL; AcDbBlockTableRecord *pBlkTblRcd = NULL; acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead); // 遍歷塊表,得到用戶自定義塊表記錄的名稱,將其添加到組合框中 AcDbBlockTableIterator *pItr = NULL; pBlkTbl->newIterator(pItr); for (pItr->start(); !pItr->done(); pItr->step()) { pItr->getRecord(pBlkTblRcd, AcDb::kForRead); char *pName = NULL; pBlkTblRcd->getName(pName); CString strName(pName); acutDelString(pName); if (strName.Compare(ACDB_MODEL_SPACE) != 0 && strName.Compare(ACDB_PAPER_SPACE) != 0 && strName.Compare("*Paper_Space0")) { m_lstBlkDef.AddString(strName); } pBlkTblRcd->close(); } delete pItr; pBlkTbl->close();
根據選擇的塊定義,查找對應的預覽圖標、對應塊參照的數量,以及塊定義是否包含屬性
// 顯示預覽圖標 CPaintDC dc(this); AcDbBlockTable *pBlkTbl = NULL; acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl, AcDb::kForRead); CString strBlkDefName;//定義塊的名稱 m_lstBlkDef.GetLBText(m_lstBlkDef.GetCurSel(), strBlkDefName); AcDbObjectId blkTblRcdId; Acad::ErrorStatus es = pBlkTbl->getAt(strBlkDefName, blkTblRcdId); HBITMAP hBitmap = BlockIconToBMP(blkTblRcdId, dc.GetSafeHdc()); m_bitmap.SetBitmap(hBitmap); // 得到塊表記錄的指針 AcDbBlockTableRecord *pBlkTblRcd = NULL; pBlkTbl->getAt(strBlkDefName, pBlkTblRcd, AcDb::kForRead); // 得到塊參照的數量 AcDbBlockReferenceIdIterator *pItr = NULL; pBlkTblRcd->newBlockReferenceIdIterator(pItr); int number = 0; for (pItr->start(); !pItr->done(); pItr->step()) { number++; } m_strBlkRefNum.Format("%d", number); // 得到塊參照是否包含屬性 if (pBlkTblRcd->hasAttributeDefinitions()) { m_strHasAttribute = "是"; } else { m_strHasAttribute = "否"; } pBlkTblRcd->close(); pBlkTbl->close(); UpdateData(FALSE);