Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
io_options.cc
1 #include <iostream>
2 #include <iterator>
3 // -------------------- OpenMesh
4 #include <OpenMesh/Core/IO/MeshIO.hh>
5 #include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
6 #include <OpenMesh/Tools/Utils/getopt.h>
7 
8 // ----------------------------------------------------------------------------
9 
10 using namespace OpenMesh;
11 
12 // ----------------------------------------------------------------------------
13 
15 
16 // ----------------------------------------------------------------------------
17 
18 #define CHKROPT( Option ) \
19  std::cout << " provides " << #Option \
20  << (ropt.check(IO::Options:: Option)?": yes\n":": no\n")
21 
22 #define CHKWOPT( Option ) \
23  std::cout << " write " << #Option \
24  << (wopt.check(IO::Options:: Option)?": yes\n":": no\n")
25 
26 #define MESHOPT( msg, tf ) \
27  std::cout << " " << msg << ": " << ((tf)?"yes\n":"no\n")
28 
29 // ----------------------------------------------------------------------------
30 
31 void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
32  IO::Options &ropt, IO::Options &wopt );
33 
34 void usage_and_exit(int xcode);
35 
36 // ----------------------------------------------------------------------------
37 
38 int main(int argc, char **argv)
39 {
40  MyMesh mesh;
41  IO::Options ropt, wopt;
42 
43  // -------------------- evaluate commandline
44 
45  parse_commandline( argc, argv, mesh, ropt, wopt );
46 
47  // -------------------- read mesh
48 
49  if ( ! IO::read_mesh(mesh,argv[optind], ropt))
50  {
51  std::cerr << "Error loading mesh from file " << argv[optind] << std::endl;
52  return 1;
53  }
54 
55  // -------------------- show options
56 
57  std::cout << "File " << argv[optind] << std::endl;
58 
59  std::cout << " is binary: "
60  << (ropt.check(IO::Options::Binary) ? " yes\n" : " no\n");
61 
62  std::cout << " byte order: ";
63  if (ropt.check(IO::Options::Swap))
64  std::cout << "swapped\n";
65  else if (ropt.check(IO::Options::LSB))
66  std::cout << "little endian\n";
67  else if (ropt.check(IO::Options::MSB))
68  std::cout << "big endian\n";
69  else
70  std::cout << "don't care\n";
71 
72  std::cout << " provides VertexNormal"
73  << ( // strange layout for doxygen
74  ropt.check(IO::Options::VertexNormal)
75  ? ": yes\n":": no\n");
76  CHKROPT( VertexColor );
77  CHKROPT( VertexTexCoord );
78  CHKROPT( FaceNormal );
79  CHKROPT( FaceColor );
80 
81 
82  // -------------------- mesh stats
83 
84  std::cout << "# Vertices: " << mesh.n_vertices() << std::endl;
85  std::cout << "# Edges : " << mesh.n_faces() << std::endl;
86  std::cout << "# Faces : " << mesh.n_faces() << std::endl;
87 
88 
89  // -------------------- show write options
90 
91  std::cout << "Selected write options:\n";
92  std::cout << " use binary: "
93  << (wopt.check(IO::Options::Binary) ? " yes\n" : " no\n");
94 
95  std::cout << " byte order: ";
96  if (wopt.check(IO::Options::Swap))
97  std::cout << "swapped\n";
98  else if (wopt.check(IO::Options::LSB))
99  std::cout << "little endian\n";
100  else if (wopt.check(IO::Options::MSB))
101  std::cout << "big endian\n";
102  else
103  std::cout << "don't care\n";
104 
105  std::cout << " write VertexNormal"
106  << (wopt.check(IO::Options::VertexNormal) ? ": yes\n":": no\n");
107  CHKWOPT( VertexColor );
108  CHKWOPT( VertexTexCoord );
109  CHKWOPT( FaceNormal );
110  CHKWOPT( FaceColor );
111 
112  // -------------------- show mesh capabilities
113 
114  std::cout << "Mesh supports\n";
115  MESHOPT("vertex normals", mesh.has_vertex_normals());
116  MESHOPT("vertex colors", mesh.has_vertex_colors());
117  MESHOPT("texcoords", mesh.has_vertex_texcoords2D());
118  MESHOPT("face normals", mesh.has_face_normals());
119  MESHOPT("face colors", mesh.has_face_colors());
120 
121  // -------------------- write mesh
122 
123  std::cout << "Write mesh to " << argv[optind+1] << "..";
124  if ( !IO::write_mesh( mesh, argv[optind+1], wopt ) )
125  {
126  std::cerr << "Error" << std::endl;
127  std::cerr << "Possible reasons:\n";
128  std::cerr << "1. Chosen format cannot handle an option!\n";
129  std::cerr << "2. Mesh does not provide necessary information!\n";
130  std::cerr << "3. Or simply cannot open file for writing!\n";
131  return 1;
132  }
133  else
134  std::cout << "Ok.\n";
135 
136  return 0;
137 }
138 
139 // ----------------------------------------------------------------------------
140 
141 void parse_commandline( int _argc, char **_argv, MyMesh& _mesh,
142  IO::Options &ropt, IO::Options &wopt )
143 {
144  int c;
145  while ((c=getopt(_argc, _argv, "bhsBF:LMSV:X:"))!=-1)
146  {
147  switch(c)
148  {
149  // -------------------- read options
150 
151  // force binary input
152  case 'b':
153  ropt += IO::Options::Binary;
154  break;
155 
156  // force swapping the byte order, when reading a binary file
157  case 's':
158  ropt += IO::Options::Swap;
159  break;
160 
161  // -------------------- write options
162 
163  // Write binary variant of format if possible
164  case 'B':
165  wopt += IO::Options::Binary;
166  break;
167 
168  //
169  case 'F':
170  for(size_t i=0; optarg[i]; ++i)
171  switch(optarg[i]) {
172  case 'n' : wopt += IO::Options::FaceNormal; break;
173  case 'c' : wopt += IO::Options::FaceColor; break;
174  }
175  break;
176 
177  // Use little endian when writing binary data
178  case 'L':
179  wopt += IO::Options::LSB;
180  break;
181 
182  // Use big endian when writing binary data
183  case 'M':
184  wopt += IO::Options::MSB;
185  break;
186 
187  // Swap byte order when writing binary data
188  case 'S':
189  wopt += IO::Options::Swap;
190  break;
191 
192  //
193  case 'V':
194  {
195  for(size_t i=0; optarg[i]; ++i)
196  switch(optarg[i]) {
197  case 'n' : // dont't change layout!!
198  wopt += IO::Options::VertexNormal;
199  break;
200  case 't' : wopt += IO::Options::VertexTexCoord; break;
201  case 'c' : wopt += IO::Options::VertexColor; break;
202  }
203  break;
204  }
205 
206  // -------------------- request mesh' standard properties
207  case 'X':
208  {
209  char entity='\0';
210  for(size_t i=0; optarg[i]; ++i)
211  switch(optarg[i]) {
212  case 'v':
213  case 'f': entity = optarg[i]; break;
214  case 'n':
215  switch(entity) {
216  case 'v': _mesh.request_vertex_normals(); break;
217  case 'f': _mesh.request_face_normals(); break;
218  }
219  break;
220  case 'c':
221  switch(entity) {
222  case 'v': _mesh.request_vertex_colors(); break;
223  case 'f': _mesh.request_face_colors(); break;
224  }
225  break;
226  case 't':
227  switch(entity) {
228  case 'v': _mesh.request_vertex_texcoords2D(); break;
229  }
230  break;
231  }
232  break;
233  }
234 
235  // -------------------- help
236  case 'h':
237  usage_and_exit(0);
238  default:
239  usage_and_exit(1);
240  }
241  }
242 
243  if ( _argc-optind != 2)
244  usage_and_exit(1);
245 }
246 
247 
248 // ----------------------------------------------------------------------------
249 
250 void usage_and_exit(int xcode)
251 {
252  std::ostream &os = xcode ? std::cerr : std::cout;
253 
254  os << "Usage: io_options [Options] <input> <output>\n"
255  << std::endl;
256  os << " Read and write a mesh, using OpenMesh::IO::Options\n"
257  << std::endl;
258  os << "Options:\n"
259  << std::endl;
260  os << "a) read options\n"
261  << std::endl
262  << " -b\n"
263  << "\tAssume input file is a binary file\n"
264  << std::endl
265  << " -s\n"
266  << "\tSwap byte order when reading a binary file!\n"
267  << std::endl;
268  os << "b) write options\n"
269  << std::endl
270  << " -B\n"
271  << "\tWrite binary data\n"
272  << std::endl
273  << " -S\n"
274  << "\tSwap byte order, when writing binary data\n"
275  << std::endl
276  << " -M/-L\n"
277  << "\tUse MSB/LSB byte ordering, when writing binary data\n"
278  << std::endl
279  << " -V{n|t|c}\n"
280  << "\tWrite vertex normals, texcoords, and/or colors\n"
281  << std::endl
282  << " -F{n|c}\n"
283  << "\tWrite face normals, and/or colors\n"
284  << std::endl;
285  os << "c) Mesh properties\n"
286  << std::endl
287  << " -Xv{n|c|t}\n"
288  << "\tRequest vertex property normals|colors|texcoords\n"
289  << std::endl
290  << " -Xf{n|c}\n"
291  << "\tRequest face property normals|colors\n"
292  << std::endl;
293  exit(xcode);
294 }
295 
296 // end of file
297 // ============================================================================
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:104
Has (r) / store (w) vertex normals.
Definition: Options.hh:109
Has (r) / store (w) face normals.
Definition: Options.hh:113
Assume big endian byte ordering.
Definition: Options.hh:106
Has (r) / store (w) face colors.
Definition: Options.hh:114
Has (r) / store (w) texture coordinates.
Definition: Options.hh:111
Set options for reader/writer modules.
Definition: Options.hh:95
Set binary mode for r/w.
Definition: Options.hh:105
Swap byte order in binary mode.
Definition: Options.hh:108
Has (r) / store (w) vertex colors.
Definition: Options.hh:110
Assume little endian byte ordering.
Definition: Options.hh:107
bool write_mesh(const Mesh &_mesh, const std::string &_filename, Options _opt=Options::Default, std::streamsize _precision=6)
Write a mesh to the file _filename.
Definition: MeshIO.hh:199