MEPP2 Project
AIFMeshReader.inl
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13 
18 
19 #include <vector>
20 #include <array>
21 #include <string>
22 
23 #ifdef FEVV_USE_VTK
25 #endif
26 
27 #ifdef FEVV_USE_FBX
28 
29 #if defined _MSC_VER
30 #pragma warning(push)
31 #pragma warning(disable : 4267)
32 #endif
33 
35 
36 #if defined _MSC_VER
37 #pragma warning(pop)
38 #endif
39 
40 #endif
41 
42 #include "FEVV/Types/Material.h"
43 
44 namespace FEVV {
45 namespace DataStructures {
46 namespace AIF {
47 
48 inline
50 AIFMeshReader::read(const std::string &filePath)
51 {
52  using namespace FileUtils;
53  using namespace StrUtils;
54 
55  if(!boost::filesystem::exists(filePath))
56  throw std::invalid_argument(
57  "Reader::read -> input file path refer to no existing file.");
58  else if(!has_extension(filePath))
59  throw std::invalid_argument(
60  "Reader::read -> input file path find without any extension.");
61 
62  // std::cout << "AIFReading of \"" << get_file_full_name(filePath) << "\"" <<
63  // std::endl;
64 
65  std::vector< std::string > validExtensions = {
66  ".obj", ".off", ".coff", ".ply", ".msh"};
67  std::vector< std::string > validVtkExtensions = {".vtk", ".vtp", ".vtu"};
68  if(!(has_extension(filePath, validExtensions)
69 #ifdef FEVV_USE_VTK
70  || has_extension(filePath, validVtkExtensions)
71 #endif
72  ))
73  {
74  throw std::invalid_argument(
75  "Reader::read -> input file extension can't be read (yet).");
76  }
77 
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;
81  // if points_coords.size() == texture_coords.size(), then
82  // texture coordinates are given by vertex
83  // else texture coordinates are given by corner
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;
88  // index of the texture coordinates in texture_coords container
89  std::vector< std::vector< index_type > > normal_face_indices;
90  std::vector< std::vector< coordC_type > > points_colors, faces_colors,
91  lines_colors;
92  std::vector< std::vector< std::vector< double > > > field_attributes;
93  std::vector< std::string > field_names;
94  // std::vector< Material > materials;
95  std::string texture_file_name; // TODO-elo-rm when this file really supports
96  // multitexture
97  std::vector< FEVV::Types::Material > materials;
98  std::vector< index_type > face_material;
99 
100  bool obj_file = false;
101 
102  if(has_extension(filePath, ".obj"))
103  {
104  IO::read_obj_file(filePath,
105  points_coords,
106  normals_coords,
107  texture_coords,
108  vertex_color_coords,
109  faces_indices,
110  texture_face_indices,
111  normal_face_indices,
112  materials,
113  face_material);
114  obj_file = true;
115 
116  if(!materials.empty())
117  texture_file_name = materials[0].diffuse_texture_filename;
118  }
119  else if(has_extension(filePath, ".off") || has_extension(filePath, ".coff"))
120  {
121  IO::read_off_file(filePath,
122  points_coords,
123  normals_coords,
124  texture_coords,
125  vertex_color_coords,
126  faces_indices,
127  face_color_coords);
128  }
129  else if(has_extension(filePath, ".ply"))
130  {
131  IO::read_ply_file(filePath,
132  points_coords,
133  normals_coords,
134  texture_coords,
135  vertex_color_coords,
136  faces_indices,
137  texture_face_indices);
138  }
139  else if(has_extension(filePath, ".msh"))
140  {
141  IO::read_gmsh_file(filePath,
142  points_coords,
143  normals_coords,
144  vertex_color_coords,
145  lines_indices,
146  lines_colors,
147  faces_indices,
148  faces_colors,
149  field_attributes,
150  field_names);
151  }
152 #ifdef FEVV_USE_VTK
153  else if(has_extension(filePath, ".vtk") || has_extension(filePath, ".vtp") ||
154  has_extension(filePath, ".vtu"))
155  {
157  points_coords,
158  normals_coords,
159  vertex_color_coords,
160  lines_indices,
161  lines_colors,
162  faces_indices,
163  faces_colors,
164  field_attributes,
165  field_names);
166  }
167 #endif
168 #ifdef FEVV_USE_FBX
169  else if(FEVV::FileUtils::has_extension(filePath, ".fbx"))
170  {
171  IO::read_fbx_file(filePath,
172  points_coords,
173  normals_coords,
174  texture_coords,
175  vertex_color_coords,
176  faces_indices,
177  texture_face_indices,
178  normal_face_indices,
179  materials,
180  face_material);
181  }
182 #endif
183 
186  typedef AIFTopologyHelpers helpers;
187  typedef AIFPropertiesHelpers PropHelpers;
188  ptr_output outputMesh = AIFMesh::New();
189 
192 
193 
194  // vertex-color must be defined for all vertices or none
195  if(vertex_color_coords.size() != points_coords.size())
196  vertex_color_coords.clear();
197  for(auto &color : vertex_color_coords)
198  {
199  if(color.size() < 3 || color.size() > 4)
200  {
201  std::cout << "AIFMeshReader::read(): found vertex color with size neither "
202  "3 nor 4. Disabling vertex color for all vertices."
203  << std::endl;
204  vertex_color_coords.clear();
205  break;
206  }
207  }
208 
209  // face-color must be defined for all faces or none
210  if(face_color_coords.size() != faces_indices.size())
211  face_color_coords.clear();
212  for(auto &color : face_color_coords)
213  {
214  if(color.size() < 3 || color.size() > 4)
215  {
216  std::cout << "AIFMeshReader::read(): found face color with size neither 3 nor 4. "
217  "Disabling face color for all vertices."
218  << std::endl;
219  face_color_coords.clear();
220  break;
221  }
222  }
223 
224  // material must be defined for all faces or none
225  if(!face_material.empty())
226  {
227  if(face_material.size() != faces_indices.size())
228  {
229  std::cout << "AIFMeshReader::read(): found some faces with a material and some "
230  "without. Disabling material for all faces."
231  << std::endl;
232  face_material.clear();
233  }
234  }
235 
236  // check if all faces have a valid material
237  if(!face_material.empty())
238  {
239  for(auto &mtl_id : face_material)
240  {
241  if(mtl_id == static_cast< index_type >(-1))
242  {
243  std::cout << "AIFMeshReader::read(): found some faces with an invalid material. "
244  "Disabling material for all faces."
245  << std::endl;
246  face_material.clear();
247  break;
248  }
249  }
250  }
251 
252  // store texture filename
253  if(!texture_file_name.empty())
254  {
255  // create a property map to store the texture name
256  auto tfn_pm =
257  outputMesh->AddAssocPropertyMap< helpers::ptr_mesh, std::string >(
258  "m:texturefilename");
259  if(!outputMesh->isAssocPropertyMap("m:texturefilename"))
260  throw std::runtime_error(
261  "Failed to create texture-filename property map.");
262 
263  (*tfn_pm)[outputMesh.get()] = texture_file_name;
264 
265  std::cout << "AIF property map for texture-filename created." << std::endl;
266  }
267 
268  if (!field_names.empty())
269  {
270  auto it = field_names.begin();
271  auto ite = field_names.end();
272  for (; it != ite; ++it)
273  {
274  if (it->find("POINT_DATA_") != std::string::npos )
275  { // property map associated to vertices
276 
277  // create property map to store vertex current data field
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.");
283  }
284  else if (it->find("ELEMENT_DATA_") != std::string::npos)
285  { // property map associated to faces
286 
287  // create property map to store face current data field
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.");
293  }
294  else if (it->find("CELL_DATA_") != std::string::npos)
295  { // property map associated to faces
296 
297  // create property map to store face current data field
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.");
303  }
304  }
305  }
306 
307  // import data into AIF datastructure
308 
309  bool useVertexNormal = false;
310  bool useVertexColor = false;
311  bool useVertexTextureCoord = false;
312  bool useCornerTextureCoord = false;
313  bool useFaceColor = false;
314  bool useFaceNormal = false; // per-face vertices normals
315  //unused bool useLineColor = false;
316 
317  if(!texture_coords.empty())
318  {
319  // choose between vertex-texcoord and corner-texcoord
320  if(obj_file)
321  {
322  // support corner-texture only with OBJ file
323  useCornerTextureCoord = true;
324  }
325  else if(texture_coords.size() == points_coords.size())
326  {
327  // texture coordinates are given by vertex
328  useVertexTextureCoord = true;
329  }
330  else if(texture_face_indices.size() == faces_indices.size())
331  {
332  // texture coordinates are given by corner
333  useCornerTextureCoord = true;
334  }
335 
336  // create property map to store texcoord
337  if(useVertexTextureCoord)
338  {
339  // create property map to store vertex texture-coord
340  outputMesh->AddPropertyMap< AIFVertex::ptr, AIFMesh::PointUV >(
341  "v:texcoord");
342  if(!outputMesh->isPropertyMap< AIFVertex::ptr >("v:texcoord"))
343  throw std::runtime_error(
344  "Failed to create vertex-texture-coordinate property map.");
345 
346  std::cout << "AIF property map for vertex-texture-coordinate created."
347  << std::endl;
348  }
349  else if(useCornerTextureCoord)
350  {
351  // create property map to store corner texture-coord
352  outputMesh->AddAssocPropertyMap< helpers::halfedge_descriptor,
353  AIFMesh::PointUV >("h:texcoord");
354  if(!outputMesh->isAssocPropertyMap("h:texcoord"))
355  throw std::runtime_error(
356  "Failed to create halfedge-texture-coordinate property map.");
357 
358  std::cout << "AIF property map for halfedge-texture-coordinate created."
359  << std::endl;
360  }
361  }
362 
363  if(!normals_coords.empty())
364  {
365  // per-vertex normal or per-face-vertex normal ?
366  // if there are as many normals as vertices, then it's per-vertex normal
367 
368  if(normals_coords.size() == points_coords.size())
369  {
370  useVertexNormal = true;
371 
372  // create property map to store vertex normal
373  outputMesh->AddPropertyMap< AIFVertex::ptr, AIFMesh::Normal >("v:normal");
374  if(!outputMesh->isPropertyMap< AIFVertex::ptr >("v:normal"))
375  throw std::runtime_error(
376  "Failed to create vertex-normal property map.");
377 
378  std::cout << "AIF property map for vertex-normal created." << std::endl;
379  }
380  else if(!normal_face_indices[0].empty())
381  {
382  // per-face-vertex normal
383  useFaceNormal = true;
384 
385  // create property map to store face-vertex normal
386  outputMesh->AddPropertyMap< AIFFace::ptr, AIFMesh::Normal >("f:normal");
387  if(!outputMesh->isPropertyMap< AIFFace::ptr >("f:normal"))
388  throw std::runtime_error("Failed to create face-normal property map.");
389 
390  std::cout << "AIF property map for face-normal created." << std::endl;
391  }
392  }
393 
394  if(!vertex_color_coords.empty())
395  {
396  useVertexColor = true;
397 
398  // create property map to store vertex color
399  outputMesh->AddPropertyMap< AIFVertex::ptr, AIFMesh::Vector >("v:color");
400  if(!outputMesh->isPropertyMap< AIFVertex::ptr >("v:color"))
401  throw std::runtime_error("Failed to create vertex-color property map.");
402 
403  std::cout << "AIF property map for vertex-color created." << std::endl;
404  }
405 
406  if(!face_color_coords.empty())
407  {
408  useFaceColor = true;
409 
410  // create property map to store face color
411  outputMesh->AddPropertyMap< AIFFace::ptr, AIFMesh::Vector >("f:color");
412  if(!outputMesh->isPropertyMap< AIFFace::ptr >("f:color"))
413  throw std::runtime_error("Failed to create face-color property map.");
414 
415  std::cout << "AIF property map for face-color created." << std::endl;
416  }
417 
420  // bool useLineColor=(lines.size() == lines_c.size()) ;
421  std::vector< helpers::vertex_type::ptr > vertices;
422  vertices.reserve(points_coords.size());
423 
424  typedef std::vector< std::vector< coord_type > >::const_iterator point_it;
425  int vertexNbr = 0;
426  for(point_it itP = points_coords.begin(); itP != points_coords.end(); ++itP)
427  {
428  helpers::vertex_descriptor currentVertex = helpers::add_vertex(outputMesh);
429  vertexNbr++;
430 
431  PropHelpers::set_point(
432  outputMesh, currentVertex, (*itP)[0], (*itP)[1], (*itP)[2]);
433  vertices.push_back(
434  currentVertex); // Warning : must keep the vertex in a vector to handle
435  // vertex indices for faces
436 
437  // Vertex normal/color/texture-coords addition when present
438  if(useVertexNormal || useVertexColor || useVertexTextureCoord)
439  {
440  if(useVertexNormal)
441  {
442  // DBG std::cout << "store normal by vertex #" << vertexNbr <<
443  // std::endl;
444  std::vector< coordN_type > &coords = normals_coords[vertexNbr - 1];
445 
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!");
449  // store normal in property map
450  AIFMesh::Normal vn(coords[0], coords[1], coords[2]);
451  outputMesh->SetProperty< AIFVertex::ptr, AIFMesh::Normal >(
452  "v:normal", currentVertex->GetIndex(), vn);
453  }
454  if(useVertexColor)
455  {
456  // DBG std::cout << "store color for vertex #" << vertexNbr <<
457  // std::endl;
458  std::vector< coordC_type > &coords = vertex_color_coords[vertexNbr - 1];
459  // at this point we are sure that coords.size() == 3 because of
460  // previous sanity checks
461 
462  // store color in property map
463  AIFMesh::Vector vc(coords[0], coords[1], coords[2]);
464  outputMesh->SetProperty< AIFVertex::ptr, AIFMesh::Vector >(
465  "v:color", currentVertex->GetIndex(), vc);
466  }
467  if(useVertexTextureCoord)
468  {
469  // DBG std::cout << "store tex coord for vertex #" << vertexNbr <<
470  // std::endl;
471  std::vector< coordT_type > &coords = texture_coords[vertexNbr - 1];
472 
473  if(coords.size() != 2)
474  throw std::runtime_error("Support of texture coordinates of size != "
475  "2 not yet implemented!");
476 
477  // store texture coordinates in property map
478  AIFMesh::PointUV texCoords = {coords[0], coords[1]};
479  outputMesh->SetProperty< AIFVertex::ptr, AIFMesh::PointUV >(
480  "v:texcoord", currentVertex->GetIndex(), texCoords);
481  }
482  }
483  if (!field_names.empty())
484  {
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)
489  {
490  if (it->find("POINT_DATA_") != std::string::npos)
491  { // property map associated to vertices
492 
493  outputMesh->SetProperty< AIFVertex::ptr, std::vector<double> >(
494  ("v:datafield:" + it->substr(11)), currentVertex->GetIndex(), (*it_d)[vertexNbr - 1]);
495  }
496  }
497  }
498  }
499 
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)
504  {
505  if((*itL).size() >
506  3) // case where a line is used to describe a volume element (we do not
507  // allows polyline loading, only segment loading+a particular use of
508  // lines to descrime volume cells)
509  continue;
510 
511  // find the corresponding vertices in the vertices std::vector (care about
512  // the potential decrementation)
513  helpers::vertex_descriptor firstVertex = vertices[(*itL)[0]];
514  helpers::vertex_descriptor secondVertex = vertices[(*itL)[1]];
515 
516  // Dangling edge
517  // create the edge in the mesh
518  helpers::edge_type::ptr danglingEdge;
519 
520  if((danglingEdge = helpers::common_edge(firstVertex, secondVertex)) ==
522  { // we avoid multiple similar edges
523  danglingEdge = helpers::add_edge(outputMesh);
524 
525  // link the edge and the vertices
527  firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
529  secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
530  }
531  }
534  typedef std::vector< std::vector< index_type > >::/*const_*/ iterator face_it;
535  typedef std::vector< index_type >::const_iterator index_it;
536  size_t faceId = 0;
537  for(face_it itF = faces_indices.begin(); itF != faces_indices.end();
538  ++itF, ++faceId)
539  {
540  if(itF->size() < 2)
541  {
542  throw std::runtime_error("Reader::read -> find a face with less than two "
543  "vertices : not complying case.");
544  }
545  else if(itF->size() == 2)
546  {
547  // find the corresponding vertices in the vertices std::vector (care about
548  // the potential decrementation)
549  helpers::vertex_descriptor firstVertex = vertices[(*itF)[0]];
550  helpers::vertex_descriptor secondVertex = vertices[(*itF)[1]];
551 
552  // Dangling edge
553  // create the edge in the mesh
554  helpers::edge_type::ptr danglingEdge;
555  if((danglingEdge = helpers::common_edge(firstVertex, secondVertex)) ==
557  { // we avoid multiple similar edges
558  danglingEdge = helpers::add_edge(outputMesh);
559 
560  // link the edge and the vertices
562  firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
564  secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
565  }
566  }
567  else
568  {
569  // create the face in the mesh
570  helpers::face_descriptor currentFace = helpers::add_face(outputMesh);
571  // helpers::face_descriptor currentFace = helpers::add_face(*outputMesh);
573  if(!FEVV::FaceIndicesUtils::are_all_face_indices_unique< index_type >(
574  *itF))
575  {
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;
582  out_lines_indices);
585  typedef std::vector< std::vector< index_type > >::const_iterator
586  line_it;
587  for(line_it itL = out_lines_indices.begin();
588  itL != out_lines_indices.end();
589  ++itL)
590  {
591  // find the corresponding vertices in the vertices std::vector (care
592  // about the potential decrementation)
593  helpers::vertex_descriptor firstVertex = vertices[(*itL)[0]];
594  helpers::vertex_descriptor secondVertex = vertices[(*itL)[1]];
595 
596  // Dangling edge
597  // create the edge in the mesh
598  helpers::edge_type::ptr danglingEdge;
599  if((danglingEdge = helpers::common_edge(firstVertex, secondVertex)) ==
601  { // we avoid multiple similar edges
602  danglingEdge = helpers::add_edge(outputMesh);
603 
604  // link the edge and the vertices
606  firstVertex, danglingEdge, helpers::vertex_pos::FIRST);
608  secondVertex, danglingEdge, helpers::vertex_pos::SECOND);
609  }
610  }
611  }
613  // get the first vertex of the face to successively constructs the face's
614  // edges (we can use back() here as vertices is explicitly an std::vector)
615  helpers::vertex_descriptor prevVertex = vertices[itF->back()];
616  helpers::vertex_descriptor currentVertex;
617  helpers::edge_descriptor currentEdge;
618 
619  // loop over face's vertices
620  index_type faceVertexId = 0;
621  for(index_it it = itF->begin(); it != itF->end(); ++it, ++faceVertexId)
622  {
623  currentVertex = vertices[(*it)];
624 
625  // check if the 2 vertices ain't already link by an edge
626  helpers::edge_descriptor currentEdge;
627  if((currentEdge = helpers::common_edge(prevVertex, currentVertex)) ==
629  {
630  // create the edge in the mesh
631  currentEdge = helpers::add_edge(outputMesh);
632  // currentEdge = helpers::add_edge(*outputMesh);
633 
634  // link the edge and the vertices
636  prevVertex, currentEdge, helpers::vertex_pos::FIRST);
638  currentVertex, currentEdge, helpers::vertex_pos::SECOND);
639  }
640  bool face_has_that_incident_edge =
641  helpers::are_incident(currentFace, currentEdge);
642  bool edge_has_that_incident_face =
643  helpers::are_incident(currentEdge, currentFace);
644  if(!face_has_that_incident_edge ||
645  !edge_has_that_incident_face) // Even if data in file is not normal
646  // (e.g. double dangling edge), file
647  // loading can be performed.
648  {
649  // link the edge and the face
650  helpers::link_edge_and_face(currentEdge, currentFace);
651  }
652 
653  // corner (aka halfedge) texture
654  if(useCornerTextureCoord)
655  {
656 #if 0
657  switch (texture_face_indices[faceId].size())
658  {
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");
662  }
663 #endif
664  if(texture_face_indices[faceId].size() ==
665  faces_indices[faceId].size())
666  { // in some files, it happens that a part of the faces have no
667  // texture corners, while others have
668  // retrieve texture coords
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!");
674  AIFMesh::PointUV texCoords = {coords[0], coords[1]};
675 
676  // retrieve halfedge
678  helpers::AIFHalfEdge(prevVertex, currentVertex, currentFace);
679 
680  // fill in property map
681  auto pm =
682  outputMesh->GetAssocPropertyMap< helpers::halfedge_descriptor,
684  "h:texcoord");
685  (*pm)[he] = texCoords;
686 
687  // DBG std::cout << __FILE__ << ":" << __LINE__ << " he=" << he << "
688  // (*pm)[he][0]=" << (*pm)[he][0] << " (*pm)[he][1]=" <<
689  // (*pm)[he][1] << " coords[0]=" << coords[0] << " coords[1]=" <<
690  // coords[1] << " texCoords[0]=" << texCoords[0] << "
691  // texCoords[1]=" << texCoords[1] << std::endl;
692  }
693  }
694 
695  // face-vertex-normal
696  if(useFaceNormal)
697  {
698  // DBG std::cout << "compute normal for face #" << faceId << " (vertex
699  // #" << faceVertexId << ")" << std::endl;
700 
701  // retrieve current vertex normal
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!");
707  AIFMesh::Normal vnormal = {normal[0], normal[1], normal[2]};
708 
709  // retrieve face normal
710  auto pm = outputMesh->GetPropertyMap< AIFFace::ptr, AIFMesh::Normal >(
711  "f:normal");
712  AIFMesh::Normal fnormal = (*pm)[currentFace];
713 
714  // computation of face normal (mean of the vertices normals)
715  fnormal = fnormal + vnormal;
716  if(it == itF->end() - 1)
717  fnormal =
718  fnormal / (faceVertexId +
719  1); // \todo: why to compute face normal not based on
720  // its underlying plane and just use the vertex
721  // normals to ensure correct orientation?
722 
723  // update face-normal map
724  (*pm)[currentFace] = fnormal;
725  }
726 
727  prevVertex = currentVertex;
728  }
729 
730  if(currentFace->GetDegree() == 2)
731  { // case of n>=2 edges describing the same non-oriented edge
733  currentFace,
734  outputMesh); // we just remove that face (we always must ensure that
735  // a face is valid <=> degree>=3)
736  continue;
737  }
738 
739  if(useFaceColor)
740  {
741  // DBG std::cout << "store color for face #" << faceId << std::endl;
742  std::vector< coordC_type > &color = face_color_coords[faceId];
743  // at this point we are sure that color.size() == 3 because of
744  // previous sanity checks
745 
746  // store color in property map
747  AIFMesh::Vector fc(color[0], color[1], color[2]);
748  outputMesh->SetProperty< AIFFace::ptr, AIFMesh::Vector >(
749  "f:color", currentFace->GetIndex(), fc);
750  }
751  if (!field_names.empty())
752  {
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)
757  {
758  if (it->find("ELEMENT_DATA_") != std::string::npos)
759  { // property map associated to faces
760 
761  outputMesh->SetProperty< AIFFace::ptr, std::vector<double> >(
762  ("f:datafield:" + it->substr(13)), currentFace->GetIndex(), (*it_d)[faceId]);
763  }
764  else if (it->find("CELL_DATA_") != std::string::npos)
765  { // property map associated to faces
766 
767  outputMesh->SetProperty< AIFFace::ptr, std::vector<double> >(
768  ("f:datafield:" + it->substr(10)), currentFace->GetIndex(), (*it_d)[faceId]);
769  }
770  }
771  }
772  }
773  }
774 
775  // std::cout << "AIFReading of \"" << get_file_full_name(filePath) << "\"
776  // Done." << std::endl;
777 
778  return outputMesh;
779 }
780 
781 } // namespace AIF
782 } // namespace DataStructures
783 } // namespace FEVV
FEVV::DataStructures::AIF::vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator > vertices(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the vertices of the mesh.
Definition: Graph_traits_aif.h:172
FEVV::DataStructures::AIF::AIFTopologyHelpers::halfedge_descriptor
AIFHalfEdge halfedge_descriptor
Definition: AIFTopologyHelpers.h:5755
FEVV::DataStructures::AIF::AIFTopologyHelpers::common_edge
static edge_descriptor common_edge(vertex_descriptor vertex1, vertex_descriptor vertex2)
Definition: AIFTopologyHelpers.h:458
helpers
AIFTopologyHelpers helpers
Definition: test_helpers_aif.cpp:16
FEVV::StrUtils::convert
void convert(const std::string &str, ConvertType &elem)
Definition: StringUtilities.hpp:81
FEVV::DataStructures::AIF::AIFVertex::ptr
boost::shared_ptr< self > ptr
Definition: AIFVertex.hpp:47
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_face
static face_descriptor add_face(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2887
FEVV::DataStructures::AIF::AIFMeshReader::ptr_output
superclass::ptr_output ptr_output
Definition: AIFMeshReader.hpp:43
FEVV::DataStructures::AIF::AIFTopologyHelpers::AIFHalfEdge
Definition: AIFTopologyHelpers.h:4748
FEVV::DataStructures::AIF::AIFTopologyHelpers::link_edge_and_face
static void link_edge_and_face(edge_descriptor edge, face_descriptor face)
Definition: AIFTopologyHelpers.h:1305
FEVV::DataStructures::AIF::AIFTopologyHelpers::vertex_descriptor
vertex_type::ptr vertex_descriptor
Definition: AIFTopologyHelpers.h:70
FEVV::IO::read_ply_file
void read_ply_file(std::string file_path, std::vector< std::vector< CoordType > > &points_coords, std::vector< std::vector< CoordNType > > &normals_coords, std::vector< std::vector< CoordTType > > &texture_coords, std::vector< std::vector< CoordCType > > &vertex_color_coords, std::vector< std::vector< IndexType > > &face_indices, std::vector< std::vector< IndexType > > &texture_face_indices)
Definition: PlyFileReader.h:41
MshFileReader.h
FEVV::IO::read_vtk_or_vtp_or_vtu_file
void read_vtk_or_vtp_or_vtu_file(std::string file_path, std::vector< std::vector< CoordType > > &points_coords, std::vector< std::vector< CoordNType > > &normals_coords, std::vector< std::vector< CoordCType > > &vertex_color_coords, std::vector< std::vector< IndexType > > &line_indices, std::vector< std::vector< CoordCType > > &lines_color_coords, std::vector< std::vector< IndexType > > &face_indices, std::vector< std::vector< CoordCType > > &face_color_coords, std::vector< std::vector< std::vector< double > > > &field_attributes, std::vector< std::string > &field_names, bool if_unstructured_grid_then_take_surface=false)
Definition: VtkFileReader.h:929
VtkFileReader.h
FEVV::DataStructures::AIF::AIFMeshReader::read
ptr_output read(const std::string &filePath)
Definition: AIFMeshReader.inl:50
FEVV::DataStructures::AIF::AIFTopologyHelpers::remove_face
static void remove_face(face_descriptor face, ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:3120
FEVV::DataStructures::AIF::AIFFace::ptr
boost::shared_ptr< self > ptr
Definition: AIFFace.hpp:52
FEVV::IO::read_fbx_file
void read_fbx_file(const std::string &filePath, std::vector< std::vector< coord_type > > &points_coords, std::vector< std::vector< coordN_type > > &normals_coords, std::vector< std::vector< coordT_type > > &texture_coords, std::vector< std::vector< coordC_type > > &, std::vector< std::vector< index_type > > &face_indices, std::vector< std::vector< index_type > > &texture_face_indices, std::vector< std::vector< index_type > > &normal_face_indices, std::vector< material_type > &materials, std::vector< index_type > &face_material)
Read the FBX file and load its data into given parameters.
Definition: FbxFileReader.h:176
FEVV::DataStructures::AIF::AIFTopologyHelpers::edge_descriptor
edge_type::ptr edge_descriptor
Definition: AIFTopologyHelpers.h:71
Material.h
FEVV::DataStructures::AIF::AIFMesh::New
static ptr_mesh New()
Definition: AIFMesh.inl:720
FEVV::DataStructures::AIF::AIFTopologyHelpers::face_descriptor
face_type::ptr face_descriptor
Definition: AIFTopologyHelpers.h:72
FEVV::FaceIndicesUtils::lines_indices_to_segments_indices
void lines_indices_to_segments_indices(std::vector< std::vector< IndexType > > &in_out_lines_indices)
Definition: FaceIndicesUtilities.h:30
FEVV::DataStructures::AIF::AIFTopologyHelpers::null_edge
static edge_descriptor null_edge()
Definition: AIFTopologyHelpers.h:113
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_edge
static edge_descriptor add_edge(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2772
FEVV::FaceIndicesUtils::face_indices_to_face_and_lines_indices
void face_indices_to_face_and_lines_indices(const std::vector< IndexType > &in_face_indices, std::vector< IndexType > &out_face_indices, std::vector< std::vector< IndexType > > &out_lines_indices)
Definition: FaceIndicesUtilities.h:71
FEVV::DataStructures::AIF::AIFTopologyHelpers::link_vertex_and_edge
static void link_vertex_and_edge(vertex_descriptor vertex, edge_descriptor edge, vertex_pos position)
Definition: AIFTopologyHelpers.h:515
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::IO::read_off_file
void read_off_file(std::string file_path, std::vector< std::vector< CoordType > > &points_coords, std::vector< std::vector< CoordNType > > &normals_coords, std::vector< std::vector< CoordTType > > &texture_coords, std::vector< std::vector< CoordCType > > &vertex_color_coords, std::vector< std::vector< IndexType > > &face_indices, std::vector< std::vector< CoordCType > > &face_color_coords)
Definition: OffFileReader.h:40
FbxFileReader.h
FEVV::face_material
@ face_material
Definition: properties.h:85
FEVV::DataStructures::AIF::AIFEdge::ptr
boost::shared_ptr< self > ptr
Definition: AIFEdge.hpp:56
FEVV::DataStructures::AIF::AIFVector
Definition: AIFProperties.h:173
OffFileReader.h
FEVV::IO::read_obj_file
void read_obj_file(const std::string &file_path, std::vector< std::vector< CoordType > > &points_coords, std::vector< std::vector< CoordNType > > &normals_coords, std::vector< std::vector< CoordTType > > &texture_coords, std::vector< std::vector< CoordCType > > &vertex_color_coords, std::vector< std::vector< IndexType > > &face_indices, std::vector< std::vector< IndexType > > &texture_face_indices, std::vector< std::vector< IndexType > > &normal_face_indices, std::vector< MaterialType > &materials, std::vector< IndexType > &face_material)
Definition: ObjFileReader.h:324
FEVV::DataStructures::AIF::AIFMesh::PointUV
std::array< CoordinateType, 2 > PointUV
Definition: AIFMesh.hpp:65
FEVV::DataStructures::AIF::AIFTopologyHelpers::ptr_mesh
mesh_type * ptr_mesh
Definition: AIFTopologyHelpers.h:66
FEVV::DataStructures::AIF::AIFTopologyHelpers
This class is an helper class associated to the AIFMesh structure. AIFTopologyHelpers implements all ...
Definition: AIFTopologyHelpers.h:57
PlyFileReader.h
FEVV::DataStructures::AIF::AIFTopologyHelpers::add_vertex
static vertex_descriptor add_vertex(ptr_mesh mesh)
Definition: AIFTopologyHelpers.h:2709
FEVV::FileUtils::has_extension
bool has_extension(const std::string &file_name)
Definition: FileUtilities.hpp:58
FEVV::IO::read_gmsh_file
bool read_gmsh_file(const std::string &file_path, std::vector< std::vector< CoordType > > &points_coords, std::vector< std::vector< CoordNType > > &normals_coords, std::vector< std::vector< CoordCType > > &vertex_color_coords, std::vector< std::vector< IndexType > > &line_indices, std::vector< std::vector< CoordCType > > &lines_color_coords, std::vector< std::vector< IndexType > > &face_indices, std::vector< std::vector< CoordCType > > &face_color_coords, std::vector< std::vector< std::vector< double > > > &field_attributes, std::vector< std::string > &field_names)
Definition: MshFileReader.h:427
FEVV::DataStructures::AIF::AIFTopologyHelpers::are_incident
static bool are_incident(vertex_descriptor vertex, edge_descriptor edge)
Function determining if the arguments share an incidence relation.
Definition: AIFTopologyHelpers.h:303
FileUtilities.hpp
FaceIndicesUtilities.h
FEVV::DataStructures::AIF::AIFMeshReader::index_type
unsigned long index_type
Definition: AIFMeshReader.hpp:50
ObjFileReader.h
FEVV::DataStructures::AIF::AIFPropertiesHelpers
This class is an helper class associated to the AIFMesh structure. AIFPropertiesHelpers implements al...
Definition: AIFPropertiesHelpers.h:28