31 #pragma warning(disable : 4267)
45 namespace DataStructures {
52 using namespace FileUtils;
53 using namespace StrUtils;
55 if(!boost::filesystem::exists(filePath))
56 throw std::invalid_argument(
57 "Reader::read -> input file path refer to no existing file.");
59 throw std::invalid_argument(
60 "Reader::read -> input file path find without any extension.");
65 std::vector< std::string > validExtensions = {
66 ".obj",
".off",
".coff",
".ply",
".msh"};
67 std::vector< std::string > validVtkExtensions = {
".vtk",
".vtp",
".vtu"};
74 throw std::invalid_argument(
75 "Reader::read -> input file extension can't be read (yet).");
78 std::vector< std::vector< coord_type > > points_coords;
79 std::vector< std::vector< coordN_type > > normals_coords;
80 std::vector< std::vector< coordT_type > > texture_coords;
84 std::vector< std::vector< coordC_type > > vertex_color_coords;
85 std::vector< std::vector< coordC_type > > face_color_coords;
86 std::vector< std::vector< index_type > > lines_indices, faces_indices;
87 std::vector< std::vector< index_type > > texture_face_indices;
89 std::vector< std::vector< index_type > > normal_face_indices;
90 std::vector< std::vector< coordC_type > > points_colors, faces_colors,
92 std::vector< std::vector< std::vector< double > > > field_attributes;
93 std::vector< std::string > field_names;
95 std::string texture_file_name;
97 std::vector< FEVV::Types::Material > materials;
100 bool obj_file =
false;
110 texture_face_indices,
116 if(!materials.empty())
117 texture_file_name = materials[0].diffuse_texture_filename;
137 texture_face_indices);
177 texture_face_indices,
195 if(vertex_color_coords.size() != points_coords.size())
196 vertex_color_coords.clear();
197 for(
auto &color : vertex_color_coords)
199 if(color.size() < 3 || color.size() > 4)
201 std::cout <<
"AIFMeshReader::read(): found vertex color with size neither "
202 "3 nor 4. Disabling vertex color for all vertices."
204 vertex_color_coords.clear();
210 if(face_color_coords.size() != faces_indices.size())
211 face_color_coords.clear();
212 for(
auto &color : face_color_coords)
214 if(color.size() < 3 || color.size() > 4)
216 std::cout <<
"AIFMeshReader::read(): found face color with size neither 3 nor 4. "
217 "Disabling face color for all vertices."
219 face_color_coords.clear();
229 std::cout <<
"AIFMeshReader::read(): found some faces with a material and some "
230 "without. Disabling material for all faces."
243 std::cout <<
"AIFMeshReader::read(): found some faces with an invalid material. "
244 "Disabling material for all faces."
253 if(!texture_file_name.empty())
258 "m:texturefilename");
259 if(!outputMesh->isAssocPropertyMap(
"m:texturefilename"))
260 throw std::runtime_error(
261 "Failed to create texture-filename property map.");
263 (*tfn_pm)[outputMesh.get()] = texture_file_name;
265 std::cout <<
"AIF property map for texture-filename created." << std::endl;
268 if (!field_names.empty())
270 auto it = field_names.begin();
271 auto ite = field_names.end();
272 for (; it != ite; ++it)
274 if (it->find(
"POINT_DATA_") != std::string::npos )
278 outputMesh->AddPropertyMap<
AIFVertex::ptr, std::vector<double> >(
279 "v:datafield:"+ it->substr(11));
280 if (!outputMesh->isPropertyMap<
AIFVertex::ptr >(
"v:datafield:" + it->substr(11)))
281 throw std::runtime_error(
282 "Failed to create a vertex data field property map.");
284 else if (it->find(
"ELEMENT_DATA_") != std::string::npos)
288 outputMesh->AddPropertyMap<
AIFFace::ptr, std::vector<double> >(
289 "f:datafield:" + it->substr(13));
290 if (!outputMesh->isPropertyMap<
AIFFace::ptr >(
"f:datafield:" + it->substr(13)))
291 throw std::runtime_error(
292 "Failed to create a face data field property map.");
294 else if (it->find(
"CELL_DATA_") != std::string::npos)
298 outputMesh->AddPropertyMap<
AIFFace::ptr, std::vector<double> >(
299 "f:datafield:" + it->substr(10));
300 if (!outputMesh->isPropertyMap<
AIFFace::ptr >(
"f:datafield:" + it->substr(10)))
301 throw std::runtime_error(
302 "Failed to create a face data field property map.");
309 bool useVertexNormal =
false;
310 bool useVertexColor =
false;
311 bool useVertexTextureCoord =
false;
312 bool useCornerTextureCoord =
false;
313 bool useFaceColor =
false;
314 bool useFaceNormal =
false;
317 if(!texture_coords.empty())
323 useCornerTextureCoord =
true;
325 else if(texture_coords.size() == points_coords.size())
328 useVertexTextureCoord =
true;
330 else if(texture_face_indices.size() == faces_indices.size())
333 useCornerTextureCoord =
true;
337 if(useVertexTextureCoord)
343 throw std::runtime_error(
344 "Failed to create vertex-texture-coordinate property map.");
346 std::cout <<
"AIF property map for vertex-texture-coordinate created."
349 else if(useCornerTextureCoord)
354 if(!outputMesh->isAssocPropertyMap(
"h:texcoord"))
355 throw std::runtime_error(
356 "Failed to create halfedge-texture-coordinate property map.");
358 std::cout <<
"AIF property map for halfedge-texture-coordinate created."
363 if(!normals_coords.empty())
368 if(normals_coords.size() == points_coords.size())
370 useVertexNormal =
true;
375 throw std::runtime_error(
376 "Failed to create vertex-normal property map.");
378 std::cout <<
"AIF property map for vertex-normal created." << std::endl;
380 else if(!normal_face_indices[0].empty())
383 useFaceNormal =
true;
387 if(!outputMesh->isPropertyMap<
AIFFace::ptr >(
"f:normal"))
388 throw std::runtime_error(
"Failed to create face-normal property map.");
390 std::cout <<
"AIF property map for face-normal created." << std::endl;
394 if(!vertex_color_coords.empty())
396 useVertexColor =
true;
401 throw std::runtime_error(
"Failed to create vertex-color property map.");
403 std::cout <<
"AIF property map for vertex-color created." << std::endl;
406 if(!face_color_coords.empty())
412 if(!outputMesh->isPropertyMap<
AIFFace::ptr >(
"f:color"))
413 throw std::runtime_error(
"Failed to create face-color property map.");
415 std::cout <<
"AIF property map for face-color created." << std::endl;
421 std::vector< helpers::vertex_type::ptr >
vertices;
422 vertices.reserve(points_coords.size());
424 typedef std::vector< std::vector< coord_type > >::const_iterator point_it;
426 for(point_it itP = points_coords.begin(); itP != points_coords.end(); ++itP)
431 PropHelpers::set_point(
432 outputMesh, currentVertex, (*itP)[0], (*itP)[1], (*itP)[2]);
438 if(useVertexNormal || useVertexColor || useVertexTextureCoord)
444 std::vector< coordN_type > &coords = normals_coords[vertexNbr - 1];
446 if(coords.size() < 3 || coords.size() > 4)
447 throw std::runtime_error(
"Support of normal coordinates of size "
448 "neither 3 nor 4 not supported!");
452 "v:normal", currentVertex->GetIndex(), vn);
458 std::vector< coordC_type > &coords = vertex_color_coords[vertexNbr - 1];
465 "v:color", currentVertex->GetIndex(), vc);
467 if(useVertexTextureCoord)
471 std::vector< coordT_type > &coords = texture_coords[vertexNbr - 1];
473 if(coords.size() != 2)
474 throw std::runtime_error(
"Support of texture coordinates of size != "
475 "2 not yet implemented!");
480 "v:texcoord", currentVertex->GetIndex(), texCoords);
483 if (!field_names.empty())
485 auto it = field_names.begin();
486 auto ite = field_names.end();
487 auto it_d = field_attributes.begin();
488 for (; it != ite; ++it, ++it_d)
490 if (it->find(
"POINT_DATA_") != std::string::npos)
494 (
"v:datafield:" + it->substr(11)), currentVertex->GetIndex(), (*it_d)[vertexNbr - 1]);
502 typedef std::vector< std::vector< index_type > >::const_iterator line_it;
503 for(line_it itL = lines_indices.begin(); itL != lines_indices.end(); ++itL)
527 firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
529 secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
534 typedef std::vector< std::vector< index_type > >:: iterator face_it;
535 typedef std::vector< index_type >::const_iterator index_it;
537 for(face_it itF = faces_indices.begin(); itF != faces_indices.end();
542 throw std::runtime_error(
"Reader::read -> find a face with less than two "
543 "vertices : not complying case.");
545 else if(itF->size() == 2)
562 firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
564 secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
573 if(!FEVV::FaceIndicesUtils::are_all_face_indices_unique< index_type >(
576 std::vector< index_type > out_face_indices;
577 std::vector< std::vector< index_type > > out_lines_indices;
579 index_type >(*itF, out_face_indices, out_lines_indices);
580 *itF = out_face_indices;
585 typedef std::vector< std::vector< index_type > >::const_iterator
587 for(line_it itL = out_lines_indices.begin();
588 itL != out_lines_indices.end();
606 firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
608 secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
621 for(index_it it = itF->begin(); it != itF->end(); ++it, ++faceVertexId)
636 prevVertex, currentEdge, helpers::vertex_pos::FIRST);
638 currentVertex, currentEdge, helpers::vertex_pos::SECOND);
640 bool face_has_that_incident_edge =
642 bool edge_has_that_incident_face =
644 if(!face_has_that_incident_edge ||
645 !edge_has_that_incident_face)
654 if(useCornerTextureCoord)
657 switch (texture_face_indices[faceId].size())
659 case 0:
throw std::runtime_error(
"corner texture: found a face (index " +
FEVV::StrUtils::convert(faceId) +
") without any texture coord index");
660 case 1:
throw std::runtime_error(
"corner texture: found a face (index " +
FEVV::StrUtils::convert(faceId) +
") associated with only one texture coord index");
661 case 2:
throw std::runtime_error(
"corner texture: found a face (index " +
FEVV::StrUtils::convert(faceId) +
") associated with only two texture coord indices");
664 if(texture_face_indices[faceId].size() ==
665 faces_indices[faceId].size())
669 index_type textureId = texture_face_indices[faceId][faceVertexId];
670 std::vector< coordT_type > &coords = texture_coords[textureId];
671 if(coords.size() != 2)
672 throw std::runtime_error(
"Support of texture coordinates of size "
673 "!= 2 not yet implemented!");
685 (*pm)[he] = texCoords;
702 index_type normalId = normal_face_indices[faceId][faceVertexId];
703 std::vector< coordN_type > &normal = normals_coords[normalId];
704 if(normal.size() != 3)
705 throw std::runtime_error(
706 "Support of normals of size != 3 not yet implemented!");
715 fnormal = fnormal + vnormal;
716 if(it == itF->end() - 1)
718 fnormal / (faceVertexId +
724 (*pm)[currentFace] = fnormal;
727 prevVertex = currentVertex;
730 if(currentFace->GetDegree() == 2)
742 std::vector< coordC_type > &color = face_color_coords[faceId];
749 "f:color", currentFace->GetIndex(), fc);
751 if (!field_names.empty())
753 auto it = field_names.begin();
754 auto ite = field_names.end();
755 auto it_d = field_attributes.begin();
756 for (; it != ite; ++it, ++it_d)
758 if (it->find(
"ELEMENT_DATA_") != std::string::npos)
761 outputMesh->SetProperty<
AIFFace::ptr, std::vector<double> >(
762 (
"f:datafield:" + it->substr(13)), currentFace->GetIndex(), (*it_d)[faceId]);
764 else if (it->find(
"CELL_DATA_") != std::string::npos)
767 outputMesh->SetProperty<
AIFFace::ptr, std::vector<double> >(
768 (
"f:datafield:" + it->substr(10)), currentFace->GetIndex(), (*it_d)[faceId]);