12 Commits

Author SHA1 Message Date
Syoyo Fujita
b2ad2cd11e Remove invalid file.
Fix compilation.
2017-12-10 00:35:02 +09:00
tigrazone
05f06d09d8 hashed tokens as keys of map. 5% speedup 2017-12-09 13:17:04 +02:00
tigrazone
3c0196bfb7 map vs unordered_map remake 2017-12-09 11:59:33 +02:00
tigrazone
dc4c970262 small speedups - up to 1-3% 2017-12-08 23:39:07 +02:00
tigrazone
aeb0f05c0e remove stringstream for simple string copy 2017-12-08 23:19:31 +02:00
tigrazone
c016910317 minimize token checks 2017-12-08 21:53:36 +02:00
tigrazone
5d7f6bf539 buffered file read 2017-12-08 13:21:45 +02:00
tigrazone
b818a34f1a small fixes2 2017-12-08 09:05:42 +02:00
tigrazone
baa62f4d89 small fixes 2017-12-08 08:43:33 +02:00
tigrazone
b2f07d10aa 1.1.2 : new hashed keywords 2017-12-07 08:38:44 +02:00
tigrazone
ee2c734c15 refactoring for new speedup release1 2017-12-06 22:44:04 +02:00
tigrazone
6e579f027f refactoring for new speedup release 2017-12-06 22:37:44 +02:00
9 changed files with 1157 additions and 1187 deletions

View File

@@ -172,3 +172,5 @@ bool WriteObj(const std::string& filename, const std::vector<tinyobj::shape_t>&
return ret; return ret;
} }

View File

@@ -37,11 +37,11 @@ extern "C" {
#include <windows.h> #include <windows.h>
#ifdef max #ifdef max
#undef max #undef max
#endif #endif
#ifdef min #ifdef min
#undef min #undef min
#endif #endif
#include <mmsystem.h> #include <mmsystem.h>
@@ -143,15 +143,15 @@ float eye[3], lookat[3], up[3];
GLFWwindow* window; GLFWwindow* window;
static std::string GetBaseDir(const std::string& filepath) { static std::string GetBaseDir(const std::string &filepath) {
if (filepath.find_last_of("/\\") != std::string::npos) if (filepath.find_last_of("/\\") != std::string::npos)
return filepath.substr(0, filepath.find_last_of("/\\")); return filepath.substr(0, filepath.find_last_of("/\\"));
return ""; return "";
} }
static bool FileExists(const std::string& abs_filename) { static bool FileExists(const std::string &abs_filename) {
bool ret; bool ret;
FILE* fp = fopen(abs_filename.c_str(), "rb"); FILE *fp = fopen(abs_filename.c_str(), "rb");
if (fp) { if (fp) {
ret = true; ret = true;
fclose(fp); fclose(fp);
@@ -190,96 +190,15 @@ static void CalcNormal(float N[3], float v0[3], float v1[3], float v2[3]) {
float len = sqrtf(len2); float len = sqrtf(len2);
N[0] /= len; N[0] /= len;
N[1] /= len; N[1] /= len;
N[2] /= len;
} }
} }
namespace // Local utility functions
{
void addBtoA(float a[3], float b[3])
{
for (size_t i = 0; i < 3; ++i)
a[i] += b[i];
}
void assignBtoA(float a[3], float b[3])
{
for (size_t i = 0; i < 3; ++i)
a[i] = b[i];
}
void normalizeVector(float N[3])
{
float len2 = N[0] * N[0] + N[1] * N[1] + N[2] * N[2];
if (len2 > 0.0f) {
float len = sqrtf(len2);
N[0] /= len;
N[1] /= len;
N[2] /= len;
}
}
void computeSmoothingNormals(tinyobj::attrib_t &attrib, tinyobj::shape_t &shape,
std::map<int, float[3]>& smoothVertexNormals)
{
smoothVertexNormals.clear();
std::map<int, float[3]>::iterator iter;
for (size_t f = 0; f < shape.mesh.indices.size() / 3; f++) {
// Get the three indexes of the face (all faces are triangular)
tinyobj::index_t idx0 = shape.mesh.indices[3 * f + 0];
tinyobj::index_t idx1 = shape.mesh.indices[3 * f + 1];
tinyobj::index_t idx2 = shape.mesh.indices[3 * f + 2];
// Get the three vertex indexes and coordinates
int vi[3]; // indexes
float v[3][3]; // coordinates
for (int k = 0; k < 3; k++) {
vi[0] = idx0.vertex_index;
vi[1] = idx1.vertex_index;
vi[2] = idx2.vertex_index;
assert(vi[0] >= 0);
assert(vi[1] >= 0);
assert(vi[2] >= 0);
v[0][k] = attrib.vertices[3 * vi[0] + k];
v[1][k] = attrib.vertices[3 * vi[1] + k];
v[2][k] = attrib.vertices[3 * vi[2] + k];
}
// Compute the normal of the face
float normal[3];
CalcNormal(normal, v[0], v[1], v[2]);
// Add the normal to the three vertexes
for (size_t i = 0; i < 3; ++i)
{
iter = smoothVertexNormals.find(vi[i]);
if (iter != smoothVertexNormals.end())
addBtoA(iter->second, normal);
else
assignBtoA(smoothVertexNormals[vi[i]], normal);
}
} // f
// Normalize the normals, that is, make them unit vectors
for (iter = smoothVertexNormals.begin(); iter != smoothVertexNormals.end(); iter++)
{
normalizeVector(iter->second);
}
} // computeSmoothingNormals
} // namespace
static bool LoadObjAndConvert(float bmin[3], float bmax[3], static bool LoadObjAndConvert(float bmin[3], float bmax[3],
std::vector<DrawObject>* drawObjects, std::vector<DrawObject>* drawObjects,
std::vector<tinyobj::material_t>& materials, std::vector<tinyobj::material_t>& materials,
std::map<std::string, GLuint>& textures, std::map<std::string, GLuint>& textures,
const char* filename) { const char* filename) {
tinyobj::attrib_t attrib; tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes; std::vector<tinyobj::shape_t> shapes;
@@ -298,8 +217,8 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
#endif #endif
std::string err; std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, bool ret =
base_dir.c_str()); tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, base_dir.c_str());
if (!err.empty()) { if (!err.empty()) {
std::cerr << err << std::endl; std::cerr << err << std::endl;
} }
@@ -323,62 +242,56 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
materials.push_back(tinyobj::material_t()); materials.push_back(tinyobj::material_t());
for (size_t i = 0; i < materials.size(); i++) { for (size_t i = 0; i < materials.size(); i++) {
printf("material[%d].diffuse_texname = %s\n", int(i), printf("material[%d].diffuse_texname = %s\n", int(i), materials[i].diffuse_texname.c_str());
materials[i].diffuse_texname.c_str());
} }
// Load diffuse textures // Load diffuse textures
{ {
for (size_t m = 0; m < materials.size(); m++) { for (size_t m = 0; m < materials.size(); m++) {
tinyobj::material_t* mp = &materials[m]; tinyobj::material_t* mp = &materials[m];
if (mp->diffuse_texname.length() > 0) {
// Only load the texture if it is not already loaded
if (textures.find(mp->diffuse_texname) == textures.end()) {
GLuint texture_id;
int w, h;
int comp;
if (mp->diffuse_texname.length() > 0) { std::string texture_filename = mp->diffuse_texname;
// Only load the texture if it is not already loaded if (!FileExists(texture_filename)) {
if (textures.find(mp->diffuse_texname) == textures.end()) { // Append base dir.
GLuint texture_id; texture_filename = base_dir + mp->diffuse_texname;
int w, h; if (!FileExists(texture_filename)) {
int comp; std::cerr << "Unable to find file: " << mp->diffuse_texname << std::endl;
exit(1);
}
}
unsigned char* image = stbi_load(texture_filename.c_str(), &w, &h, &comp, STBI_default);
if (!image) {
std::cerr << "Unable to load texture: " << texture_filename << std::endl;
exit(1);
}
std::cout << "Loaded texture: " << texture_filename << ", w = " << w << ", h = " << h << ", comp = " << comp << std::endl;
std::string texture_filename = mp->diffuse_texname; glGenTextures(1, &texture_id);
if (!FileExists(texture_filename)) { glBindTexture(GL_TEXTURE_2D, texture_id);
// Append base dir. glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
texture_filename = base_dir + mp->diffuse_texname; glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (!FileExists(texture_filename)) { if (comp == 3) {
std::cerr << "Unable to find file: " << mp->diffuse_texname glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB, GL_UNSIGNED_BYTE, image);
<< std::endl; }
exit(1); else if (comp == 4) {
} glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, image);
} else {
assert(0); // TODO
}
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(image);
textures.insert(std::make_pair(mp->diffuse_texname, texture_id));
}
} }
unsigned char* image =
stbi_load(texture_filename.c_str(), &w, &h, &comp, STBI_default);
if (!image) {
std::cerr << "Unable to load texture: " << texture_filename
<< std::endl;
exit(1);
}
std::cout << "Loaded texture: " << texture_filename << ", w = " << w
<< ", h = " << h << ", comp = " << comp << std::endl;
glGenTextures(1, &texture_id);
glBindTexture(GL_TEXTURE_2D, texture_id);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
if (comp == 3) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, w, h, 0, GL_RGB,
GL_UNSIGNED_BYTE, image);
} else if (comp == 4) {
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA,
GL_UNSIGNED_BYTE, image);
} else {
assert(0); // TODO
}
glBindTexture(GL_TEXTURE_2D, 0);
stbi_image_free(image);
textures.insert(std::make_pair(mp->diffuse_texname, texture_id));
}
} }
}
} }
bmin[0] = bmin[1] = bmin[2] = std::numeric_limits<float>::max(); bmin[0] = bmin[1] = bmin[2] = std::numeric_limits<float>::max();
@@ -388,53 +301,30 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
for (size_t s = 0; s < shapes.size(); s++) { for (size_t s = 0; s < shapes.size(); s++) {
DrawObject o; DrawObject o;
std::vector<float> buffer; // pos(3float), normal(3float), color(3float) std::vector<float> buffer; // pos(3float), normal(3float), color(3float)
for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) {
// Check for smoothing group and compute smoothing normals
std::map<int, float[3]> smoothVertexNormals;
if (shapes[s].smoothingGroupId > 0)
computeSmoothingNormals(attrib, shapes[s], smoothVertexNormals);
for (size_t f = 0; f < shapes[s].mesh.indices.size() / 3; f++) {
tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0]; tinyobj::index_t idx0 = shapes[s].mesh.indices[3 * f + 0];
tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1]; tinyobj::index_t idx1 = shapes[s].mesh.indices[3 * f + 1];
tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2]; tinyobj::index_t idx2 = shapes[s].mesh.indices[3 * f + 2];
int current_material_id = shapes[s].mesh.material_ids[f]; int current_material_id = shapes[s].mesh.material_ids[f];
if ((current_material_id < 0) || if ((current_material_id < 0) || (current_material_id >= static_cast<int>(materials.size()))) {
(current_material_id >= static_cast<int>(materials.size()))) {
// Invaid material ID. Use default material. // Invaid material ID. Use default material.
current_material_id = current_material_id = materials.size() - 1; // Default material is added to the last item in `materials`.
materials.size() -
1; // Default material is added to the last item in `materials`.
} }
// if (current_material_id >= materials.size()) { //if (current_material_id >= materials.size()) {
// std::cerr << "Invalid material index: " << current_material_id << // std::cerr << "Invalid material index: " << current_material_id << std::endl;
// std::endl;
//} //}
// //
float diffuse[3]; float diffuse[3];
for (size_t i = 0; i < 3; i++) { for (size_t i = 0; i < 3; i++) {
diffuse[i] = materials[current_material_id].diffuse[i]; diffuse[i] = materials[current_material_id].diffuse[i];
} }
float tc[3][2]; float tc[3][2];
if (attrib.texcoords.size() > 0) { if (attrib.texcoords.size() > 0) {
if ((idx0.texcoord_index < 0) || (idx1.texcoord_index < 0) || assert(attrib.texcoords.size() > 2 * idx0.texcoord_index + 1);
(idx2.texcoord_index < 0)) { assert(attrib.texcoords.size() > 2 * idx1.texcoord_index + 1);
// face does not contain valid uv index. assert(attrib.texcoords.size() > 2 * idx2.texcoord_index + 1);
tc[0][0] = 0.0f;
tc[0][1] = 0.0f;
tc[1][0] = 0.0f;
tc[1][1] = 0.0f;
tc[2][0] = 0.0f;
tc[2][1] = 0.0f;
} else {
assert(attrib.texcoords.size() >
size_t(2 * idx0.texcoord_index + 1));
assert(attrib.texcoords.size() >
size_t(2 * idx1.texcoord_index + 1));
assert(attrib.texcoords.size() >
size_t(2 * idx2.texcoord_index + 1));
// Flip Y coord. // Flip Y coord.
tc[0][0] = attrib.texcoords[2 * idx0.texcoord_index]; tc[0][0] = attrib.texcoords[2 * idx0.texcoord_index];
@@ -443,14 +333,13 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
tc[1][1] = 1.0f - attrib.texcoords[2 * idx1.texcoord_index + 1]; tc[1][1] = 1.0f - attrib.texcoords[2 * idx1.texcoord_index + 1];
tc[2][0] = attrib.texcoords[2 * idx2.texcoord_index]; tc[2][0] = attrib.texcoords[2 * idx2.texcoord_index];
tc[2][1] = 1.0f - attrib.texcoords[2 * idx2.texcoord_index + 1]; tc[2][1] = 1.0f - attrib.texcoords[2 * idx2.texcoord_index + 1];
}
} else { } else {
tc[0][0] = 0.0f; tc[0][0] = 0.0f;
tc[0][1] = 0.0f; tc[0][1] = 0.0f;
tc[1][0] = 0.0f; tc[1][0] = 0.0f;
tc[1][1] = 0.0f; tc[1][1] = 0.0f;
tc[2][0] = 0.0f; tc[2][0] = 0.0f;
tc[2][1] = 0.0f; tc[2][1] = 0.0f;
} }
float v[3][3]; float v[3][3];
@@ -474,54 +363,27 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
} }
float n[3][3]; float n[3][3];
{ if (attrib.normals.size() > 0) {
bool invalid_normal_index = false; int f0 = idx0.normal_index;
if (attrib.normals.size() > 0) { int f1 = idx1.normal_index;
int nf0 = idx0.normal_index; int f2 = idx2.normal_index;
int nf1 = idx1.normal_index; assert(f0 >= 0);
int nf2 = idx2.normal_index; assert(f1 >= 0);
assert(f2 >= 0);
if ((nf0 < 0) || (nf1 < 0) || (nf2 < 0)) { for (int k = 0; k < 3; k++) {
// normal index is missing from this face. n[0][k] = attrib.normals[3 * f0 + k];
invalid_normal_index = true; n[1][k] = attrib.normals[3 * f1 + k];
} else { n[2][k] = attrib.normals[3 * f2 + k];
for (int k = 0; k < 3; k++) {
assert(size_t(3 * nf0 + k) < attrib.normals.size());
assert(size_t(3 * nf1 + k) < attrib.normals.size());
assert(size_t(3 * nf2 + k) < attrib.normals.size());
n[0][k] = attrib.normals[3 * nf0 + k];
n[1][k] = attrib.normals[3 * nf1 + k];
n[2][k] = attrib.normals[3 * nf2 + k];
}
}
} else {
invalid_normal_index = true;
}
if (invalid_normal_index && !smoothVertexNormals.empty()) {
// Use smoothing normals
int f0 = idx0.vertex_index;
int f1 = idx1.vertex_index;
int f2 = idx2.vertex_index;
if (f0 >= 0 && f1 >= 0 && f2 >= 0) {
assignBtoA(n[0], smoothVertexNormals[f0]);
assignBtoA(n[1], smoothVertexNormals[f1]);
assignBtoA(n[2], smoothVertexNormals[f2]);
invalid_normal_index = false;
}
}
if (invalid_normal_index) {
// compute geometric normal
CalcNormal(n[0], v[0], v[1], v[2]);
n[1][0] = n[0][0];
n[1][1] = n[0][1];
n[1][2] = n[0][2];
n[2][0] = n[0][0];
n[2][1] = n[0][1];
n[2][2] = n[0][2];
} }
} else {
// compute geometric normal
CalcNormal(n[0], v[0], v[1], v[2]);
n[1][0] = n[0][0];
n[1][1] = n[0][1];
n[1][2] = n[0][2];
n[2][0] = n[0][0];
n[2][1] = n[0][1];
n[2][2] = n[0][2];
} }
for (int k = 0; k < 3; k++) { for (int k = 0; k < 3; k++) {
@@ -534,9 +396,11 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
// Combine normal and diffuse to get color. // Combine normal and diffuse to get color.
float normal_factor = 0.2; float normal_factor = 0.2;
float diffuse_factor = 1 - normal_factor; float diffuse_factor = 1 - normal_factor;
float c[3] = {n[k][0] * normal_factor + diffuse[0] * diffuse_factor, float c[3] = {
n[k][1] * normal_factor + diffuse[1] * diffuse_factor, n[k][0] * normal_factor + diffuse[0] * diffuse_factor,
n[k][2] * normal_factor + diffuse[2] * diffuse_factor}; n[k][1] * normal_factor + diffuse[1] * diffuse_factor,
n[k][2] * normal_factor + diffuse[2] * diffuse_factor
};
float len2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2]; float len2 = c[0] * c[0] + c[1] * c[1] + c[2] * c[2];
if (len2 > 0.0f) { if (len2 > 0.0f) {
float len = sqrtf(len2); float len = sqrtf(len2);
@@ -548,7 +412,7 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
buffer.push_back(c[0] * 0.5 + 0.5); buffer.push_back(c[0] * 0.5 + 0.5);
buffer.push_back(c[1] * 0.5 + 0.5); buffer.push_back(c[1] * 0.5 + 0.5);
buffer.push_back(c[2] * 0.5 + 0.5); buffer.push_back(c[2] * 0.5 + 0.5);
buffer.push_back(tc[k][0]); buffer.push_back(tc[k][0]);
buffer.push_back(tc[k][1]); buffer.push_back(tc[k][1]);
} }
@@ -558,22 +422,19 @@ static bool LoadObjAndConvert(float bmin[3], float bmax[3],
o.numTriangles = 0; o.numTriangles = 0;
// OpenGL viewer does not support texturing with per-face material. // OpenGL viewer does not support texturing with per-face material.
if (shapes[s].mesh.material_ids.size() > 0 && if (shapes[s].mesh.material_ids.size() > 0 && shapes[s].mesh.material_ids.size() > s) {
shapes[s].mesh.material_ids.size() > s) { o.material_id = shapes[s].mesh.material_ids[0]; // use the material ID of the first face.
o.material_id = shapes[s].mesh.material_ids[0]; // use the material ID
// of the first face.
} else { } else {
o.material_id = materials.size() - 1; // = ID for default material. o.material_id = materials.size() - 1; // = ID for default material.
} }
printf("shape[%d] material_id %d\n", int(s), int(o.material_id)); printf("shape[%d] material_id %d\n", int(s), int(o.material_id));
if (buffer.size() > 0) { if (buffer.size() > 0) {
glGenBuffers(1, &o.vb_id); glGenBuffers(1, &o.vb_id);
glBindBuffer(GL_ARRAY_BUFFER, o.vb_id); glBindBuffer(GL_ARRAY_BUFFER, o.vb_id);
glBufferData(GL_ARRAY_BUFFER, buffer.size() * sizeof(float), glBufferData(GL_ARRAY_BUFFER, buffer.size() * sizeof(float), &buffer.at(0),
&buffer.at(0), GL_STATIC_DRAW); GL_STATIC_DRAW);
o.numTriangles = buffer.size() / (3 + 3 + 3 + 2) / o.numTriangles = buffer.size() / (3 + 3 + 3 + 2) / 3; // 3:vtx, 3:normal, 3:col, 2:texcoord
3; // 3:vtx, 3:normal, 3:col, 2:texcoord
printf("shape[%d] # of triangles = %d\n", static_cast<int>(s), printf("shape[%d] # of triangles = %d\n", static_cast<int>(s),
o.numTriangles); o.numTriangles);
@@ -606,7 +467,7 @@ static void reshapeFunc(GLFWwindow* window, int w, int h) {
} }
static void keyboardFunc(GLFWwindow* window, int key, int scancode, int action, static void keyboardFunc(GLFWwindow* window, int key, int scancode, int action,
int mods) { int mods) {
(void)window; (void)window;
(void)scancode; (void)scancode;
(void)mods; (void)mods;
@@ -688,9 +549,7 @@ static void motionFunc(GLFWwindow* window, double mouse_x, double mouse_y) {
prevMouseY = mouse_y; prevMouseY = mouse_y;
} }
static void Draw(const std::vector<DrawObject>& drawObjects, static void Draw(const std::vector<DrawObject>& drawObjects, std::vector<tinyobj::material_t>& materials, std::map<std::string, GLuint>& textures) {
std::vector<tinyobj::material_t>& materials,
std::map<std::string, GLuint>& textures) {
glPolygonMode(GL_FRONT, GL_FILL); glPolygonMode(GL_FRONT, GL_FILL);
glPolygonMode(GL_BACK, GL_FILL); glPolygonMode(GL_BACK, GL_FILL);
@@ -713,7 +572,7 @@ static void Draw(const std::vector<DrawObject>& drawObjects,
if ((o.material_id < materials.size())) { if ((o.material_id < materials.size())) {
std::string diffuse_texname = materials[o.material_id].diffuse_texname; std::string diffuse_texname = materials[o.material_id].diffuse_texname;
if (textures.find(diffuse_texname) != textures.end()) { if (textures.find(diffuse_texname) != textures.end()) {
glBindTexture(GL_TEXTURE_2D, textures[diffuse_texname]); glBindTexture(GL_TEXTURE_2D, textures[diffuse_texname]);
} }
} }
glVertexPointer(3, GL_FLOAT, stride, (const void*)0); glVertexPointer(3, GL_FLOAT, stride, (const void*)0);
@@ -809,8 +668,7 @@ int main(int argc, char** argv) {
float bmin[3], bmax[3]; float bmin[3], bmax[3];
std::vector<tinyobj::material_t> materials; std::vector<tinyobj::material_t> materials;
std::map<std::string, GLuint> textures; std::map<std::string, GLuint> textures;
if (false == LoadObjAndConvert(bmin, bmax, &gDrawObjects, materials, textures, if (false == LoadObjAndConvert(bmin, bmax, &gDrawObjects, materials, textures, argv[1])) {
argv[1])) {
return -1; return -1;
} }

View File

@@ -1440,9 +1440,7 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
// std::cout << "mtllib :" << material_filename << std::endl; // std::cout << "mtllib :" << material_filename << std::endl;
auto t1 = std::chrono::high_resolution_clock::now(); auto t1 = std::chrono::high_resolution_clock::now();
if (material_filename.back() == '\r') {
material_filename.pop_back();
}
std::ifstream ifs(material_filename); std::ifstream ifs(material_filename);
if (ifs.good()) { if (ifs.good()) {
LoadMtl(&material_map, materials, &ifs); LoadMtl(&material_map, materials, &ifs);
@@ -1518,13 +1516,13 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
StackVector<std::thread, 16> workers; StackVector<std::thread, 16> workers;
for (size_t t = 0; t < num_threads; t++) { for (size_t t = 0; t < num_threads; t++) {
int material_id = -1; // -1 = default unknown material.
workers->push_back(std::thread([&, t]() { workers->push_back(std::thread([&, t]() {
size_t v_count = v_offsets[t]; size_t v_count = v_offsets[t];
size_t n_count = n_offsets[t]; size_t n_count = n_offsets[t];
size_t t_count = t_offsets[t]; size_t t_count = t_offsets[t];
size_t f_count = f_offsets[t]; size_t f_count = f_offsets[t];
size_t face_count = face_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++) { for (size_t i = 0; i < commands[t].size(); i++) {
if (commands[t][i].type == COMMAND_EMPTY) { if (commands[t][i].type == COMMAND_EMPTY) {
@@ -1581,19 +1579,7 @@ bool parseObj(attrib_t *attrib, std::vector<shape_t> *shapes,
for (size_t t = 0; t < workers->size(); t++) { for (size_t t = 0; t < workers->size(); t++) {
workers[t].join(); 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;
}
}
}
}
auto t_end = std::chrono::high_resolution_clock::now(); auto t_end = std::chrono::high_resolution_clock::now();
ms_merge = t_end - t_start; ms_merge = t_end - t_start;
} }

View File

@@ -29,13 +29,6 @@ extern "C" {
#endif #endif
#endif #endif
#ifdef __clang__
#pragma clang diagnostic push
#if __has_warning("-Wzero-as-null-pointer-constant")
#pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
#endif
#endif
class timerutil { class timerutil {
public: public:
#ifdef _WIN32 #ifdef _WIN32
@@ -368,7 +361,7 @@ static bool TestStreamLoadObj() {
virtual ~MaterialStringStreamReader() {} virtual ~MaterialStringStreamReader() {}
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::map<unsigned int, int>* matMap,
std::string* err) { std::string* err) {
(void)matId; (void)matId;
std::string warning; std::string warning;

View File

@@ -1,37 +0,0 @@
o cube
mtllib cube.mtl
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
g cube
usemtl cube
s 1
f 1/1 2/2 3/3
f 3/3 2/2 4/4
s 2
f 3/1 4/2 5/3
f 5/3 4/2 6/4
s 3
f 5/4 6/3 7/2
f 7/2 6/3 8/1
s 4
f 7/1 8/2 1/3
f 1/3 8/2 2/4
s 5
f 2/1 8/2 4/3
f 4/3 8/2 6/4
s 6
f 7/1 1/2 5/3
f 5 1 3

View File

@@ -1,23 +0,0 @@
newmtl test1
Ns 10.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5 0.2 0.2
Ks 0.0000 0.0000 0.0000
Ke 0.0000 0.0000 0.0000
newmtl test2
Ns 10.0000
Ni 1.5000
d 1.0000
Tr 0.0000
Tf 1.0000 1.0000 1.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.2 0.5 0.2
Ks 0.0000 0.0000 0.0000
Ke 0.0000 0.0000 0.0000

View File

@@ -1,51 +0,0 @@
# cube.obj
#
mtllib issue-162-smoothing-group.mtl
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
usemtl test1
g test1
s 1
f 1/1/1 2/2/1 3/3/1
f 3/3/1 2/2/1 4/4/1
usemtl test2
g test2
s off
f 3/1/2 4/2/2 5/3/2
f 5/3/2 4/2/2 6/4/2
s 3
f 5/4/3 6/3/3 7/2/3
f 7/2/3 6/3/3 8/1/3
s 4
f 7/1/4 8/2/4 1/3/4
f 1/3/4 8/2/4 2/4/4
s 0
f 2/1/5 8/2/5 4/3/5
f 4/3/5 8/2/5 6/4/5
s 6
f 7/1/6 1/2/6 5/3/6
f 5/3/6 1/2/6 3/4/6

View File

@@ -303,7 +303,7 @@ std::string matStream(
virtual bool operator() ( virtual bool operator() (
const std::string& matId, const std::string& matId,
std::vector<material_t>* materials, std::vector<material_t>* materials,
std::map<std::string, int>* matMap, std::map<unsigned int, int>* matMap,
std::string* err) std::string* err)
{ {
(void)matId; (void)matId;
@@ -717,40 +717,6 @@ TEST_CASE("texture-name-whitespace", "[Issue145]") {
} }
TEST_CASE("smoothing-group", "[Issue162]") {
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, "../models/issue-162-smoothing-group.obj", gMtlBasePath);
if (!err.empty()) {
std::cerr << "[Issue162] " << err << std::endl;
}
REQUIRE(true == ret);
REQUIRE(2 == shapes.size());
REQUIRE(2 == shapes[0].mesh.smoothing_group_ids.size());
REQUIRE(1 == shapes[0].mesh.smoothing_group_ids[0]);
REQUIRE(1 == shapes[0].mesh.smoothing_group_ids[1]);
REQUIRE(10 == shapes[1].mesh.smoothing_group_ids.size());
REQUIRE(0 == shapes[1].mesh.smoothing_group_ids[0]);
REQUIRE(0 == shapes[1].mesh.smoothing_group_ids[1]);
REQUIRE(3 == shapes[1].mesh.smoothing_group_ids[2]);
REQUIRE(3 == shapes[1].mesh.smoothing_group_ids[3]);
REQUIRE(4 == shapes[1].mesh.smoothing_group_ids[4]);
REQUIRE(4 == shapes[1].mesh.smoothing_group_ids[5]);
REQUIRE(0 == shapes[1].mesh.smoothing_group_ids[6]);
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]);
}
#if 0 #if 0
int int
main( main(

File diff suppressed because it is too large Load Diff