Use google C++ code style.

This commit is contained in:
Syoyo Fujita
2016-04-16 20:25:33 +09:00
parent ee7d6cc0fd
commit 54bd46014c
3 changed files with 197 additions and 224 deletions

View File

@@ -1,5 +1,5 @@
--- ---
BasedOnStyle: LLVM BasedOnStyle: Google
IndentWidth: 2 IndentWidth: 2
TabWidth: 2 TabWidth: 2
UseTab: Never UseTab: Never

28
test.cc
View File

@@ -10,18 +10,18 @@
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 positions : " << (attrib.positions.size() / 3) << std::endl; std::cout << "# of vertices : " << (attrib.vertices.size() / 3) << std::endl;
std::cout << "# of normals : " << (attrib.normals.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 shapes : " << shapes.size() << std::endl;
std::cout << "# of materials : " << materials.size() << std::endl; std::cout << "# of materials : " << materials.size() << std::endl;
for (size_t v = 0; v < attrib.positions.size() / 3; v++) { for (size_t v = 0; v < attrib.vertices.size() / 3; v++) {
printf(" v[%ld] = (%f, %f, %f)\n", v, printf(" v[%ld] = (%f, %f, %f)\n", v,
static_cast<const double>(attrib.positions[3*v+0]), static_cast<const double>(attrib.vertices[3*v+0]),
static_cast<const double>(attrib.positions[3*v+1]), static_cast<const double>(attrib.vertices[3*v+1]),
static_cast<const double>(attrib.positions[3*v+2])); static_cast<const double>(attrib.vertices[3*v+2]));
} }
for (size_t v = 0; v < attrib.normals.size() / 3; v++) { for (size_t v = 0; v < attrib.normals.size() / 3; v++) {
@@ -126,15 +126,15 @@ static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj
for (size_t i = 0; i < materials.size(); i++) { for (size_t i = 0; i < materials.size(); i++) {
printf("material[%ld].name = %s\n", i, materials[i].name.c_str()); printf("material[%ld].name = %s\n", i, materials[i].name.c_str());
printf(" material.Ka = (%f, %f ,%f)\n", materials[i].ambient[0], materials[i].ambient[1], materials[i].ambient[2]); 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", materials[i].diffuse[0], materials[i].diffuse[1], materials[i].diffuse[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", materials[i].specular[0], materials[i].specular[1], materials[i].specular[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", materials[i].transmittance[0], materials[i].transmittance[1], materials[i].transmittance[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", materials[i].emission[0], materials[i].emission[1], materials[i].emission[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", materials[i].shininess); printf(" material.Ns = %f\n", static_cast<const double>(materials[i].shininess));
printf(" material.Ni = %f\n", materials[i].ior); printf(" material.Ni = %f\n", static_cast<const double>(materials[i].ior));
printf(" material.dissolve = %f\n", 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.illum = %d\n", materials[i].illum);
printf(" material.map_Ka = %s\n", materials[i].ambient_texname.c_str()); 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_Kd = %s\n", materials[i].diffuse_texname.c_str());
printf(" material.map_Ks = %s\n", materials[i].specular_texname.c_str()); printf(" material.map_Ks = %s\n", materials[i].specular_texname.c_str());

View File

@@ -5,7 +5,8 @@
// //
// //
// version devel : Change data structure. Support different index for vertex/normal/texcoord(#73, #39) // version devel : Change data structure. Support different index for
// vertex/normal/texcoord(#73, #39)
// version 0.9.20: Fixes creating per-face material using `usemtl`(#68) // version 0.9.20: Fixes creating per-face material using `usemtl`(#68)
// version 0.9.17: Support n-polygon and crease tag(OpenSubdiv extension) // version 0.9.17: Support n-polygon and crease tag(OpenSubdiv extension)
// version 0.9.16: Make tinyobjloader header-only // version 0.9.16: Make tinyobjloader header-only
@@ -57,20 +58,20 @@ typedef struct {
float transmittance[3]; float transmittance[3];
float emission[3]; float emission[3];
float shininess; float shininess;
float ior; // index of refraction float ior; // index of refraction
float dissolve; // 1 == opaque; 0 == fully transparent float dissolve; // 1 == opaque; 0 == fully transparent
// illumination model (see http://www.fileformat.info/format/material/) // illumination model (see http://www.fileformat.info/format/material/)
int illum; int illum;
int dummy; // Suppress padding warning. int dummy; // Suppress padding warning.
std::string ambient_texname; // map_Ka std::string ambient_texname; // map_Ka
std::string diffuse_texname; // map_Kd std::string diffuse_texname; // map_Kd
std::string specular_texname; // map_Ks std::string specular_texname; // map_Ks
std::string specular_highlight_texname; // map_Ns std::string specular_highlight_texname; // map_Ns
std::string bump_texname; // map_bump, bump std::string bump_texname; // map_bump, bump
std::string displacement_texname; // disp std::string displacement_texname; // disp
std::string alpha_texname; // map_d std::string alpha_texname; // map_d
std::map<std::string, std::string> unknown_parameter; std::map<std::string, std::string> unknown_parameter;
} material_t; } material_t;
@@ -93,9 +94,9 @@ typedef struct {
typedef struct { typedef struct {
std::vector<index_t> indices; std::vector<index_t> indices;
std::vector<unsigned char> std::vector<unsigned char>
num_vertices; // The number of vertices per face. Up to 255. num_vertices; // The number of vertices per face. Up to 255.
std::vector<int> material_ids; // per-face material ID std::vector<int> material_ids; // per-face material ID
std::vector<tag_t> tags; // SubD tag std::vector<tag_t> tags; // SubD tag
} mesh_t; } mesh_t;
typedef struct { typedef struct {
@@ -103,14 +104,15 @@ typedef struct {
mesh_t mesh; mesh_t mesh;
} shape_t; } shape_t;
// Vertex attributes
typedef struct { typedef struct {
std::vector<float> positions; std::vector<float> vertices; // 'v'
std::vector<float> normals; std::vector<float> normals; // 'vn'
std::vector<float> texcoords; std::vector<float> texcoords; // 'vt'
} attrib_t; } attrib_t;
class MaterialReader { class MaterialReader {
public: public:
MaterialReader() {} MaterialReader() {}
virtual ~MaterialReader(); virtual ~MaterialReader();
@@ -121,15 +123,15 @@ public:
}; };
class MaterialFileReader : public MaterialReader { class MaterialFileReader : public MaterialReader {
public: public:
MaterialFileReader(const std::string &mtl_basepath) explicit MaterialFileReader(const std::string &mtl_basepath)
: m_mtlBasePath(mtl_basepath) {} : m_mtlBasePath(mtl_basepath) {}
virtual ~MaterialFileReader() {} virtual ~MaterialFileReader() {}
virtual bool operator()(const std::string &matId, virtual bool operator()(const std::string &matId,
std::vector<material_t> *materials, std::vector<material_t> *materials,
std::map<std::string, int> *matMap, std::string *err); std::map<std::string, int> *matMap, std::string *err);
private: private:
std::string m_mtlBasePath; std::string m_mtlBasePath;
}; };
@@ -142,10 +144,8 @@ private:
/// 'mtl_basepath' is optional, and used for base path for .mtl file. /// 'mtl_basepath' is optional, and used for base path for .mtl file.
/// 'triangulate' is optional, and used whether triangulate polygon face in .obj /// 'triangulate' is optional, and used whether triangulate polygon face in .obj
/// or not. /// or not.
bool LoadObj(attrib_t *attrib, bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
std::vector<shape_t> *shapes, std::vector<material_t> *materials, std::string *err,
std::vector<material_t> *materials,
std::string *err,
const char *filename, const char *mtl_basepath = NULL, const char *filename, const char *mtl_basepath = NULL,
bool triangulate = true); bool triangulate = true);
@@ -153,18 +153,16 @@ bool LoadObj(attrib_t *attrib,
/// std::istream for materials. /// std::istream for materials.
/// Returns true when loading .obj become success. /// Returns true when loading .obj become success.
/// Returns warning and error message into `err` /// Returns warning and error message into `err`
bool LoadObj(attrib_t *attrib, bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
std::vector<shape_t> *shapes, std::vector<material_t> *materials, std::string *err,
std::vector<material_t> *materials,
std::string *err,
std::istream *inStream, MaterialReader *readMatFn, std::istream *inStream, MaterialReader *readMatFn,
bool triangulate = true); bool triangulate = true);
/// Loads materials into std::map /// Loads materials into std::map
void LoadMtl(std::map<std::string, int> *material_map, void LoadMtl(std::map<std::string, int> *material_map,
std::vector<material_t> *materials, std::vector<material_t> *materials, std::istream *inStream);
std::istream *inStream);
} } // namespace tinyobj
#ifdef TINYOBJLOADER_IMPLEMENTATION #ifdef TINYOBJLOADER_IMPLEMENTATION
#include <cstdlib> #include <cstdlib>
@@ -173,12 +171,11 @@ void LoadMtl(std::map<std::string, int> *material_map,
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
#include <cctype> #include <cctype>
#include <utility>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
#include "tiny_obj_loader.h"
namespace tinyobj { namespace tinyobj {
MaterialReader::~MaterialReader() {} MaterialReader::~MaterialReader() {}
@@ -202,12 +199,9 @@ struct tag_sizes {
// for std::map // for std::map
static inline bool operator<(const vertex_index &a, const vertex_index &b) { static inline bool operator<(const vertex_index &a, const vertex_index &b) {
if (a.v_idx != b.v_idx) if (a.v_idx != b.v_idx) return (a.v_idx < b.v_idx);
return (a.v_idx < b.v_idx); if (a.vn_idx != b.vn_idx) return (a.vn_idx < b.vn_idx);
if (a.vn_idx != b.vn_idx) if (a.vt_idx != b.vt_idx) return (a.vt_idx < b.vt_idx);
return (a.vn_idx < b.vn_idx);
if (a.vt_idx != b.vt_idx)
return (a.vt_idx < b.vt_idx);
return false; return false;
} }
@@ -218,32 +212,31 @@ struct obj_shape {
std::vector<float> vt; std::vector<float> vt;
}; };
#define IS_SPACE( x ) ( ( (x) == ' ') || ( (x) == '\t') ) #define IS_SPACE(x) (((x) == ' ') || ((x) == '\t'))
#define IS_DIGIT( x ) ( static_cast<unsigned int>( (x) - '0' ) < static_cast<unsigned int>(10) ) #define IS_DIGIT(x) \
#define IS_NEW_LINE( x ) ( ( (x) == '\r') || ( (x) == '\n') || ( (x) == '\0') ) (static_cast<unsigned int>((x) - '0') < static_cast<unsigned int>(10))
#define IS_NEW_LINE(x) (((x) == '\r') || ((x) == '\n') || ((x) == '\0'))
// Make index zero-base, and also support relative index. // Make index zero-base, and also support relative index.
static inline int fixIndex(int idx, int n) { static inline int fixIndex(int idx, int n) {
if (idx > 0) if (idx > 0) return idx - 1;
return idx - 1; if (idx == 0) return 0;
if (idx == 0) return n + idx; // negative value = relative
return 0;
return n + idx; // negative value = relative
} }
static inline std::string parseString(const char *&token) { static inline std::string parseString(const char **token) {
std::string s; std::string s;
token += strspn(token, " \t"); (*token) += strspn((*token), " \t");
size_t e = strcspn(token, " \t\r"); size_t e = strcspn((*token), " \t\r");
s = std::string(token, &token[e]); s = std::string((*token), &(*token)[e]);
token += e; (*token) += e;
return s; return s;
} }
static inline int parseInt(const char *&token) { static inline int parseInt(const char **token) {
token += strspn(token, " \t"); (*token) += strspn((*token), " \t");
int i = atoi(token); int i = atoi((*token));
token += strcspn(token, " \t\r"); (*token) += strcspn((*token), " \t\r");
return i; return i;
} }
@@ -261,7 +254,7 @@ static inline int parseInt(const char *&token) {
// float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ; // float = ( decimal , END ) | ( decimal , ("E" | "e") , integer , END ) ;
// //
// Valid strings are for example: // Valid strings are for example:
// -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2 // -0 +3.1417e+2 -0.0E-3 1.0324 -1.41 11e2
// //
// If the parsing is a success, result is set to the parsed value and true // If the parsing is a success, result is set to the parsed value and true
// is returned. // is returned.
@@ -322,11 +315,9 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
} }
// We must make sure we actually got something. // We must make sure we actually got something.
if (read == 0) if (read == 0) goto fail;
goto fail;
// We allow numbers of form "#", "###" etc. // We allow numbers of form "#", "###" etc.
if (!end_not_reached) if (!end_not_reached) goto assemble;
goto assemble;
// Read the decimal part. // Read the decimal part.
if (*curr == '.') { if (*curr == '.') {
@@ -343,8 +334,7 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
goto assemble; goto assemble;
} }
if (!end_not_reached) if (!end_not_reached) goto assemble;
goto assemble;
// Read the exponent part. // Read the exponent part.
if (*curr == 'e' || *curr == 'E') { if (*curr == 'e' || *curr == 'E') {
@@ -367,8 +357,7 @@ static bool tryParseDouble(const char *s, const char *s_end, double *result) {
read++; read++;
} }
exponent *= (exp_sign == '+' ? 1 : -1); exponent *= (exp_sign == '+' ? 1 : -1);
if (read == 0) if (read == 0) goto fail;
goto fail;
} }
assemble: assemble:
@@ -378,121 +367,118 @@ assemble:
fail: fail:
return false; return false;
} }
static inline float parseFloat(const char *&token) {
token += strspn(token, " \t"); static inline float parseFloat(const char **token) {
(*token) += strspn((*token), " \t");
#ifdef TINY_OBJ_LOADER_OLD_FLOAT_PARSER #ifdef TINY_OBJ_LOADER_OLD_FLOAT_PARSER
float f = (float)atof(token); float f = static_cast<float>(atof(*token));
token += strcspn(token, " \t\r"); (*token) += strcspn((*token), " \t\r");
#else #else
const char *end = token + strcspn(token, " \t\r"); const char *end = (*token) + strcspn((*token), " \t\r");
double val = 0.0; double val = 0.0;
tryParseDouble(token, end, &val); tryParseDouble((*token), end, &val);
float f = static_cast<float>(val); float f = static_cast<float>(val);
token = end; (*token) = end;
#endif #endif
return f; return f;
} }
static inline void parseFloat2(float &x, float &y, const char *&token) { static inline void parseFloat2(float *x, float *y, const char **token) {
x = parseFloat(token); (*x) = parseFloat(token);
y = parseFloat(token); (*y) = parseFloat(token);
} }
static inline void parseFloat3(float &x, float &y, float &z, static inline void parseFloat3(float *x, float *y, float *z,
const char *&token) { const char **token) {
x = parseFloat(token); (*x) = parseFloat(token);
y = parseFloat(token); (*y) = parseFloat(token);
z = parseFloat(token); (*z) = parseFloat(token);
} }
static tag_sizes parseTagTriple(const char *&token) { static tag_sizes parseTagTriple(const char **token) {
tag_sizes ts; tag_sizes ts;
ts.num_ints = atoi(token); ts.num_ints = atoi((*token));
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
if (token[0] != '/') { if ((*token)[0] != '/') {
return ts; return ts;
} }
token++; (*token)++;
ts.num_floats = atoi(token); ts.num_floats = atoi((*token));
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
if (token[0] != '/') { if ((*token)[0] != '/') {
return ts; return ts;
} }
token++; (*token)++;
ts.num_strings = atoi(token); ts.num_strings = atoi((*token));
token += strcspn(token, "/ \t\r") + 1; (*token) += strcspn((*token), "/ \t\r") + 1;
return ts; return ts;
} }
// Parse triples: i, i/j/k, i//k, i/j // Parse triples: i, i/j/k, i//k, i/j
static vertex_index parseTriple(const char *&token, int vsize, int vnsize, static vertex_index parseTriple(const char **token, int vsize, int vnsize,
int vtsize) { int vtsize) {
vertex_index vi(-1); vertex_index vi(-1);
vi.v_idx = fixIndex(atoi(token), vsize); vi.v_idx = fixIndex(atoi((*token)), vsize);
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
if (token[0] != '/') { if ((*token)[0] != '/') {
return vi; return vi;
} }
token++; (*token)++;
// i//k // i//k
if (token[0] == '/') { if ((*token)[0] == '/') {
token++; (*token)++;
vi.vn_idx = fixIndex(atoi(token), vnsize); vi.vn_idx = fixIndex(atoi((*token)), vnsize);
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
return vi; return vi;
} }
// i/j/k or i/j // i/j/k or i/j
vi.vt_idx = fixIndex(atoi(token), vtsize); vi.vt_idx = fixIndex(atoi((*token)), vtsize);
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
if (token[0] != '/') { if ((*token)[0] != '/') {
return vi; return vi;
} }
// i/j/k // i/j/k
token++; // skip '/' (*token)++; // skip '/'
vi.vn_idx = fixIndex(atoi(token), vnsize); vi.vn_idx = fixIndex(atoi((*token)), vnsize);
token += strcspn(token, "/ \t\r"); (*token) += strcspn((*token), "/ \t\r");
return vi; return vi;
} }
static void InitMaterial(material_t &material) { static void InitMaterial(material_t *material) {
material.name = ""; material->name = "";
material.ambient_texname = ""; material->ambient_texname = "";
material.diffuse_texname = ""; material->diffuse_texname = "";
material.specular_texname = ""; material->specular_texname = "";
material.specular_highlight_texname = ""; material->specular_highlight_texname = "";
material.bump_texname = ""; material->bump_texname = "";
material.displacement_texname = ""; material->displacement_texname = "";
material.alpha_texname = ""; material->alpha_texname = "";
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
material.ambient[i] = 0.f; material->ambient[i] = 0.f;
material.diffuse[i] = 0.f; material->diffuse[i] = 0.f;
material.specular[i] = 0.f; material->specular[i] = 0.f;
material.transmittance[i] = 0.f; material->transmittance[i] = 0.f;
material.emission[i] = 0.f; material->emission[i] = 0.f;
} }
material.illum = 0; material->illum = 0;
material.dissolve = 1.f; material->dissolve = 1.f;
material.shininess = 1.f; material->shininess = 1.f;
material.ior = 1.f; material->ior = 1.f;
material.unknown_parameter.clear(); material->unknown_parameter.clear();
} }
static bool exportFaceGroupToShape( static bool exportFaceGroupToShape(
shape_t &shape, shape_t *shape, const std::vector<std::vector<vertex_index> > &faceGroup,
const std::vector<float> &in_positions, const std::vector<tag_t> &tags, const int material_id,
const std::vector<float> &in_normals, const std::string &name, bool triangulate) {
const std::vector<float> &in_texcoords,
const std::vector<std::vector<vertex_index> > &faceGroup,
std::vector<tag_t> &tags, const int material_id, const std::string &name,
bool triangulate) {
if (faceGroup.empty()) { if (faceGroup.empty()) {
return false; return false;
} }
@@ -508,7 +494,6 @@ static bool exportFaceGroupToShape(
size_t npolys = face.size(); size_t npolys = face.size();
if (triangulate) { if (triangulate) {
// Polygon -> triangle fan conversion // Polygon -> triangle fan conversion
for (size_t k = 2; k < npolys; k++) { for (size_t k = 2; k < npolys; k++) {
i1 = i2; i1 = i2;
@@ -525,15 +510,14 @@ static bool exportFaceGroupToShape(
idx2.normal_index = i2.vn_idx; idx2.normal_index = i2.vn_idx;
idx2.texcoord_index = i2.vt_idx; idx2.texcoord_index = i2.vt_idx;
shape.mesh.indices.push_back(idx0); shape->mesh.indices.push_back(idx0);
shape.mesh.indices.push_back(idx1); shape->mesh.indices.push_back(idx1);
shape.mesh.indices.push_back(idx2); shape->mesh.indices.push_back(idx2);
shape.mesh.num_vertices.push_back(3); shape->mesh.num_vertices.push_back(3);
shape.mesh.material_ids.push_back(material_id); shape->mesh.material_ids.push_back(material_id);
} }
} else { } else {
for (size_t k = 0; k < npolys; k++) { for (size_t k = 0; k < npolys; k++) {
index_t idx; index_t idx;
idx.vertex_index = face[k].v_idx; idx.vertex_index = face[k].v_idx;
@@ -541,26 +525,25 @@ static bool exportFaceGroupToShape(
idx.texcoord_index = face[k].vt_idx; idx.texcoord_index = face[k].vt_idx;
} }
shape.mesh.num_vertices.push_back(static_cast<unsigned char>(npolys)); shape->mesh.num_vertices.push_back(static_cast<unsigned char>(npolys));
shape.mesh.material_ids.push_back(material_id); // per face shape->mesh.material_ids.push_back(material_id); // per face
} }
} }
shape.name = name; shape->name = name;
shape.mesh.tags.swap(tags); shape->mesh.tags = tags;
return true; return true;
} }
void LoadMtl(std::map<std::string, int> *material_map, void LoadMtl(std::map<std::string, int> *material_map,
std::vector<material_t> *materials, std::istream *inStream) { std::vector<material_t> *materials, std::istream *inStream) {
// Create a default material anyway. // Create a default material anyway.
material_t material; material_t material;
InitMaterial(material); InitMaterial(&material);
size_t maxchars = 8192; // Alloc enough size. size_t maxchars = 8192; // Alloc enough size.
std::vector<char> buf(maxchars); // Alloc enough size. std::vector<char> buf(maxchars); // Alloc enough size.
while (inStream->peek() != -1) { while (inStream->peek() != -1) {
inStream->getline(&buf[0], static_cast<std::streamsize>(maxchars)); inStream->getline(&buf[0], static_cast<std::streamsize>(maxchars));
@@ -586,11 +569,9 @@ void LoadMtl(std::map<std::string, int> *material_map,
token += strspn(token, " \t"); token += strspn(token, " \t");
assert(token); assert(token);
if (token[0] == '\0') if (token[0] == '\0') continue; // empty line
continue; // empty line
if (token[0] == '#') if (token[0] == '#') continue; // comment line
continue; // comment line
// new mtl // new mtl
if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) { if ((0 == strncmp(token, "newmtl", 6)) && IS_SPACE((token[6]))) {
@@ -602,7 +583,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
} }
// initial temporary material // initial temporary material
InitMaterial(material); InitMaterial(&material);
// set new mtl name // set new mtl name
char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE];
@@ -620,7 +601,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) { if (token[0] == 'K' && token[1] == 'a' && IS_SPACE((token[2]))) {
token += 2; token += 2;
float r, g, b; float r, g, b;
parseFloat3(r, g, b, token); parseFloat3(&r, &g, &b, &token);
material.ambient[0] = r; material.ambient[0] = r;
material.ambient[1] = g; material.ambient[1] = g;
material.ambient[2] = b; material.ambient[2] = b;
@@ -631,7 +612,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) { if (token[0] == 'K' && token[1] == 'd' && IS_SPACE((token[2]))) {
token += 2; token += 2;
float r, g, b; float r, g, b;
parseFloat3(r, g, b, token); parseFloat3(&r, &g, &b, &token);
material.diffuse[0] = r; material.diffuse[0] = r;
material.diffuse[1] = g; material.diffuse[1] = g;
material.diffuse[2] = b; material.diffuse[2] = b;
@@ -642,7 +623,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) { if (token[0] == 'K' && token[1] == 's' && IS_SPACE((token[2]))) {
token += 2; token += 2;
float r, g, b; float r, g, b;
parseFloat3(r, g, b, token); parseFloat3(&r, &g, &b, &token);
material.specular[0] = r; material.specular[0] = r;
material.specular[1] = g; material.specular[1] = g;
material.specular[2] = b; material.specular[2] = b;
@@ -653,7 +634,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
if (token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) { if (token[0] == 'K' && token[1] == 't' && IS_SPACE((token[2]))) {
token += 2; token += 2;
float r, g, b; float r, g, b;
parseFloat3(r, g, b, token); parseFloat3(&r, &g, &b, &token);
material.transmittance[0] = r; material.transmittance[0] = r;
material.transmittance[1] = g; material.transmittance[1] = g;
material.transmittance[2] = b; material.transmittance[2] = b;
@@ -663,7 +644,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
// ior(index of refraction) // ior(index of refraction)
if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) { if (token[0] == 'N' && token[1] == 'i' && IS_SPACE((token[2]))) {
token += 2; token += 2;
material.ior = parseFloat(token); material.ior = parseFloat(&token);
continue; continue;
} }
@@ -671,7 +652,7 @@ void LoadMtl(std::map<std::string, int> *material_map,
if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) { if (token[0] == 'K' && token[1] == 'e' && IS_SPACE(token[2])) {
token += 2; token += 2;
float r, g, b; float r, g, b;
parseFloat3(r, g, b, token); parseFloat3(&r, &g, &b, &token);
material.emission[0] = r; material.emission[0] = r;
material.emission[1] = g; material.emission[1] = g;
material.emission[2] = b; material.emission[2] = b;
@@ -681,27 +662,27 @@ void LoadMtl(std::map<std::string, int> *material_map,
// shininess // shininess
if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) { if (token[0] == 'N' && token[1] == 's' && IS_SPACE(token[2])) {
token += 2; token += 2;
material.shininess = parseFloat(token); material.shininess = parseFloat(&token);
continue; continue;
} }
// illum model // illum model
if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) { if (0 == strncmp(token, "illum", 5) && IS_SPACE(token[5])) {
token += 6; token += 6;
material.illum = parseInt(token); material.illum = parseInt(&token);
continue; continue;
} }
// dissolve // dissolve
if ((token[0] == 'd' && IS_SPACE(token[1]))) { if ((token[0] == 'd' && IS_SPACE(token[1]))) {
token += 1; token += 1;
material.dissolve = parseFloat(token); material.dissolve = parseFloat(&token);
continue; continue;
} }
if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) { if (token[0] == 'T' && token[1] == 'r' && IS_SPACE(token[2])) {
token += 2; token += 2;
// Invert value of Tr(assume Tr is in range [0, 1]) // Invert value of Tr(assume Tr is in range [0, 1])
material.dissolve = 1.0f - parseFloat(token); material.dissolve = 1.0f - parseFloat(&token);
continue; continue;
} }
@@ -805,13 +786,11 @@ bool MaterialFileReader::operator()(const std::string &matId,
return true; return true;
} }
bool LoadObj(attrib_t *attrib, bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
std::vector<shape_t> *shapes, std::vector<material_t> *materials, std::string *err,
std::vector<material_t> *materials, const char *filename, const char *mtl_basepath,
std::string *err, const char *filename, const char *mtl_basepath,
bool trianglulate) { bool trianglulate) {
attrib->vertices.clear();
attrib->positions.clear();
attrib->normals.clear(); attrib->normals.clear();
attrib->texcoords.clear(); attrib->texcoords.clear();
shapes->clear(); shapes->clear();
@@ -833,14 +812,14 @@ bool LoadObj(attrib_t *attrib,
} }
MaterialFileReader matFileReader(basePath); MaterialFileReader matFileReader(basePath);
return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader, trianglulate); return LoadObj(attrib, shapes, materials, err, &ifs, &matFileReader,
trianglulate);
} }
bool LoadObj(attrib_t *attrib, bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
std::vector<shape_t> *shapes, std::vector<material_t> *materials, std::string *err,
std::vector<material_t> *materials, std::istream *inStream, MaterialReader *readMatFn,
std::string *err, std::istream *inStream, bool triangulate) {
MaterialReader *readMatFn, bool triangulate) {
std::stringstream errss; std::stringstream errss;
std::vector<float> v; std::vector<float> v;
@@ -852,13 +831,13 @@ bool LoadObj(attrib_t *attrib,
// material // material
std::map<std::string, int> material_map; std::map<std::string, int> material_map;
//std::map<vertex_index, unsigned int> vertexCache; // std::map<vertex_index, unsigned int> vertexCache;
int material = -1; int material = -1;
shape_t shape; shape_t shape;
int maxchars = 8192; // Alloc enough size. int maxchars = 8192; // Alloc enough size.
std::vector<char> buf(static_cast<size_t>(maxchars)); // Alloc enough size. std::vector<char> buf(static_cast<size_t>(maxchars)); // Alloc enough size.
while (inStream->peek() != -1) { while (inStream->peek() != -1) {
inStream->getline(&buf[0], maxchars); inStream->getline(&buf[0], maxchars);
@@ -884,17 +863,15 @@ bool LoadObj(attrib_t *attrib,
token += strspn(token, " \t"); token += strspn(token, " \t");
assert(token); assert(token);
if (token[0] == '\0') if (token[0] == '\0') continue; // empty line
continue; // empty line
if (token[0] == '#') if (token[0] == '#') continue; // comment line
continue; // comment line
// vertex // vertex
if (token[0] == 'v' && IS_SPACE((token[1]))) { if (token[0] == 'v' && IS_SPACE((token[1]))) {
token += 2; token += 2;
float x, y, z; float x, y, z;
parseFloat3(x, y, z, token); parseFloat3(&x, &y, &z, &token);
v.push_back(x); v.push_back(x);
v.push_back(y); v.push_back(y);
v.push_back(z); v.push_back(z);
@@ -905,7 +882,7 @@ bool LoadObj(attrib_t *attrib,
if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) { if (token[0] == 'v' && token[1] == 'n' && IS_SPACE((token[2]))) {
token += 3; token += 3;
float x, y, z; float x, y, z;
parseFloat3(x, y, z, token); parseFloat3(&x, &y, &z, &token);
vn.push_back(x); vn.push_back(x);
vn.push_back(y); vn.push_back(y);
vn.push_back(z); vn.push_back(z);
@@ -916,7 +893,7 @@ bool LoadObj(attrib_t *attrib,
if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) { if (token[0] == 'v' && token[1] == 't' && IS_SPACE((token[2]))) {
token += 3; token += 3;
float x, y; float x, y;
parseFloat2(x, y, token); parseFloat2(&x, &y, &token);
vt.push_back(x); vt.push_back(x);
vt.push_back(y); vt.push_back(y);
continue; continue;
@@ -931,7 +908,7 @@ bool LoadObj(attrib_t *attrib,
face.reserve(3); face.reserve(3);
while (!IS_NEW_LINE(token[0])) { while (!IS_NEW_LINE(token[0])) {
vertex_index vi = parseTriple(token, static_cast<int>(v.size() / 3), vertex_index vi = parseTriple(&token, static_cast<int>(v.size() / 3),
static_cast<int>(vn.size() / 3), static_cast<int>(vn.size() / 3),
static_cast<int>(vt.size() / 2)); static_cast<int>(vt.size() / 2));
face.push_back(vi); face.push_back(vi);
@@ -948,7 +925,6 @@ bool LoadObj(attrib_t *attrib,
// use mtl // use mtl
if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) { if ((0 == strncmp(token, "usemtl", 6)) && IS_SPACE((token[6]))) {
char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE]; char namebuf[TINYOBJ_SSCANF_BUFFER_SIZE];
token += 7; token += 7;
#ifdef _MSC_VER #ifdef _MSC_VER
@@ -966,8 +942,8 @@ bool LoadObj(attrib_t *attrib,
if (newMaterialId != material) { if (newMaterialId != material) {
// Create per-face material // Create per-face material
exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
material, name, triangulate); triangulate);
faceGroup.clear(); faceGroup.clear();
material = newMaterialId; material = newMaterialId;
} }
@@ -992,7 +968,7 @@ bool LoadObj(attrib_t *attrib,
} }
if (!ok) { if (!ok) {
faceGroup.clear(); // for safety faceGroup.clear(); // for safety
return false; return false;
} }
@@ -1001,11 +977,9 @@ bool LoadObj(attrib_t *attrib,
// group name // group name
if (token[0] == 'g' && IS_SPACE((token[1]))) { if (token[0] == 'g' && IS_SPACE((token[1]))) {
// flush previous face group. // flush previous face group.
bool ret = bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, triangulate);
material, name, triangulate);
if (ret) { if (ret) {
shapes->push_back(shape); shapes->push_back(shape);
} }
@@ -1019,9 +993,9 @@ bool LoadObj(attrib_t *attrib,
names.reserve(2); names.reserve(2);
while (!IS_NEW_LINE(token[0])) { while (!IS_NEW_LINE(token[0])) {
std::string str = parseString(token); std::string str = parseString(&token);
names.push_back(str); names.push_back(str);
token += strspn(token, " \t\r"); // skip tag token += strspn(token, " \t\r"); // skip tag
} }
assert(names.size() > 0); assert(names.size() > 0);
@@ -1038,11 +1012,9 @@ bool LoadObj(attrib_t *attrib,
// object name // object name
if (token[0] == 'o' && IS_SPACE((token[1]))) { if (token[0] == 'o' && IS_SPACE((token[1]))) {
// flush previous face group. // flush previous face group.
bool ret = bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
exportFaceGroupToShape(shape, v, vn, vt, faceGroup, tags, triangulate);
material, name, triangulate);
if (ret) { if (ret) {
shapes->push_back(shape); shapes->push_back(shape);
} }
@@ -1078,7 +1050,7 @@ bool LoadObj(attrib_t *attrib,
token += tag.name.size() + 1; token += tag.name.size() + 1;
tag_sizes ts = parseTagTriple(token); tag_sizes ts = parseTagTriple(&token);
tag.intValues.resize(static_cast<size_t>(ts.num_ints)); tag.intValues.resize(static_cast<size_t>(ts.num_ints));
@@ -1089,7 +1061,7 @@ bool LoadObj(attrib_t *attrib,
tag.floatValues.resize(static_cast<size_t>(ts.num_floats)); tag.floatValues.resize(static_cast<size_t>(ts.num_floats));
for (size_t i = 0; i < static_cast<size_t>(ts.num_floats); ++i) { for (size_t i = 0; i < static_cast<size_t>(ts.num_floats); ++i) {
tag.floatValues[i] = parseFloat(token); tag.floatValues[i] = parseFloat(&token);
token += strcspn(token, "/ \t\r") + 1; token += strcspn(token, "/ \t\r") + 1;
} }
@@ -1098,7 +1070,8 @@ bool LoadObj(attrib_t *attrib,
char stringValueBuffer[4096]; char stringValueBuffer[4096];
#ifdef _MSC_VER #ifdef _MSC_VER
sscanf_s(token, "%s", stringValueBuffer, (unsigned)_countof(stringValueBuffer)); sscanf_s(token, "%s", stringValueBuffer,
(unsigned)_countof(stringValueBuffer));
#else #else
sscanf(token, "%s", stringValueBuffer); sscanf(token, "%s", stringValueBuffer);
#endif #endif
@@ -1112,26 +1085,26 @@ bool LoadObj(attrib_t *attrib,
// Ignore unknown command. // Ignore unknown command.
} }
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, bool ret = exportFaceGroupToShape(&shape, faceGroup, tags, material, name,
tags, material, name, triangulate); triangulate);
if (ret) { if (ret) {
shapes->push_back(shape); shapes->push_back(shape);
} }
faceGroup.clear(); // for safety faceGroup.clear(); // for safety
if (err) { if (err) {
(*err) += errss.str(); (*err) += errss.str();
} }
attrib->positions.swap(v); attrib->vertices.swap(v);
attrib->normals.swap(vn); attrib->normals.swap(vn);
attrib->texcoords.swap(vt); attrib->texcoords.swap(vt);
return true; return true;
} }
} // namespace } // namespace tinyobj
#endif #endif
#endif // TINY_OBJ_LOADER_H_ #endif // TINY_OBJ_LOADER_H_