C ++ 03으로 작성된 작지만 강력한 단일 파일 웨이브 프론트 OBJ 로더. C ++ STL을 제외하고 의존성이 없습니다. 중간 정도의 기억과 시간으로 10m 다각형 이상을 구문 분석 할 수 있습니다.
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.x로 제공됩니다.
python Binding! 이전 기존 버전은 v0.9.x Branch에서 사용할 수 있습니다.

TinyoBjloader는 6m Triangles Rungholt 장면을 성공적으로로드 할 수 있습니다. http://casual-effects.com/data/index.html

TinyObjloader는 성공적으로 사용됩니다 ...
TINYOBJLOADER_USE_DOUBLE 통한 이중 정밀 지원
- 최신 그래픽이있는 3D 엔진python 폴더를 참조하십시오.f ) l ) p ) TinyoBjloader는 MIT 라이센스에 따라 라이센스가 부여됩니다.
한 가지 옵션은 단순히 헤더 파일을 프로젝트에 복사하고 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 vertex 데이터가 포함되어 있지 않지만 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 파일이있는 경우 tiny_obj_loader.h 에 포함되지 않도록 TINYOBJLOADER_DONOT_INCLUDE_MAPBOX_EARCUT mapbox/earcut.hpp 할 수 있습니다.
# 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 Upload는 Github Actions 및 Cirrus CI (ARM 빌드)에서 처리됩니다.
black 적용 ( python/sample.py )release . CI 빌드가 정상인지 확인하십시오.v 로 시작하여 태그 생성 (예 : v2.1.0 )git push --tags 단위 테스트는 tests 디렉토리에 제공됩니다. 자세한 내용은 tests/README.md 참조하십시오.