37 using namespace StrUtils;
38 using namespace FileUtils;
43 template<
typename MaterialType >
47 std::cout <<
"materials:" << std::endl;
48 for(
auto mat : materials)
50 std::cout <<
" " << mat.name << std::endl;
51 std::cout <<
"\tdiffuse/albedo: " << mat.diffuse_texture_filename
53 std::cout <<
"\tspecular: " << mat.specular_texture_filename << std::endl;
54 std::cout <<
"\ttransparency: " << mat.transparency_texture_filename
56 std::cout <<
"\tbump/normal: " << mat.normal_map_filename << std::endl;
57 std::cout <<
"\tmetallic: " << mat.metallic_map_filename << std::endl;
58 std::cout <<
"\troughness: " << mat.roughness_map_filename << std::endl;
59 std::cout <<
"\temissive: " << mat.emissive_texture_filename << std::endl;
60 std::cout <<
"\tambient/ambient occlusion: " << mat.ambient_texture_filename
69 template<
typename MaterialType >
72 std::vector< MaterialType > &materials)
76 std::ifstream file(mtl_file_name);
79 std::cout <<
"Failed to open MTL file '" << mtl_file_name <<
"'"
99 if(!new_material.
name.empty())
101 materials.push_back(new_material);
105 file >> new_material.
name;
107 else if(word[0] ==
'm')
110 std::string texture_filename;
111 file >> texture_filename;
112 texture_filename.insert(0, parent_directory +
"/");
126 else if(word[5] ==
's')
130 else if(word[5] ==
'e')
135 else if(word[4] ==
'P')
141 else if(word[5] ==
'r')
148 else if(word[4] ==
'd')
152 else if(word[4] ==
'b')
158 const std::string lower_tex_filename =
159 boost::algorithm::to_lower_copy(texture_filename);
160 if(lower_tex_filename.find(
"normal") != std::string::npos ||
161 lower_tex_filename.find(
"nrm") != std::string::npos)
165 else if(word[0] ==
'K')
167 std::string token_r, token_g, token_b;
168 file >> token_r >> token_g >> token_b;
176 else if(word[1] ==
'd')
182 else if(word[1] ==
's')
188 else if(word[1] ==
'e')
195 else if(word[0] ==
'P')
204 else if(word[1] ==
'r')
211 else if(word[0] ==
'T')
226 else if(word[0] ==
'b')
228 std::string texture_filename;
229 file >> texture_filename;
230 texture_filename.insert(0, parent_directory +
"/");
236 const std::string lower_tex_filename =
237 boost::algorithm::to_lower_copy(texture_filename);
238 if(lower_tex_filename.find(
"normal") != std::string::npos ||
239 lower_tex_filename.find(
"nrm") != std::string::npos)
242 else if(word ==
"norm")
244 std::string texture_filename;
245 file >> texture_filename;
246 texture_filename.insert(0, parent_directory +
"/");
251 else if(word[0] ==
'd')
258 else if(word[0] ==
'i')
265 switch(std::stoul(value))
307 std::getline(file, word);
311 materials.push_back(new_material);
317 template<
typename CoordType,
325 std::vector< std::vector< CoordType > > &points_coords,
326 std::vector< std::vector< CoordNType > > &normals_coords,
327 std::vector< std::vector< CoordTType > > &texture_coords,
328 std::vector< std::vector< CoordCType > > &vertex_color_coords,
329 std::vector< std::vector< IndexType > > &face_indices,
330 std::vector< std::vector< IndexType > > &texture_face_indices,
331 std::vector< std::vector< IndexType > > &normal_face_indices,
332 std::vector< MaterialType > &materials,
335 points_coords.clear();
336 normals_coords.clear();
337 face_indices.clear();
338 texture_face_indices.clear();
341 points_coords.reserve((
size_t)(cpt_l * 0.4f));
343 normals_coords.reserve((
size_t)(cpt_l * 0.4f));
344 face_indices.reserve((
size_t)(cpt_l * 0.6f));
347 std::ifstream file(file_path);
351 throw std::runtime_error(
352 "Reader::read_obj_file -> input file failed to open.");
355 std::string line_str, word;
356 std::istringstream line_ss, word_ss;
359 bool usemtl_found =
false;
360 IndexType current_material_id = -1;
366 int64_t v_ind, t_ind, n_ind;
370 std::vector< CoordNType > normal;
371 std::vector< CoordTType > tex_coord;
372 std::vector< CoordType > point;
373 std::vector< CoordCType > color;
374 std::vector< IndexType > face_points, face_textures, face_normals;
385 else if(word ==
"mtllib")
392 if(str_parent_directory.empty())
393 str_parent_directory =
".";
394 std::string mtl_file_name = str_parent_directory +
"/" + word;
400 else if(word ==
"vn")
404 for(
unsigned int i = 1; i < 4; ++i)
407 normal.push_back(n_coord);
409 normals_coords.push_back(normal);
411 else if(word ==
"vt")
415 for(
unsigned int i = 1; i < 3; ++i)
418 tex_coord.push_back(t_coord);
420 texture_coords.push_back(tex_coord);
433 for(
unsigned int i = 0; i < 3; ++i)
436 point.push_back(coord);
442 if(line_str.back() ==
'\r')
445 throw std::runtime_error(
446 "Reader::read_obj_file -> unsupported line format at line "
447 "'" + line_str +
"'. "
448 "Supported format is 'v x y z [r g b]'.");
452 for(
unsigned int i = 0; i < 3; ++i)
455 color.push_back(c_coord);
464 points_coords.push_back(point);
465 vertex_color_coords.push_back(color);
480 face_textures.clear();
481 face_normals.clear();
484 while(line_ss >> word)
491 face_points.push_back(
static_cast< IndexType
>(
492 v_ind < 0 ? v_ind + points_coords.size() : v_ind - 1));
497 if((word_ss >> delim) && (word_ss >> t_ind))
499 face_textures.push_back(
static_cast< IndexType
>(
500 t_ind < 0 ? t_ind + texture_coords.size() : t_ind - 1));
508 if((word_ss >> delim) && (word_ss >> n_ind))
510 face_normals.push_back(
static_cast< IndexType
>(
511 n_ind < 0 ? n_ind + normals_coords.size() : n_ind - 1));
517 face_textures.empty() ||
518 (face_textures.size() == face_points.size());
520 face_normals.empty() ||
521 (face_normals.size() == face_points.size());
522 if(! (texture_ok && normal_ok))
525 if(line_str.back() ==
'\r')
528 throw std::runtime_error(
529 "Reader::read_obj_file -> unsupported line format at line "
530 "'" + line_str +
"'. "
531 "Supported formats are: "
532 "'f v1 v2 v3 ....', "
533 "'f v1/vt1 v2/vt2 v3/vt3 ...', "
534 "'f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ...', "
535 "'f v1//vn1 v2//vn2 v3//vn3 ...'.");
538 face_indices.push_back(face_points);
539 texture_face_indices.push_back(face_textures);
540 normal_face_indices.push_back(face_normals);
544 else if(word ==
"usemtl")
547 std::string mtl_name;
549 current_material_id = -1;
551 for(IndexType i = 0; i < materials.size(); i++)
555 if(materials[i].name == mtl_name)
557 current_material_id = i;