development of

Tieghaに関する備忘録とおまけ

【AutoCAD Mechanical】パーツ参照を作成する その1

パーツ参照の作成には AcmPartRef クラスを使用する

ObjectARX + AutoCAD_Mechanical_SDK を使用して、でモデル空間にパーツ参照を作成してみました。

パーツ参照を作成するまでの、一連の流れは次の通りです。

  1. パーツ参照オブジェクトを作成
  2. 標準規格を取得
  3. 部品表の標準規格を取得
  4. パーツ参照のデータの作成
  5. 部品表にパーツ参照のデータを追加

カニカル関連の図形には、標準規格のさまざまなデータを保持しているので、パーツ参照を作成するより、データを用意する方が面倒です…  

サンプルコード

AcGePoint3d pickPoint;
if (acedGetPoint(NULL, _T("\nパーツ参照を作成する位置を指定"), asDblArray(pickPoint)) != RTNORM) return;

AcDbDatabase *pDb = acdbHostApplicationServices()->workingDatabase();
AcDbTransactionManager *pTransMgr = pDb->transactionManager();

try
{
    AcTransaction *pTrans = pTransMgr->startTransaction();

    // パーツ参照を作成
    AcmPartRef *pPartRef = new AcmPartRef();
    pPartRef->setSymbolDefaults(pDb);
    pPartRef->setOrigin(pickPoint);

    // 現在の空間を取得
    AcDbBlockTableRecord *pCurSpace;
    pTrans->getObject((AcDbObject*&)pCurSpace, pDb->currentSpaceId(), AcDb::kForWrite);

    // パーツ参照を現在の空間に追加
    AcDbObjectId partRefId;
    if (pCurSpace->appendAcDbEntity(partRefId, pPartRef) != Acad::eOk)
    {
        delete pPartRef;
        pTransMgr->abortTransaction();
        return;
    }
    pTransMgr->addNewlyCreatedDBRObject(pPartRef);

    // 現在の標準規格のObjectIdを取得
    AcDbObjectId stdId;
    if (acmStdMgr->getCurrent(stdId) != Acm::eOk)
    {
        pTransMgr->abortTransaction();
        return;
    }

    // 現在の標準規格を取得
    AcmStandard *pStandard;
    if (pTrans->getObject((AcDbObject*&)pStandard, stdId, AcDb::kForRead) != Acad::eOk)
    {
        pTransMgr->abortTransaction();
        return;
    }

    // BOMの標準規格のObjectIdを取得
    AcDbObjectId bomStdId;
    if (pStandard->getCurrentSymbolStd(L"AcmBOMStd", bomStdId) != Acad::eOk)
    {
        pTransMgr->abortTransaction();
        return;
    }

    // BOMの標準規格を取得
    AcmBOMStd *pBOMStd;
    if (pTrans->getObject((AcDbObject*&)pBOMStd, bomStdId, AcDb::kForRead) != Acad::eOk)
    {
        pTransMgr->abortTransaction();
        return;
    }

    // パーツ参照のデータ
    CMapStringToString valueMap;
    int numOfItems = 1;

    // 標準規格の列数だけループ
    for (int i = 0; i < pBOMStd->columnLength(); i++)
    {
        // 列を取得
        const AcmCColumnDef *pColumn = ((const AcmBOMStd*)pBOMStd)->column(i);
        switch (pColumn->type())
        {
        case Acm::kQuantity:
            // 数量を設定
            valueMap.SetAt(pColumn->name(), std::to_wstring(numOfItems).c_str());
            break;
        default:
            // その他の値を設定
            valueMap.SetAt(pColumn->name(), _T(""));
            break;
        }
    }

    // 部品表にパーツ参照のデータをセット
    acmBomMgr->setPartData(partRefId, numOfItems, valueMap);

    pTransMgr->endTransaction();
}
catch (...)
{
    pTransMgr->abortTransaction();
}

実行結果

結果はこのような感じで、パーツ参照のみ作成された状態です。

f:id:tknmt:20190311171607p:plain

部品表にも新しい行が追加されています。

f:id:tknmt:20190311171742p:plain