OdDbジオメトリとSATデータをDirectShapeに変換する

この記事では、B-Reps(例:OdDb3dSolid、OdDbRegionなど)に基づくOdDbエンティティとSATデータをBimRv DirectShapeエンティティに変換する方法について説明します。

他の変換と同様に、OdBrepBuilderFiller を使用して変換が実行されます。ただし、OdDb エンティティのトポロジは DirectShape エンティティとは大きく異なります。DirectShape は周期的な面やエッジを許可しないため、完全な球体や完全な円のようなエンティティは不可能です。さらに、OdDb トポロジは分離ループを持つことができるため、シームエッジがなく、複雑な修正が必要です。変換は、ODA Solid Modeler の OdMdBody への中間変換を使用して実行されます。OdMdBody には OdDb と DirectShape の間に制限があります。周期的な面とエッジは許可しますが、分離ループは禁止し、シームエッジを必要とします。

色とマテリアルの変換

DirectShape には色がありませんが、代わりにマテリアルがあります。OdDb の面マテリアルは現在サポートされていませんが、面の色は RGB とカラーインデックスの両方でサポートされています。これらを変換するには、OdBaseMaterialAndColorHelper のインスタンスを OdBrepBuilderFiller に渡します。OdDb2BmMaterialAndColorHelper を使用して、.dwg ファイルから OdMdBody へ、および OdMdBody から DirectShape へエンティティを変換できます。SAT データを使用する場合、SAT から OdMdBody へ、および OdMdBody から DirectShape へ変換するために、それぞれ OdSat2MdForBmMaterialAndColorHelper と OdMd2BmFromSatMaterialAndColorHelper を使用できます。面の色はそのまま OdMdBody に変換されます。この色を持つ新しいマテリアルが DirectShape 用に作成されます。入力エンティティの色は、OdMdBody をバイパスして DirectShape に直接渡されます。

アルゴリズム

以下のセクションには、DirectShape への変換例が含まれています。

  1. 入力ファイルからOdBrBrepを取得します。
    .dwgファイルの場合、brep()メソッドを使用します。
    OdDbDatabasePtr pDwgDb = pHostApp->readFile(fileName);
    OdDbBlockTableRecordPtr pMs = pDwgDb->getModelSpaceId().safeOpenObject(OdDb::kForWrite);
    for (OdDbObjectIteratorPtr pObjIt = pMs->newIterator(); !pObjIt->done(); pObjIt->step())
    {
      OdDbEntityPtr inputEntity = pObjIt->entity();
      if (!inputEntity.isNull())
      {
        OdBrBrep brep;
        BrepType bType = kOpenShell;
        if (inputEntity->isA() == OdDbRegion::desc())
        {
          OdDbRegionPtr pBody = inputEntity;
          pBody->brep(brep);
        }
        /*other geometry types of OdDbEntity*/
    
        /*conversion*/
      }
    }
    SATファイルの場合、acisIn()メソッドを使用してOdDbEntityを取得するか、ISATConverterを使用します。
    for (unsigned idx = 0; idx < out.size(); ++idx)
    {
      OdBrBrep brep;
      ISATConverter* pIS = out[idx];
      brep.set(pIS->getIBr());
      /*conversion*/
    }
  2. OdBrepBuilderFillerを使用してOdBrBrepをOdMdBodyに変換します。
    OdBrepBuilder mdBrepBuilder;
    std::unique_ptr attribSetter(createDwgAttribSetter());
    initMDBrepBuilder(mdBrepBuilder, bType, attribSetter.get());
    
    OdGeMatrix3d mx;
    bool hasTransform = brep.getTransformation(mx);
    
    OdBrepBuilderFiller BBFiller;
    BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, OdBrepBuilderFillerParams::kBrepMd);
    OdResult res = BBFiller.initFrom(mdBrepBuilder, brep);
    if (res == eOk)
    {
      mdBrepBuilder.enableValidator(false);
      OdMdBodyResultPtr pMdBody;
      try
      {
        pMdBody = OdMdBodyResult::cast(mdBrepBuilder.finish());
      }
      catch (...)
      {
        res = eGeneralModelingFailure;
      }
    }
  3. OdMdBodyのトポロジをBimRv形式に変更し、新しいOdBrBrepを取得します。
    OdBrBrep mdBrep;
    if (eOk == res && !pMdBody.isNull())
    {
      if (hasTransform)
        res = transformMdBody(pMdBody, mx);
      if (eOk == res)
      {
        res = convertToBimRvFormat(pMdBody);
        if (eOk == res)
        {
          res = getBrepFromMdBody(pMdBody, mdBrep);
        }
      }
    }
  4. OdBrBrepをDirectShapeに変換し、BimRvデータベースに追加します。
    OdBrepBuilder bmBrepBuilder;
    res = pBmDb->appServices()->brepBuilder(bmBrepBuilder, bType);
    if (res == eOk)
    {
      BBFiller.params().setupFor(OdBrepBuilderFillerParams::kBrepAcisDwg, pDwgDb, pBmDb);
      res = BBFiller.initFrom(bmBrepBuilder, mdBrep, bmMaterialHelper);
      if (res == eOk)
      {
        try
        {
          OdBmGeometryPtr resultGeometry = OdBmGeometry::cast(bmBrepBuilder.finish());
          if (!resultGeometry.isNull())
          {
            OdArray aFaces;
            resultGeometry->getFaces(aFaces);
            OdArray aEdges;
            resultGeometry->getEdges(aEdges);
            if (aFaces.size() != 0 || aEdges.size() != 0) 
            {
              ODBM_TRANSACTION_BEGIN(t, pBmDb)
                t.start();
                 OdBmGNodePtrArray nodes;
                nodes.append(resultGeometry);
                OdBmDirectShapePtr pDirectShape = OdBmDirectShape::createObject();
                OdBmObjectId retId = pBmDb->addElement(pDirectShape);
                pDirectShape->setOwningElementId(pBmDb->getOwnerFamilyId());
                res = pDirectShape->setShape(nodes);
                t.commit();
              ODBM_TRANSACTION_END()
            }
          }
        }
        catch (...)
        {
          res = eGeneralModelingFailure;
        }
      }
    }

DwgDirectShapeImportEx および SatDirectShapeImportEx のサンプルはアーカイブに同梱されており、CommonApplications/BimRv ディレクトリにあります。これらのサンプルには、.dwg ファイル内の B-Rep エンティティまたは SAT ファイル内の SAT データに基づく OdDb エンティティを RVT または RFA ファイル内の DirectShape に変換するコードが含まれています。BimRv の入力データベースを取得するには、空の RFA または RVT ファイルが必要です。

今すぐ始める

ODAソフトウェアを60日間無料でお試しください。
リスクなし、クレジットカード不要。

無料で試す