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