MEPP2 Project
OffFileWriter.h
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.
11 #pragma once
12 
13 /*
14  * Imported from
15  * https://github.com/MEPP-team/Gharial/blob/bb01259715c325baab0d8806604e7c8898a4e420/Src/DataStructures/IO_Tools/STLoffWriter.cxx
16  * and
17  * https://github.com/MEPP-team/Gharial/blob/a0fb8e078d35023b578a84d5578035606851b9ca/Src/DataStructures/IO_Tools/STLoffWriter.h
18  */
19 
20 #include <iostream>
21 #include <fstream>
22 #include <cassert>
23 #include <vector>
24 
27 
28 /*
29  * OFF format description is available at
30  * http://www.geomview.org/docs/html/OFF.html#OFF
31  * and
32  * http://people.sc.fsu.edu/~jburkardt/data/off/off.html
33  */
34 
35 namespace FEVV {
36 namespace IO {
37 
38 using namespace StrUtils;
39 using namespace FileUtils;
40 
44 template< typename CoordType,
45  typename CoordNType,
46  typename CoordTType,
47  typename CoordCType,
48  typename IndexType >
49 void
50 write_off_file(std::string file_path,
51  std::vector< std::vector< CoordType > > &points_coords,
52  std::vector< std::vector< CoordNType > > &normals_coords,
53  std::vector< std::vector< CoordTType > >
54  &texture_coords, // vertex texture coord only
55  std::vector< std::vector< CoordCType > > &vertex_color_coords,
56  std::vector< std::vector< IndexType > > &face_indices,
57  std::vector< std::vector< CoordCType > > &face_color_coords,
58  unsigned long nb_total_edges = 0)
59 {
60  const bool vertices_have_color =
61  (points_coords.size() == vertex_color_coords.size()),
62  vertices_have_normals =
63  (points_coords.size() == normals_coords.size()),
64  vertices_have_tex_coord =
65  (points_coords.size() == texture_coords.size()),
66  faces_have_colors =
67  (face_indices.size() == face_color_coords.size());
68 
69  std::ofstream file(file_path);
70 
71  if(file.is_open())
72  {
73  unsigned long nb_writen_vertices = 0,
74  nb_total_vertices =
75  static_cast< unsigned long >(points_coords.size()),
76  nb_total_faces =
77  static_cast< unsigned long >(face_indices.size());
78 
79  std::string mystring;
80  if(vertices_have_color)
81  {
82  if(vertices_have_normals)
83  {
84  if(vertices_have_tex_coord)
85  mystring = "STCNOFF";
86  else
87  mystring = "CNOFF";
88  }
89  else
90  {
91  if(vertices_have_tex_coord)
92  mystring = "STCOFF";
93  else
94  mystring = "COFF";
95  }
96  }
97  else
98  {
99  if(vertices_have_normals)
100  {
101  if(vertices_have_tex_coord)
102  mystring = "STNOFF";
103  else
104  mystring = "NOFF";
105  }
106  else
107  {
108  if(vertices_have_tex_coord)
109  mystring = "STOFF";
110  else
111  mystring = "OFF";
112  }
113  }
114  file << mystring << std::endl;
115 
116  if(nb_total_edges == 0)
117  nb_total_edges = nb_total_vertices + nb_total_faces - 2;
118  // this number may be incorrect but it is not a problem since
119  // most OFF readers do not use it
120 
121  file << nb_total_vertices << " " << nb_total_faces << " " << nb_total_edges
122  << std::endl;
123  file << "# #vertices #faces #edges" << std::endl;
124  file << "# generated by MEPP2 software" << std::endl;
125 
126  // VERTICES
127 
128  typename std::vector< std::vector< CoordType > >::const_iterator it(
129  points_coords.begin()),
130  ite(points_coords.end());
131  typename std::vector< std::vector< CoordNType > >::const_iterator itn(
132  normals_coords.begin());
133  typename std::vector< std::vector< CoordCType > >::const_iterator itc(
134  vertex_color_coords.begin());
135  typename std::vector< std::vector< CoordTType > >::const_iterator itt(
136  texture_coords.begin());
137  typename std::vector< CoordType >::const_iterator itv, itve;
138  typename std::vector< CoordNType >::const_iterator itvn, itvne;
139  typename std::vector< CoordCType >::const_iterator itvc, itvce;
140  typename std::vector< CoordTType >::const_iterator itvt, itvte;
141  for(; it != ite; ++it)
142  {
143  // vertex position
144  for(itv = it->begin(), itve = it->end(); itv != itve; ++itv)
145  file << *itv << " ";
146 
147  if(vertices_have_normals)
148  {
149  for(itvn = itn->begin(), itvne = itn->end(); itvn != itvne; ++itvn)
150  file << *itvn << " ";
151  ++itn;
152  }
153 
154  if(vertices_have_color)
155  {
156  for(itvc = itc->begin(), itvce = itc->end(); itvc != itvce; ++itvc)
157  file << *itvc << " ";
158  ++itc;
159  }
160 
161  if(vertices_have_tex_coord)
162  {
163  for(itvt = itt->begin(), itvte = itt->end(); itvt != itvte; ++itvt)
164  file << *itvt << " ";
165  ++itt;
166  }
167 
168  file << std::endl;
169  nb_writen_vertices++;
170  }
171 
172  assert(nb_writen_vertices == nb_total_vertices);
173 
174  // INDEXED FACES
175 
176  typename std::vector< std::vector< IndexType > >::const_iterator itf(
177  face_indices.begin()),
178  itfe(face_indices.end());
179  typename std::vector< std::vector< CoordCType > >::const_iterator itfc(
180  face_color_coords.begin());
181 
182  typename std::vector< IndexType >::const_iterator itfindex, itfindexe;
183  typename std::vector< CoordCType >::const_iterator itffc, itffce;
184  for(; itf != itfe; ++itf)
185  {
186  file << itf->size() << " ";
187 
188  for(itfindex = itf->begin(), itfindexe = itf->end();
189  itfindex != itfindexe;
190  ++itfindex)
191  file << *itfindex << " ";
192 
193  if(faces_have_colors)
194  {
195  file << " ";
196  for(itffc = itfc->begin(), itffce = itfc->end(); itffc != itffce;
197  ++itffc)
198  file << *itffc << " ";
199  ++itfc;
200  }
201 
202  file << std::endl;
203  }
204 
205  file.close();
206  }
207  else
208  {
209  throw std::runtime_error("writer_off_file: failed to open output file.");
210  }
211 }
212 
213 } // namespace IO
214 } // namespace FEVV
215 
FEVV::IO::write_off_file
void write_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, unsigned long nb_total_edges=0)
Definition: OffFileWriter.h:50
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
StringUtilities.hpp
FileUtilities.hpp