Teigha BIMの多くの要素は、要素のジオメトリキャッシュであるGElementにB-Repジオメトリを含んでいます。しかし、B-Repは普遍的な形式ではありません。各製品にはB-Repの特定の表現があります。
B-RepとBIMの具体的な概要は、ドキュメント(ログインが必要)で確認できます。
OdaBimAppを使用したB-Repデータの出力
\Examples\TB_DevGuideCommandsフォルダにある_BrBrepDump_funcは、ドキュメントのサンプルであり、B-Repデータを出力するために使用できます。
- OdaBimAppを実行します
- DevGuideCommands.txをロードします
- BrBrepDumpコマンドを実行します(編集->登録済みコマンド->TBDevGuideCommands->BrBrepDump)
B-Repデータはコンソールに出力されます。
これはBIM B-Repのデータを解析する良い方法ですが、BIMデータ構造を考慮する必要があります。
BrBrepクラスの使用
BrBrepクラスは、異なるB-Rep表現のための一般的なインターフェースを提供します。
このインターフェースは、Teigha BIM、.dgnファイル(Siemens Parasolid®)、および.dwgファイル(Spatial ACIS®)に使用されます。これは顧客向けの一般的なインターフェースですが、各製品には製品固有のデータで動作する実装があります。インターフェースは内部データを必要なインターフェースに変換しますが、異なるTeigha製品の異なるB-Repデータに対して同じコードを使用できます。
\Examples\TB_DevGuideCommandsフォルダにある_BmBrepDump_funcは、BrBrepクラスの使用例です。
void _BmBrepDump_func(OdEdCommandContext* pCmdCtx)
{
OdBmCommandContextPtr pDbCmdCtx(pCmdCtx);
OdBmDatabasePtr pDb = pDbCmdCtx->database();
OdSmartPtr<OdEdBaseUserIO> pIO = pDbCmdCtx->userIO();
OdInt32 iHandle = pIO->getInt("Enter id of an element for dumping:", OdEd::kInpDefault, -1);
if (iHandle > -1)
{
// Get object
OdBmElementPtr pElem = pDb->getObjectId(OdDbHandle(OdUInt64(iHandle))).safeOpenObject();
// Get object's geometry
OdBmObjectPtr pGeom = pElem->getGeometry();
if (pGeom->isA() == OdBmGElement::desc())
{
OdBmGElement* pGElem = dynamic_cast<OdBmGElement*>(pGeom.get());
//Get nodes
OdBmGNodePtrArray nodes;
pGElem->getAllSubNodes(nodes);
//Test all nodes until OdBmGeometry found or all nodes verified
for (OdUInt32 iIdx = 0; iIdx < nodes.size(); ++iIdx)
{
if (nodes[iIdx]->isA() == OdBmGeometry::desc())
{
const OdBmGeometry* pGeometry = dynamic_cast<const OdBmGeometry*>(nodes[iIdx].get());
OdString message;
// Get faces
OdBmFacePtrArray faceNodes;
pGeometry->getFaces(faceNodes);
message.format(L"Number of faces is %x", faceNodes.size());
pIO->putString(message);
// Use Face Iterator to iterate all faces of the object
int faceNum = 0;
for (OdBmFacePtrArray::iterator faceIt = faceNodes.begin(); faceIt != faceNodes.end(); ++faceIt)
{
message.format(L"Face %x", faceNum);
pIO->putString(message);
faceNum++;
// Get first EdgeLoop of a face
OdBmFacePtr pFace = *faceIt;
OdBmGEdgeLoopPtr pFirstEdgeLoop = pFace->getFirstLoop();
if (pFirstEdgeLoop.isNull()) //it is possible
continue;
int loopNum = 0;
OdBmGEdgeLoopPtr pNextEdgeLoop = pFirstEdgeLoop;
while (!pNextEdgeLoop.isNull())
{
message.format(L" Loop %x", loopNum);
pIO->putString(message);
// Get first edge in loop
OdBmGEdgeBase* pNext = pNextEdgeLoop->getNext();
int edgeNum = 0;
while (!pNext->isLoop())
{
OdBmGEdge* pGEdge = dynamic_cast<OdBmGEdge*>(pNext);
bool bForvardDir = true;
int iEdgeForFace = 0;
{
OdBmFace* pFaceInt = pGEdge->getFacesItem(iEdgeForFace);
if (pFaceInt != pFace.get())
{
pFaceInt = pGEdge->getFacesItem(1);
if (pFaceInt == pFace.get())
{
bForvardDir = false;
iEdgeForFace = 1;
}
}
}
if (pGEdge->isFlipped())
bForvardDir = !bForvardDir;
// Get start and end points of the Edge
OdGePoint3dArray egepnts;
pGEdge->getFirstAndLastEdgeGePnts(egepnts);
if (bForvardDir)
message.format(L" Edge %i points: [%f , %f , %f], [%f , %f , %f]", edgeNum++, egepnts[0].x, egepnts[0].y, egepnts[0].z, egepnts[1].x, egepnts[1].y, egepnts[1].z);
else
message.format(L" Edge %i points: [%f , %f , %f], [%f , %f , %f]", edgeNum++, egepnts[1].x, egepnts[1].y, egepnts[1].z, egepnts[0].x, egepnts[0].y, egepnts[0].z);
pIO->putString(message);
// Go to next edge in loop
try
{
pNext = pGEdge->getNextItem(iEdgeForFace);
}
catch (const OdError& err)
{
message.format(L"%ls", err.description().c_str());
pIO->putString(message);
break;
}
}//while (!pNext->isLoop())
loopNum++;
pNextEdgeLoop = pNextEdgeLoop->getNextLoop();
}//while (!pNextEdgeLoop.isNull())
}//for (OdBmFacePtrArray::iterator faceIt = faceNodes.begin(); faceIt != faceNodes.end(); ++faceIt)
}//if (nodes[0]->isA() == OdBmGeometry::desc())
}//for (OdBmGNodePtrArray::const_iterator it = nodes.begin(); it != nodes.end(); ++it)
}//if (pGeom->isA() == OdBmGElement::desc())
}//if (iHandle > -1)
}