23 namespace DataStructures {
30 write(*inputMesh, filePath);
36 const std::string &filePath)
38 using namespace FileUtils;
41 throw std::invalid_argument(
42 "Writer::write -> output file path find without any extension.");
47 std::vector< std::string > validExtensions = {
48 ".obj",
".off",
".coff",
"ply",
".msh"};
49 std::vector< std::string > validVtkExtensions = {
".vtk",
".vtp",
".vtu"};
56 throw std::invalid_argument(
57 "Writer::write -> output file extension can't be read (yet).");
64 typedef boost::iterator_range< vertex_iterator > vertex_range;
66 typedef boost::iterator_range< edge_iterator > edge_range;
68 typedef boost::iterator_range< face_iterator > face_range;
69 typedef helpers::vertex_container_in_face::const_iterator
71 typedef boost::iterator_range< vertex_face_iterator > vertex_face_range;
73 std::vector< std::vector< coord_type > > points_coords;
74 std::vector< std::vector< coordN_type > > normals_coords;
75 std::vector< std::vector< coordT_type > > texture_coords;
76 std::vector< std::vector< coordC_type > > vertex_color_coords;
77 std::vector< std::vector< coordC_type > > face_color_coords;
78 std::vector< std::vector< index_type > > lines_indices, faces_indices;
79 std::vector< std::vector< index_type > > texture_face_indices;
80 std::vector< std::vector< index_type > > normal_face_indices;
81 std::vector< std::vector< coordC_type > > line_colors_coords;
83 std::vector< FEVV::Types::Material > materials;
85 std::vector< std::vector< std::vector< double > > > field_attributes;
86 std::vector< std::string > field_names;
90 bool useVertexColor =
false;
91 bool useFaceColor =
false;
92 bool useVertexTextureCoord =
false;
93 bool useVertexDatafield =
false;
94 bool useFaceDatafield =
false;
106 useVertexColor =
true;
110 useVertexTextureCoord =
true;
111 if (inputMesh.isAPropertyMapStartingWithPrefix<
AIFVertex::ptr >(
"v:datafield:"))
112 useVertexDatafield =
true;
113 if (inputMesh.isAPropertyMapStartingWithPrefix<
AIFFace::ptr >(
"f:datafield:"))
114 useFaceDatafield =
true;
116 std::vector<std::string> dfv_names = inputMesh.GetPropertyMapNamesStartingWithPrefix<
AIFVertex::ptr >(
"v:datafield:");
117 std::vector<std::string> dff_names = inputMesh.GetPropertyMapNamesStartingWithPrefix<
AIFFace::ptr >(
"f:datafield:");
119 long vertexIndex = 0;
120 std::map< helpers::vertex_descriptor, long >
127 for(vertex_iterator itV = vRange.begin(); itV != vRange.end(); ++itV)
130 std::vector< coord_type > point;
132 for(
unsigned int i = 0; i < p.size(); ++i)
133 point.push_back(p[i]);
135 points_coords.push_back(point);
137 indexMap[*itV] = vertexIndex;
147 "v:normal", (*itV)->GetIndex());
148 std::vector< coordN_type > normal(vn.cbegin(), vn.cend());
149 normals_coords.push_back(normal);
157 "v:color", (*itV)->GetIndex());
158 std::vector< coordC_type > color(vc.cbegin(), vc.cend());
159 vertex_color_coords.push_back(color);
162 if(useVertexTextureCoord)
167 "v:texcoord", (*itV)->GetIndex());
168 std::vector< coordT_type > vt(uv.cbegin(), uv.cend());
169 texture_coords.push_back(vt);
172 if (useVertexDatafield)
174 auto it_s = dfv_names.begin(), it_se = dfv_names.end();
176 for (; it_s != it_se; ++it_s, ++i)
178 const std::vector< double >&vdata =
180 *it_s, (*itV)->GetIndex());
182 if (itV == vRange.begin())
184 field_names.push_back(
"POINT_DATA_" + it_s->substr(12));
185 field_attributes.resize(field_attributes.size() + 1);
188 field_attributes[i].push_back(vdata);
196 for(edge_iterator itE = eRange.begin(); itE != eRange.end(); ++itE)
200 std::vector< index_type > line;
202 line.push_back(indexMap[(*itE)->get_first_vertex()]);
203 line.push_back(indexMap[(*itE)->get_second_vertex()]);
205 lines_indices.push_back(line);
212 "e:color", (*itE)->GetIndex());
213 std::vector< coordC_type > color(vc.cbegin(), vc.cend());
214 line_colors_coords.push_back(color);
221 std::set< AIFVertex::ptr > already_processed;
224 for(face_iterator itF = fRange.begin(); itF != fRange.end(); ++itF)
226 std::vector< index_type >
face;
227 std::vector< index_type > normal_indices;
228 std::vector< index_type > texture_indices;
232 for(vertex_face_iterator itVF = vfRange.begin(); itVF != vfRange.end();
238 if(nb_incident_dangling_edges>1)
239 throw std::runtime_error(
"Writer::write -> multiple dangling edge integration into face indices is not available for .off");
240 else if ( (nb_incident_dangling_edges == 1) && (already_processed.find(*itVF)==already_processed.end()))
242 already_processed.insert(*itVF);
247 face.push_back(indexMap[*itVF]);
248 int nb_indices_before =
static_cast<int>(
face.size());
252 face.push_back(indexMap[current_v]);
256 auto iterE = evRange.begin();
257 for(; iterE != evRange.end(); ++iterE)
259 if (*iterE != current_e)
265 }
while (nb_incident_dangling_edges==2);
266 int nb_indices_after =
static_cast<int>(
face.size());
267 std::vector<index_type> additional_indices;
268 for (
int i = nb_indices_after-2; i >= nb_indices_before; --i)
270 additional_indices.push_back(
face[i]);
272 face.insert(
face.end(), additional_indices.begin(), additional_indices.end());
283 normal_indices.push_back(indexMap[*itVF]);
284 if(useVertexTextureCoord)
285 texture_indices.push_back(indexMap[*itVF]);
288 faces_indices.push_back(
face);
290 normal_face_indices.push_back(normal_indices);
291 if(useVertexTextureCoord)
292 texture_face_indices.push_back(texture_indices);
300 "f:color", (*itF)->GetIndex());
303 std::vector< coordC_type > color(fc.cbegin(), fc.cend());
304 face_color_coords.push_back(color);
307 if (useFaceDatafield)
309 auto it_s = dff_names.begin(), it_se = dff_names.end();
311 for (; it_s != it_se; ++it_s, ++i)
313 const std::vector< double >&vdata =
314 inputMesh.GetProperty<
AIFFace::ptr, std::vector< double > >(
315 *it_s, (*itF)->GetIndex());
317 if (itF == fRange.begin())
319 field_names.push_back(
"CELL_DATA_" + it_s->substr(12));
320 field_attributes.resize(field_attributes.size() + 1);
322 if (useVertexDatafield && (it_s == dff_names.begin()))
323 i = dfv_names.size();
325 field_attributes[i].push_back(vdata);
338 texture_face_indices,
356 throw std::runtime_error(
357 "Writer::write -> ply writer has not been implemented yet");