天天看點

2.4、在ObjectARX中建立對象

這節将介紹如何在ObjectARX中建立上一節在AutoCAD中建立的相同實體,一個線,一個圓,建立一個圖層的代碼,改變一條線的顔色,添加一個組到組字典當中去。

1、建立實體

下面的代碼建立一條直線,并且将它添加到模型資料庫的塊表記錄當中。(其中的注釋為譯者加注)

AcDbObjectId
createLine()
{
    AcGePoint3d startPt(4.0, 2.0, 0.0);//起點坐标 x:4.0 y:2.0 z:0.0
    AcGePoint3d endPt(10.0, 7.0, 0.0);//終點坐标
    AcDbLine *pLine = new AcDbLine(startPt, endPt);

    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()//獲得目前資料庫
        ->getSymbolTable(pBlockTable, AcDb::kForRead);//獲得資料庫的塊表

    AcDbBlockTableRecord *pBlockTableRecord;
    pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,//獲得模型空間的記錄
        AcDb::kForWrite);
    pBlockTable->close();

    AcDbObjectId lineId;
    pBlockTableRecord->appendAcDbEntity(lineId, pLine);//将實體添加到塊表記錄中去

    pBlockTableRecord->close();
    pLine->close();

    return lineId;//傳回實體的ID
}
           

這個函數首先獲得目前圖紙的塊表。然後以寫模式打開模型空間的塊表記錄,然後添加實體到塊表記錄中。(譯注:實體添加到資料庫後調用close關閉,由資料庫管理,不用删除。同樣獲得了資料庫的指針後,最後都需調用close關閉指針,讓資料庫接手管理)

提示:當你使用完任何ObjectARX對象後,都應該盡可能早的關閉它。

下面的函數createCircle函數建立一個圓,并将其添加到資料庫。

AcDbObjectId
createCircle()
{
    AcGePoint3d center(9.0, 3.0, 0.0);//圓的中心點
    AcGeVector3d normal(0.0, 0.0, 1.0);//圓的法向量
    AcDbCircle *pCirc = new AcDbCircle(center, normal, 2.0);//半徑為2.0

    AcDbBlockTable *pBlockTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pBlockTable, AcDb::kForRead);

    AcDbBlockTableRecord *pBlockTableRecord;
    pBlockTable->getAt(ACDB_MODEL_SPACE, pBlockTableRecord,
        AcDb::kForWrite);
    pBlockTable->close();

    AcDbObjectId circleId;
    pBlockTableRecord->appendAcDbEntity(circleId, pCirc);

    pBlockTableRecord->close();
    pCirc->close();

    return circleId;
}
           

2、建立一個新的圖層

下面的代碼先獲得資料庫的圖層符号表然後建立一個新的圖層表記錄,并且命名為:ASDK_MYLAYER,然後添加到圖層符号表記錄中。

void
createNewLayer()
{
    AcDbLayerTable *pLayerTable;
    acdbHostApplicationServices()->workingDatabase()
        ->getSymbolTable(pLayerTable, AcDb::kForWrite);

    AcDbLayerTableRecord *pLayerTableRecord =
        new AcDbLayerTableRecord;
    pLayerTableRecord->setName("ASDK_MYLAYER");

    // Defaults are used for other properties of 
    // the layer if they are not otherwise specified.
    //
    pLayerTable->add(pLayerTableRecord);
    pLayerTable->close();
    pLayerTableRecord->close();
}
           

3、打開通路然後關閉ObjectARX對象

下面的代碼說明了當你無論什麼時候使用了資料庫内部對象後應該遵守的協定(當打開和關閉)。這個協定確定當你通路一個資料庫對象的時候它是在記憶體裡的,而當你不需要的時候寫到硬碟記憶體裡。在你能夠修改一個對象前,你需要打開它,用下面的這個函數:

acdbOpenObject(pObject, objId, AcDb::kForWrite);      

這個函數有個枚舉參數,用來限定你打開這個對象的用途,可以是隻讀,可寫,或者通知。其中當你以寫模式打開的時候,你可以修改這個對象。無論你用那種模式打開,當你不在使用這個對象的時候,你必須像下面一樣關閉這個對象:

pObject->close();      

下面的例子打開一個對象然後改變它的顔色:

Acad::ErrorStatus
changeColor(AcDbObjectId entId, Adesk::UInt16 newColor)
{
    AcDbEntity *pEntity;
    acdbOpenObject(pEntity, entId,
        AcDb::kForWrite);

    pEntity->setColorIndex(newColor);
    pEntity->close();

    return Acad::eOk;
}
           

有一些函數獲得對象的ID的時候同時也打開了這個對象,比如 AcDbBlockTable::getAt()函數。一個對象在添加到資料庫之前不能close,你擁有這個對象的控制,可以删除它。然而,一旦這個對象被添加到資料庫裡面了後,你就不能直接删除它了,要删除它,你可以調用它的基類函數AcDbObject::erase()來删除,這個函數标記一個對象被删除了,被标記删除的對象還存在在資料庫裡,直到這個資料庫對象消失。但是資料庫儲存的時候被标記删除的對象不會儲存(譯注:下次打開就沒有了)。

警告:直接删除一個被添加到資料庫中的對象會導緻AutoCAD立即結束程式。

4、添加一個組到組字典

下面的代碼建立一個組,這個組由AcDbObjectIdArray裡面的對象組成。然後将這個組添加到組字典中。注意組字典是如何打開,修改和關閉的。

void
createGroup(AcDbObjectIdArray& objIds, char* pGroupName)
{
    AcDbGroup *pGroup = new AcDbGroup(pGroupName);//建立組,名字為pGroupName

    for (int i = 0; i < objIds.length(); i++) {
        pGroup->append(objIds[i]);//組中添加對象
    }

    // Put the group in the group dictionary that resides
    // in the named object dictionary.
    //
    AcDbDictionary *pGroupDict;
    acdbHostApplicationServices()->workingDatabase()
        ->getGroupDictionary(pGroupDict, AcDb::kForWrite);//獲得組字典

    AcDbObjectId pGroupId;
    pGroupDict->setAt(pGroupName, pGroup, pGroupId);
    pGroupDict->close();
    pGroup->close();
}