以下是做CAD二次開發(fā)一年多來(lái)的一些讀書筆記﹕
節(jié)選于《AutoCAD高級(jí)開發(fā)技術(shù):ARX編程及應(yīng)用》
跟大家分享
一.圖塊設(shè)計(jì)技術(shù):
在AutoCAD數(shù)據(jù)庫(kù)中,以各圖塊實(shí)際上市存儲(chǔ)在塊表記錄里的實(shí)體集合。每個(gè)圖塊從一格AcDbBlockBegin對(duì)象開始,緊接著是一個(gè)或多個(gè)AcDbEntity對(duì)象,最后以AcDbBolckEnd對(duì)象結(jié)束,按其所屬關(guān)系得層次結(jié)構(gòu)分為三層:第一層為塊表,是屬于數(shù)據(jù)庫(kù)管理的根對(duì)象;第二層為塊表記錄,是屬于塊表管理的對(duì)象;第三層為組成圖塊的實(shí)體對(duì)象,是屬于塊表記錄管理的基本對(duì)象。因而,在AutoCAD數(shù)據(jù)庫(kù)中,定義圖塊的第一個(gè)過程式向塊表中加入一條新的塊表記錄,然后將組成圖塊的實(shí)體對(duì)象寫入該塊表記錄中。
1.AutoCAD數(shù)據(jù)庫(kù)中圖塊的引用
在AutoCAD系統(tǒng)中插入已定義的塊并不是將塊中所有實(shí)體復(fù)制到數(shù)據(jù)庫(kù)中,而是通過塊引用機(jī)制向塊表記錄增加一個(gè)AcDbBlockReference類引用對(duì)象。所謂的塊引用實(shí)際上是用戶用Insert命令或ARX引用程序向AutoCAD數(shù)據(jù)庫(kù)中插入的圖塊。在ARX應(yīng)用程序中,利用定義的AcDbBlockReference類實(shí)例及相應(yīng)的成員函數(shù)可以設(shè)置插入塊的有關(guān)特性,如插入點(diǎn)、旋轉(zhuǎn)角以及XYZ方向的比例系數(shù)等。插入不帶屬性的簡(jiǎn)單圖塊的編程技術(shù)相對(duì)比較簡(jiǎn)單,做法如下:
A.創(chuàng)建一個(gè)指向AcDbBlockReference類對(duì)象實(shí)例的指針。
B.調(diào)用該類的成員函數(shù)setBlockTableRecord()設(shè)置引用圖塊的ID號(hào)。
C.調(diào)用該類的成員函數(shù)setPosition(),setRotation()和setScaleFactors()分別設(shè)置塊引用的插入點(diǎn)、旋轉(zhuǎn)角和XYZ方向的比例系數(shù)等。
D.打開當(dāng)前圖形模型空間的塊表,利用getBlockTable()函數(shù)獲得指向當(dāng)前圖形的塊表指針。
E.調(diào)用appendAcDbEntity()函數(shù)將塊引用加入當(dāng)前數(shù)據(jù)庫(kù)模型空間塊表記錄中。
2. 屬性塊的引用:
在塊定義中的附加屬性信息必須通過調(diào)用AcDbBlockReference類的成員函數(shù)appendAttribute()才能加入到塊引用中。
定義屬性塊時(shí),屬性實(shí)質(zhì)上是附加于構(gòu)成圖塊的某一實(shí)體上的一個(gè)或多個(gè)非圖形信息。因此,在插入屬性時(shí)必須檢索出屬性塊定義時(shí)的所有附加信息,然后將其附加于塊引用的相應(yīng)實(shí)體上,這就需要遍歷塊中的全部實(shí)體。
通過屬性塊的ID號(hào)打開其塊表記錄,從而獲得指向塊表記錄的指針。程序代碼為:
AcDbBlockTableRecord *pBlockDef; //定義指向塊表記錄的指針
acdbOpenObject(pBlockDef,blockid,AcDb::kForRead); //獲得指向塊表記錄的指針
參數(shù)blockid為屬性的ID號(hào),然后,定義一個(gè)用于遍歷塊表記錄的瀏覽器,獲得指向塊表記錄的瀏覽器指針,如:
AcDbBlockTableIterator *pIterator; //定義指向塊表記錄瀏覽器的指針
pBlockDef->newIterator(pIterator); //獲得指向塊表記錄的瀏覽器指針
成員函數(shù)newIterator()用于創(chuàng)建塊表記錄的瀏覽器對(duì)象,參數(shù)pIterator為指向塊表記錄的瀏覽器指針。在此基礎(chǔ)上建立一個(gè)循環(huán)結(jié)構(gòu),用于遍歷圖塊中的全部實(shí)體,得到指向某一實(shí)體的指針,其結(jié)構(gòu)如下:
AcDbEntity *pEnt; //定義指向?qū)嶓w的指針
AcDbAttributeDefinition *pAttdef; //定義指向?qū)傩远x的指針
For (pIterator->state(); !pterator->done(); pIterator->step())
{
pIterator->getEntity(pEnt,AcDb::kForRead); //得到指向?qū)嶓w的指針
pAttdef = AcDbAttributeDefinition::cast(pEnt); //得到指向?qū)傩远x的指針
//處理屬性插入的代碼
……
pEnt->close(); //關(guān)閉尸體對(duì)象
}
實(shí)體屬性的插入代碼的執(zhí)行機(jī)理如下:
1). 創(chuàng)建AcDbAttribute類對(duì)象,獲得指向該對(duì)象的指針。
如: AcDbAttribute *pAtt = new AcDbAttribute;
2). 設(shè)置新建的AcDbAttribute類對(duì)象的屬性值及特性,如屬性位置,字高,旋轉(zhuǎn)角度,屬性文本等.
3) . 調(diào)用appendAttribute()函數(shù)將屬性附加于pBlkRef指向的塊引用中。
如: pBlkRef->appendAttribute(attid,pAtt);
其中,pBlkRef為指向塊引用的指針,pAtt為前面創(chuàng)建的AcDbAttribute類對(duì)象的指針。
3. AutoCAD數(shù)據(jù)庫(kù)中圖塊的檢索
對(duì)于AutoCAD數(shù)據(jù)庫(kù)來(lái)說(shuō),圖塊的檢索主要包括用戶定義的有名塊和圖形中已插入的塊引用兩個(gè)方面。
1). 先介紹當(dāng)前圖形數(shù)據(jù)庫(kù)中塊的檢索技術(shù):
用ads_tblnext()函數(shù)可以得到當(dāng)前圖形的數(shù)據(jù)庫(kù)中表示塊定義得鏈表,將改鏈表存儲(chǔ)于結(jié)果緩沖區(qū)類型的變量中,利用結(jié)果緩沖區(qū)中的聯(lián)合體成員就可以獲得塊名、基點(diǎn)等信息。重復(fù)調(diào)用ads_tblnext()函數(shù)將遍歷整個(gè)數(shù)據(jù)庫(kù)鏈表中的所有塊表記錄,從而得到全部已定義的圖塊信息。
2) . 用戶定義數(shù)據(jù)庫(kù)中塊的檢索:
對(duì)于在ARX應(yīng)用中定義的其他數(shù)據(jù)庫(kù),只能用ARX庫(kù)的函數(shù)才能檢索出該數(shù)據(jù)庫(kù)中所定義的圖塊,程序的主要設(shè)計(jì)技術(shù)如下:
A. 利用AcDbBlockTable類的成員函數(shù)newIterator()創(chuàng)建塊表瀏覽器.
如: pBTable->newiterator(pBIterator);
pBTable為AcDbBlockTable類指針;pBIterator為AcDbBlockTableIterator類塊表瀏覽器指針.
B. 利用循環(huán)結(jié)構(gòu)和塊表瀏覽器遍歷塊表。
C.利用AcDbBlockTableIterator類成員函數(shù)getRecord()獲得塊表記錄。
如:pIterator->getRecord(pBTRecord,AcDb::kForRead);
D. 利用塊表記錄類的成員函數(shù)getName()得到塊名。
4. 塊中實(shí)體的檢索:
在檢索任意數(shù)據(jù)庫(kù)中的圖塊時(shí),主要是利用塊表瀏覽器遍歷塊表,從而獲得圖塊名。而在獲得塊名的前提下,利用ARX庫(kù)提供的塊表記錄瀏覽器遍歷塊表記錄中的所有實(shí)體,從而實(shí)現(xiàn)對(duì)塊中實(shí)體的檢索。方法為:
A.用一種合適的方式獲得圖塊名,得到指向該圖快的塊表記錄。
B.生成塊表記錄瀏覽器。
C.遍歷塊中的多有實(shí)體,得到檢索結(jié)果。
現(xiàn)在知道圖框的名字是A3,要求遍歷圖框中屬性:pBlkRef為AcDbBlockReference實(shí)體。
AcDbObjectIterator *pBlkRefAttItr=pBlkRef->attributeIterator();
for (pBlkRefAttItr->start(); !pBlkRefAttItr->done();pBlkRefAttItr->step())
{
AcDbObjectId attObjId;
attObjId = pBlkRefAttItr->objectId();
AcDbAttribute *pAtt = NULL;
Acad::ErrorStatus es = acdbOpenObject(pAtt, attObjId, AcDb::kForRead);
if (es != Acad::eOk)
{
acutPrintf("\nFailed to open attribute");
delete pBlkRefAttItr;
continue;
}
if (strcmp(pAtt->tag(),"TITLE:") == 0)
{
CString title = pAtt->textString();
if (strcmp(title,"PROGRESS(D)") == 0)
{ //操作
}
else if (strcmp(title,"PROGRESS(P)") == 0)
{
//操作
}
}
pAtt->close();
}
二.容器對(duì)象:符號(hào)表的操作和使用技術(shù)
符號(hào)表的操作主要分為向符號(hào)表中加入一條符號(hào)表記錄,符號(hào)表記錄的檢索和符號(hào)表記錄中對(duì)象的處理等,每一種操作都是通過相應(yīng)的符號(hào)表類提供的成員函數(shù)來(lái)實(shí)現(xiàn)的。
1.層表的操作和使用技術(shù):
A. 創(chuàng)建新層:
1). 以寫的方式調(diào)用getSymbolTable()函數(shù)打開當(dāng)前數(shù)據(jù)庫(kù)的層表,獲得指向該表的指針。
2) 調(diào)用構(gòu)造函數(shù)AcDbLayerTableRecord()創(chuàng)建層表建立對(duì)象。
3) 設(shè)置層名。
4) 設(shè)置層的有關(guān)屬性。
5) 調(diào)用add()函數(shù)將層表記錄加入到層表中。
6) 關(guān)閉層表和層表記錄。
2. 層的屬性設(shè)置和查詢函數(shù)
層的屬性包括:顏色、凍結(jié)狀態(tài)、鎖定狀態(tài)、開關(guān)狀態(tài)、在新視口中層的凍結(jié)狀態(tài)和線型,下面列出的設(shè)置和查詢函數(shù)均是AcDbLayerTableRecord類的成員函數(shù)。
A.設(shè)置顏色:setColor(const AcCmColor color);
B.設(shè)置凍結(jié)狀態(tài):setIsFrozen(bool frozen);
如果參數(shù)frozen為true表層凍結(jié);frozen為false表層凍結(jié)。
C.設(shè)置鎖定狀態(tài):setIsLocked(bool locked);
如果參數(shù)locked為true表層鎖定;locked為false表層解鎖。
D.設(shè)置開關(guān)狀態(tài):setIsOff(bool off);
如果參數(shù)off為true表層關(guān)閉;off為false表層打開。
E.設(shè)置在新視口中層的凍結(jié)狀態(tài):setVPDFLT(bool frozen);
如果參數(shù)frozen為true表在新視口中層將凍結(jié);frozen為false表在新視口中層解凍。
F.設(shè)置線型:setLinetypeObjectId(AcDbObjectId id);
在調(diào)用構(gòu)造函數(shù)AcDbLayerTableRecord()創(chuàng)建層表記錄時(shí),上述參數(shù)的缺省值為:
Color為7(white),isFrozen為false,isLocked為false,isoff為false,VPDFLT為false,線型的ID號(hào)為NULL。
3. 層屬性的修改和查詢實(shí)例的基本方法:
A.以讀方式打開層表,獲得指向?qū)颖淼闹羔槨?BR>B.調(diào)用層表類的成員函數(shù)getAt(),以寫的方式獲得指定層名的層表記錄指針。
C.調(diào)用屬性設(shè)置函數(shù)修改屬性或調(diào)用屬性查詢函數(shù)獲得屬性;
4. 數(shù)據(jù)庫(kù)中層的檢索的基本方法:
A.利用AcDbLayerTable類的成員函數(shù)newIterator()創(chuàng)建層表瀏覽器。
B.利用循環(huán)結(jié)構(gòu)和塊表瀏覽器遍歷塊表。
C.利用AcDbLayerTableIterator類的成員函數(shù)getRecord()獲得塊表記錄。
D.利用成員函數(shù)getName()得到層名。
5. 設(shè)置圖形數(shù)據(jù)庫(kù)的當(dāng)前層:
調(diào)用AcDbDatabase類的成員函數(shù)setClayer()設(shè)置圖形數(shù)據(jù)庫(kù)的當(dāng)前層,其函數(shù)原型為:
Acad::ErrorStatus setClayer(AcDbObjectId objId);
函數(shù)的參數(shù)為層表的ID號(hào)。獲得層表記錄ID號(hào)的主要方法有:
1) 將新建的層表記錄加入層表時(shí),用下面的形式調(diào)用add()函數(shù):
AcDbLayerTable::add(AcDbObjectId & layerID,AcDbLayerTableRecord *pRecord);
在關(guān)閉層表和層表記錄的代碼后,加入“acdbCurDwg()->setClayer(layerID);”設(shè)置當(dāng)前層。
2) 若層已經(jīng)存在,則可利用獲得指定符號(hào)表ID號(hào)的形式調(diào)用getAt()函數(shù):
AcDbLayerTable:: getAt(const char* entryName, AcDbObjectId& recordId, bool getErasedRecord = false) const;
然后調(diào)用加入“acdbCurDwg()->setClayer(layerID);”設(shè)置當(dāng)前層。
6. 定義字體樣式
AutoCAD數(shù)據(jù)庫(kù)的字體樣式是字體樣式中的一條記錄,其缺省的字體樣式名為STANDARD,字體文件名為txt.shx。用STYLE定義一個(gè)新的字體樣式包括建立樣式名,選擇字體文件和確定字體效果三步操作。用戶新定義的字體樣式是作為一條字體樣式表記錄加入字體樣式表中。
A.以寫方式調(diào)用getTextStyleTable()哈數(shù)打開當(dāng)前圖形數(shù)據(jù)庫(kù)的字體樣式表,獲得指向該表的指針。
B.調(diào)用構(gòu)造函數(shù)AcDbTextStyleRecord()創(chuàng)建字體樣式表記錄對(duì)象。
C.設(shè)置字體樣式名和字體文件名。
D.設(shè)置字體的效果,包括倒置、反向、垂直、寬度比例和傾斜角的設(shè)置。
E.調(diào)用add()函數(shù)將字體樣式表記錄加入字體樣式表中。
F.關(guān)閉字體樣式表和字體樣式表記錄。
7. 尺寸標(biāo)注樣式和尺寸變量
尺寸標(biāo)注樣式是AutoCAD數(shù)據(jù)庫(kù)中尺寸標(biāo)注樣式表的一條記錄,其缺省的尺寸標(biāo)注樣式名為STANDSRD,該樣式由系統(tǒng)自動(dòng)建立。尺寸變量是確定組成尺寸標(biāo)注線、尺寸界線、尺寸文字以及箭頭的樣式、大小和它們之間相對(duì)位置等的變量。
對(duì)標(biāo)注樣式名為STANDARD的尺寸變量進(jìn)行修改,首先要打開當(dāng)前圖形數(shù)據(jù)庫(kù)的尺寸標(biāo)注樣式表,并調(diào)用getAt()函數(shù)獲得指向尺寸標(biāo)注樣式表記錄STANDARD的指針,然后調(diào)用AcDbDimStyleTableRecord類成員函數(shù)設(shè)置尺寸變量。
建立新的尺寸標(biāo)注樣式與建立圖層和定義字體樣式基本相同。,其步驟為:
A.以寫的方式調(diào)用getDimStyleTable()函數(shù)打開當(dāng)前圖形數(shù)據(jù)庫(kù)的尺寸標(biāo)注樣式表,獲得指向該表的指針.
B.調(diào)用構(gòu)造函數(shù)AcDbDimStyleRecord()創(chuàng)建尺寸標(biāo)注樣式表記錄對(duì)象。
C.設(shè)置尺寸標(biāo)注樣式名。
D.調(diào)用AcDbDimStyleRecord類的成員函數(shù)設(shè)置尺寸變量。
E.調(diào)用add()函數(shù)將尺寸標(biāo)注樣式表記錄加入到尺寸標(biāo)注樣式中。
F.關(guān)閉尺寸標(biāo)注樣式表和尺寸標(biāo)注樣式表記錄。
8. 符號(hào)表記錄的建立:
9種符號(hào)表作為AutoCAD數(shù)據(jù)庫(kù)中的根對(duì)象和容器,包含的下級(jí)對(duì)象為相應(yīng)的符號(hào)表記錄。符號(hào)表本身只能由AutoCAD系統(tǒng)建立而不能由應(yīng)用程序創(chuàng)建,應(yīng)用程序只能創(chuàng)建符號(hào)表記錄。如塊表中的塊表記錄,層表中的層表記錄,字體樣式表中的字體樣式記錄等,雖然各種具體的符號(hào)表記錄名稱不同,但建立的基本方法相同。歸納主要以下幾步:
A.以寫的方式調(diào)用get##BASE_NAME##Table()函數(shù)打開數(shù)據(jù)庫(kù)的## BASE_NAME##表,獲得指向該表的指針。
B.調(diào)用構(gòu)造函數(shù)AcDb##BASE_NAME##Record()創(chuàng)建相應(yīng)的符號(hào)表記錄對(duì)象。
C.調(diào)用setName()函數(shù)設(shè)置相應(yīng)的符號(hào)表記錄名。
D.調(diào)用符號(hào)記錄表的成員函數(shù)設(shè)置其屬性。
E.調(diào)用add()函數(shù)將所創(chuàng)建立的符號(hào)表記錄加入其符號(hào)表。
F.關(guān)閉符號(hào)表和符號(hào)表記錄。
9. 符號(hào)表記錄的編輯:
對(duì)于符號(hào)表的符號(hào)表記錄,可以通過符號(hào)表記錄類的成員函數(shù)對(duì)其屬性進(jìn)行編輯,如更改字體樣式表的字型文件、文字的字高和寬度比例等。符號(hào)表記錄的編輯實(shí)現(xiàn)技術(shù)可以分三步:
A.以讀的方式調(diào)用get##BASE_NAME##Table()函數(shù)打開數(shù)據(jù)庫(kù)的##BASE_NAME##表,獲得指向該表的指針。
B.調(diào)用符號(hào)表類的成員函數(shù)getAt()獲得符號(hào)表記錄指針。
C.調(diào)用相應(yīng)的符號(hào)表記錄成員函數(shù)修改其屬性。
10.符號(hào)表記錄的查詢:
符號(hào)表記錄的查詢主要利用符號(hào)表瀏覽器和循環(huán)結(jié)構(gòu)實(shí)現(xiàn),步驟如下:
A.利用AcDb##BASE_NAME##Table類的成員函數(shù)newIterator()創(chuàng)建符號(hào)表瀏覽器。
B.利用循環(huán)結(jié)構(gòu)和塊表瀏覽器遍歷塊表。
C.利用AcDb##BASE_NAME##TableIterator類的成員函數(shù)getRecord()獲得符號(hào)表記錄。
D.利用成員函數(shù)getName()得到符號(hào)表記錄名。
例子:
AcDb##BASE_NAME##Table *pTable;
acdbHostApplicationServices()->workingDatabase()
->get##BASE_NAME##Table (pTable,AcDb::kForRead);
AcDb##BASE_NAME##TableIterator *pIter;
pTable ->newIterator(pIter);
pTable ->close();
AcDb##BASE_NAME##TableRecord *pRecord;
for (pIter ->start();!pIter ->done();pIter ->step())
{
pIter ->getRecord(pRecord,AcDb::kForWrite);
char *m_name;
pRecord ->getName(m_name);
//添加相應(yīng)的操作
free(m_Layername);
pRecord ->close();
}
delete pLayerIter;
三.對(duì)象字典的操作
對(duì)象字典和符號(hào)表均是AutoCAD圖形數(shù)據(jù)庫(kù)中的容器對(duì)象。在9種符號(hào)表中,每一種符號(hào)表只能用來(lái)存儲(chǔ)特定的對(duì)象,如塊表用來(lái)存儲(chǔ)塊表記錄,層表用來(lái)存儲(chǔ)層表記錄等,而對(duì)象字典卻不受此限制,它可以存儲(chǔ)任何類型的對(duì)象,包括其他對(duì)象字典、數(shù)據(jù)庫(kù)對(duì)象和應(yīng)用程序創(chuàng)建的對(duì)象。因此,所謂的對(duì)象字典實(shí)際上是一種通用的對(duì)象容器。
1. 組字典的操作使用技術(shù):
組是實(shí)體等數(shù)據(jù)庫(kù)對(duì)象的有序集合,是組字典的成員。從層次關(guān)系來(lái)看,組是管理其所包含對(duì)象的容器,而組字典則是管理組對(duì)象的容器。一個(gè)組實(shí)際上可以認(rèn)為是一個(gè)選擇集,但又不同于一般的選擇集,它是組字典中一個(gè)有名的常駐對(duì)象。當(dāng)組中的一個(gè)實(shí)體被刪除時(shí),該實(shí)體自動(dòng)地從組中移出;當(dāng)恢復(fù)被刪除的是天時(shí),該實(shí)體又自動(dòng)地加入到該組中。使用組可以簡(jiǎn)化操作,容易實(shí)現(xiàn)對(duì)一批對(duì)象的顏色、層和線型等屬性的統(tǒng)一修改。
組字典中可以包含若干個(gè)組,每個(gè)組通過其組名來(lái)區(qū)分。
A.直接從數(shù)據(jù)庫(kù)中獲得指向組字典的指針:
Acad::ErrorStatus getGroupDictionary(AcDbDictionary*& pDict,AcDb::OpenMode mode);
B.從對(duì)象字典中獲得組字典的指針:
由于組字典是對(duì)象字典中的一個(gè)名為“ACAD_GROUP”的成員,因此先獲得數(shù)據(jù)庫(kù)中指向?qū)ο笞值涞闹羔槪缓笳{(diào)用getAt()函數(shù)獲得指向組字典的指針。
AcDbDictionary *pNamedObj,*pGroupDict;
acdbCurDwg()->getNamedObjectsDictionary(pNamedObj,AcDb::kForRead);
pNamedObj->getAt("ACAD_GROUP",(AcDbObject *&)pGroupDict,AcDb::kForWrite);
2. 將組加入組字典中:
setAt(const char* srchKey,AcDbObject *newValue,AcDbObjectId& retObjId);
各參數(shù)的意義為:srchKey為組名,用字符串表示;newValue為加入到組字典中的新組的指針;retObjId為函數(shù)返回的已加入組字典中的組對(duì)象的ID號(hào)。如果在組字典中已有同名的組存在,則將被新加入的組取代。調(diào)用該函數(shù)時(shí),必須先創(chuàng)建組對(duì)象,將指向組對(duì)象的指針和定義的組名作為輸入?yún)?shù),并獲得加入組字典中的組對(duì)象ID號(hào)。
其中組對(duì)象為AcDbGroup類。具體的操作查相關(guān)的類函數(shù)即可!
3.建立多線樣式:
多線是指多條互相平行的直線,各條線的線型、顏色和他們之間的間距等屬性可互不相同。多條的這些屬性由多線樣式定義。定義一個(gè)多線樣式的步驟為:
A.通過getMLStyleDictionary()函數(shù)獲得指向圖形數(shù)據(jù)庫(kù)中的多線樣式字典的指針。
B.用多線樣式的構(gòu)造函數(shù)AcDbMlineStyle()創(chuàng)建多線樣式對(duì)象。
C.利用AcDbDictionary類的成員函數(shù)setAt()將所建立的多線樣式加入字典中。
D.調(diào)用有關(guān)函數(shù)設(shè)置多線樣式的屬性,如設(shè)置多次按名稱、元素特性和多線特性等。
4.用戶對(duì)象字典的操作和使用技術(shù):
在AutoCAD數(shù)據(jù)庫(kù)中,對(duì)象字典是字典類數(shù)據(jù)庫(kù)對(duì)象的總稱。按其層次關(guān)系可分為兩類,一是由AutoCAD數(shù)據(jù)庫(kù)直接管理的第一層對(duì)象字典;二是由第一層對(duì)象字典管理的第二層對(duì)象字典。為了便于區(qū)別,我們把第一層對(duì)象字典成為有名對(duì)象字典,用戶在應(yīng)用程序中定義的字典成為用戶字典。前面提到的組字典、多線樣式字典和用戶對(duì)象字典均屬于第二層對(duì)象字典,其中組字典和多線字典是系統(tǒng)自動(dòng)生成的對(duì)象字典。
對(duì)象字典的第三層為字典中的對(duì)象。如:組詩(shī)組字典中的對(duì)象,多線樣式是多線樣式字典中的對(duì)象,在用戶對(duì)象字典中可以包含任何類型的對(duì)象,如實(shí)體對(duì)象、自定義對(duì)象和數(shù)據(jù)庫(kù)對(duì)象等。有名對(duì)象字典中的各用戶對(duì)象字典之間,通過其字名來(lái)表示;用戶字典中的對(duì)象利用其對(duì)象名來(lái)區(qū)分。
4.1 用戶對(duì)象字典的定義和字典對(duì)象的查詢:
在有名對(duì)象字典中定義一個(gè)用戶對(duì)象字典的實(shí)質(zhì)是創(chuàng)建一個(gè)AcDbDictionary類對(duì)象,并將其加入有名對(duì)象字典中,其步驟為:第一,調(diào)用AcDbDatabase類的成員函數(shù)getNameObjectDictionary()得到有名對(duì)象字典的地址(即指針);第二,定義新的用戶對(duì)象字典并加入有名對(duì)象字典中。
例子:
AcDbDictionary *pNamedObj; //定義有名對(duì)象字典
acdbCurDwg()->getNamedObjectsDictionary(pNamedObj,AcDb::kForWrite);
AcDbDictionary *pDict = new AcDbDictionary; //定義用戶對(duì)象字典
AcDbObjectId eid;
pNamedObj->setAt("Name",pDict,eid);
而在用戶字典中對(duì)象查詢的第一步是建立字典瀏覽器遍歷對(duì)象字典:
AcDbDictionaryIterator *pDictIter = pDict->newIterator();
字典對(duì)象查詢的第二步是得到指向?qū)ο蟮闹羔槪?BR>pDictIter->getObject(pObj,AcDb::kForRead);
在獲得對(duì)象指針的前提下,可以利用對(duì)象的成員函數(shù)進(jìn)行查詢、檢索和編輯等操作。
另外,用戶字典中的對(duì)象名可以用AcDbDictionaryIterator類的成員函數(shù)name()獲得。而該對(duì)象名表示的對(duì)象類名可以用“pObj->isA()->name()”形式獲得。
需要注意的是:將塊表記錄中的實(shí)體對(duì)象加入用戶字典,并不是將實(shí)體復(fù)制到字典中,而是在字典中存儲(chǔ)其對(duì)象的指針。因此,當(dāng)塊表記錄中的實(shí)體被刪除后,在字典中相應(yīng)的對(duì)象名和指針也不再存在。
4.2 用戶對(duì)象字典:擴(kuò)展記錄的加入和查詢。
擴(kuò)展記錄屬于AcDbxrecord類的對(duì)象,可用來(lái)定義任何類型的數(shù)據(jù)。擴(kuò)展記錄的數(shù)據(jù)項(xiàng)采用結(jié)果緩沖區(qū)鏈表的形式定義,每一項(xiàng)由DXF組碼和相應(yīng)的組值構(gòu)成。擴(kuò)展記錄是一個(gè)在應(yīng)用程序中定義的數(shù)據(jù)庫(kù)對(duì)象,屬于有名對(duì)象字典的下級(jí)對(duì)象或某一對(duì)象的擴(kuò)展字典和其他擴(kuò)展記錄的下級(jí)對(duì)象。
在ARX中創(chuàng)建擴(kuò)展記錄的主要步驟如下:
1.獲得數(shù)據(jù)庫(kù)中指向有名對(duì)象字典的指針。
2.建立一個(gè)新的用戶脆響字典,并加入有名對(duì)象字典中。
3.創(chuàng)建新的擴(kuò)展記錄,并加入用戶對(duì)象字典中,如:
AcDbXrecord *pXrec = new AcDbXrecord;
pDict->setAt("XREC1", pXrec, xrecObjId);
4.用ads_buildlist()函數(shù)構(gòu)造由擴(kuò)展記錄數(shù)據(jù)項(xiàng)組成的緩沖區(qū)鏈表,其一般形式為:
ads_buildlist(<組碼1>,<組值1>,<組碼2>,<組值2>,……,0);
5. 調(diào)用AcDbXrecord的成員函數(shù)setFromRbChain()設(shè)置擴(kuò)展記錄所指向的鏈表指針。
三.ARX應(yīng)用程序中的尺寸標(biāo)注技術(shù)
1. 尺寸對(duì)象的組成和常用的尺寸標(biāo)注類:
尺寸標(biāo)注也是AutoCAD數(shù)據(jù)庫(kù)中塊表記錄中的一種對(duì)象。一個(gè)完整的尺寸對(duì)象由尺寸標(biāo)注線,尺寸界線,尺寸箭頭和尺寸文字構(gòu)成。
在AutoCAD數(shù)據(jù)庫(kù)中,AcDbDimension類為尺寸標(biāo)注的基類,其派生類主要有對(duì)齊標(biāo)注(AcDbAlignedDimension),兩線定角標(biāo)注(AcDb2LineAngularDimension),三點(diǎn)定角標(biāo)注(AcDb3PointAngularDimension),直徑標(biāo)注(AcDbDiametricDimension),半徑標(biāo)注(AcDbRadialDimension),坐標(biāo)尺寸標(biāo)注(AcDbOrdinateDimension),定角標(biāo)注(AcDbRotatedDimension)等。
尺寸標(biāo)注類是實(shí)體類(AcDbEntity)的派生類,其主要成員函數(shù)的原型為:
1.設(shè)置尺寸文字位置:
Acad::ErrorStatus setTextPosition(const AcGePoint3d& unnamed);
2. 設(shè)置尺寸標(biāo)注樣式:
Acad::ErrorStatus setDimensionStyle(AcDbObjectId unnamed);
3. 設(shè)置尺寸文字:
Acad::ErrorStatus setDimensionText(const char* unnamed);
4. 設(shè)置尺寸文字旋轉(zhuǎn)角度:
Acad::ErrorStatus setTextRotation(double unnamed);
5. 查詢尺寸文字:
Char* dimensionText()const;
6. 查詢尺寸文字位置:
AcGePoint3d textPosition()const;
7. 查詢尺寸文字旋轉(zhuǎn)角度
double textRotation()const;
2.尺寸標(biāo)注的鼠標(biāo)拖動(dòng)技術(shù):
實(shí)現(xiàn)尺寸標(biāo)注線和尺寸文字為字的鼠標(biāo)拖動(dòng)的關(guān)鍵是跟蹤鼠標(biāo)的移動(dòng),并根據(jù)鼠標(biāo)的位置動(dòng)態(tài)顯示尺寸標(biāo)注。用ads_grread()憾事跟蹤鼠標(biāo)的移動(dòng),其函數(shù)原型為:
Int ads_grread(int track,int *type,struct resbuf *result);
參數(shù)track為控制位,其值為1則將鼠標(biāo)的坐標(biāo)存入result中;type表示輸入的種類,如按鼠標(biāo)左鍵,則type=3;
尺寸標(biāo)注的鼠標(biāo)拖動(dòng)原理為:
首先,設(shè)置ads_grread()函數(shù)控制位track=1,在循環(huán)結(jié)構(gòu)中用ads_grread()函數(shù)追蹤鼠標(biāo)的移動(dòng),獲得當(dāng)前鼠標(biāo)位置的x,y坐標(biāo)。用ads_grread(track,&type,&result)形式調(diào)用,則點(diǎn)的x和y坐標(biāo)值可分別用result.resval.rpoint[X]和result.resval.rpoint[Y]形式獲得。其次,以寫方式打開尺寸標(biāo)注對(duì)象,用獲得的X,Y坐標(biāo)設(shè)置尺寸標(biāo)注線和尺寸位置,并關(guān)閉對(duì)象。循環(huán)執(zhí)行,實(shí)現(xiàn)尺寸步標(biāo)注對(duì)象的拖動(dòng)。如果按鼠標(biāo)左鍵拾取一個(gè)點(diǎn),則type=3,結(jié)束循環(huán)。
例子:公差標(biāo)注設(shè)置函數(shù):
void SetDimtpAndDimtm(double tp,double tm)
{
AcDbDimStyleTable *pDimStyleTbl;
acdbCurDwg()->getDimStyleTable(pDimStyleTbl,AcDb::kForRead);
AcDbDimStyleTableRecord *pDimStyleTblRcd;
pDimStyleTbl->getAt("",pDimStyleTblRcd,AcDb::kForWrite);
if (fabs(tp) == fabs(tm))
{
pDimStyleTblRcd->setDimtfac(1.0)
}
else pDimStyleTblRcd->setDimtfac(0.5);
if (tp == 0.0 && tm == 0.0)
{
pDimStyleTblRcd->setDimtol(0);
}
else
{
pDimStyleTblRcd->setDimtp(tp);
pDimStyleTblRcd->setDimtol(1);
pDimStyleTblRcd->setDimtm(tm);
}
pDimStyleTblRcd->close();
pDimStyleTbl->close();
}
3.圖案填充函數(shù)介紹:
圖案填充函數(shù)AcDbHatCh也是實(shí)體立體(AcDbEntity)的派生類,與尺寸標(biāo)注類似,圖案填充也是 AutoCAD數(shù)據(jù)庫(kù)中塊表記錄中的一種對(duì)象。
生成圖案填充對(duì)象的步驟為:
A.調(diào)用圖案填充類的構(gòu)造函數(shù)創(chuàng)建AcDbHatch類對(duì)象。
B.調(diào)用AcDbHatch類的成員函數(shù)設(shè)置填充圖案的法向矢量,關(guān)聯(lián),標(biāo)高,縮放比例,填充圖案,填充方式和填充邊界等屬性。
C.調(diào)用evaluateHatch()顯示填充圖案。
D.將AcDbHatch類對(duì)象寫入當(dāng)前圖形數(shù)據(jù)庫(kù)的塊表記錄中。
4.ARX應(yīng)用程序中視圖管理技術(shù)和應(yīng)用:
視圖和視口是AutoCAD環(huán)境中圖形顯示中經(jīng)常涉及到的基本概念。圖形屏幕上用于顯示圖形的一個(gè)矩形區(qū)域稱為視口,可以把整個(gè)圖形屏幕作為一個(gè)視口,也可以把整個(gè)視圖屏幕設(shè)置成多個(gè)視口。當(dāng)前視口中顯示的復(fù)雜圖形按不同的窗口大小設(shè)置,并以視圖名為表示在圖形數(shù)據(jù)庫(kù)中保存。在需要時(shí),顯示指定視圖以滿足對(duì)圖形編輯和瀏覽的需要。
視圖的管理包括視圖的定義,顯示,屬性設(shè)置和查詢等功能。在AutoCAD的交互環(huán)境中,用戶可以使用VIEW命令對(duì)視圖進(jìn)行命名,保存,恢復(fù)和刪除。在ARX應(yīng)用程序中,主要是通過使圖表類及視圖表記錄類的成員函數(shù)實(shí)現(xiàn)視圖的管理功能。
視圖類作為視圖表(AcDbViewTable)中的一條視圖記錄(AcDbViewTableRecord)保存在AutoCAD數(shù)據(jù)庫(kù)中。把當(dāng)前視口中指定窗口每得圖形定義為一個(gè)新的視圖的操作等價(jià)于向數(shù)據(jù)庫(kù)中添加一個(gè)AcDbViewTableRecord類對(duì)象。其實(shí)現(xiàn)步驟為:
A.調(diào)用視圖標(biāo)記錄類的構(gòu)造函數(shù)創(chuàng)建AcDbViewTableRecord類對(duì)象;
B.調(diào)用AcDbViewTableRecord類的成員函數(shù)設(shè)置視圖名,視圖中心點(diǎn),視圖高度和寬度等屬性;
C.獲得當(dāng)前圖形數(shù)據(jù)庫(kù)中的視圖表指針,將AcDbViewTableRecord類對(duì)象添加到數(shù)據(jù)庫(kù)中。
視圖的查詢首先要獲得當(dāng)前圖形數(shù)據(jù)庫(kù)中指定視圖師表記錄的指針,然后調(diào)用相應(yīng)的成員函數(shù)得到該視圖的屬性。
四.ARX中的實(shí)體造型技術(shù)和應(yīng)用
三維造型包括線框模型、表面模型和實(shí)體模型三種形式,其中三維實(shí)體具有體的特征。能夠較全面地反映形體的物理特征。在機(jī)械CAD中,利用實(shí)體造型技術(shù)用戶不僅可以通過并、交、差布爾運(yùn)算生成所需的機(jī)械零部件模型,而且還能夠?qū)π误w進(jìn)行剖切成剖視圖以進(jìn)行體積、重心和慣性矩等物性計(jì)算和分析,進(jìn)而在實(shí)體模型的基礎(chǔ)上生成NC代碼,在ARX應(yīng)用程序中,并不是直接使用AutoCAD系統(tǒng)本身提供的有關(guān)實(shí)體造型和編輯命令,而是通過直接生成數(shù)據(jù)庫(kù)對(duì)象及調(diào)用AcDb3dSolid類的成員函數(shù)來(lái)進(jìn)行實(shí)體造型。
1.基本三維實(shí)體生成方法:
在AutoCAD數(shù)據(jù)庫(kù)中,三維實(shí)體屬于AcDb3dSolid類對(duì)象,該類是AcDbEntity類的派生類。
對(duì)于一個(gè)具體的幾何實(shí)體,即ACIS對(duì)象來(lái)說(shuō),AcDb3dSolid實(shí)體是一個(gè)容器和接口。
通過AcDb3dSolid類的成員函數(shù)可以生成各種基本的三維實(shí)體以及實(shí)現(xiàn)實(shí)體的布爾運(yùn)算。生成三維實(shí)體的基本步驟為:
A.調(diào)用AcDb3dSolid類的構(gòu)造函數(shù)創(chuàng)建一個(gè)容器對(duì)象:
如:AcDb3dSolid *p3dObj = new AcDb3dSolid;
B.調(diào)用AcDb3dSolid類的成員函數(shù)創(chuàng)建基本三維實(shí)體對(duì)象。其一般形式為:
指向AcDb3dSolid類對(duì)象的指針-〉創(chuàng)建基本三維實(shí)體對(duì)象成員函數(shù)。
B.將AcDb3dSolid類對(duì)象寫入當(dāng)前圖形數(shù)據(jù)庫(kù)的塊表記錄中,其代碼設(shè)計(jì)方法與二維對(duì)象的添加完全相同。
ARX程序的消息響應(yīng):
ARX程序?qū)嵸|(zhì)上是一動(dòng)態(tài)庫(kù),它直接與AutoCAD進(jìn)行對(duì)話,即AutoCAD發(fā)送各種消息給ARX程序,ARX程序負(fù)責(zé)對(duì)各種消息作出相應(yīng)的處理。
kInitAppMsg:
當(dāng)ARX程序被加載時(shí)發(fā)送該消息,用以建立AutoCAD和應(yīng)用程序之間的對(duì)話。
kUnloadAppMsg:
當(dāng)ARX程序卸載時(shí)(不論是用戶卸載應(yīng)用程序,還是由AutoCAD終止退出)發(fā)送該消息,關(guān)閉文件以及執(zhí)行必要的清理工作。
kOleUnloadAppMsg:
發(fā)送該消息確定應(yīng)用程序是否可以卸載,即該應(yīng)用程序的ActiveX對(duì)象或接口是否被其他應(yīng)用程序所引用。
kLoadDwgMsg:
當(dāng)打開一幅圖形時(shí)發(fā)送消息,此時(shí)AutoCAD的圖形編輯環(huán)境進(jìn)行了初始化,并且,應(yīng)用程序可以調(diào)用ARX的全局函數(shù),而acedCommand()函數(shù)除外。
kUnLoadDwgMsg:
當(dāng)用戶退出當(dāng)前的圖形編輯時(shí)發(fā)送該消息。
下面的代碼將實(shí)例生成由 某一圖層上所有的實(shí)體組成的選擇集:
struct resbuf *plb;
char sbuf[32];
ads_name ss1;
plb = acutNewRb(8) //圖層DXF組碼是8
strcpy(sbuf,”PARTS”); //圖層名為PARTS
plb->resval.rstring = sbuf;
plb->rbnext = NULL;
acedSSGet(“X”,NULL,NULL,plb,ss1);
acutRelRb(plb); //don’t forget
下面的例子是選擇“PARTS”圖層上的所有圓,這是一個(gè)利用acutBuildList()函數(shù)構(gòu)造結(jié)果緩沖區(qū)表后再傳給acedSSGet()函數(shù)的實(shí)例:
ads_name ss1;
struct resbuf *rb1;
rb1 = acutBuildList(RTDXFO,”CIRCLE”,8,”PARTS”,RTNONE);
acedSSGet(“X”,NULL,NULL,rb1,ss1);
acutRelRb(plb); //don’t forget
以上經(jīng)為個(gè)人筆記﹐愿與大家分享﹐共同進(jìn)步﹗
如有錯(cuò)誤﹐敬請(qǐng)指出﹗