この記事では、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 への変換例が含まれています。
- 入力ファイルからOdBrBrepを取得します。
.dwgファイルの場合、brep()メソッドを使用します。
SATファイルの場合、acisIn()メソッドを使用してOdDbEntityを取得するか、ISATConverterを使用します。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*/ } }for (unsigned idx = 0; idx < out.size(); ++idx) { OdBrBrep brep; ISATConverter* pIS = out[idx]; brep.set(pIS->getIBr()); /*conversion*/ } - 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; } } - 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); } } } - 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 ファイルが必要です。