OBJはWavefrontによって開発されたファイル形式で、3Dモデルの幾何学的定義を保存するためによく使用されます。主に異なる3Dアプリケーション間の交換形式として使用され、モデルの相互運用性のデファクトスタンダードの1つとなっています。多くの3Dモデルライブラリは、この中立的な形式でモデルをダウンロードするオプションを提供しています。
.objファイルに保存されたモデルは、.objファイルから参照される.mtlファイルで材料の詳細な仕様を付加することができます。これにより、OBJに変換した後もエクスポートされたモデルの表示が失われることはありません。材料は面に割り当てられ、.mtlファイルは常に.objファイルとは別になっているため、1つの.mtlファイルが多くの.objファイルから参照されることがあります。または、材料が不要な場合は、.mtlファイルを単に削除することもできます。Teighaを使用して.objファイルをインポートする機能は、人気のあるWebベースの3Dモデルライブラリ(またはメーカーのクローズドライブラリ)からの一連のモデルへのアクセスもユーザーに提供し、これらはたとえば、追加/装飾的なデザイン要素として図面内で迅速に使用できます。
OBJはオープンなテキスト形式であり、ファイルの構造は厳密に固定されていません。Web上にはいくつかの.objのバリエーションや方言さえ見られます。Teighaは、ファイルを読み込みおよび解析する際に、一般的な仕様からの発見されたすべての逸脱をサポートしようとします。
Teighaアプリケーションでのモジュールの使用
OBJのインポート/エクスポート機能は、Components/OBJToolkitディレクトリにあるComponentsライブラリの一部であるOBJToolkitプロジェクト内に実装されています。プロジェクトソリューション内のパスも同じです。Teighaユーザー向けには、単一のヘッダーファイルOBJToolkit.hが提供されており、これには.objおよび.mtlファイルでの作業を開始するためのすべてのインターフェース、変数、および定義が含まれています。デフォルトの.txモジュール名OdObjToolkitModuleName(「OBJToolkit.tx」)は、Kernel\Include\OdModuleNames.hヘッダー内に定義されており、このヘッダーを含めることで利用できます。ただし、モジュールのロードは、OBJToolkit.hにも実装されているloadObjToolkitModule()関数を呼び出すことで実行できます。以下に、アプリケーションで.objのサポートを開始する最も速い方法を示します。
OdObjToolkitModulePtr module = loadObjToolkitModule();
メインモジュールがエクスポートするOdObjToolkitModuleクラスには、いくつかのメソッドがあります。
- OdObjImportPtr createObjImporter() — OdObjDb構造(インポートされたジオメトリデータを保持)および関連するOdMtlDb(インポートされた.objファイルに割り当てられたマテリアル定義を格納)内の.objファイルローダーの実装であるオブジェクトを作成します。
- OdObjExportPtr createObjExporter() — 割り当てられたOdObjDb構造を.objファイルに保存できるオブジェクトを作成します。
- OdMtlImportPtr createMtlImporter() — マテリアル情報を含む.mtlファイルをOdMtlDbにロードできる、作成されたオブジェクトへのポインタを返します。
- OdMtlExportPtr createMtlExporter() — 割り当てられたOdMtlDbを.mtlファイルにエクスポートするオブジェクトへのポインタを作成して返します。
- OdResult exportObj(OdDbBaseDatabase *pDb, const OdGiDrawable *pEntity, const OdString &fileName, OdObjExportOptions *options = NULL) — 定義されたOdGiDrawableオブジェクトを.objファイルにエクスポートします。このメソッドは、ExCustObjs.txモジュール(Drawings/Examples)をロードした後、OdaMfcAppから呼び出すことができるExCustObjsサンプルコマンド「OBJExport」で使用されます。
- OdResult exportObj(OdDbBaseDatabase *pDb, const OdString &fileName, OdObjExportOptions *options = NULL) — 定義されたビューを.objファイルにエクスポートします。このメソッドは、Teigha Visualize Viewerからビューをエクスポートするためにも使用されます。
.objファイルがOdObjDbにインポートされると、インポートされたエンティティにアクセスするために次の構造を使用できます。
- グループ化は、.obj構文のタグ「g」(グループ)によって実行されます。各グループは、点群、ポリライン、曲線(現在はBスプライン曲線のみがサポートされています)、面などのオブジェクトを保持できます。たとえば、点群はポイントクラウドを定義するために使用できます。
- OBJ形式の観点から見ると、各面は個別のエンティティであるため、skipFaceパラメータがfalseの場合に作成されるOdObjEntityIteratorを使用して、ユーザーは各面に個別にアクセスできます。
グループのすべての面を単一のシェルに集めて複雑なメッシュモデルを取得する機能は、OdObjDbクラスのgetGroupShellメソッドにも実装されています。
要するに、Teighaにおける.objファイルオブジェクトモデルの階層は次のとおりです。
- OdObjDbは名前付きグループのセットを保持します。
- 各グループは複数のオブジェクト(点群、ポリライン、曲線、面)を保持します。
- グループのすべての面から単一のシェルを、OdObjDbのgetGroupShellメソッドを使用して作成できます。
.objファイルをインポートし、インポートされたすべてのグループとそのエンティティを走査するサンプルコードを次に示します(同様のコードはComponents/Visualize/Examples/Obj2Visualizeプロジェクトで見つけることができます)。
OdObjImportPtr pObjImporter = OBJToolkit::createObjImporter();
OdResult res = pObjImporter->importFile(filePath);
OdObjDbPtr pObjDb = pObjImporter->getObjDb();
OdString modelName = pObjImporter->getDrawingName();
OdObjGroupIteratorPtr itGroups = pObjDb->createGroupsIterator();
while (itGroups->done() == false)
{
OdObjGroupPtr pGroup = itGroups->element();
if (pGroup.isNull() == false && pGroup->isEmpty() == false)
{
if (eOk == pObjDb->getGroupShell(pGroup, vertices, texCoo, normals, faces, faceMtls) && faces.size() > 0)
{
// process shell data
}
// and walking through all other entities in the group
OdObjEntityIteratorPtr it = pGroup->createEntitiesIterator();
while (it->done() == false)
{
const OdObjGeomEntity *pEntity = it->element();
const eOBJEntType entType = pEntity->type();
switch (entType)
{
case eOBJEntPoints:
{
if (!pEntity->m_vind.isEmpty())
{
// process set of points
}
}
break;
case eOBJEntLine:
{
if (!pEntity->m_vind.isEmpty())
{
// process polyline
}
}
break;
case eOBJEntCurve:
{
// process curve
}
break;
}
it->step();
}
}
itGroups->step();
}
OBJを使えばすべてが非常にシンプルです!