Developer Documentation

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
14 typedef TriMesh_ArrayKernelT<> MyMesh;
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 // ============================================================================
OpenMesh::TriMesh_ArrayKernelT
Definition: PolyMesh_ArrayKernelT.hh:73
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:105
OpenMesh::IO::Options::Swap
Swap byte order in binary mode.
Definition: Options.hh:103
OpenMesh::IO::Options::LSB
Assume little endian byte ordering.
Definition: Options.hh:102
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:109
OpenMesh::IO::write_mesh
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:207
OpenMesh::IO::Options::FaceNormal
Has (r) / store (w) face normals.
Definition: Options.hh:108
OpenMesh::IO::Options::VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:106
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:90
OpenMesh::IO::Options::Binary
Set binary mode for r/w.
Definition: Options.hh:100
OpenMesh::IO::Options::VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:104
OpenMesh::IO::read_mesh
bool read_mesh(Mesh &_mesh, const std::string &_filename)
Read a mesh from file _filename.
Definition: MeshIO.hh:112
OpenMesh
Definition: MeshItems.hh:59
OpenMesh::IO::Options::MSB
Assume big endian byte ordering.
Definition: Options.hh:101