ARX(AutoCAD Runtime eXtension實時運行擴展)作為繼AutoLISP、ADS后的第三代開發工具,采用全新的面向對象編程技術。
1985年6月推出的AutoCAD2.17版本使用AutoLISP作為AUTOCAD內嵌語言,與AUTOCAD綁定一起,向用戶提供了用AutoLISP設計應用程序的二次開發環境。AutoLISP是種解釋型語言,主要用來修改和擴充ACAD的命令及系統菜單、設計對話框驅動程序、實現對圖形庫的直接訪問和修改。這是AUTOCAD提供的第一代開發環境。
第二代開發環境是R11版本提供的ADS(AUTOCAD Development System)開發系統。該系統實際上向用戶提供了用C語言編寫應用程序的開發環境。ADS環境用C語言編寫,除了可以使用標準C庫函數外,還可以使用對AUTOCAD進行操作的ADS函數。ADS雖脫離了AUTOCAD環境,但其編寫的程序不能單獨運行,只能作為一組外部函數被AUTOLISP裝入和調用,實際上就是在AUTOLISP之上包了一層,是AUTOLISP的客戶。
如今,在AUTOCAD2000中不再支持ADS開發。ADS已完全被ARX所取代。
AUTOCAD第三代開發環境和工具包括ObjectARX、VBA、Visual LISP。
存儲在AutoCAD數據庫的對象(DBObject),包括可見幾何實體對象和不可見的非幾何對象等,以—組符號表和一個有名對象字典的結構形式組織而成,符號表和數據字典為容器對象(Container Object),包含了其他對象,其作用是組織和管理數據庫對象。數據庫主要包括有9個符號表和1個對象字典。
符號表
在AutoCAD數據庫中的9個符號表,分別是:
1)塊表(BlockTabLe)
2)尺寸標注樣式表(DimStyleTable)
3)層表(LayerTable)
4)線型表(LinetypeTable)
5)應用程序注冊表(RegAppTable)
6)文字樣式表(TextStyleTable)
7)用戶坐標系表(UCSTable)
8)視口表(ViewportTable)
9)視圖表(ViewTable)
塊表中存儲實體的記錄稱為塊表記錄,即所有的實體均存儲在塊表記錄中,通常的實體都存儲在MODEL_SPACE塊中;層表中的記錄存儲層的有關信息;尺寸標注樣式表、層表、線型表和文字樣式表等均用來存儲相應的表記錄。
對象字典
有名對象字典是存儲一般對象的容器,可用來存儲任何數據庫對象和子類,主要包括組(GROUP)和多線(MLINE)樣式兩個數據庫字典。用戶也可以創建一個新的“用戶對象字典”,并存儲于對象字典中。 在實際開發中,可以將應用程序的“擴展對象”存放在“用戶對象字典”中,“擴展對象”的“擴展記錄和數據”通過鏈表的形式存儲在對象字典中,對于該類對象,不另外存儲到塊表。關于擴展對象,后面有詳細說明。
數據庫的創建及訪問
略
數據庫的初始化
進入AUTOCAD環境,系統會自動生成一個缺省的數據庫,庫中包含9個符號表和一個有名對象字典。如,層表有一個0層記錄;塊表中有“MODEL_SPACE”(模型空間)和“PAPER_SPACE”(圖紙空間)兩條記錄;線型表中有“CONTINUOUS”、“BY_LAYER”和“BY_BLOCK”記錄;應用程序注冊表中有“ACAD”記錄;文字樣式表中有“STANDARD”記錄;有名對象字典中包含“GROUP字典”和“MLINE字典”,其中“MLINE字典”中有一條“STANDARD”字體樣式記錄。
基本實體的創建及訪問
略
圖塊
圖塊是若干實體的集合,也是AUTOCAD數據庫中的一種對象,通常分為不帶屬性的簡單圖塊和帶屬性的復雜圖塊兩種。作為一個整體來看待,以簡化操作。
用戶自定義的圖塊分為“塊”和“屬性塊”兩種。塊只包含圖形信息,屬性塊還可以包含非圖形信息,這些屬性信息是塊的組成部分之一。屬性塊必須先用ATTDEF定義屬性,然后用BLOCK將其定義為圖塊的一部分。
簡單塊的定義
略
屬性塊的定義
屬性塊是由構成圖塊的實體和附加信息(屬性)組成。定義屬性塊主要包括塊和屬性的的定義,塊的定義與不帶屬性塊簡單塊一樣,屬性的定義主要是通過調用AcDbAtrributeDefinition實現。如下示例代碼定義了圓度公差標注符號,其中圓度公差值定義為塊的屬性,在圖塊插入時輸入,缺省值為0.3。
//1.定義塊
OdDbBlockTableRecord *pBTableRec = new OdDbBlockTableRecord();
pBTableRec->setName();
…. ..
OdDbBlockTable *pBTable = pDwgDB->getBlockTable(pBTable,acdb:kForWrite);
OdDbObjectID id;
pBTable->add(id,pBTableRec);
//2.生成組成塊的實體:基本線、圓
//基本實體創建過程略
……
//將實體附到塊中
pBTableRec->appendAcDbEntity(pLine,id);
pBTableRec->appendAcDbEntity(pCirle,id);
……
//3.定義塊的屬性
OdGePoint3d pt(8,1.5,0);
OdDbAtrributeDefinition *pAttDef = new OdDbAtrributeDefinition();
//設置塊的屬性值 略
pAttDef->setPoint(pt); //設置屬性位置
pAttDef ->setPrompt(“請輸入圓度公差:”); //設置屬性提示
pAttDef->setTextString(0.3); //設置缺省值
pAttDef->setXXX();
……
//4。將屬性定義加入到圖塊中
pBTableRec->appendAcDbEntity(id,pAttDef);
……
創建屬性實體函數原型:
OdDbAtrributeDefinition{ const OdDbPoint3d &position,
const char* text, const char* tag,
const char* prompt,
OdDbObjectID style
};
參數說明:
Position: 屬性在WCS坐標系中的位置。
Text: 屬性的缺省值
Tag: 屬性標簽
Prompt: 屬性提示
Style: 文字樣式ID
簡單塊的引用
pBlkRef->setBlockTableRecord(blockid);//設置關聯。
略
屬性塊的引用
屬性塊的引用分成塊引用和向插入的塊中附加屬性信息兩步。
與創建簡單塊引用一樣,將一個屬性塊插入當前圖形的塊表記錄中并未包含其屬性。在塊定義中的附加屬性信息必須通過調用AcDbBlockReference類的成員函數appendAttribute才能加入到塊引用中。塊引用方法與前一致,先主要說說屬性的插入方法。
在插入屬性時,必須檢索出屬性塊定義的所有附加信息,然后將其附加于塊引用的相應實體上,這需要遍歷塊的所有實體。
過程如下:
1.得到塊引用。
2.遍歷塊引用中的實體。
3.得到屬性實體指針。
4.將屬性對象附加給塊引用。
對象字典的操作和使用
對象字典是一種通用的對象存儲容器,它可以存儲任何類型的對象,包括其他對象字典、數據庫對象和應用程序創建的對象。與符號表相比,對象字典使用比較靈活,它可以實現符號表無法實現的一些特殊功能。
它由三個部分構成:
1. 組字典(Group Dictionary)
2. 多線樣式字典(Mline Style Dictionary)
3. 用戶定義的對象字典。
前兩者為ACAD缺省的數據庫對象。用戶定義的對象字典一般由應用程序創建。
組字典
組是數據庫對象的有序集合,是組字典的成員。從層次關系看,組是管理其所包含對象的容器,而組字典是管理組對象的容器。一個組實可以認為是一個選擇集。當組中一個實體被刪除時,該實體自動地從組中移出,當恢復被刪除實體時,該實體又自動加入到組中。使用組的目的就是為了簡化操作,容易實現對一批對象的顏色、層和線型屬性的統一修改。
組字典中包含若干個組。
組字典的操作大致步驟如下:
1.通過getGroupDictionary()獲得組字典指針。
2.創建組對象new OdDbGroup,并加到組字典中。
3.將實體加入到組對象中。
4.設置各組的屬性。
多線樣式字典的操作及使用
多線是指多條互相平行的直線,其中各條線的顏色、線型和間距等屬性可不相同,多線的這些屬性由多線樣式定義。多線樣式作為一個數據庫對象存儲在多線樣式字典中。定義多線樣式步驟如下:
1.通過getMLineDictionary獲得多線樣式字典指針。
2.創建多線樣式對象OdDbMLineStyle
3.利用OdDbDictionary成員函數setAt將多線樣式對象加入到樣式字典中。
3.設置多線樣式的屬性。如名稱、元素屬性、多線特性。
多線對象
多線實體,是塊表記錄中的OdDbMline類對象。創建多線對象方法及過程與OdDbLine基本一樣。
用戶對象字典操作及使用
用戶在應用程序中定義的字典為用戶字典。用戶對象字典的特別之處在于它可以包含任何類型的對象。如實體對象、自定義對象和數據對象等。
用戶對象字典創建步驟:
1通過getNamedObjectsDictionary得到對象字典指針。
2定義新的用戶對象字典加入到對象字典中。
如:
pNamedObj = getNamedObjectsDictionary();
pDict = new OdDbDictionary();
pNamedObj->setAt(“USER_DICT”,pDict,dictID);
3加入實體對象到用戶字典中
pDict->setAt(ObjName,pObj,objID);
通常加入到用戶字典中的對象為ACAD的可見對象,該對象已存在于數據庫的塊表記錄中。如果在程序中直接生成實體時,必須先將其加入到塊表記錄中,然后才能加入到用戶字典中。
擴展記錄
擴展記錄屬于OdDbXRecord類的對象。可用來定義任何類型的數據。擴展記錄的數據項采用結果緩沖區鏈表的形式定義。每項由數據類型(也就是組碼)和值組成。
擴展記錄通常用來表示應用程序定義的特定數據。在ACAD中,應用程序可以定義擴展數據xdata和擴展記錄。
擴展記錄的創建過程:
1.獲得對象字典指針。
2.新建一個用戶字典,并加入到對象字典中。
3.創建新的擴展記錄,并加入到用戶對象字典中。
如:OdDbXRecord* pRec = new OdDbXRecord();
pDic->setAt(“USER_DIC”,pRec,recID);
4.用ads_buildlist函數構造由擴展記錄數據項組成的緩沖區鏈表
5.調用setFromRbChain將鏈表設置到擴展記錄中。
示例如下:
//1。獲得對象字典指針
OdDbDictionay* pNamedDict = NULL;
pDwgDb->getNamedObjectsDictionary(pNamedDict,OdDb::kForWrite);
//2.新建一個用戶對象字典,并加入到對象字典中。
OdDbDictionary* pDic = new OdDbDictionary();
OdDbObjectID dicID;
pNamedDict->setAt(“USER_DIC”,pDic,dicID);
//3.創建擴展記錄,并加入到用戶對象字典中。
OdDbXRecord * pRec= new OdDbXRecord();
OdDbObjectID recID;
pDic->setAt(“DIC_REC1”,pRec,recID);
//4。創建擴展數據緩沖區,并加入到擴展記錄中。
Struct_resBuf* pHead= NULL;
//創建鏈表數據
//(數據類型,值)數據對形成鏈表
pHead= buildlist(OdDb::kDxfText,“圖號:01-05”,
OdDb::kDxfText,“材料:鑄鐵”,
OdDb::kDxfText,“數量:3件”,
OdDb::kDxfReal,,…… ,
0);
//將緩沖區存到擴展記錄中。
pRec->setFromRbChain(*pHead);
……
用戶對象(Object)/實體(Entity)
在ACAD數據庫中,用戶自定義對象為不可見的數據對象,從 OdDbObject類派生,新建的用戶對象,不需作為塊表記錄加到塊表中,通常只加到用戶對象字典; 自定義實體為可見的幾何對象,從OdDbEntity派生(該類實際上也是OdDbObject的子類),新建用戶實體時,除加到用戶對象字典外,還需加到塊表中。
在使用用戶定義對象前,必須先調用類的虛接口rxInit()對用戶類進行初始化.
xInit()函數內部完成如下幾項工作:
1. 登記用戶類
2. 創建類描述符對象
3. 將類描述符對象加入類字典(OdrxClassDictionary,專為存放用戶類信息)。
(在ObjectARX中,初始化時還調用了acarBuildClassHieranchy()函數將新類添加到ACAD系統的類層次結構中)。
如:
void ExCustObjsModule::initApp()
{
ExCustObject::rxInit();
ExCustEntity::rxInit();
ExSphere::rxInit();
}
另外在定義用戶對象/實體的頭文件和實現文件中,分別利用如下兩個宏,以協助xInit()函數完成用戶類的登記及相關工作。
//頭文件
ODDB_DECLARE_MEMBERS(ExCustObject);
//定義文件
ODRX_DXF_DEFINE_MEMBERS(ExCustObject,
OdDbObject,
DBOBJECT_CONSTR,
OdDb::vAC15,
OdDb::kMRelease0,
0,
EXCUSTOBJECT,
ExCustObjs|Description: DWGdirect Run-time Extension Example)
在定義時,不論是定義用戶對象還是定義用戶實體,都必須重載如下四個虛接口:
/** Description: Reads the DWG data of this object.
Arguments: pFiler (I) Filer object from which data are read.
Remarks: Returns the filer status
This function is called by dwgIn() to allow the object to read its data.
When overriding this function:
1) Call assertWriteEnabled().
2) Call the parent class's dwgInFields(pFiler).
3) If it returns eOK, continue; otherwise return whatever the parent's dwgInFields(pFiler) returned.
4) Call the OdDbDwgFiler(pFiler) methods to read each of the object's data items in the order they were written.
5) Return pFiler->filerStatus().
*/
virtual OdResult dwgInFields( OdDbDwgFiler* pFiler);
/**Description: Writes the DWG data of this object.
Arguments: pFiler (I) Pointer to the filer to which data are written.
Remarks: Returns the filer status.
This function is called by dwgIn() to allow the object to write its data.
When overriding this function:
1) Call assertReadEnabled().
2) Call the parent class's dwgOutFields(pFiler).
3) If it returns eOK, continue; otherwise return whatever the parent's dwgOutFields(pFiler) returned.
4) Call the OdDbDwgFiler(pFiler) methods to write each of the object's data items in the order they were written.
5) Return pFiler->filerStatus(). */
virtual OdResult dwgOutFields(OdDbDwgFiler* pFiler);
virtual OdResult dxfInFields(OdDbDxfFiler* pFiler);
virtual OdResult dxfOutFields(OdDbDxfFiler* pFiler);
另外,自定義對象和自定義實體根據實現不同的功能和需要,將重載不同的接口,:
1.自定義對象:
根據功能需要,可能需重載的函數
/** Description: Perform an *audit* operation on this object.
Arguments: pAuditInfo (I) Pointer to an OdDbAuditInfo object.
Remarks: When overriding this function for a custom class, first call OdDbObject::audit(pAuditInfo) to validate the *audit* operation. */
virtual void audit( OdDbAuditInfo* pAuditInfo);
/** Description: Called as the first operation as this object is being closed, for
*database* -resident objects only.
Remarks: This function is notified just before the current open operation is to be closed, giving this function the ability to cancel the close.
Returns Od::eOk if and only if close() is to continue.**/
virtual void subClose();
/** Description: Performs a deep *clone* of this object.
Arguments: ownerIdMap (I) Owner's ID map.
Remarks: Returns a smart pointer to the newly created *clone*,and adds a record to the specified ID map.**/
virtual OdDbObjectPtr deepClone(OdDbIdMapping& ownerIdMap) const;
/** Description: Performs a shallow *clone* of this object.
Arguments: ownerIdMap (I) Owner's ID map.
Remarks: Returns a smart pointer to the newly created *clone*, and adds a record to the specified ID map.*/
virtual OdDbObjectPtr wblockClone(OdDbIdMapping& ownerIdMap) const;
virtual OdResult subErase(bool erasing);
virtual void subHandOverTo( OdDbObject* newObject);
virtual void subOpen( OdDb::OpenMode mode);
virtual void subSwapIdWith( const OdDbObjectId& otherId, bool swapXdata = false, bool swapExtDict = false);
2.自定義實體
由于自定義實體,為可見對象,則必須重載如下接口:
//繪制自定義實體,用于實體的顯示
//模型空間的顯示
virtual bool worldDraw( OdGiWorldDraw* pWd) const;
//視圖關聯的顯示
virtual void viewportDraw( OdGiViewportDraw* pVd) const;
//當自定義實體作為代理對象保存時,則需重載saveas()接口(該接口在DWGdirect中未實現):
virtual void saveAs(OdGiWorldDraw* mode, OdDb::EntSaveAsType st);
/** Description: Returns the WCS geometric *extents* of this entity.
Arguments: extents (O) Receives the *extents*.
The *extents* are the WCS corner points of a box, aligned with the
WCS axes, that encloses the 3D *extents* of this entity. */
//包含實體的長方體的頂點,也即實體所占的空間
virtual OdResult getGeomExtents(
OdGeExtents3d& extents) const;
/* Description: Applies the 3D transformation matrix to this entity.
*/
virtual OdResult transformBy( const OdGeMatrix3d& xfm);
/** Description: Creates a copy of this entity, and applies the supplied transformation
to the newly created copy.
*/
virtual OdResult getTransformedCopy( const OdGeMatrix3d& xfm, OdDbEntityPtr& pCopy) const;
/** Description: Returns all grip points of this entity. */
virtual OdResult getGripPoints( OdGePoint3dArray& gripPoints ) const;
/** Description: Moves the specified grip points of this entity
Remarks: Each element in gripPoints has a corresponding entry in indices, which specifies the index of the grip point as returned by getGripPoints. */
virtual OdResult moveGripPointsAt( const OdGePoint3dArray& gripPoints,
const OdIntArray& indices );
/** Description: Explodes this entity into a set of simpler entities.
Note: Entities resulting from the explosion are appended to the specified array.
The newly created entities are not *database* resident.
The default implementation of this function returns eNotApplicable. This f unction can be overridden in custom classes. */
virtual OdResult explode(OdRxObjectPtrArray& entitySet) const;
//高亮顯示,DWGdirect未實現.
virtual void highlight(const OdDbFullSubentPath& subId = OdDb::kNullSubent,
const bool highlightAll = false) const;
virtual void unhighlight(const OdDbFullSubentPath& subId = kNullSubent,
const bool highlightAll = false) const;
根據需要,可能要重載的函數
/** Description: Returns all appropriate object snap points of this entity.
osnapMode will be one of the following: */
virtual OdResult getOsnapPoints(
OdDb::OsnapMode osnapMode,
int gsSelectionMark,
const OdGePoint3d& pickPoint,
const OdGePoint3d& lastPoint,
const OdGeMatrix3d& viewXform,
const OdGeMatrix3d& ucs,
OdGePoint3dArray& snapPoints ) const;
/** Description: Returns all stretch points of this entity. */
virtual OdResult getStretchPoints( OdGePoint3dArray& stretchPoints ) const;
/** Description: Moves the specified stretch points of this entity.
virtual OdResult moveStretchPointsAt( const OdGePoint3dArray& stretchPoints,
const OdIntArray& indices );
3.用戶對象簡單示例:
//聲明自定義對象
class EXCUSTOBJEXPORT ExCustObject : public OdDbObject
{
static const int lastKnownVersion;
UINT m_nCustValue;
public:
// Macro to declare
ODDB_DECLARE_MEMBERS(ExCustObject);
ExCustObject();
virtual ~ExCustObject();
static int getVersion();
// Methods to override
OdResult dwgInFields(OdDbDwgFiler* pFiler);
void dwgOutFields(OdDbDwgFiler* pFiler) const;
OdResult dxfInFields(OdDbDxfFiler* pFiler);
void dxfOutFields(OdDbDxfFiler* pFiler) const;
};
//定義
ODRX_DXF_DEFINE_MEMBERS(ExCustObject,
OdDbObject,
DBOBJECT_CONSTR,
OdDb::vAC15,
OdDb::kMRelease0,
0,
EXCUSTOBJECT,
ExCustObjs|Description: DWGdirect Run-time Extension Example)
const int ExCustObject::lastKnownVersion = 2;
//讀
OdResult ExCustObject::dwgInFields(OdDbDwgFiler* pFiler)
{
OdDbObject::dwgInFields(pFiler);
m_nCustValue = pFiler->rdInt32();
return eOk;
}
//寫
void ExCustObject::dwgOutFields(OdDbDwgFiler* pFiler) const
{
OdDbObject::dwgOutFields(pFiler);
pFiler->wrInt32(m_nCustValue);
}
4.用戶實體簡單示例:
//聲明自定義實體
class EXCUSTOBJEXPORT ExCustEntity : public OdDbCircle
{
static const OdInt16 lastKnownVersion;
OdInt16 m_nCount;
public:
// Macro to declare
ODDB_DECLARE_MEMBERS(ExCustEntity);
ExCustEntity();
virtual ~ExCustEntity();
// Methods to override
//讀寫
OdResult dwgInFields(OdDbDwgFiler* pFiler);
void dwgOutFields(OdDbDwgFiler* pFiler) const;
OdResult dxfInFields(OdDbDxfFiler* pFiler);
void dxfOutFields(OdDbDxfFiler* pFiler) const;
//繪制
bool worldDraw(OdGiWorldDraw * pWd) const;
};
//定義
ODRX_DXF_DEFINE_MEMBERS(ExCustEntity,
OdDbCircle,
DBOBJECT_CONSTR,
OdDb::vAC15,
OdDb::kMRelease0,
OdDbProxyEntity::kAllAllowedBits,
EXCUSTENTITY,
ExCustObjs|Description: DWGdirect Run-time Extension Example)
const OdInt16 ExCustEntity::lastKnownVersion = 1;
OdResult ExCustEntity::dwgInFields(OdDbDwgFiler* pFiler)
{
OdResult res = OdDbCircle::dwgInFields(pFiler);
if (res != eOk)
{
return res;
}
m_nCount = pFiler->rdInt16();
return eOk;
}
void ExCustEntity::dwgOutFields(OdDbDwgFiler* pFiler) const
{
OdDbCircle::dwgOutFields(pFiler);
pFiler->wrInt16(m_nCount);
}
//繪制實體
bool ExCustEntity::worldDraw(OdGiWorldDraw * pWd) const
{
assertReadEnabled();
OdGePoint3d ptCenter(center());
OdGeVector3d vNormal(normal());
double dRadius = radius();
int nCount = m_nCount;
OdDbHatchPtr pHatch = OdDbHatch::createObject();
// Set the hatch properties.
pHatch->setPropertiesFrom(this);
pHatch->setAssociative(false);
pHatch->setPattern(OdDbHatch::kPreDefined, "ANGLE");
pHatch->setHatchStyle(OdDbHatch::kNormal);
pHatch->setNormal(vNormal);
pHatch->setElevation(ptCenter.z);
EdgeArray edgePtrs;
if (nCount < 1)
{
pWd->geometry().circle(ptCenter, dRadius, vNormal);
OdGeCircArc2d *cirArc = new OdGeCircArc2d(OdGePoint2d(ptCenter.x, ptCenter.y), dRadius);
edgePtrs.append(cirArc);
pHatch->appendLoop(OdDbHatch::kDefault, edgePtrs);
}
else
{
OdGeVector3d vDisp(radius(), 0., 0.);
double step = Oda2PI / nCount;
while (nCount--)
{
OdGePoint3d ptC(ptCenter + vDisp);
pWd->geometry().circle(ptC, dRadius, vNormal);
vDisp.rotateBy(step, vNormal);
OdGeCircArc2d *cirArc = new OdGeCircArc2d(OdGePoint2d(ptC.x, ptC.y), dRadius);
edgePtrs.resize(0);
edgePtrs.append(cirArc);
pHatch->appendLoop(OdDbHatch::kDefault, edgePtrs);
}
}
pHatch->worldDraw(pWd);
return true;
}
代理對象/實體(OdDbProxyObject/OdDbProxyEntity)
代理對象/實體是AutoCad在內存中創建的,作為自定義對象/實體的一個代理數據容器。當AUTOCAD讀取一個包含不可能實例化的用戶自定義對象/實體的文件時(也就是定義用戶對象/實體的二次開發模塊未加載),ACAD就自動為自定義實體和對象創建代理對象/實體。但如果加載了可以實例化自定義對象的二次開發模塊后,代理對象/實體就可恢復為自定義對象/實體。代理通常存在于系統的內存中,只是個中間過渡數據。
可以將代理對象/實體看成一個包含用戶對象的塊包,就是對用戶對象屬性和數據的一個封裝。寫入文件時,如果二次開發模塊未加載,代理包就自動進行串行化保存,通常情況下,寫入的數據與讀取的數據一致,不包含代理對象的數據,如果保存前后文件類型不同時(dwg\dxf),寫入時將整個代理對象數據寫到文件中。
代理實體顯示
如果二次開發模塊未加載,ACAD就不能使用自定義實體的worldDraw()或viewportDraw()函數來顯示代理實體,但可以利用自定義實體的圖形元文件中的信息,這些信息包含實體最后一次保存文件時,繼承于worldDraw()函數或saveAs()函數的數據。顯示格式分:實體和邊界框兩種。
五種坐標系
1.世界坐標系(WCS)
是其它坐標系的參照坐標系,其他坐標系都相對于它定義的(是種概念坐標系.)
2.用戶坐標系(UCS)
是一種工作坐標系,通常,ACAD內部存儲或參數傳遞的點都是UCS坐標點.
3.實體坐標(ECS)
為了減少存儲空間,而設置的坐標系,在ACAD中,不能直接該坐標的點,必須先轉換成UCS點.
4.顯示坐標系(DCS).
5.圖紙空間坐標系(PSDCS).
視圖、視口
圖形屏幕上用于顯示圖形的一個矩形區域稱為視口,通常可以把整個圖形屏幕作為一個視口,也可以將屏幕設置成多個視口。視口中的圖形稱為視圖。利用視圖管理技術,可以把當前視口中復雜的圖形按不同的窗口大小設置,并以視圖名為標識保存在數據庫中。在需要時,顯示指定視圖以滿足對圖形編輯和瀏覽的需求。
視圖作為視圖表OdDbViewTable中一條視圖記錄OdDbViewTableRecord保存在數據庫中。把當前視口中指定窗口內的圖形定義為一個新的視圖操作過程如下:
1.創建視圖類對象OdDbViewTableRecord
2.設置視圖屬性:名、中心點、高、寬
3.獲得視圖表OdDbViewTable指針。并將視圖記錄加入其中。
附加
三維實體造型
ACAD三維造型包括線框模型、表面模型和實體模型三種形式。ACADR14版本后,三維造型核心采用ACIS(Amercian Committee for Interoperable)平臺來生成和編輯三維實體。
基本三維實體生成方法
三維實體屬于OdDb3dSolid類對象。對于一個具體的幾何實體,即ACIS對象來說,OdDb3dSolid是個容器和接口,通過其接口可生成基本的三維實體及實體的布爾運算。
基本三維實體指:長方體Box、平截頭體Frustum、球體Sphere、圓環體Torus、鍥體Wedge等。
1、 長方體
createBox()
參數:長、寬、高。生成長方體中心為WCS的原點。
2、 平截頭體(圓柱、圓錐、橢圓錐)
createFrustum()
參數:高度、X半徑、Y半徑、頂端半徑
XY半徑相同,頂端半徑為0,則為圓錐體。
XY半徑不相等,頂端半徑為0,則為橢圓錐。
頂端半徑不為0,則為圓柱或橢圓柱。
3、 球體
createSphere()
參數:球體半徑。
4、 圓環體
createTorus()
質心在WCS原點,Z軸為中心軸。
參數:圓環半徑和圓管半徑。
5、 契體
CreateWedge()
長寬高分別與XYZ軸平行。
參數:長、寬、高
有上述函數可創建中心點在WCS原點的簡單實體。要將實體在指定位置生成,則必須進行坐標變換。如,方向矢量:
OdGeVector3d X(1,0,0),Y(0,1,0),Z(0,0,1)
表示所定義的新坐標系統與原WCS坐標系統的XYZ軸平行。
三維變換矩陣是用OdDbMatrix3d類的成員函數:
OdDbMatrix3d& setCoordSystem{
Const OdDbPoint& origin,
Const OdDbVector3d& e0,
Const OdDbVector3d& e1,
Const OdDbVector3d& e2
}
參數:
Origin表示新坐標系統的原點。
e0\e1\e2表示XYZ坐標軸的方向矢量
(一個矩陣可看成一個新坐標系統的表示形式,由新的坐標原點和XYZ坐標軸方向矢量構成一個矩陣,也即一個新的坐標系統,根據新的坐標系統,就可推算出實體新的坐標值)
變換
transformBy(const OdDbMatrix3d& xform)
該函數功能是將生成的三維實體按三維幾何變換矩陣變換。也就是將實體的控制點或特征點進行變換,其拓撲特性保持不變。
基于二維對象生成三維實體
在二維對象的基礎上,通常用拉伸(擠出)或旋轉的方法生成三維實體。
拉伸或擠出
是指在圓、橢圓或封閉多線段PloyLine等對象基礎上,按拉伸或擠出高或指定路徑生成三維實體。這種方法可以滿足一些簡單的實體造型:
1. 給定高度拉伸或擠出
Extrude{
Const OdDbRegion* pRegion,
Double height,
Double taper
}
Region表示面域對象的指針;
面域對象可以理解為由線條組成的一個封閉的區域。
Height高度
Taper錐角
2. 指定路徑拉伸或擠出
extrudeAlongPath{
const OdDbRegion* pRegion,
const OdDbCurve* path
}
Path為 擠出路徑,必須是 OdDbLine,OdDbArc,OdDbCircle,OdDbEllipse,OdDbSpline,OdDb2DployLine或非樣條擬合的OdDb3dPloyLine對象。
并、交、差。
旋轉
是指在圓、橢圓、封閉的二維多段線的基礎上按指定軸旋轉,從而生成三維實體。
Revolve{
Const OdDbRegion* pRegion,
Const OdGePoint3d& axisPoint,
Const OdGeVection3D& axisDir,
Double Angle
}
axisPoint軸上一點。
axisDir軸方向矢量。
Angle旋轉角度。
拉伸實體生成過程如下:
(凸度值:在生成多段線對象時,該值為0,表示線與線以直線相連接;為1,表示與弧線連接) 1.確定三維坐標點數組。
2.根據點,生成封閉的多段線,設置多線段法向矢量(0,0,1),通常于Z軸平行
3.根據多線段對象獲得封閉邊界線指針數組
4.根據封閉邊界,生成面域對象。
5.然后根據面域對象和高度,拉伸生成三維實體。
三維實體布爾運算
以上通過拉伸和旋轉只能生成簡單的實體,對于復雜的實體必須通過布爾運算才能實現。
1.并(UNION):求兩個或兩個以上實體的并集,即合并為一個實體
2.交(INTERSECTION):求兩個或兩個以上實體的交集,即生成實體的公共部分。
3.差(SUBTRACT):將一個實體集從另一個實體集減去。
布爾運算原型:
BooleanOper{
OdDb::BooleanOperType operator,
OdDb3dSolid *pSolid
}
Operator 取值為OdDb::kBoolUnion,OdDb::kBoolIntersect,OdDb::kBoolSubtract,分別表示并、交、差運算。
pSolid為參加布爾運算的實體指針。
復雜零件的造型
對于實體表面為空間曲面構成的零件,如斜齒輪的齒廓表面,對這類復雜的零件用簡單的并、交和差運算方法來造型難以達到要求,在這種情況下,宜采用機械加工的方法來構造零件的實體模型。步驟如下:
1.分別定義零件毛坯和加工刀具的OdDb3dSolid類對象。
2.利用變換矩陣將刀具移至毛坯位置。
3.調用booleanOper進行差運算,毛坯實體減去刀具實體,也就是除去被加工的部分
4.循環重復差運算,直到完成全部加工。
示例:蝸桿齒輪造型

刀具的生成:

OdDbPolyLine * poly = new OdDbPolyline();
For(int I =0; i<5;i++)
{
//pt2d[]為各頂點的數組
Poly->addVertexAt(I,pt2d[i],(i==3)?0.315:0,0,0)
//參數分別為頂點序號、坐標值、凸度值、起點和終點的寬度
//凸度值表示當前頂點與下一頂點的連接形式,0為直線連接,非0為圓 //弧連接,其值0.315為圓弧半徑。
}
Poly->setNormal((0,0,1));//設置方向矢量
經如上過程形成封閉多段線,隨后就可求出封閉邊界構成的面域對象,旋轉revolve()生成刀具實體。實現代碼略。
毛坯的生成:
通過圓拉伸造型,生成圓柱體,過程略。
初始狀態下,圓柱體的質心在WCS原點,Z軸為軸線,為便于運算,將其轉換為以X軸為軸線,則方向適量設置為:
OdDbVector3d x1(0,0,1),y1(0,1,0),z1(1,0,1)
繞X軸旋轉,則方向矢量相應設置為:
X1.set(1,0,0)
Y1.set(0,cos(a),sin(a));
Z1.set(0,-sin(a),cos(a))
a為旋轉角度。
加工造型過程:
刀具的移動和圓柱體的旋轉是通過變換矩陣實現,偽碼例如:
OdDb3dMatrix mat,mat1;
Mat.setCoordSystem(pt,x,y)
Mat.setCoordSystem(pt1,x1,y1)
//使圓柱體饒X軸旋轉
p3dSolid->transformBy(mat);
//使刀具移到加工位置
p3dSolid1->transformBy(mat1);
//減去加工刀具
p3dSolid->booleanOper(OdDb::kBoolSubtract, p3dSolid1);