Compare commits
55 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
934788785e | ||
|
|
e07a835f02 | ||
|
|
1cdfd786d8 | ||
|
|
803b65b8a0 | ||
|
|
50518a515b | ||
|
|
c9b1bccf97 | ||
|
|
1f17833657 | ||
|
|
bb58a8f8c3 | ||
|
|
b1f594d682 | ||
|
|
02df4943f9 | ||
|
|
826a892d0b | ||
|
|
68350e2fc7 | ||
|
|
7d20e9b901 | ||
|
|
fdc70abdc6 | ||
|
|
8a885e14b8 | ||
|
|
cd65de860b | ||
|
|
4924857fd3 | ||
|
|
1a7bdc6192 | ||
|
|
fd06fa49e4 | ||
|
|
0d68262246 | ||
|
|
0e950513a3 | ||
|
|
a4b115a584 | ||
|
|
bb3e27d4f3 | ||
|
|
c4e7e65acb | ||
|
|
eba327b9c0 | ||
|
|
3cbf45a572 | ||
|
|
6650dbf397 | ||
|
|
7befd59de4 | ||
|
|
c5b3139653 | ||
|
|
adb2309110 | ||
|
|
3edca81a75 | ||
|
|
7a88cddefc | ||
|
|
d541711a79 | ||
|
|
d1ce2082f6 | ||
|
|
8fd9f6e57b | ||
|
|
24bd8b49ff | ||
|
|
4a0e79985d | ||
|
|
64d1e3f883 | ||
|
|
a39a6b481c | ||
|
|
bce1bb8387 | ||
|
|
7fcfafb39a | ||
|
|
5eda671225 | ||
|
|
f95510b04b | ||
|
|
94f1dc15b3 | ||
|
|
a4eabf54b1 | ||
|
|
72c38f64d5 | ||
|
|
d174e625a2 | ||
|
|
707014f843 | ||
|
|
12837cc8b2 | ||
|
|
b85714b4cf | ||
|
|
e060b4f4aa | ||
|
|
2dca72724f | ||
|
|
72529f02fe | ||
|
|
16f3041c76 | ||
|
|
73e9b4dc3a |
@@ -129,6 +129,7 @@ int main(int argc, char **argv) {
|
||||
cb.object_cb = object_cb;
|
||||
|
||||
MyMesh mesh;
|
||||
std::string warn;
|
||||
std::string err;
|
||||
std::string filename = "../../models/cornell_box.obj";
|
||||
if (argc > 1) {
|
||||
@@ -143,7 +144,11 @@ int main(int argc, char **argv) {
|
||||
|
||||
tinyobj::MaterialFileReader mtlReader("../../models/");
|
||||
|
||||
bool ret = tinyobj::LoadObjWithCallback(ifs, cb, &mesh, &mtlReader, &err);
|
||||
bool ret = tinyobj::LoadObjWithCallback(ifs, cb, &mesh, &mtlReader, &warn, &err);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//
|
||||
// Stiches multiple .obj files into one .obj.
|
||||
//
|
||||
#include "../../tiny_obj_loader.h"
|
||||
#include "obj_writer.h"
|
||||
|
||||
#include "../../tiny_obj_loader.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
@@ -11,27 +12,59 @@
|
||||
|
||||
typedef std::vector<tinyobj::shape_t> Shape;
|
||||
typedef std::vector<tinyobj::material_t> Material;
|
||||
typedef tinyobj::attrib_t Attribute;
|
||||
|
||||
void
|
||||
StichObjs(
|
||||
tinyobj::attrib_t& out_attribute,
|
||||
std::vector<tinyobj::shape_t>& out_shape,
|
||||
std::vector<tinyobj::material_t>& out_material,
|
||||
const std::vector<Attribute>& attributes,
|
||||
const std::vector<Shape>& shapes,
|
||||
const std::vector<Material>& materials)
|
||||
{
|
||||
int numShapes = 0;
|
||||
for (size_t i = 0; i < shapes.size(); i++) {
|
||||
numShapes += (int)shapes[i].size();
|
||||
// The amount of attributes, shape-vectors and material-vecotrs should be the same.
|
||||
if(attributes.size() != shapes.size() && attributes.size() != materials.size()){
|
||||
std::cerr << "Size of attributes, shapes and Materials don't fit!" << attributes.size() << " " << shapes.size() <<" " << materials.size() << std::endl;;
|
||||
exit(1);
|
||||
}
|
||||
int num_shapes = 0;
|
||||
// 4 values (vertices, normals, texcoords, colors)
|
||||
std::vector<int> num_attributes(4, 0);
|
||||
int num_materials = 0;
|
||||
for(int i = 0; i < shapes.size(); i++){
|
||||
num_shapes += shapes[i].size();
|
||||
}
|
||||
for(int i = 0; i < attributes.size(); i++){
|
||||
num_attributes[0] += attributes[i].vertices.size();
|
||||
num_attributes[1] += attributes[i].normals.size();
|
||||
num_attributes[2] += attributes[i].texcoords.size();
|
||||
num_attributes[3] += attributes[i].colors.size();
|
||||
}
|
||||
for(int i = 0; i < materials.size(); i++){
|
||||
num_materials += materials[i].size();
|
||||
}
|
||||
|
||||
printf("Total # of shapes = %d\n", numShapes);
|
||||
int materialIdOffset = 0;
|
||||
// More performant, than push_back
|
||||
out_attribute.vertices.resize(num_attributes[0]);
|
||||
out_attribute.normals.resize(num_attributes[1]);
|
||||
out_attribute.texcoords.resize(num_attributes[2]);
|
||||
out_attribute.colors.resize(num_attributes[3]);
|
||||
out_shape.resize(num_shapes);
|
||||
out_material.resize(num_materials);
|
||||
|
||||
size_t face_offset = 0;
|
||||
int material_id_offset = 0;
|
||||
int shape_id_offset = 0;
|
||||
int vertex_idx_offset = 0;
|
||||
int normal_idx_offset = 0;
|
||||
int texcoord_idx_offset = 0;
|
||||
int color_idx_offset = 0;
|
||||
|
||||
// shapes.size() = attributes.size() = materials.size()
|
||||
for (size_t i = 0; i < shapes.size(); i++) {
|
||||
|
||||
// Copy shapes
|
||||
for (size_t k = 0; k < shapes[i].size(); k++) {
|
||||
|
||||
std::string new_name = shapes[i][k].name;
|
||||
// Add suffix
|
||||
char buf[1024];
|
||||
@@ -39,36 +72,51 @@ StichObjs(
|
||||
new_name += std::string(buf);
|
||||
|
||||
printf("shape[%ld][%ld].name = %s\n", i, k, shapes[i][k].name.c_str());
|
||||
assert((shapes[i][k].mesh.indices.size() % 3) == 0);
|
||||
assert((shapes[i][k].mesh.positions.size() % 3) == 0);
|
||||
|
||||
tinyobj::shape_t new_shape = shapes[i][k];
|
||||
// Add offset.
|
||||
for (size_t f = 0; f < new_shape.mesh.material_ids.size(); f++) {
|
||||
new_shape.mesh.material_ids[f] += materialIdOffset;
|
||||
// Add material offset.
|
||||
for(size_t f = 0; f < new_shape.mesh.material_ids.size(); f++) {
|
||||
new_shape.mesh.material_ids[f] += material_id_offset;
|
||||
}
|
||||
// Add indices offset.
|
||||
for(size_t f = 0; f < new_shape.mesh.indices.size(); f++){
|
||||
tinyobj::index_t& ref = new_shape.mesh.indices[f];
|
||||
if(ref.vertex_index > -1){
|
||||
ref.vertex_index += vertex_idx_offset;
|
||||
}
|
||||
if(ref.normal_index > -1){
|
||||
ref.normal_index += normal_idx_offset;
|
||||
}
|
||||
if(ref.texcoord_index > -1){
|
||||
ref.texcoord_index += texcoord_idx_offset;
|
||||
}
|
||||
}
|
||||
|
||||
new_shape.name = new_name;
|
||||
printf("shape[%ld][%ld].new_name = %s\n", i, k, new_shape.name.c_str());
|
||||
|
||||
out_shape.push_back(new_shape);
|
||||
out_shape[shape_id_offset++] = new_shape;
|
||||
}
|
||||
|
||||
materialIdOffset += materials[i].size();
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < materials.size(); i++) {
|
||||
// Copy materials
|
||||
for (size_t k = 0; k < materials[i].size(); k++) {
|
||||
out_material.push_back(materials[i][k]);
|
||||
}
|
||||
out_material[material_id_offset++] = materials[i][k];
|
||||
}
|
||||
|
||||
// Copy attributes (3 floats per vertex, 3 floats per normal, 2 floats per texture-coordinate, 3 floats per color)
|
||||
// You could also include a check here, if the sizes are dividable by 3 (resp. 2), but it's safe to simply assume, they do.
|
||||
std::copy(attributes[i].vertices.begin(), attributes[i].vertices.end(), out_attribute.vertices.begin() + vertex_idx_offset * 3);
|
||||
vertex_idx_offset += attributes[i].vertices.size() / 3;
|
||||
std::copy(attributes[i].normals.begin(), attributes[i].normals.end(), out_attribute.normals.begin() + normal_idx_offset * 3);
|
||||
normal_idx_offset += attributes[i].normals.size() / 3;
|
||||
std::copy(attributes[i].texcoords.begin(), attributes[i].texcoords.end(), out_attribute.texcoords.begin() + texcoord_idx_offset * 2);
|
||||
texcoord_idx_offset += attributes[i].texcoords.size() / 2;
|
||||
std::copy(attributes[i].colors.begin(), attributes[i].colors.end(), out_attribute.colors.begin() + color_idx_offset);
|
||||
color_idx_offset += attributes[i].colors.size();
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(
|
||||
int argc,
|
||||
char **argv)
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
if (argc < 3) {
|
||||
printf("Usage: obj_sticher input0.obj input1.obj ... output.obj\n");
|
||||
@@ -78,16 +126,16 @@ main(
|
||||
int num_objfiles = argc - 2;
|
||||
std::string out_filename = std::string(argv[argc-1]); // last element
|
||||
|
||||
std::vector<Shape> shapes;
|
||||
std::vector<Material> materials;
|
||||
shapes.resize(num_objfiles);
|
||||
materials.resize(num_objfiles);
|
||||
std::vector<Attribute> attributes(num_objfiles);
|
||||
std::vector<Shape> shapes(num_objfiles);
|
||||
std::vector<Material> materials(num_objfiles);
|
||||
|
||||
for (int i = 0; i < num_objfiles; i++) {
|
||||
std::cout << "Loading " << argv[i+1] << " ... " << std::flush;
|
||||
|
||||
std::string warn;
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(shapes[i], materials[i], err, argv[i+1]);
|
||||
bool ret = tinyobj::LoadObj(&attributes[i], &shapes[i], &materials[i], &warn, &err, argv[i+1]);
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
@@ -98,12 +146,13 @@ main(
|
||||
std::cout << "DONE." << std::endl;
|
||||
}
|
||||
|
||||
std::vector<tinyobj::shape_t> out_shape;
|
||||
std::vector<tinyobj::material_t> out_material;
|
||||
StichObjs(out_shape, out_material, shapes, materials);
|
||||
Attribute out_attribute;
|
||||
Shape out_shape;
|
||||
Material out_material;
|
||||
StichObjs(out_attribute, out_shape, out_material, attributes, shapes, materials);
|
||||
|
||||
bool coordTransform = true;
|
||||
bool ret = WriteObj(out_filename, out_shape, out_material, coordTransform);
|
||||
bool ret = WriteObj(out_filename, out_attribute, out_shape, out_material, coordTransform);
|
||||
assert(ret);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -30,6 +30,8 @@ bool WriteMat(const std::string& filename, const std::vector<tinyobj::material_t
|
||||
fprintf(fp, "Ke %f %f %f\n", mat.emission[0], mat.emission[1], mat.emission[2]);
|
||||
fprintf(fp, "Ns %f\n", mat.shininess);
|
||||
fprintf(fp, "Ni %f\n", mat.ior);
|
||||
fprintf(fp, "illum %d\n", mat.illum);
|
||||
fprintf(fp, "\n");
|
||||
// @todo { texture }
|
||||
}
|
||||
|
||||
@@ -38,7 +40,7 @@ bool WriteMat(const std::string& filename, const std::vector<tinyobj::material_t
|
||||
return true;
|
||||
}
|
||||
|
||||
bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform) {
|
||||
bool WriteObj(const std::string& filename, const tinyobj::attrib_t& attributes, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform) {
|
||||
FILE* fp = fopen(filename.c_str(), "w");
|
||||
if (!fp) {
|
||||
fprintf(stderr, "Failed to open file [ %s ] for write.\n", filename.c_str());
|
||||
@@ -48,17 +50,53 @@ bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>&
|
||||
std::string basename = GetFileBasename(filename);
|
||||
std::string material_filename = basename + ".mtl";
|
||||
|
||||
int v_offset = 0;
|
||||
int vn_offset = 0;
|
||||
int vt_offset = 0;
|
||||
int prev_material_id = -1;
|
||||
|
||||
fprintf(fp, "mtllib %s\n", material_filename.c_str());
|
||||
fprintf(fp, "mtllib %s\n\n", material_filename.c_str());
|
||||
|
||||
// facevarying vtx
|
||||
for (size_t k = 0; k < attributes.vertices.size(); k+=3) {
|
||||
if (coordTransform) {
|
||||
fprintf(fp, "v %f %f %f\n",
|
||||
attributes.vertices[k + 0],
|
||||
attributes.vertices[k + 2],
|
||||
-attributes.vertices[k + 1]);
|
||||
} else {
|
||||
fprintf(fp, "v %f %f %f\n",
|
||||
attributes.vertices[k + 0],
|
||||
attributes.vertices[k + 1],
|
||||
attributes.vertices[k + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// facevarying normal
|
||||
for (size_t k = 0; k < attributes.normals.size(); k += 3) {
|
||||
if (coordTransform) {
|
||||
fprintf(fp, "vn %f %f %f\n",
|
||||
attributes.normals[k + 0],
|
||||
attributes.normals[k + 2],
|
||||
-attributes.normals[k + 1]);
|
||||
} else {
|
||||
fprintf(fp, "vn %f %f %f\n",
|
||||
attributes.normals[k + 0],
|
||||
attributes.normals[k + 1],
|
||||
attributes.normals[k + 2]);
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// facevarying texcoord
|
||||
for (size_t k = 0; k < attributes.texcoords.size(); k += 2) {
|
||||
fprintf(fp, "vt %f %f\n",
|
||||
attributes.texcoords[k + 0],
|
||||
attributes.texcoords[k + 1]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < shapes.size(); i++) {
|
||||
|
||||
bool has_vn = false;
|
||||
bool has_vt = false;
|
||||
fprintf(fp, "\n");
|
||||
|
||||
if (shapes[i].name.empty()) {
|
||||
fprintf(fp, "g Unknown\n");
|
||||
@@ -66,101 +104,53 @@ bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>&
|
||||
fprintf(fp, "g %s\n", shapes[i].name.c_str());
|
||||
}
|
||||
|
||||
//if (!shapes[i].material.name.empty()) {
|
||||
// fprintf(fp, "usemtl %s\n", shapes[i].material.name.c_str());
|
||||
//}
|
||||
|
||||
// facevarying vtx
|
||||
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
int idx = shapes[i].mesh.indices[3*k+j];
|
||||
if (coordTransform) {
|
||||
fprintf(fp, "v %f %f %f\n",
|
||||
shapes[i].mesh.positions[3*idx+0],
|
||||
shapes[i].mesh.positions[3*idx+2],
|
||||
-shapes[i].mesh.positions[3*idx+1]);
|
||||
} else {
|
||||
fprintf(fp, "v %f %f %f\n",
|
||||
shapes[i].mesh.positions[3*idx+0],
|
||||
shapes[i].mesh.positions[3*idx+1],
|
||||
shapes[i].mesh.positions[3*idx+2]);
|
||||
bool has_vn = false;
|
||||
bool has_vt = false;
|
||||
// Assumes normals and textures are set shape-wise.
|
||||
if(shapes[i].mesh.indices.size() > 0){
|
||||
has_vn = shapes[i].mesh.indices[0].normal_index != -1;
|
||||
has_vt = shapes[i].mesh.indices[0].texcoord_index != -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// facevarying normal
|
||||
if (shapes[i].mesh.normals.size() > 0) {
|
||||
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
int idx = shapes[i].mesh.indices[3*k+j];
|
||||
if (coordTransform) {
|
||||
fprintf(fp, "vn %f %f %f\n",
|
||||
shapes[i].mesh.normals[3*idx+0],
|
||||
shapes[i].mesh.normals[3*idx+2],
|
||||
-shapes[i].mesh.normals[3*idx+1]);
|
||||
} else {
|
||||
fprintf(fp, "vn %f %f %f\n",
|
||||
shapes[i].mesh.normals[3*idx+0],
|
||||
shapes[i].mesh.normals[3*idx+1],
|
||||
shapes[i].mesh.normals[3*idx+2]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shapes[i].mesh.normals.size() > 0) has_vn = true;
|
||||
|
||||
// facevarying texcoord
|
||||
if (shapes[i].mesh.texcoords.size() > 0) {
|
||||
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
|
||||
for (int j = 0; j < 3; j++) {
|
||||
int idx = shapes[i].mesh.indices[3*k+j];
|
||||
fprintf(fp, "vt %f %f\n",
|
||||
shapes[i].mesh.texcoords[2*idx+0],
|
||||
shapes[i].mesh.texcoords[2*idx+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (shapes[i].mesh.texcoords.size() > 0) has_vt = true;
|
||||
|
||||
// face
|
||||
for (size_t k = 0; k < shapes[i].mesh.indices.size() / 3; k++) {
|
||||
|
||||
// Face index is 1-base.
|
||||
//int v0 = shapes[i].mesh.indices[3*k+0] + 1 + v_offset;
|
||||
//int v1 = shapes[i].mesh.indices[3*k+1] + 1 + v_offset;
|
||||
//int v2 = shapes[i].mesh.indices[3*k+2] + 1 + v_offset;
|
||||
int v0 = (3*k + 0) + 1 + v_offset;
|
||||
int v1 = (3*k + 1) + 1 + v_offset;
|
||||
int v2 = (3*k + 2) + 1 + v_offset;
|
||||
|
||||
int vt0 = (3*k + 0) + 1 + vt_offset;
|
||||
int vt1 = (3*k + 1) + 1 + vt_offset;
|
||||
int vt2 = (3*k + 2) + 1 + vt_offset;
|
||||
|
||||
int material_id = shapes[i].mesh.material_ids[k];
|
||||
int face_index = 0;
|
||||
for (size_t k = 0; k < shapes[i].mesh.indices.size(); k += shapes[i].mesh.num_face_vertices[face_index++]) {
|
||||
// Check Materials
|
||||
int material_id = shapes[i].mesh.material_ids[face_index];
|
||||
if (material_id != prev_material_id) {
|
||||
std::string material_name = materials[material_id].name;
|
||||
fprintf(fp, "usemtl %s\n", material_name.c_str());
|
||||
prev_material_id = material_id;
|
||||
}
|
||||
|
||||
if (has_vn && has_vt) {
|
||||
fprintf(fp, "f %d/%d/%d %d/%d/%d %d/%d/%d\n",
|
||||
v0, vt0, v0, v1, vt1, v1, v2, vt2, v2);
|
||||
} else if (has_vn && !has_vt) {
|
||||
fprintf(fp, "f %d//%d %d//%d %d//%d\n", v0, v0, v1, v1, v2, v2);
|
||||
} else if (!has_vn && has_vt) {
|
||||
fprintf(fp, "f %d/%d %d/%d %d/%d\n", v0, v0, v1, v1, v2, v2);
|
||||
} else {
|
||||
fprintf(fp, "f %d %d %d\n", v0, v1, v2);
|
||||
unsigned char v_per_f = shapes[i].mesh.num_face_vertices[face_index];
|
||||
// Imperformant, but if you want to have variable vertices per face, you need some kind of a dynamic loop.
|
||||
fprintf(fp, "f");
|
||||
for(int l = 0; l < v_per_f; l++){
|
||||
const tinyobj::index_t& ref = shapes[i].mesh.indices[k + l];
|
||||
if(has_vn && has_vt){
|
||||
// v0/t0/vn0
|
||||
fprintf(fp, " %d/%d/%d", ref.vertex_index + 1, ref.texcoord_index + 1, ref.normal_index + 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(has_vn && !has_vt){
|
||||
// v0//vn0
|
||||
fprintf(fp, " %d//%d", ref.vertex_index + 1, ref.normal_index + 1);
|
||||
continue;
|
||||
}
|
||||
if(!has_vn && has_vt){
|
||||
// v0/vt0
|
||||
fprintf(fp, " %d/%d", ref.vertex_index + 1, ref.texcoord_index + 1);
|
||||
continue;
|
||||
}
|
||||
if(!has_vn && !has_vt){
|
||||
// v0 v1 v2
|
||||
fprintf(fp, " %d", ref.vertex_index + 1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
v_offset += shapes[i].mesh.indices.size();
|
||||
//vn_offset += shapes[i].mesh.normals.size() / 3;
|
||||
vt_offset += shapes[i].mesh.texcoords.size() / 2;
|
||||
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "../../tiny_obj_loader.h"
|
||||
|
||||
extern bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform = false);
|
||||
|
||||
extern bool WriteObj(const std::string& filename, const tinyobj::attrib_t& attributes, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool coordTransform = false);
|
||||
|
||||
#endif // __OBJ_WRITER_H__
|
||||
|
||||
@@ -308,9 +308,13 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
|
||||
base_dir += "/";
|
||||
#endif
|
||||
|
||||
std::string warn;
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename,
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename,
|
||||
base_dir.c_str());
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
}
|
||||
|
||||
@@ -9,8 +9,9 @@ bool Voxelize(const char* filename, float voxelsizex, float voxelsizey, float vo
|
||||
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, &err, filename);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename);
|
||||
|
||||
if (!err.empty()) {
|
||||
printf("err: %s\n", err.c_str());
|
||||
|
||||
@@ -6,11 +6,21 @@
|
||||
|
||||
* C++-11 compiler
|
||||
|
||||
## How to build
|
||||
|
||||
```
|
||||
$ premak5 gmake
|
||||
```
|
||||
|
||||
## Compile options
|
||||
|
||||
* zstd compressed .obj support. `--with-zstd` premake option.
|
||||
* gzip compressed .obj support. `--with-zlib` premake option.
|
||||
|
||||
## Notes on AMD GPU + Linux
|
||||
|
||||
You may need to link with libdrm(`-ldrm`).
|
||||
|
||||
## Licenses
|
||||
|
||||
* lfpAlloc : MIT license.
|
||||
|
||||
@@ -312,6 +312,10 @@ typedef struct {
|
||||
|
||||
typedef struct {
|
||||
std::string name; // group name or object name.
|
||||
// Shape's corresponding faces are accessed by attrib.indices[face_offset,
|
||||
// face_offset + length] NOTE: you'll need to sum up
|
||||
// attrib.face_num_verts[face_offset, face_offset + length] to find actual
|
||||
// number of faces.
|
||||
unsigned int face_offset;
|
||||
unsigned int length;
|
||||
} shape_t;
|
||||
@@ -330,7 +334,14 @@ typedef struct {
|
||||
std::vector<float, lfpAlloc::lfpAllocator<float> > normals;
|
||||
std::vector<float, lfpAlloc::lfpAllocator<float> > texcoords;
|
||||
std::vector<index_t, lfpAlloc::lfpAllocator<index_t> > indices;
|
||||
|
||||
// # of vertices for each face.
|
||||
// 3 for triangle, 4 for qual, ...
|
||||
// If triangulation is enabled and the original face are quad,
|
||||
// face_num_verts will be 6(3 + 3)
|
||||
std::vector<int, lfpAlloc::lfpAllocator<int> > face_num_verts;
|
||||
|
||||
// Per-face material IDs.
|
||||
std::vector<int, lfpAlloc::lfpAllocator<int> > material_ids;
|
||||
} attrib_t;
|
||||
|
||||
@@ -1238,6 +1249,8 @@ typedef struct {
|
||||
// 3. Do parallel parsing for each line.
|
||||
// 4. Reconstruct final mesh data structure.
|
||||
|
||||
// Raise # of max threads if you have more CPU cores...
|
||||
// In 2018, 32 cores are getting common in high-end workstaion PC.
|
||||
#define kMaxThreads (32)
|
||||
|
||||
static inline bool is_line_ending(const char *p, size_t i, size_t end_i) {
|
||||
@@ -1306,15 +1319,19 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
end_idx = len - 1;
|
||||
}
|
||||
|
||||
// true if the line currently read must be added to the current line
|
||||
// info
|
||||
bool new_line_found =
|
||||
(t == 0) || is_line_ending(buf, start_idx - 1, end_idx);
|
||||
|
||||
size_t prev_pos = start_idx;
|
||||
for (size_t i = start_idx; i < end_idx; i++) {
|
||||
if (is_line_ending(buf, i, end_idx)) {
|
||||
if ((t > 0) && (prev_pos == start_idx) &&
|
||||
(!is_line_ending(buf, start_idx - 1, end_idx))) {
|
||||
if (!new_line_found) {
|
||||
// first linebreak found in (chunk > 0), and a line before this
|
||||
// linebreak belongs to previous chunk, so skip it.
|
||||
prev_pos = i + 1;
|
||||
continue;
|
||||
new_line_found = true;
|
||||
} else {
|
||||
LineInfo info;
|
||||
info.pos = prev_pos;
|
||||
@@ -1329,11 +1346,11 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
}
|
||||
}
|
||||
|
||||
// Find extra line which spand across chunk boundary.
|
||||
if ((t < num_threads) && (buf[end_idx - 1] != '\n')) {
|
||||
auto extra_span_idx = (std::min)(end_idx - 1 + chunk_size, len);
|
||||
for (size_t i = end_idx; i < extra_span_idx; i++) {
|
||||
if (is_line_ending(buf, i, extra_span_idx)) {
|
||||
// If at least one line started in this chunk, find where it ends in the
|
||||
// rest of the buffer
|
||||
if (new_line_found && (t < num_threads) && (buf[end_idx - 1] != '\n')) {
|
||||
for (size_t i = end_idx; i < len; i++) {
|
||||
if (is_line_ending(buf, i, len)) {
|
||||
LineInfo info;
|
||||
info.pos = prev_pos;
|
||||
info.len = i - prev_pos;
|
||||
@@ -1390,7 +1407,6 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
|
||||
for (size_t t = 0; t < num_threads; t++) {
|
||||
workers->push_back(std::thread([&, t]() {
|
||||
|
||||
for (size_t i = 0; i < line_infos[t].size(); i++) {
|
||||
Command command;
|
||||
bool ret = parseLine(&command, &buf[line_infos[t][i].pos],
|
||||
@@ -1415,7 +1431,6 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
commands[t].emplace_back(std::move(command));
|
||||
}
|
||||
}
|
||||
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -1493,7 +1508,7 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
attrib->texcoords.resize(num_vt * 2);
|
||||
attrib->indices.resize(num_f);
|
||||
attrib->face_num_verts.resize(num_indices);
|
||||
attrib->material_ids.resize(num_indices);
|
||||
attrib->material_ids.resize(num_indices, -1);
|
||||
|
||||
size_t v_offsets[kMaxThreads];
|
||||
size_t n_offsets[kMaxThreads];
|
||||
@@ -1524,22 +1539,46 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
size_t t_count = t_offsets[t];
|
||||
size_t f_count = f_offsets[t];
|
||||
size_t face_count = face_offsets[t];
|
||||
int material_id = -1; // -1 = default unknown material.
|
||||
|
||||
for (size_t i = 0; i < commands[t].size(); i++) {
|
||||
if (commands[t][i].type == COMMAND_EMPTY) {
|
||||
continue;
|
||||
} else if (commands[t][i].type == COMMAND_USEMTL) {
|
||||
if (commands[t][i].material_name &&
|
||||
commands[t][i].material_name_len > 0) {
|
||||
commands[t][i].material_name_len > 0 &&
|
||||
// check if there are still faces after this command
|
||||
face_count < num_indices) {
|
||||
// Find next face
|
||||
bool found = false;
|
||||
size_t i_start = i + 1, t_next, i_next;
|
||||
for (t_next = t; t_next < num_threads; t_next++) {
|
||||
for (i_next = i_start; i_next < commands[t_next].size();
|
||||
i_next++) {
|
||||
if (commands[t_next][i_next].type == COMMAND_F) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found) break;
|
||||
i_start = 0;
|
||||
}
|
||||
// Assign material to this face
|
||||
if (found) {
|
||||
std::string material_name(commands[t][i].material_name,
|
||||
commands[t][i].material_name_len);
|
||||
|
||||
for (size_t k = 0;
|
||||
k < commands[t_next][i_next].f_num_verts.size(); k++) {
|
||||
if (material_map.find(material_name) != material_map.end()) {
|
||||
material_id = material_map[material_name];
|
||||
attrib->material_ids[face_count + k] =
|
||||
material_map[material_name];
|
||||
} else {
|
||||
// Assign invalid material ID
|
||||
material_id = -1;
|
||||
// Set a different value than the default, to
|
||||
// prevent following faces from being assigned a valid
|
||||
// material
|
||||
attrib->material_ids[face_count + k] = -2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (commands[t][i].type == COMMAND_V) {
|
||||
@@ -1566,7 +1605,6 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
index_t(vertex_index, texcoord_index, normal_index);
|
||||
}
|
||||
for (size_t k = 0; k < commands[t][i].f_num_verts.size(); k++) {
|
||||
attrib->material_ids[face_count + k] = material_id;
|
||||
attrib->face_num_verts[face_count + k] =
|
||||
commands[t][i].f_num_verts[k];
|
||||
}
|
||||
@@ -1581,19 +1619,13 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
for (size_t t = 0; t < workers->size(); t++) {
|
||||
workers[t].join();
|
||||
}
|
||||
if(material_map.size()>1&& num_threads>1) {
|
||||
for (size_t t = 0; t < num_threads; t++) {
|
||||
size_t face_count = face_offsets[t];
|
||||
if (-1 == attrib->material_ids[face_count]) {
|
||||
int prev_material_id = attrib->material_ids[face_count - 1];
|
||||
size_t max_face_offset = (t == num_threads - 1) ? attrib->material_ids.size() : face_offsets[t + 1];
|
||||
for (int i = face_count; i<max_face_offset; ++i) {
|
||||
if (attrib->material_ids[i] != -1) break;
|
||||
attrib->material_ids[i] = prev_material_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// To each face with uninitialized material id,
|
||||
// assign the material id of the last face preceding it that has one
|
||||
for (size_t face_count = 1; face_count < num_indices; ++face_count)
|
||||
if (attrib->material_ids[face_count] == -1)
|
||||
attrib->material_ids[face_count] = attrib->material_ids[face_count - 1];
|
||||
|
||||
auto t_end = std::chrono::high_resolution_clock::now();
|
||||
ms_merge = t_end - t_start;
|
||||
}
|
||||
@@ -1653,7 +1685,8 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
|
||||
}
|
||||
}
|
||||
if (commands[t][i].type == COMMAND_F) {
|
||||
face_count++;
|
||||
// Consider generation of multiple faces per `f` line by triangulation
|
||||
face_count += commands[t][i].f_num_verts.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -357,7 +357,7 @@ bool LoadObjAndConvert(float bmin[3], float bmax[3], const char* filename, int n
|
||||
std::vector<float> vb; // pos(3float), normal(3float), color(3float)
|
||||
size_t face_offset = 0;
|
||||
for (size_t v = 0; v < attrib.face_num_verts.size(); v++) {
|
||||
assert(attrib.face_num_verts[v] % 3 == 0); // assume all triangle face.
|
||||
assert(attrib.face_num_verts[v] % 3 == 0); // assume all triangle face(multiple of 3).
|
||||
for (size_t f = 0; f < attrib.face_num_verts[v] / 3; f++) {
|
||||
tinyobj_opt::index_t idx0 = attrib.indices[face_offset+3*f+0];
|
||||
tinyobj_opt::index_t idx1 = attrib.indices[face_offset+3*f+1];
|
||||
|
||||
BIN
fuzzer/afl.tar.gz
Normal file
BIN
fuzzer/afl.tar.gz
Normal file
Binary file not shown.
@@ -137,8 +137,10 @@ static void PrintInfo(const tinyobj::attrib_t& attrib,
|
||||
for (size_t i = 0; i < shapes.size(); i++) {
|
||||
printf("shape[%ld].name = %s\n", static_cast<long>(i),
|
||||
shapes[i].name.c_str());
|
||||
printf("Size of shape[%ld].indices: %lu\n", static_cast<long>(i),
|
||||
printf("Size of shape[%ld].mesh.indices: %lu\n", static_cast<long>(i),
|
||||
static_cast<unsigned long>(shapes[i].mesh.indices.size()));
|
||||
printf("Size of shape[%ld].path.indices: %lu\n", static_cast<long>(i),
|
||||
static_cast<unsigned long>(shapes[i].path.indices.size()));
|
||||
|
||||
size_t index_offset = 0;
|
||||
|
||||
@@ -283,14 +285,19 @@ static bool TestLoadObj(const char* filename, const char* basepath = NULL,
|
||||
|
||||
timerutil t;
|
||||
t.start();
|
||||
std::string warn;
|
||||
std::string err;
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename,
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, filename,
|
||||
basepath, triangulate);
|
||||
t.end();
|
||||
printf("Parsing time: %lu [msecs]\n", t.msec());
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@@ -374,16 +381,12 @@ static bool TestStreamLoadObj() {
|
||||
virtual bool operator()(const std::string& matId,
|
||||
std::vector<material_t>* materials,
|
||||
std::map<std::string, int>* matMap,
|
||||
std::string* warn,
|
||||
std::string* err) {
|
||||
(void)err;
|
||||
(void)matId;
|
||||
std::string warning;
|
||||
LoadMtl(matMap, materials, &m_matSStream, &warning);
|
||||
LoadMtl(matMap, materials, &m_matSStream, warn, err);
|
||||
|
||||
if (!warning.empty()) {
|
||||
if (err) {
|
||||
(*err) += warning;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -395,8 +398,9 @@ static bool TestStreamLoadObj() {
|
||||
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, &err, &objStream,
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err, &objStream,
|
||||
&matSSReader);
|
||||
|
||||
if (!err.empty()) {
|
||||
|
||||
9
models/colorspace-issue-184.mtl
Normal file
9
models/colorspace-issue-184.mtl
Normal file
@@ -0,0 +1,9 @@
|
||||
newmtl default
|
||||
Ka 0 0 0
|
||||
Kd 0 0 0
|
||||
Ks 0 0 0
|
||||
Kt 0.1 0.2 0.3
|
||||
map_Kd -colorspace sRGB -o 0.1 diffuse.jpg
|
||||
map_Ks -s 0.1 0.2 specular.jpg
|
||||
map_bump -colorspace linear -bm 3 bumpmap.jpg
|
||||
|
||||
7
models/colorspace-issue-184.obj
Normal file
7
models/colorspace-issue-184.obj
Normal file
@@ -0,0 +1,7 @@
|
||||
mtllib colorspace-issue-184.mtl
|
||||
o Test
|
||||
v 1.864151 -1.219172 -5.532511
|
||||
v 0.575869 -0.666304 5.896140
|
||||
v 0.940448 1.000000 -1.971128
|
||||
usemtl default
|
||||
f 1 2 3
|
||||
@@ -13,6 +13,7 @@ v 2.000000 2.000000 0.000000
|
||||
g front cube
|
||||
usemtl white
|
||||
f 1 2 3 4
|
||||
# two white spaces between 'back' and 'cube'
|
||||
g back cube
|
||||
# expects white material
|
||||
f 8 7 6 5
|
||||
|
||||
24
models/invalid-face-definition.mtl
Normal file
24
models/invalid-face-definition.mtl
Normal file
@@ -0,0 +1,24 @@
|
||||
newmtl white
|
||||
Ka 0 0 0
|
||||
Kd 1 1 1
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl red
|
||||
Ka 0 0 0
|
||||
Kd 1 0 0
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl green
|
||||
Ka 0 0 0
|
||||
Kd 0 1 0
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl blue
|
||||
Ka 0 0 0
|
||||
Kd 0 0 1
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl light
|
||||
Ka 20 20 20
|
||||
Kd 1 1 1
|
||||
Ks 0 0 0
|
||||
18
models/invalid-face-definition.obj
Normal file
18
models/invalid-face-definition.obj
Normal file
@@ -0,0 +1,18 @@
|
||||
mtllib invalid-face-definition.mtl
|
||||
|
||||
v 0.000000 2.000000 2.000000
|
||||
v 0.000000 0.000000 2.000000
|
||||
v 2.000000 0.000000 2.000000
|
||||
v 2.000000 2.000000 2.000000
|
||||
v 0.000000 2.000000 0.000000
|
||||
v 0.000000 0.000000 0.000000
|
||||
v 2.000000 0.000000 0.000000
|
||||
v 2.000000 2.000000 0.000000
|
||||
# 8 vertices
|
||||
|
||||
g front cube
|
||||
usemtl white
|
||||
f 1
|
||||
g back cube
|
||||
# expects white material
|
||||
f 8 7
|
||||
16
models/line-prim.obj
Normal file
16
models/line-prim.obj
Normal file
@@ -0,0 +1,16 @@
|
||||
mtllib cube.mtl
|
||||
|
||||
v 0.000000 2.000000 2.000000
|
||||
v 0.000000 0.000000 2.000000
|
||||
v 2.000000 0.000000 2.000000
|
||||
v 2.000000 2.000000 2.000000
|
||||
v 0.000000 2.000000 0.000000
|
||||
v 0.000000 0.000000 0.000000
|
||||
v 2.000000 0.000000 0.000000
|
||||
v 2.000000 2.000000 0.000000
|
||||
# 8 vertices
|
||||
|
||||
g g0
|
||||
usemtl white
|
||||
l 1 2 3 4
|
||||
l 5 6 7
|
||||
@@ -1,17 +0,0 @@
|
||||
Command line used to find this crash:
|
||||
|
||||
afl-fuzz -i in -o out ./test_loader @@
|
||||
|
||||
If you can't reproduce a bug outside of afl-fuzz, be sure to set the same
|
||||
memory limit. The limit used for this fuzzing session was 50.0 MB.
|
||||
|
||||
Need a tool to minimize test cases before investigating the crashes or sending
|
||||
them to a vendor? Check out the afl-tmin that comes with the fuzzer!
|
||||
|
||||
Found any cool bugs in open-source tools using afl-fuzz? If yes, please drop
|
||||
me a mail at <lcamtuf@coredump.cx> once the issues are fixed - I'd love to
|
||||
add your finds to the gallery at:
|
||||
|
||||
http://lcamtuf.coredump.cx/afl/
|
||||
|
||||
Thanks :-)
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,33 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
} cube
|
||||
|
||||
v d.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1/6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
f 1//4 5//4 55555555555555 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
@@ -1,35 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
4
|
||||
f 1//4 6//4 2//4
|
||||
f
|
||||
g cube
|
||||
|
||||
v 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
n 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 //5
|
||||
f 5//5 8//5 6//5
|
||||
f 1//4 5//4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
@@ -1,34 +0,0 @@
|
||||
# cube.ob7//3
|
||||
f 3//3 4//3 8//3j
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1˙0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
f 1//4 5//4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,29 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1,0
|
||||
T 0.0 1.0 0.0
|
||||
v 4.0 1c0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 /////////////////////////////.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
v˙ 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8K/31
|
||||
f/6 4//6 3//6
|
||||
f 1//6 2 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5"
|
||||
f 1//4 5//4 2222222222224f 1//2 7//2 5 6//4 2//4
|
||||
f 3//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
@@ -1,33 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0<>0 0.0 -1.0
|
||||
vn 0.0 1.0 00
|
||||
vn 0.0 -Ę.0 0.0
|
||||
vn 1. 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 40000000000000000vvvvvvvvvvvvvvvv00000080000000//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
f 1//4 56//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
@@ -1,32 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 08//3
|
||||
f 5//5 7//5 8//5!Šf 5//5 8//5 6//5
|
||||
f 1//4 5//4 65555//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
@@ -1,33 +0,0 @@
|
||||
# cube.7//3
|
||||
f 3//3 4//3 8//3
|
||||
obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v .0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5!Šf 5//5 8//5 6//5
|
||||
f 1//4 5//4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
@@ -1,30 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cuvP 0.0 0.0 .0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5!Šf 5//5 8//5 6//5
|
||||
f 1//4 5//4 6//4
|
||||
f 1//4 6666666666666666//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
@@ -1,33 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
t 1//4 5/-4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
@@ -1,33 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
t 1//4 -5//4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
@@ -1,35 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v 1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 !.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0 0.0
|
||||
vn 0.0 8//5 6//5
|
||||
t 1//4 -1.0 0.0
|
||||
vn 1.0 0.0 0.0
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 8//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
t 1//4 5//4 6//4
|
||||
f 1//4 6//4 2//4 f 2//1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,32 +0,0 @@
|
||||
# cube.obj
|
||||
#
|
||||
|
||||
g cube
|
||||
|
||||
v 0.0 0.0 0.0
|
||||
v 0.0 0.0 1.0
|
||||
v 0.0 1.0 0.0
|
||||
v 0.0 1.0 1.0
|
||||
v Ď1.0 0.0 0.0
|
||||
v 1.0 0.0 1.0
|
||||
v 1.0 1.0 0.0
|
||||
v 1.0 1.0 1.0
|
||||
|
||||
vn 0.0 0.0 1.0
|
||||
vn 0.0 0.0 -1.0
|
||||
vn 0.0 1.0
|
||||
vn 1.0 0.0 0.0
|
||||
vn -1.0 0.0 0.0
|
||||
|
||||
f 1//2 7//2 5//2
|
||||
f 1//2 3//2 7//2
|
||||
f 1//6 4//6 3//6
|
||||
f 1//6 2//6 4//6
|
||||
f 3//3 8//3 7//3
|
||||
f 3//3 4//3 811111//3
|
||||
f 5//5 7//5 8//5
|
||||
f 5//5 8//5 6//5
|
||||
t 1//4 5//4 6//4
|
||||
f 1//4 6//4 2//4
|
||||
f 2B/1 6//1 8//1
|
||||
f 2//1 8//1 4//1
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
24
tests/issue-177.mtl
Normal file
24
tests/issue-177.mtl
Normal file
@@ -0,0 +1,24 @@
|
||||
newmtl white
|
||||
Ka 0 0 0
|
||||
Kd 1 1 1
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl red
|
||||
Ka 0 0 0
|
||||
Kd 1 0 0
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl green
|
||||
Ka 0 0 0
|
||||
Kd 0 1 0
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl blue
|
||||
Ka 0 0 0
|
||||
Kd 0 0 1
|
||||
Ks 0 0 0
|
||||
|
||||
newmtl light
|
||||
Ka 20 20 20
|
||||
Kd 1 1 1
|
||||
Ks 0 0 0
|
||||
31
tests/issue-177.obj
Normal file
31
tests/issue-177.obj
Normal file
@@ -0,0 +1,31 @@
|
||||
mtllib issue-177.mtl
|
||||
|
||||
v 0.000000 2.000000 2.000000
|
||||
v 0.000000 0.000000 2.000000
|
||||
v 2.000000 0.000000 2.000000
|
||||
v 2.000000 2.000000 2.000000
|
||||
v 0.000000 2.000000 0.000000
|
||||
v 0.000000 0.000000 0.000000
|
||||
v 2.000000 0.000000 0.000000
|
||||
v 2.000000 2.000000 0.000000
|
||||
# 8 vertices
|
||||
|
||||
g front cube
|
||||
usemtl white
|
||||
f 1 2 3 4
|
||||
g back cube
|
||||
# expects white material
|
||||
f 8 7 6 5
|
||||
g right cube
|
||||
usemtl red
|
||||
f 4 3 7 8
|
||||
g top cube
|
||||
usemtl white
|
||||
f 5 1 4 8
|
||||
g left cube
|
||||
usemtl green
|
||||
f 5 6 2 1
|
||||
g bottom cube
|
||||
usemtl white
|
||||
f 2 6 7 3
|
||||
# 6 elements
|
||||
550
tests/tester.cc
550
tests/tester.cc
@@ -1,57 +1,62 @@
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "../tiny_obj_loader.h"
|
||||
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
|
||||
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do
|
||||
// this in one cpp file
|
||||
#include "catch.hpp"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
|
||||
static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool triangulate = true)
|
||||
{
|
||||
static void PrintInfo(const tinyobj::attrib_t& attrib,
|
||||
const std::vector<tinyobj::shape_t>& shapes,
|
||||
const std::vector<tinyobj::material_t>& materials,
|
||||
bool triangulate = true) {
|
||||
std::cout << "# of vertices : " << (attrib.vertices.size() / 3) << std::endl;
|
||||
std::cout << "# of normals : " << (attrib.normals.size() / 3) << std::endl;
|
||||
std::cout << "# of texcoords : " << (attrib.texcoords.size() / 2) << std::endl;
|
||||
std::cout << "# of texcoords : " << (attrib.texcoords.size() / 2)
|
||||
<< std::endl;
|
||||
|
||||
std::cout << "# of shapes : " << shapes.size() << std::endl;
|
||||
std::cout << "# of materials : " << materials.size() << std::endl;
|
||||
|
||||
for (size_t v = 0; v < attrib.vertices.size() / 3; v++) {
|
||||
printf(" v[%ld] = (%f, %f, %f)\n", v,
|
||||
static_cast<const double>(attrib.vertices[3*v+0]),
|
||||
static_cast<const double>(attrib.vertices[3*v+1]),
|
||||
static_cast<const double>(attrib.vertices[3*v+2]));
|
||||
static_cast<const double>(attrib.vertices[3 * v + 0]),
|
||||
static_cast<const double>(attrib.vertices[3 * v + 1]),
|
||||
static_cast<const double>(attrib.vertices[3 * v + 2]));
|
||||
}
|
||||
|
||||
for (size_t v = 0; v < attrib.normals.size() / 3; v++) {
|
||||
printf(" n[%ld] = (%f, %f, %f)\n", v,
|
||||
static_cast<const double>(attrib.normals[3*v+0]),
|
||||
static_cast<const double>(attrib.normals[3*v+1]),
|
||||
static_cast<const double>(attrib.normals[3*v+2]));
|
||||
static_cast<const double>(attrib.normals[3 * v + 0]),
|
||||
static_cast<const double>(attrib.normals[3 * v + 1]),
|
||||
static_cast<const double>(attrib.normals[3 * v + 2]));
|
||||
}
|
||||
|
||||
for (size_t v = 0; v < attrib.texcoords.size() / 2; v++) {
|
||||
printf(" uv[%ld] = (%f, %f)\n", v,
|
||||
static_cast<const double>(attrib.texcoords[2*v+0]),
|
||||
static_cast<const double>(attrib.texcoords[2*v+1]));
|
||||
static_cast<const double>(attrib.texcoords[2 * v + 0]),
|
||||
static_cast<const double>(attrib.texcoords[2 * v + 1]));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < shapes.size(); i++) {
|
||||
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
|
||||
printf("Size of shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
|
||||
printf("Size of shape[%ld].indices: %ld\n", i,
|
||||
shapes[i].mesh.indices.size());
|
||||
|
||||
if (triangulate)
|
||||
{
|
||||
printf("Size of shape[%ld].material_ids: %ld\n", i, shapes[i].mesh.material_ids.size());
|
||||
if (triangulate) {
|
||||
printf("Size of shape[%ld].material_ids: %ld\n", i,
|
||||
shapes[i].mesh.material_ids.size());
|
||||
assert((shapes[i].mesh.indices.size() % 3) == 0);
|
||||
for (size_t f = 0; f < shapes[i].mesh.indices.size() / 3; f++) {
|
||||
tinyobj::index_t i0 = shapes[i].mesh.indices[3*f+0];
|
||||
tinyobj::index_t i1 = shapes[i].mesh.indices[3*f+1];
|
||||
tinyobj::index_t i2 = shapes[i].mesh.indices[3*f+2];
|
||||
tinyobj::index_t i0 = shapes[i].mesh.indices[3 * f + 0];
|
||||
tinyobj::index_t i1 = shapes[i].mesh.indices[3 * f + 1];
|
||||
tinyobj::index_t i2 = shapes[i].mesh.indices[3 * f + 2];
|
||||
printf(" idx[%ld] = %d/%d/%d, %d/%d/%d, %d/%d/%d. mat_id = %d\n", f,
|
||||
i0.vertex_index, i0.normal_index, i0.texcoord_index,
|
||||
i1.vertex_index, i1.normal_index, i1.texcoord_index,
|
||||
@@ -61,27 +66,29 @@ static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj
|
||||
} else {
|
||||
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
|
||||
tinyobj::index_t idx = shapes[i].mesh.indices[f];
|
||||
printf(" idx[%ld] = %d/%d/%d\n", f, idx.vertex_index, idx.normal_index, idx.texcoord_index);
|
||||
printf(" idx[%ld] = %d/%d/%d\n", f, idx.vertex_index, idx.normal_index,
|
||||
idx.texcoord_index);
|
||||
}
|
||||
|
||||
printf("Size of shape[%ld].material_ids: %ld\n", i, shapes[i].mesh.material_ids.size());
|
||||
assert(shapes[i].mesh.material_ids.size() == shapes[i].mesh.num_face_vertices.size());
|
||||
printf("Size of shape[%ld].material_ids: %ld\n", i,
|
||||
shapes[i].mesh.material_ids.size());
|
||||
assert(shapes[i].mesh.material_ids.size() ==
|
||||
shapes[i].mesh.num_face_vertices.size());
|
||||
for (size_t m = 0; m < shapes[i].mesh.material_ids.size(); m++) {
|
||||
printf(" material_id[%ld] = %d\n", m,
|
||||
shapes[i].mesh.material_ids[m]);
|
||||
printf(" material_id[%ld] = %d\n", m, shapes[i].mesh.material_ids[m]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
printf("shape[%ld].num_faces: %ld\n", i, shapes[i].mesh.num_face_vertices.size());
|
||||
printf("shape[%ld].num_faces: %ld\n", i,
|
||||
shapes[i].mesh.num_face_vertices.size());
|
||||
for (size_t v = 0; v < shapes[i].mesh.num_face_vertices.size(); v++) {
|
||||
printf(" num_vertices[%ld] = %ld\n", v,
|
||||
static_cast<long>(shapes[i].mesh.num_face_vertices[v]));
|
||||
}
|
||||
|
||||
//printf("shape[%ld].vertices: %ld\n", i, shapes[i].mesh.positions.size());
|
||||
//assert((shapes[i].mesh.positions.size() % 3) == 0);
|
||||
//for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) {
|
||||
// printf("shape[%ld].vertices: %ld\n", i, shapes[i].mesh.positions.size());
|
||||
// assert((shapes[i].mesh.positions.size() % 3) == 0);
|
||||
// for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) {
|
||||
// printf(" v[%ld] = (%f, %f, %f)\n", v,
|
||||
// static_cast<const double>(shapes[i].mesh.positions[3*v+0]),
|
||||
// static_cast<const double>(shapes[i].mesh.positions[3*v+1]),
|
||||
@@ -92,33 +99,28 @@ static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj
|
||||
for (size_t t = 0; t < shapes[i].mesh.tags.size(); t++) {
|
||||
printf(" tag[%ld] = %s ", t, shapes[i].mesh.tags[t].name.c_str());
|
||||
printf(" ints: [");
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].intValues.size(); ++j)
|
||||
{
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].intValues.size(); ++j) {
|
||||
printf("%ld", static_cast<long>(shapes[i].mesh.tags[t].intValues[j]));
|
||||
if (j < (shapes[i].mesh.tags[t].intValues.size()-1))
|
||||
{
|
||||
if (j < (shapes[i].mesh.tags[t].intValues.size() - 1)) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("]");
|
||||
|
||||
printf(" floats: [");
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].floatValues.size(); ++j)
|
||||
{
|
||||
printf("%f", static_cast<const double>(shapes[i].mesh.tags[t].floatValues[j]));
|
||||
if (j < (shapes[i].mesh.tags[t].floatValues.size()-1))
|
||||
{
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].floatValues.size(); ++j) {
|
||||
printf("%f", static_cast<const double>(
|
||||
shapes[i].mesh.tags[t].floatValues[j]));
|
||||
if (j < (shapes[i].mesh.tags[t].floatValues.size() - 1)) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
printf("]");
|
||||
|
||||
printf(" strings: [");
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].stringValues.size(); ++j)
|
||||
{
|
||||
for (size_t j = 0; j < shapes[i].mesh.tags[t].stringValues.size(); ++j) {
|
||||
printf("%s", shapes[i].mesh.tags[t].stringValues[j].c_str());
|
||||
if (j < (shapes[i].mesh.tags[t].stringValues.size()-1))
|
||||
{
|
||||
if (j < (shapes[i].mesh.tags[t].stringValues.size() - 1)) {
|
||||
printf(", ");
|
||||
}
|
||||
}
|
||||
@@ -129,25 +131,45 @@ static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj
|
||||
|
||||
for (size_t i = 0; i < materials.size(); i++) {
|
||||
printf("material[%ld].name = %s\n", i, materials[i].name.c_str());
|
||||
printf(" material.Ka = (%f, %f ,%f)\n", static_cast<const double>(materials[i].ambient[0]), static_cast<const double>(materials[i].ambient[1]), static_cast<const double>(materials[i].ambient[2]));
|
||||
printf(" material.Kd = (%f, %f ,%f)\n", static_cast<const double>(materials[i].diffuse[0]), static_cast<const double>(materials[i].diffuse[1]), static_cast<const double>(materials[i].diffuse[2]));
|
||||
printf(" material.Ks = (%f, %f ,%f)\n", static_cast<const double>(materials[i].specular[0]), static_cast<const double>(materials[i].specular[1]), static_cast<const double>(materials[i].specular[2]));
|
||||
printf(" material.Tr = (%f, %f ,%f)\n", static_cast<const double>(materials[i].transmittance[0]), static_cast<const double>(materials[i].transmittance[1]), static_cast<const double>(materials[i].transmittance[2]));
|
||||
printf(" material.Ke = (%f, %f ,%f)\n", static_cast<const double>(materials[i].emission[0]), static_cast<const double>(materials[i].emission[1]), static_cast<const double>(materials[i].emission[2]));
|
||||
printf(" material.Ns = %f\n", static_cast<const double>(materials[i].shininess));
|
||||
printf(" material.Ka = (%f, %f ,%f)\n",
|
||||
static_cast<const double>(materials[i].ambient[0]),
|
||||
static_cast<const double>(materials[i].ambient[1]),
|
||||
static_cast<const double>(materials[i].ambient[2]));
|
||||
printf(" material.Kd = (%f, %f ,%f)\n",
|
||||
static_cast<const double>(materials[i].diffuse[0]),
|
||||
static_cast<const double>(materials[i].diffuse[1]),
|
||||
static_cast<const double>(materials[i].diffuse[2]));
|
||||
printf(" material.Ks = (%f, %f ,%f)\n",
|
||||
static_cast<const double>(materials[i].specular[0]),
|
||||
static_cast<const double>(materials[i].specular[1]),
|
||||
static_cast<const double>(materials[i].specular[2]));
|
||||
printf(" material.Tr = (%f, %f ,%f)\n",
|
||||
static_cast<const double>(materials[i].transmittance[0]),
|
||||
static_cast<const double>(materials[i].transmittance[1]),
|
||||
static_cast<const double>(materials[i].transmittance[2]));
|
||||
printf(" material.Ke = (%f, %f ,%f)\n",
|
||||
static_cast<const double>(materials[i].emission[0]),
|
||||
static_cast<const double>(materials[i].emission[1]),
|
||||
static_cast<const double>(materials[i].emission[2]));
|
||||
printf(" material.Ns = %f\n",
|
||||
static_cast<const double>(materials[i].shininess));
|
||||
printf(" material.Ni = %f\n", static_cast<const double>(materials[i].ior));
|
||||
printf(" material.dissolve = %f\n", static_cast<const double>(materials[i].dissolve));
|
||||
printf(" material.dissolve = %f\n",
|
||||
static_cast<const double>(materials[i].dissolve));
|
||||
printf(" material.illum = %d\n", materials[i].illum);
|
||||
printf(" material.map_Ka = %s\n", materials[i].ambient_texname.c_str());
|
||||
printf(" material.map_Kd = %s\n", materials[i].diffuse_texname.c_str());
|
||||
printf(" material.map_Ks = %s\n", materials[i].specular_texname.c_str());
|
||||
printf(" material.map_Ns = %s\n", materials[i].specular_highlight_texname.c_str());
|
||||
printf(" material.map_Ns = %s\n",
|
||||
materials[i].specular_highlight_texname.c_str());
|
||||
printf(" material.map_bump = %s\n", materials[i].bump_texname.c_str());
|
||||
printf(" material.map_d = %s\n", materials[i].alpha_texname.c_str());
|
||||
printf(" material.disp = %s\n", materials[i].displacement_texname.c_str());
|
||||
printf(" material.refl = %s\n", materials[i].reflection_texname.c_str());
|
||||
std::map<std::string, std::string>::const_iterator it(materials[i].unknown_parameter.begin());
|
||||
std::map<std::string, std::string>::const_iterator itEnd(materials[i].unknown_parameter.end());
|
||||
std::map<std::string, std::string>::const_iterator it(
|
||||
materials[i].unknown_parameter.begin());
|
||||
std::map<std::string, std::string>::const_iterator itEnd(
|
||||
materials[i].unknown_parameter.end());
|
||||
|
||||
for (; it != itEnd; it++) {
|
||||
printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str());
|
||||
@@ -156,23 +178,25 @@ static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
TestLoadObj(
|
||||
const char* filename,
|
||||
const char* basepath = NULL,
|
||||
bool triangulate = true)
|
||||
{
|
||||
static bool TestLoadObj(const char* filename, const char* basepath = NULL,
|
||||
bool triangulate = true) {
|
||||
std::cout << "Loading " << filename << std::endl;
|
||||
|
||||
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, &err, filename, basepath, triangulate);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
filename, basepath, triangulate);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@@ -185,13 +209,10 @@ TestLoadObj(
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
TestLoadObjFromPreopenedFile(
|
||||
const char* filename,
|
||||
static bool TestLoadObjFromPreopenedFile(const char* filename,
|
||||
const char* basepath = NULL,
|
||||
bool readMaterials = true,
|
||||
bool triangulate = true)
|
||||
{
|
||||
bool triangulate = true) {
|
||||
std::string fullFilename = std::string(basepath) + filename;
|
||||
std::cout << "Loading " << fullFilename << std::endl;
|
||||
|
||||
@@ -203,19 +224,24 @@ TestLoadObjFromPreopenedFile(
|
||||
}
|
||||
|
||||
tinyobj::MaterialStreamReader materialStreamReader(fileStream);
|
||||
tinyobj::MaterialStreamReader* materialReader = readMaterials
|
||||
? &materialStreamReader
|
||||
: NULL;
|
||||
tinyobj::MaterialStreamReader* materialReader =
|
||||
readMaterials ? &materialStreamReader : NULL;
|
||||
|
||||
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, &err, &fileStream, materialReader);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
&fileStream, materialReader);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@@ -228,14 +254,11 @@ TestLoadObjFromPreopenedFile(
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool
|
||||
TestStreamLoadObj()
|
||||
{
|
||||
static bool TestStreamLoadObj() {
|
||||
std::cout << "Stream Loading " << std::endl;
|
||||
|
||||
std::stringstream objStream;
|
||||
objStream
|
||||
<< "mtllib cube.mtl\n"
|
||||
objStream << "mtllib cube.mtl\n"
|
||||
"\n"
|
||||
"v 0.000000 2.000000 2.000000\n"
|
||||
"v 0.000000 0.000000 2.000000\n"
|
||||
@@ -267,7 +290,7 @@ TestStreamLoadObj()
|
||||
"f 2 6 7 3\n"
|
||||
"# 6 elements";
|
||||
|
||||
std::string matStream(
|
||||
std::string matStream(
|
||||
"newmtl white\n"
|
||||
"Ka 0 0 0\n"
|
||||
"Kd 1 1 1\n"
|
||||
@@ -294,22 +317,21 @@ std::string matStream(
|
||||
"Ks 0 0 0");
|
||||
|
||||
using namespace tinyobj;
|
||||
class MaterialStringStreamReader:
|
||||
public MaterialReader
|
||||
{
|
||||
class MaterialStringStreamReader : public MaterialReader {
|
||||
public:
|
||||
MaterialStringStreamReader(const std::string& matSStream): m_matSStream(matSStream) {}
|
||||
MaterialStringStreamReader(const std::string& matSStream)
|
||||
: m_matSStream(matSStream) {}
|
||||
virtual ~MaterialStringStreamReader() {}
|
||||
virtual bool operator() (
|
||||
const std::string& matId,
|
||||
virtual bool operator()(const std::string& matId,
|
||||
std::vector<material_t>* materials,
|
||||
std::map<std::string, int>* matMap,
|
||||
std::string* err)
|
||||
{
|
||||
std::string* warn, std::string* err) {
|
||||
(void)matId;
|
||||
(void)warn;
|
||||
(void)err;
|
||||
std::string warning;
|
||||
LoadMtl(matMap, materials, &m_matSStream, &warning);
|
||||
std::string error_msg;
|
||||
LoadMtl(matMap, materials, &m_matSStream, &warning, &error_msg);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -321,11 +343,17 @@ std::string matStream(
|
||||
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, &err, &objStream, &matSSReader);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
&objStream, &matSSReader);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
@@ -340,21 +368,26 @@ std::string matStream(
|
||||
const char* gMtlBasePath = "../models/";
|
||||
|
||||
TEST_CASE("cornell_box", "[Loader]") {
|
||||
|
||||
REQUIRE(true == TestLoadObj("../models/cornell_box.obj", gMtlBasePath));
|
||||
}
|
||||
|
||||
TEST_CASE("catmark_torus_creases0", "[Loader]") {
|
||||
|
||||
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, &err, "../models/catmark_torus_creases0.obj", gMtlBasePath, /*triangulate*/false);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/catmark_torus_creases0.obj",
|
||||
gMtlBasePath, /*triangulate*/ false);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
@@ -364,16 +397,22 @@ TEST_CASE("catmark_torus_creases0", "[Loader]") {
|
||||
}
|
||||
|
||||
TEST_CASE("pbr", "[Loader]") {
|
||||
|
||||
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, &err, "../models/pbr-mat-ext.obj", gMtlBasePath, /*triangulate*/false);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/pbr-mat-ext.obj", gMtlBasePath,
|
||||
/*triangulate*/ false);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -391,18 +430,18 @@ TEST_CASE("pbr", "[Loader]") {
|
||||
REQUIRE(0 == materials[0].normal_texname.compare("normalmap.tex"));
|
||||
}
|
||||
|
||||
TEST_CASE("stream_load", "[Stream]") {
|
||||
REQUIRE(true == TestStreamLoadObj());
|
||||
}
|
||||
TEST_CASE("stream_load", "[Stream]") { REQUIRE(true == TestStreamLoadObj()); }
|
||||
|
||||
TEST_CASE("stream_load_from_file_skipping_materials", "[Stream]") {
|
||||
REQUIRE(true == TestLoadObjFromPreopenedFile(
|
||||
"../models/pbr-mat-ext.obj", gMtlBasePath, /*readMaterials*/false, /*triangulate*/false));
|
||||
"../models/pbr-mat-ext.obj", gMtlBasePath,
|
||||
/*readMaterials*/ false, /*triangulate*/ false));
|
||||
}
|
||||
|
||||
TEST_CASE("stream_load_from_file_with_materials", "[Stream]") {
|
||||
REQUIRE(true == TestLoadObjFromPreopenedFile(
|
||||
"../models/pbr-mat-ext.obj", gMtlBasePath, /*readMaterials*/true, /*triangulate*/false));
|
||||
"../models/pbr-mat-ext.obj", gMtlBasePath,
|
||||
/*readMaterials*/ true, /*triangulate*/ false));
|
||||
}
|
||||
|
||||
TEST_CASE("trailing_whitespace_in_mtl", "[Issue92]") {
|
||||
@@ -410,11 +449,17 @@ TEST_CASE("trailing_whitespace_in_mtl", "[Issue92]") {
|
||||
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, &err, "../models/issue-92.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-92.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -426,11 +471,17 @@ TEST_CASE("transmittance_filter", "[Issue95]") {
|
||||
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, &err, "../models/issue-95.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-95.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -444,11 +495,17 @@ TEST_CASE("transmittance_filter_Tf", "[Issue95-Tf]") {
|
||||
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, &err, "../models/issue-95-2.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-95-2.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -462,11 +519,17 @@ TEST_CASE("transmittance_filter_Kt", "[Issue95-Kt]") {
|
||||
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, &err, "../models/issue-95.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-95.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -480,11 +543,17 @@ TEST_CASE("usemtl_at_last_line", "[Issue104]") {
|
||||
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, &err, "../models/usemtl-issue-104.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/usemtl-issue-104.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
@@ -495,11 +564,18 @@ TEST_CASE("texture_opts", "[Issue85]") {
|
||||
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, &err, "../models/texture-options-issue-85.obj", gMtlBasePath);
|
||||
bool ret =
|
||||
tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/texture-options-issue-85.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
@@ -525,11 +601,13 @@ TEST_CASE("texture_opts", "[Issue85]") {
|
||||
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_SPHERE == materials[2].diffuse_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_TOP == materials[2].specular_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BOTTOM == materials[2].specular_highlight_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BOTTOM ==
|
||||
materials[2].specular_highlight_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_LEFT == materials[2].ambient_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_RIGHT == materials[2].alpha_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_FRONT == materials[2].bump_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BACK == materials[2].displacement_texopt.type);
|
||||
REQUIRE(tinyobj::TEXTURE_TYPE_CUBE_BACK ==
|
||||
materials[2].displacement_texopt.type);
|
||||
}
|
||||
|
||||
TEST_CASE("mtllib_multiple_filenames", "[Issue112]") {
|
||||
@@ -537,11 +615,18 @@ TEST_CASE("mtllib_multiple_filenames", "[Issue112]") {
|
||||
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, &err, "../models/mtllib-multiple-files-issue-112.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/mtllib-multiple-files-issue-112.obj",
|
||||
gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == materials.size());
|
||||
@@ -552,11 +637,17 @@ TEST_CASE("tr_and_d", "[Issue43]") {
|
||||
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, &err, "../models/tr-and-d-issue-43.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/tr-and-d-issue-43.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(2 == materials.size());
|
||||
@@ -570,11 +661,17 @@ TEST_CASE("refl", "[refl]") {
|
||||
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, &err, "../models/refl.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/refl.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
PrintInfo(attrib, shapes, materials);
|
||||
@@ -590,11 +687,17 @@ TEST_CASE("map_Bump", "[bump]") {
|
||||
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, &err, "../models/map-bump.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/map-bump.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
PrintInfo(attrib, shapes, materials);
|
||||
@@ -610,11 +713,17 @@ TEST_CASE("g_ignored", "[Issue138]") {
|
||||
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, &err, "../models/issue-138.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-138.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
PrintInfo(attrib, shapes, materials);
|
||||
@@ -622,7 +731,6 @@ TEST_CASE("g_ignored", "[Issue138]") {
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(2 == shapes.size());
|
||||
REQUIRE(2 == materials.size());
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("vertex-col-ext", "[Issue144]") {
|
||||
@@ -630,15 +738,21 @@ TEST_CASE("vertex-col-ext", "[Issue144]") {
|
||||
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, &err, "../models/cube-vertexcol.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/cube-vertexcol.obj", gMtlBasePath);
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
//PrintInfo(attrib, shapes, materials);
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
// PrintInfo(attrib, shapes, materials);
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE((8 * 3) == attrib.colors.size());
|
||||
@@ -663,18 +777,23 @@ TEST_CASE("norm_texopts", "[norm]") {
|
||||
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, &err, "../models/norm-texopt.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/norm-texopt.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
REQUIRE(1 == materials.size());
|
||||
REQUIRE(3.0 == Approx(materials[0].normal_texopt.bump_multiplier));
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("zero-face-idx-value", "[Issue140]") {
|
||||
@@ -682,16 +801,21 @@ TEST_CASE("zero-face-idx-value", "[Issue140]") {
|
||||
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, &err, "../models/issue-140-zero-face-idx.obj", gMtlBasePath);
|
||||
bool ret =
|
||||
tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-140-zero-face-idx.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
REQUIRE(false == ret);
|
||||
REQUIRE(!err.empty());
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("texture-name-whitespace", "[Issue145]") {
|
||||
@@ -699,12 +823,18 @@ TEST_CASE("texture-name-whitespace", "[Issue145]") {
|
||||
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, &err, "../models/texture-filename-with-whitespace.obj", gMtlBasePath);
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/texture-filename-with-whitespace.obj",
|
||||
gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "[Issue145] " << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
@@ -714,7 +844,6 @@ TEST_CASE("texture-name-whitespace", "[Issue145]") {
|
||||
REQUIRE(0 == materials[0].diffuse_texname.compare("texture 01.png"));
|
||||
REQUIRE(0 == materials[1].bump_texname.compare("bump 01.png"));
|
||||
REQUIRE(2 == Approx(materials[1].bump_texopt.bump_multiplier));
|
||||
|
||||
}
|
||||
|
||||
TEST_CASE("smoothing-group", "[Issue162]") {
|
||||
@@ -722,12 +851,18 @@ TEST_CASE("smoothing-group", "[Issue162]") {
|
||||
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, &err, "../models/issue-162-smoothing-group.obj", gMtlBasePath);
|
||||
bool ret =
|
||||
tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"../models/issue-162-smoothing-group.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "[Issue162] " << err << std::endl;
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
@@ -748,11 +883,141 @@ TEST_CASE("smoothing-group", "[Issue162]") {
|
||||
REQUIRE(0 == shapes[1].mesh.smoothing_group_ids[7]);
|
||||
REQUIRE(6 == shapes[1].mesh.smoothing_group_ids[8]);
|
||||
REQUIRE(6 == shapes[1].mesh.smoothing_group_ids[9]);
|
||||
}
|
||||
|
||||
TEST_CASE("invalid-face-definition", "[face]") {
|
||||
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,
|
||||
"../models/invalid-face-definition.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
REQUIRE(0 == shapes[0].mesh.indices.size());
|
||||
}
|
||||
|
||||
TEST_CASE("Empty mtl basedir", "[Issue177]") {
|
||||
tinyobj::attrib_t attrib;
|
||||
std::vector<tinyobj::shape_t> shapes;
|
||||
std::vector<tinyobj::material_t> materials;
|
||||
|
||||
std::string warn;
|
||||
std::string err;
|
||||
|
||||
// A case where the user explicitly provides an empty string
|
||||
// Win32 specific?
|
||||
const char* userBaseDir = "";
|
||||
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &warn, &err,
|
||||
"issue-177.obj", userBaseDir);
|
||||
|
||||
// if mtl loading fails, we get an warning message here
|
||||
ret &= warn.empty();
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
}
|
||||
|
||||
TEST_CASE("line-primitive", "[line]") {
|
||||
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,
|
||||
"../models/line-prim.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
REQUIRE(6 == shapes[0].path.indices.size());
|
||||
}
|
||||
|
||||
TEST_CASE("multiple-group-names", "[group]") {
|
||||
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,
|
||||
"../models/cube.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(6 == shapes.size());
|
||||
REQUIRE(0 == shapes[0].name.compare("front cube"));
|
||||
REQUIRE(0 == shapes[1].name.compare("back cube")); // multiple whitespaces
|
||||
// are aggregated as
|
||||
// single white space.
|
||||
}
|
||||
|
||||
TEST_CASE("colorspace", "[Issue184]") {
|
||||
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,
|
||||
"../models/colorspace-issue-184.obj", gMtlBasePath);
|
||||
|
||||
if (!warn.empty()) {
|
||||
std::cout << "WARN: " << warn << std::endl;
|
||||
}
|
||||
|
||||
if (!err.empty()) {
|
||||
std::cerr << "ERR: " << err << std::endl;
|
||||
}
|
||||
|
||||
REQUIRE(true == ret);
|
||||
REQUIRE(1 == shapes.size());
|
||||
REQUIRE(1 == materials.size());
|
||||
REQUIRE(0 == materials[0].diffuse_texopt.colorspace.compare("sRGB"));
|
||||
REQUIRE(0 == materials[0].specular_texopt.colorspace.size());
|
||||
REQUIRE(0 == materials[0].bump_texopt.colorspace.compare("linear"));
|
||||
}
|
||||
|
||||
// Fuzzer test.
|
||||
// Just check if it does not crash.
|
||||
// Disable by default since Windows filesystem can't create filename of afl
|
||||
// testdata
|
||||
#if 0
|
||||
|
||||
TEST_CASE("afl000000", "[AFL]") {
|
||||
tinyobj::attrib_t attrib;
|
||||
@@ -775,6 +1040,7 @@ TEST_CASE("afl000001", "[AFL]") {
|
||||
|
||||
REQUIRE(true == ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user