C ++ 03で記述された、小さくて強力な単一ファイル波面OBJローダー。 C ++ STLを除いて依存関係はありません。中程度のメモリと時間で100mを超えるポリゴンを解析できます。
tinyobjloader 、.objローダーを(グローバル照明)レンダラーに埋め込むのに適しています;-)
C99バージョンをお探しの場合は、https://github.com/syoyo/tinyobjloader-cをご覧ください。
master ( main )ブランチを使用することをお勧めします。そのV2.0リリース候補。現在、ほとんどの機能はほぼ堅牢で安定しています(リリースV2.0の残りのタスクは、C ++およびPython APIの研磨と組み込みの三角形のコードを修正します)。
2016年8月20日に新しいバージョンv1.0.0をリリースしました。古いバージョンはv0.9.x Branch https://github.com/syoyo/tinyobjloader/tree/v0.9.9として入手できます。
pythonフォルダーを参照してください。https://pypi.org/project/tinyobjloader/も参照)以前の古いバージョンは、 v0.9.xブランチで利用できます。

TinyObjloaderは、6mの三角形Rungholtシーンを正常にロードできます。 http://casual-effects.com/data/index.html

tinyobjloaderは、に正常に使用されています...
TINYOBJLOADER_USE_DOUBLEに感謝します
-modernグラフィックを備えた3Dエンジンpythonフォルダーを参照してください。f ) l ) p ) TinyOBJLoaderは、MITライセンスに基づいてライセンスされています。
1つのオプションは、ヘッダーファイルをプロジェクトに単純にコピーし、 TINYOBJLOADER_IMPLEMENTATIONが正確に定義されていることを確認することです。
推奨される方法ではありませんが、VCPKG依存関係マネージャーを使用してTinyOBJLoaderをダウンロードしてインストールできます。
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
./bootstrap-vcpkg.sh
./vcpkg integrate install
./vcpkg install tinyobjloader
VCPKGのTinyOBJLoaderポートは、Microsoftチームのメンバーとコミュニティの貢献者によって最新の状態に保たれています。バージョンが古くなっている場合は、VCPKGリポジトリに問題を作成するか、リクエストをプルしてください。
attrib_tには、頂点データの単一および線形配列(位置、通常、およびTexcoord)が含まれています。
attrib_t::vertices => 3 floats per vertex
v[0] v[1] v[2] v[3] v[n-1]
+-----------+-----------+-----------+-----------+ +-----------+
| x | y | z | x | y | z | x | y | z | x | y | z | .... | x | y | z |
+-----------+-----------+-----------+-----------+ +-----------+
attrib_t::normals => 3 floats per vertex
n[0] n[1] n[2] n[3] n[n-1]
+-----------+-----------+-----------+-----------+ +-----------+
| x | y | z | x | y | z | x | y | z | x | y | z | .... | x | y | z |
+-----------+-----------+-----------+-----------+ +-----------+
attrib_t::texcoords => 2 floats per vertex
t[0] t[1] t[2] t[3] t[n-1]
+-----------+-----------+-----------+-----------+ +-----------+
| u | v | u | v | u | v | u | v | .... | u | v |
+-----------+-----------+-----------+-----------+ +-----------+
attrib_t::colors => 3 floats per vertex(vertex color. optional)
c[0] c[1] c[2] c[3] c[n-1]
+-----------+-----------+-----------+-----------+ +-----------+
| x | y | z | x | y | z | x | y | z | x | y | z | .... | x | y | z |
+-----------+-----------+-----------+-----------+ +-----------+
各shape_t::mesh_tは頂点データが含まれていませんが、 attrib_tの配列インデックスが含まれています。詳細については、 loader_example.ccを参照してください。
mesh_t::indices => array of vertex indices.
+----+----+----+----+----+----+----+----+----+----+ +--------+
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-1) |
+----+----+----+----+----+----+----+----+----+----+ +--------+
Each index has an array index to attrib_t::vertices, attrib_t::normals and attrib_t::texcoords.
mesh_t::num_face_vertices => array of the number of vertices per face(e.g. 3 = triangle, 4 = quad , 5 or more = N-gons).
+---+---+---+ +---+
| 3 | 4 | 3 | ...... | 3 |
+---+---+---+ +---+
| | | |
| | | +-----------------------------------------+
| | | |
| | +------------------------------+ |
| | | |
| +------------------+ | |
| | | |
|/ |/ |/ |/
mesh_t::indices
| face[0] | face[1] | face[2] | | face[n-1] |
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
| i0 | i1 | i2 | i3 | i4 | i5 | i6 | i7 | i8 | i9 | ... | i(n-3) | i(n-2) | i(n-1) |
+----+----+----+----+----+----+----+----+----+----+ +--------+--------+--------+
tinyobj::LoadObj()引数でtriangulateフラグが真である場合、 num_face_verticesはすべて3(三角形)で満たされていることに注意してください。
TinyOBJLoaderは、フローティングポイントデータ型にreal_t使用するようになりました。デフォルトはfloat(32bit)です。 TINYOBJLOADER_USE_DOUBLE defineを使用して、 double(64bit)精度を有効にすることができます。
triangulation (デフォルトが有効になっている)を有効にすると、tinyobjloaderの三角形のポリゴン(4つ以上の頂点がある顔)。
組み込みの三角測量コードは、あるポリゴンの形状ではうまく機能しない場合があります。
mapbox/earcut.hppを使用して、堅牢な三角形分割のためにTINYOBJLOADER_USE_MAPBOX_EARCUTを定義できます。ただし、C ++ 11コンパイラが必要です。また、 mapbox/earcut.hppプロジェクトにコピーする必要があります。プロジェクトに独自のmapbox/earcut.hppファイルが含まれている場合は、 TINYOBJLOADER_DONOT_INCLUDE_MAPBOX_EARCUT定義して、 mapbox/earcut.hppがtiny_obj_loader.hの内部に含まれていないように定義できます。
# define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
// Optional. define TINYOBJLOADER_USE_MAPBOX_EARCUT gives robust triangulation. Requires C++11
// #define TINYOBJLOADER_USE_MAPBOX_EARCUT
# include " tiny_obj_loader.h "
std::string inputfile = " cornell_box.obj " ;
tinyobj:: attrib_t attrib;
std::vector<tinyobj:: shape_t > shapes;
std::vector<tinyobj:: material_t > materials;
std::string warn;
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, inputfile.c_str());
if (!warn.empty()) {
std::cout << warn << std::endl;
}
if (!err.empty()) {
std::cerr << err << std::endl;
}
if (!ret) {
exit ( 1 );
}
// Loop over shapes
for ( size_t s = 0 ; s < shapes.size(); s++) {
// Loop over faces(polygon)
size_t index_offset = 0 ;
for ( size_t f = 0 ; f < shapes[s]. mesh . num_face_vertices . size (); f++) {
size_t fv = size_t (shapes[s]. mesh . num_face_vertices [f]);
// Loop over vertices in the face.
for ( size_t v = 0 ; v < fv; v++) {
// access to vertex
tinyobj:: index_t idx = shapes[s]. mesh . indices [index_offset + v];
tinyobj:: real_t vx = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 0 ];
tinyobj:: real_t vy = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 1 ];
tinyobj:: real_t vz = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 2 ];
// Check if `normal_index` is zero or positive. negative = no normal data
if (idx. normal_index >= 0 ) {
tinyobj:: real_t nx = attrib. normals [ 3 * size_t (idx. normal_index )+ 0 ];
tinyobj:: real_t ny = attrib. normals [ 3 * size_t (idx. normal_index )+ 1 ];
tinyobj:: real_t nz = attrib. normals [ 3 * size_t (idx. normal_index )+ 2 ];
}
// Check if `texcoord_index` is zero or positive. negative = no texcoord data
if (idx. texcoord_index >= 0 ) {
tinyobj:: real_t tx = attrib. texcoords [ 2 * size_t (idx. texcoord_index )+ 0 ];
tinyobj:: real_t ty = attrib. texcoords [ 2 * size_t (idx. texcoord_index )+ 1 ];
}
// Optional: vertex colors
// tinyobj::real_t red = attrib.colors[3*size_t(idx.vertex_index)+0];
// tinyobj::real_t green = attrib.colors[3*size_t(idx.vertex_index)+1];
// tinyobj::real_t blue = attrib.colors[3*size_t(idx.vertex_index)+2];
}
index_offset += fv;
// per-face material
shapes[s]. mesh . material_ids [f];
}
}
# define TINYOBJLOADER_IMPLEMENTATION // define this in only *one* .cc
// Optional. define TINYOBJLOADER_USE_MAPBOX_EARCUT gives robust triangulation. Requires C++11
// #define TINYOBJLOADER_USE_MAPBOX_EARCUT
# include " tiny_obj_loader.h "
std::string inputfile = " cornell_box.obj " ;
tinyobj::ObjReaderConfig reader_config;
reader_config.mtl_search_path = " ./ " ; // Path to material files
tinyobj::ObjReader reader;
if (!reader.ParseFromFile(inputfile, reader_config)) {
if (!reader. Error (). empty ()) {
std::cerr << " TinyObjReader: " << reader. Error ();
}
exit ( 1 );
}
if (!reader.Warning().empty()) {
std::cout << " TinyObjReader: " << reader. Warning ();
}
auto & attrib = reader.GetAttrib();
auto & shapes = reader.GetShapes();
auto & materials = reader.GetMaterials();
// Loop over shapes
for ( size_t s = 0 ; s < shapes.size(); s++) {
// Loop over faces(polygon)
size_t index_offset = 0 ;
for ( size_t f = 0 ; f < shapes[s]. mesh . num_face_vertices . size (); f++) {
size_t fv = size_t (shapes[s]. mesh . num_face_vertices [f]);
// Loop over vertices in the face.
for ( size_t v = 0 ; v < fv; v++) {
// access to vertex
tinyobj:: index_t idx = shapes[s]. mesh . indices [index_offset + v];
tinyobj:: real_t vx = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 0 ];
tinyobj:: real_t vy = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 1 ];
tinyobj:: real_t vz = attrib. vertices [ 3 * size_t (idx. vertex_index )+ 2 ];
// Check if `normal_index` is zero or positive. negative = no normal data
if (idx. normal_index >= 0 ) {
tinyobj:: real_t nx = attrib. normals [ 3 * size_t (idx. normal_index )+ 0 ];
tinyobj:: real_t ny = attrib. normals [ 3 * size_t (idx. normal_index )+ 1 ];
tinyobj:: real_t nz = attrib. normals [ 3 * size_t (idx. normal_index )+ 2 ];
}
// Check if `texcoord_index` is zero or positive. negative = no texcoord data
if (idx. texcoord_index >= 0 ) {
tinyobj:: real_t tx = attrib. texcoords [ 2 * size_t (idx. texcoord_index )+ 0 ];
tinyobj:: real_t ty = attrib. texcoords [ 2 * size_t (idx. texcoord_index )+ 1 ];
}
// Optional: vertex colors
// tinyobj::real_t red = attrib.colors[3*size_t(idx.vertex_index)+0];
// tinyobj::real_t green = attrib.colors[3*size_t(idx.vertex_index)+1];
// tinyobj::real_t blue = attrib.colors[3*size_t(idx.vertex_index)+2];
}
index_offset += fv;
// per-face material
shapes[s]. mesh . material_ids [f];
}
}
最適化されたマルチスレッド.OBJローダーはexperimental/ディレクトリで利用できます。 .OBJデータをロードする絶対パフォーマンスが必要な場合、この最適化されたローダーは目的に適合します。最適化されたローダーはC ++ 11スレッドを使用し、エラーチェックが少ないが、ほとんどの.OBJデータが機能する可能性があることに注意してください。
ベンチマークの結果を次に示します。時間はMacBook 12(2016年初頭、Core M5 1.2GHz)で測定されます。
$ python -m pip install tinyobjloader
Python/sample.pyを参照してください。たとえば、tinyobjloaderのpython結合の使用。
各gitタグ付けイベントのCibuildwheels + Twineアップロードは、GithubアクションとCirrus CI(ARMビルド)で処理されます。
black pythonファイルに適用する( python/sample.py )releaseをプッシュします。 CIビルドが問題ないことを確認してください。vで始まるタグを作成します(例: v2.1.0 )git push --tagsユニットテストは、 testsディレクトリで提供されます。詳細については、 tests/README.mdを参照してください。