Developer Documentation

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
OFFReader.cc
1 /* ========================================================================= *
2 * *
3 * OpenMesh *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openmesh.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenMesh. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 * ========================================================================= */
41
42 /*===========================================================================*\
43 * *
44 * $Revision$ *
45 * $Date$ *
46 * *
47 \*===========================================================================*/
48
49
50 #define LINE_LEN 4096
51
52
53 //== INCLUDES =================================================================
54
55 // OpenMesh
56 #include <OpenMesh/Core/System/config.h>
57 #include <OpenMesh/Core/System/omstream.hh>
58 #include <OpenMesh/Core/IO/reader/OFFReader.hh>
59 #include <OpenMesh/Core/IO/IOManager.hh>
60 #include <OpenMesh/Core/Utils/color_cast.hh>
61 // #include <OpenMesh/Core/IO/BinaryHelper.hh>
62
63 //STL
64 #include <iostream>
65 #include <fstream>
66 #include <memory>
67 #include <cstring>
68
69 #if defined(OM_CC_MIPS)
70 # include <ctype.h>
72 #elif defined(_STLPORT_VERSION) && (_STLPORT_VERSION==0x460)
73 # include <cctype>
74 #else
75 using std::isspace;
76 #endif
77
78 #ifndef WIN32
79 #endif
80
81 //=== NAMESPACES ==============================================================
82
83
84 namespace OpenMesh {
85 namespace IO {
86
87
88 //=============================================================================
89
90 //=== INSTANCIATE =============================================================
91
92
93 _OFFReader_ __OFFReaderInstance;
94 _OFFReader_& OFFReader() { return __OFFReaderInstance; }
95
96
97 //=== IMPLEMENTATION ==========================================================
98
99
100
101 _OFFReader_::_OFFReader_()
102 {
103 IOManager().register_module(this);
104 }
105
106
107 //-----------------------------------------------------------------------------
108
109
110 bool
111 _OFFReader_::read(const std::string& _filename, BaseImporter& _bi,
112 Options& _opt)
113 {
114 std::ifstream ifile(_filename.c_str(), (options_.is_binary() ? std::ios::binary | std::ios::in
115 : std::ios::in) );
116
117 if (!ifile.is_open() || !ifile.good())
118 {
119 omerr() << "[OFFReader] : cannot not open file "
120 << _filename
121 << std::endl;
122
123 return false;
124 }
125
126 assert(ifile);
127
128 bool result = read(ifile, _bi, _opt);
129
130 ifile.close();
131 return result;
132 }
133
134 //-----------------------------------------------------------------------------
135
136
137 bool
138 _OFFReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt )
139 {
140 if (!_in.good())
141 {
142 omerr() << "[OMReader] : cannot not use stream "
143 << std::endl;
144 return false;
145 }
146
147 // filter relevant options for reading
148 bool swap = _opt.check( Options::Swap );
149
150
151 userOptions_ = _opt;
152
153 // build options to be returned
154 _opt.clear();
155
156 if (options_.vertex_has_normal() && userOptions_.vertex_has_normal()) _opt += Options::VertexNormal;
157 if (options_.vertex_has_texcoord() && userOptions_.vertex_has_texcoord()) _opt += Options::VertexTexCoord;
158 if (options_.vertex_has_color() && userOptions_.vertex_has_color()) _opt += Options::VertexColor;
159 if (options_.face_has_color() && userOptions_.face_has_color()) _opt += Options::FaceColor;
160 if (options_.is_binary()) _opt += Options::Binary;
161
162 //force user-choice for the alpha value when reading binary
163 if ( options_.is_binary() && userOptions_.color_has_alpha() )
164 options_ += Options::ColorAlpha;
165
166 return (options_.is_binary() ?
167 read_binary(_in, _bi, _opt, swap) :
168 read_ascii(_in, _bi, _opt));
169
170 }
171
172
173
174 //-----------------------------------------------------------------------------
175
176 bool
177 _OFFReader_::read_ascii(std::istream& _in, BaseImporter& _bi, Options& _opt) const
178 {
179
180
181 unsigned int i, j, k, l, idx;
182 unsigned int nV, nF, dummy;
183 OpenMesh::Vec3f v, n;
184 OpenMesh::Vec2f t;
185 OpenMesh::Vec3i c3;
186 OpenMesh::Vec3f c3f;
187 OpenMesh::Vec4i c4;
188 OpenMesh::Vec4f c4f;
189 BaseImporter::VHandles vhandles;
190 VertexHandle vh;
191 std::stringstream stream;
192 std::string trash;
193
194 // read header line
195 std::string header;
196 std::getline(_in,header);
197
198 // + #Vertice, #Faces, #Edges
199 _in >> nV;
200 _in >> nF;
201 _in >> dummy;
202
203 _bi.reserve(nV, 3*nV, nF);
204
205 // read vertices: coord [hcoord] [normal] [color] [texcoord]
206 for (i=0; i<nV && !_in.eof(); ++i)
207 {
208 // Always read VERTEX
209 _in >> v[0]; _in >> v[1]; _in >> v[2];
210
211 vh = _bi.add_vertex(v);
212
213 //perhaps read NORMAL
214 if ( options_.vertex_has_normal() ){
215
216 _in >> n[0]; _in >> n[1]; _in >> n[2];
217
218 if ( userOptions_.vertex_has_normal() )
219 _bi.set_normal(vh, n);
220 }
221
222 //take the rest of the line and check how colors are defined
223 std::string line;
224 std::getline(_in,line);
225
226 int colorType = getColorType(line, options_.vertex_has_texcoord() );
227
228 stream.str(line);
229 stream.clear();
230
231 //perhaps read COLOR
232 if ( options_.vertex_has_color() ){
233
234 switch (colorType){
235 case 0 : break; //no color
236 case 1 : stream >> trash; break; //one int (isn't handled atm)
237 case 2 : stream >> trash; stream >> trash; break; //corrupt format (ignore)
238 // rgb int
239 case 3 : stream >> c3[0]; stream >> c3[1]; stream >> c3[2];
240 if ( userOptions_.vertex_has_color() )
241 _bi.set_color( vh, Vec3uc( c3 ) );
242 break;
243 // rgba int
244 case 4 : stream >> c4[0]; stream >> c4[1]; stream >> c4[2]; stream >> c4[3];
245 if ( userOptions_.vertex_has_color() )
246 _bi.set_color( vh, Vec4uc( c4 ) );
247 break;
248 // rgb floats
249 case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2];
250 if ( userOptions_.vertex_has_color() ) {
251 _bi.set_color( vh, c3f );
252 _opt += Options::ColorFloat;
253 }
254 break;
255 // rgba floats
256 case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3];
257 if ( userOptions_.vertex_has_color() ) {
258 _bi.set_color( vh, c4f );
259 _opt += Options::ColorFloat;
260 }
261 break;
262
263 default:
264 std::cerr << "Error in file format (colorType = " << colorType << ")\n";
265 break;
266 }
267 }
268 //perhaps read TEXTURE COORDs
269 if ( options_.vertex_has_texcoord() ){
270 stream >> t[0]; stream >> t[1];
271 if ( userOptions_.vertex_has_texcoord() )
272 _bi.set_texcoord(vh, t);
273 }
274 }
275
276 // faces
277 // #N <v1> <v2> .. <v(n-1)> [color spec]
278 for (i=0; i<nF; ++i)
279 {
280 // nV = number of Vertices for current face
281 _in >> nV;
282
283 if (nV == 3)
284 {
285 vhandles.resize(3);
286 _in >> j;
287 _in >> k;
288 _in >> l;
289
290 vhandles[0] = VertexHandle(j);
291 vhandles[1] = VertexHandle(k);
292 vhandles[2] = VertexHandle(l);
293 }
294 else
295 {
296 vhandles.clear();
297 for (j=0; j<nV; ++j)
298 {
299 _in >> idx;
300 vhandles.push_back(VertexHandle(idx));
301 }
302 }
303
304 FaceHandle fh = _bi.add_face(vhandles);
305
306 //perhaps read face COLOR
307 if ( options_.face_has_color() ){
308
309 //take the rest of the line and check how colors are defined
310 std::string line;
311 std::getline(_in,line);
312
313 int colorType = getColorType(line, false );
314
315 stream.str(line);
316 stream.clear();
317
318 switch (colorType){
319 case 0 : break; //no color
320 case 1 : stream >> trash; break; //one int (isn't handled atm)
321 case 2 : stream >> trash; stream >> trash; break; //corrupt format (ignore)
322 // rgb int
323 case 3 : stream >> c3[0]; stream >> c3[1]; stream >> c3[2];
324 if ( userOptions_.face_has_color() )
325 _bi.set_color( fh, Vec3uc( c3 ) );
326 break;
327 // rgba int
328 case 4 : stream >> c4[0]; stream >> c4[1]; stream >> c4[2]; stream >> c4[3];
329 if ( userOptions_.face_has_color() )
330 _bi.set_color( fh, Vec4uc( c4 ) );
331 break;
332 // rgb floats
333 case 5 : stream >> c3f[0]; stream >> c3f[1]; stream >> c3f[2];
334 if ( userOptions_.face_has_color() ) {
335 _bi.set_color( fh, c3f );
336 _opt += Options::ColorFloat;
337 }
338 break;
339 // rgba floats
340 case 6 : stream >> c4f[0]; stream >> c4f[1]; stream >> c4f[2]; stream >> c4f[3];
341 if ( userOptions_.face_has_color() ) {
342 _bi.set_color( fh, c4f );
343 _opt += Options::ColorFloat;
344 }
345 break;
346
347 default:
348 std::cerr << "Error in file format (colorType = " << colorType << ")\n";
349 break;
350 }
351 }
352 }
353
354 // File was successfully parsed.
355 return true;
356 }
357
358
359 //-----------------------------------------------------------------------------
360
361 int _OFFReader_::getColorType(std::string& _line, bool _texCoordsAvailable) const
362 {
363 /*
364 0 : no Color
365 1 : one int (e.g colormap index)
366 2 : two items (error!)
367 3 : 3 ints
368 4 : 3 ints
369 5 : 3 floats
370 6 : 4 floats
371
372 */
373 // Check if we have any additional information here
374 if ( _line.size() < 1 )
375 return 0;
376
377 //first remove spaces at start/end of the line
378 while (_line.size() > 0 && std::isspace(_line[0]))
379 _line = _line.substr(1);
380 while (_line.size() > 0 && std::isspace(_line[ _line.length()-1 ]))
381 _line = _line.substr(0, _line.length()-1);
382
383 //count the remaining items in the line
384 size_t found;
385 int count = 0;
386
387 found=_line.find_first_of(" ");
388 while (found!=std::string::npos){
389 count++;
390 found=_line.find_first_of(" ",found+1);
391 }
392
393 if (!_line.empty()) count++;
394
395 if (_texCoordsAvailable) count -= 2;
396
397 if (count == 3 || count == 4){
398 //get first item
399 found = _line.find(" ");
400 std::string c1 = _line.substr (0,found);
401
402 if (c1.find(".") != std::string::npos){
403 if (count == 3)
404 count = 5;
405 else
406 count = 6;
407 }
408 }
409 return count;
410 }
411
412 void _OFFReader_::readValue(std::istream& _in, float& _value) const{
413 float32_t tmp;
414
415 restore( _in , tmp, false ); //assuming LSB byte order
416 _value = tmp;
417 }
418
419 void _OFFReader_::readValue(std::istream& _in, int& _value) const{
420 uint32_t tmp;
421
422 restore( _in , tmp, false ); //assuming LSB byte order
423 _value = tmp;
424 }
425
426 void _OFFReader_::readValue(std::istream& _in, unsigned int& _value) const{
427 uint32_t tmp;
428
429 restore( _in , tmp, false ); //assuming LSB byte order
430 _value = tmp;
431 }
432
433 bool
434 _OFFReader_::read_binary(std::istream& _in, BaseImporter& _bi, Options& _opt, bool /*_swap*/) const
435 {
436 unsigned int i, j, k, l, idx;
437 unsigned int nV, nF, dummy;
438 OpenMesh::Vec3f v, n;
439 OpenMesh::Vec3i c;
440 OpenMesh::Vec4i cA;
441 OpenMesh::Vec3f cf;
442 OpenMesh::Vec4f cAf;
443 OpenMesh::Vec2f t;
444 BaseImporter::VHandles vhandles;
445 VertexHandle vh;
446
447 // read header line
448 std::string header;
449 std::getline(_in,header);
450
451 // + #Vertice, #Faces, #Edges
452 readValue(_in, nV);
453 readValue(_in, nF);
454 readValue(_in, dummy);
455
456 _bi.reserve(nV, 3*nV, nF);
457
458 // read vertices: coord [hcoord] [normal] [color] [texcoord]
459 for (i=0; i<nV && !_in.eof(); ++i)
460 {
461 // Always read Vertex
462 readValue(_in, v[0]);
463 readValue(_in, v[1]);
464 readValue(_in, v[2]);
465
466 vh = _bi.add_vertex(v);
467
468 if ( options_.vertex_has_normal() ) {
469 readValue(_in, n[0]);
470 readValue(_in, n[1]);
471 readValue(_in, n[2]);
472
473 if ( userOptions_.vertex_has_normal() )
474 _bi.set_normal(vh, n);
475 }
476
477 if ( options_.vertex_has_color() ) {
478 if ( userOptions_.color_is_float() ) {
479 _opt += Options::ColorFloat;
480 //with alpha
481 if ( options_.color_has_alpha() ){
482 readValue(_in, cAf[0]);
483 readValue(_in, cAf[1]);
484 readValue(_in, cAf[2]);
485 readValue(_in, cAf[3]);
486
487 if ( userOptions_.vertex_has_color() )
488 _bi.set_color( vh, cAf );
489 }else{
490
491 //without alpha
492 readValue(_in, cf[0]);
493 readValue(_in, cf[1]);
494 readValue(_in, cf[2]);
495
496 if ( userOptions_.vertex_has_color() )
497 _bi.set_color( vh, cf );
498 }
499 } else {
500 //with alpha
501 if ( options_.color_has_alpha() ){
502 readValue(_in, cA[0]);
503 readValue(_in, cA[1]);
504 readValue(_in, cA[2]);
505 readValue(_in, cA[3]);
506
507 if ( userOptions_.vertex_has_color() )
508 _bi.set_color( vh, Vec4uc( cA ) );
509 }else{
510 //without alpha
511 readValue(_in, c[0]);
512 readValue(_in, c[1]);
513 readValue(_in, c[2]);
514
515 if ( userOptions_.vertex_has_color() )
516 _bi.set_color( vh, Vec3uc( c ) );
517 }
518 }
519 }
520
521 if ( options_.vertex_has_texcoord()) {
522 readValue(_in, t[0]);
523 readValue(_in, t[1]);
524
525 if ( userOptions_.vertex_has_texcoord() )
526 _bi.set_texcoord(vh, t);
527 }
528 }
529
530 // faces
531 // #N <v1> <v2> .. <v(n-1)> [color spec]
532 // So far color spec is unsupported!
533 for (i=0; i<nF; ++i)
534 {
535 readValue(_in, nV);
536
537 if (nV == 3)
538 {
539 vhandles.resize(3);
540 readValue(_in, j);
541 readValue(_in, k);
542 readValue(_in, l);
543
544 vhandles[0] = VertexHandle(j);
545 vhandles[1] = VertexHandle(k);
546 vhandles[2] = VertexHandle(l);
547 } else {
548 vhandles.clear();
549 for (j=0; j<nV; ++j)
550 {
551 readValue(_in, idx);
552 vhandles.push_back(VertexHandle(idx));
553 }
554 }
555
556 FaceHandle fh = _bi.add_face(vhandles);
557
558 //face color
559 if ( _opt.face_has_color() ) {
560 if ( userOptions_.color_is_float() ) {
561 _opt += Options::ColorFloat;
562 //with alpha
563 if ( options_.color_has_alpha() ){
564 readValue(_in, cAf[0]);
565 readValue(_in, cAf[1]);
566 readValue(_in, cAf[2]);
567 readValue(_in, cAf[3]);
568
569 if ( userOptions_.face_has_color() )
570 _bi.set_color( fh , cAf );
571 }else{
572 //without alpha
573 readValue(_in, cf[0]);
574 readValue(_in, cf[1]);
575 readValue(_in, cf[2]);
576
577 if ( userOptions_.face_has_color() )
578 _bi.set_color( fh, cf );
579 }
580 } else {
581 //with alpha
582 if ( options_.color_has_alpha() ){
583 readValue(_in, cA[0]);
584 readValue(_in, cA[1]);
585 readValue(_in, cA[2]);
586 readValue(_in, cA[3]);
587
588 if ( userOptions_.face_has_color() )
589 _bi.set_color( fh , Vec4uc( cA ) );
590 }else{
591 //without alpha
592 readValue(_in, c[0]);
593 readValue(_in, c[1]);
594 readValue(_in, c[2]);
595
596 if ( userOptions_.face_has_color() )
597 _bi.set_color( fh, Vec3uc( c ) );
598 }
599 }
600 }
601
602 }
603
604 // File was successfully parsed.
605 return true;
606
607 }
608
609
610 //-----------------------------------------------------------------------------
611
612
613 bool _OFFReader_::can_u_read(const std::string& _filename) const
614 {
615 // !!! Assuming BaseReader::can_u_parse( std::string& )
616 // does not call BaseReader::read_magic()!!!
617 if (BaseReader::can_u_read(_filename))
618 {
619 std::ifstream ifs(_filename.c_str());
620 if (ifs.is_open() && can_u_read(ifs))
621 {
622 ifs.close();
623 return true;
624 }
625 }
626 return false;
627 }
628
629
630 //-----------------------------------------------------------------------------
631
632
633 bool _OFFReader_::can_u_read(std::istream& _is) const
634 {
635 options_.cleanup();
636
637 // read 1st line
638 char line[LINE_LEN], *p;
639 _is.getline(line, LINE_LEN);
640 p = line;
641
642 std::streamsize remainingChars = _is.gcount();
643
644 bool vertexDimensionTooHigh = false;
645
646 // check header: [ST][C][N][4][n]OFF BINARY
647
648 if ( ( remainingChars > 1 ) && ( p[0] == 'S' && p[1] == 'T') )
649 { options_ += Options::VertexTexCoord; p += 2; remainingChars -= 2; }
650
651 if ( ( remainingChars > 0 ) && ( p[0] == 'C') )
652 { options_ += Options::VertexColor;
653 options_ += Options::FaceColor; ++p; --remainingChars; }
654
655 if ( ( remainingChars > 0 ) && ( p[0] == 'N') )
656 { options_ += Options::VertexNormal; ++p; --remainingChars; }
657
658 if ( ( remainingChars > 0 ) && (p[0] == '4' ) )
659 { vertexDimensionTooHigh = true; ++p; --remainingChars; }
660
661 if ( ( remainingChars > 0 ) && ( p[0] == 'n') )
662 { vertexDimensionTooHigh = true; ++p; --remainingChars; }
663
664 if ( ( remainingChars < 3 ) || (!(p[0] == 'O' && p[1] == 'F' && p[2] == 'F') ) )
665 return false;
666
667 p += 4;
668
669 // Detect possible garbage and make sure, we don't have an underflow
670 if ( remainingChars >= 4 )
671 remainingChars -= 4;
672 else
673 remainingChars = 0;
674
675 if ( ( remainingChars >= 6 ) && ( strncmp(p, "BINARY", 6) == 0 ) )
676 options_+= Options::Binary;
677
678 // vertex Dimensions != 3 are currently not supported
679 if (vertexDimensionTooHigh)
680 return false;
681
682 return true;
683 }
684
685
686 //=============================================================================
687 } // namespace IO
688 } // namespace OpenMesh
689 //=============================================================================
OpenMesh::IO::_OFFReader_::can_u_read
bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Definition: OFFReader.cc:613
OpenMesh::IO::Options::VertexNormal
Has (r) / store (w) vertex normals.
Definition: Options.hh:109
OpenMesh
Definition: MeshItems.hh:64
OpenMesh::IO::_IOManager_::register_module
bool register_module(BaseReader *_bl)
Definition: IOManager.hh:222
BaseImporter
Definition: BaseImporter.hh:1
OpenMesh::IO::Options::FaceColor
Has (r) / store (w) face colors.
Definition: Options.hh:114
omstream.hh
OpenMesh::IO::Options::VertexTexCoord
Has (r) / store (w) texture coordinates.
Definition: Options.hh:111
OpenMesh::IO::Options
Set options for reader/writer modules.
Definition: Options.hh:95
OpenMesh::IO::_OFFReader_
Definition: OFFReader.hh:117
config.h
OpenMesh::IO::__OFFReaderInstance
_OFFReader_ __OFFReaderInstance
Declare the single entity of the OFF reader.
Definition: OFFReader.cc:93
OpenMesh::VectorT< float, 3 >
OpenMesh::VertexHandle
Handle for a vertex entity.
Definition: Handles.hh:125
OpenMesh::IO::Options::ColorFloat
Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files) ...
Definition: Options.hh:117
OpenMesh::IO::float32_t
float float32_t
Definition: SR_types.hh:97
OpenMesh::IO::Options::Binary
Set binary mode for r/w.
Definition: Options.hh:105
OpenMesh::IO::Options::cleanup
void cleanup(void)
Restore state after default constructor.
Definition: Options.hh:147
OpenMesh::IO::Options::Swap
Swap byte order in binary mode.
Definition: Options.hh:108
OpenMesh::IO::Options::clear
void clear(void)
Clear all bits.
Definition: Options.hh:151
OpenMesh::IO::_OFFReader_::read
bool read(const std::string &_filename, BaseImporter &_bi, Options &_opt)
Definition: OFFReader.cc:111
OpenMesh::IO::Options::VertexColor
Has (r) / store (w) vertex colors.
Definition: Options.hh:110
OpenMesh::IO::uint32_t
unsigned int uint32_t
Definition: SR_types.hh:90
OpenMesh::IO::Options::ColorAlpha
Has (r) / store (w) alpha values for colors.
Definition: Options.hh:116
OpenMesh::IO::IOManager
_IOManager_ & IOManager()
Definition: IOManager.cc:77
OpenMesh::IO::BaseReader::can_u_read
virtual bool can_u_read(const std::string &_filename) const
Returns true if writer can parse _filename (checks extension). _filename can also provide an extensio...
Definition: BaseReader.cc:82
OpenMesh::IO::BaseImporter
Definition: BaseImporter.hh:88