OpenMesh
OMFormat.hh
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 #ifndef OPENMESH_IO_OMFORMAT_HH
51 #define OPENMESH_IO_OMFORMAT_HH
52 
53 
54 //=== INCLUDES ================================================================
55 
56 #include <OpenMesh/Core/System/config.h>
58 #include <OpenMesh/Core/IO/SR_store.hh>
59 #include <OpenMesh/Core/Utils/GenProg.hh>
60 #include <OpenMesh/Core/Utils/Endian.hh>
61 #include <OpenMesh/Core/Utils/vector_traits.hh>
62 // --------------------
63 #include <iostream>
64 #if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000)
66 # define OM_MISSING_HEADER_LIMITS 1
67 #else
68 # include <limits>
69 #endif
70 
71 
72 //== NAMESPACES ==============================================================
73 
74 #ifndef DOXY_IGNORE_THIS
75 namespace OpenMesh {
76 namespace IO {
77 namespace OMFormat {
78 
79 
80 //=== IMPLEMENTATION ==========================================================
81 
82 
86 
87 //-----------------------------------------------------------------------------
88 
89  // <:Header>
90  // <:Comment>
91  // Chunk 0
92  // <:ChunkHeader>
93  // <:Comment>
94  // data
95  // Chunk 1
96  // <:ChunkHeader>
97  // <:Comment>
98  // data
99  // .
100  // .
101  // .
102  // Chunk N
103 
104  //
105  // NOTICE!
106  //
107  // The usage of data types who differ in size
108  // on different pc architectures (32/64 bit) and/or
109  // operating systems, e.g. (unsigned) long, size_t,
110  // is not recommended because of inconsistencies
111  // in case of cross writing and reading.
112  //
113  // Basic types that are supported are:
114 
115 
116  typedef unsigned char uchar;
117  typedef uint8_t uint8;
118  typedef uint16_t uint16;
119  typedef uint32_t uint32;
120  typedef uint64_t uint64;
121  typedef int8_t int8;
122  typedef int16_t int16;
123  typedef int32_t int32;
124  typedef int64_t int64;
125  typedef float32_t float32;
126  typedef float64_t float64;
127 
128  struct Header
129  {
130  uchar magic_[2]; // OM
131  uchar mesh_; // [T]riangles, [Q]uads, [P]olygonals
132  uint8 version_;
133  uint32 n_vertices_;
134  uint32 n_faces_;
135  uint32 n_edges_;
136 
137  size_t store( std::ostream& _os, bool _swap ) const
138  {
139  _os.write( (char*)this, 4); // magic_, mesh_, version_
140  size_t bytes = 4;
141  bytes += binary<uint32_t>::store( _os, n_vertices_, _swap );
142  bytes += binary<uint32_t>::store( _os, n_faces_, _swap );
143  bytes += binary<uint32_t>::store( _os, n_edges_, _swap );
144  return bytes;
145  }
146 
147  size_t restore( std::istream& _is, bool _swap )
148  {
149  if (_is.read( (char*)this, 4 ).eof())
150  return 0;
151 
152  size_t bytes = 4;
153  bytes += binary<uint32_t>::restore( _is, n_vertices_, _swap );
154  bytes += binary<uint32_t>::restore( _is, n_faces_, _swap );
155  bytes += binary<uint32_t>::restore( _is, n_edges_, _swap );
156  return bytes;
157  }
158 
159  };
160 
161  struct Chunk
162  {
163  // Hardcoded this size to an uint32 to make the system 32/64 bit compatible.
164  // Needs further investigation!
165  typedef uint32 esize_t; // element size, used for custom properties
166 
167  enum Type {
168  Type_Pos = 0x00,
169  Type_Normal = 0x01,
170  Type_Texcoord = 0x02,
171  Type_Status = 0x03,
172  Type_Color = 0x04,
173  Type_Custom = 0x06,
174  Type_Topology = 0x07
175  };
176 
177  enum Entity {
178  Entity_Vertex = 0x00,
179  Entity_Mesh = 0x01,
180  Entity_Face = 0x02,
181  Entity_Edge = 0x04,
182  Entity_Halfedge = 0x06,
183  Entity_Sentinel = 0x07
184  };
185 
186  enum Dim {
187  Dim_1D = 0x00,
188  Dim_2D = 0x01,
189  Dim_3D = 0x02,
190  Dim_4D = 0x03,
191  Dim_5D = 0x04,
192  Dim_6D = 0x05,
193  Dim_7D = 0x06,
194  Dim_8D = 0x07
195  };
196 
197  enum Integer_Size {
198  Integer_8 = 0x00, // 1 byte for (unsigned) char
199  Integer_16 = 0x01, // 2 bytes for short
200  Integer_32 = 0x02, // 4 bytes for long
201  Integer_64 = 0x03 // 8 bytes for long long
202  };
203 
204  enum Float_Size {
205  Float_32 = 0x00, // 4 bytes for float
206  Float_64 = 0x01, // 8 bytes for double
207  Float_128 = 0x02 // 16 bytes for long double (an assumption!)
208  };
209 
210  static const int SIZE_RESERVED = 1; // 1
211  static const int SIZE_NAME = 1; // 2
212  static const int SIZE_ENTITY = 3; // 5
213  static const int SIZE_TYPE = 4; // 9
214 
215  static const int SIZE_SIGNED = 1; // 10
216  static const int SIZE_FLOAT = 1; // 11
217  static const int SIZE_DIM = 3; // 14
218  static const int SIZE_BITS = 2; // 16
219 
220  static const int OFF_RESERVED = 0; // 0
221  static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED; // 2
222  static const int OFF_ENTITY = SIZE_NAME + OFF_NAME; // 3
223  static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY; // 5
224  static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE; // 9
225  static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED; // 10
226  static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT; // 11
227  static const int OFF_BITS = SIZE_DIM + OFF_DIM; // 14
228 
229  // !Attention! When changing the bit size, the operators
230  // << (uint16, Header) and << (Header, uint16) must be changed as well
231  //
232  // Entries signed_, float_, dim_, bits_ are not used when type_
233  // equals Type_Custom
234  //
235  struct Header // 16 bits long
236  {
237  unsigned reserved_: SIZE_RESERVED;
238  unsigned name_ : SIZE_NAME; // 1 named property, 0 anonymous
239  unsigned entity_ : SIZE_ENTITY; // 0 vertex, 1 mesh, 2 edge,
240  // 4 halfedge, 6 face
241  unsigned type_ : SIZE_TYPE; // 0 pos, 1 normal, 2 texcoord,
242  // 3 status, 4 color 6 custom 7 topology
243  unsigned signed_ : SIZE_SIGNED; // bool
244  unsigned float_ : SIZE_FLOAT; // bool
245  unsigned dim_ : SIZE_DIM; // 0 1D, 1 2D, 2 3D, .., 7 8D
246  unsigned bits_ : SIZE_BITS; // {8, 16, 32, 64} | {32, 64, 128}
247  // (integer) (float)
248  unsigned unused_ : 16; // fill up to 32 bits
249  }; // struct Header
250 
251 
252  class PropertyName : public std::string
253  {
254  public:
255 
256  static const size_t size_max = 256;
257 
258  PropertyName( ) { }
259 
260  PropertyName( const std::string& _name ) { *this = _name; }
261 
262  bool is_valid() const { return is_valid( size() ); }
263 
264  static bool is_valid( size_t _s ) { return _s <= size_max; }
265 
266  PropertyName& operator = ( const std::string& _rhs )
267  {
268  assert( is_valid( _rhs.size() ) );
269 
270  if ( is_valid( _rhs.size() ) )
271  std::string::operator = ( _rhs );
272  else
273  {
274  omerr() << "Warning! Property name too long. Will be shortened!\n";
275  this->std::string::operator = ( _rhs.substr(0, size_max) );
276  }
277 
278  return *this;
279  }
280 
281  };
282 
283  }; // Chunk
284 
285  // ------------------------------------------------------------ Helper
286 
287  // -------------------- get size information
288 
290  inline size_t header_size(void) { return sizeof(Header); }
291 
292 
294  inline size_t chunk_header_size( void ) { return sizeof(uint16); }
295 
296 
298  inline size_t scalar_size( const Chunk::Header& _hdr )
299  {
300  return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_);
301  }
302 
303 
305  inline size_t dimensions(const Chunk::Header& _chdr) { return _chdr.dim_+1; }
306 
307 
309  inline size_t vector_size( const Chunk::Header& _chdr )
310  {
311  return dimensions(_chdr)*scalar_size(_chdr);
312  }
313 
314 
316  inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr )
317  {
318  size_t C;
319  switch( _chunk_hdr.entity_ )
320  {
321  case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break;
322  case Chunk::Entity_Face: C = _hdr.n_faces_; break;
323  case Chunk::Entity_Halfedge: C = _hdr.n_edges_*2; break;
324  case Chunk::Entity_Edge: C = _hdr.n_edges_; break;
325  case Chunk::Entity_Mesh: C = 1; break;
326  default:
327  C = 0;
328  std::cerr << "Invalid value in _chunk_hdr.entity_\n";
329  assert( false );
330  break;
331  }
332 
333  return C * vector_size( _chunk_hdr );
334  }
335 
336  inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr )
337  {
338  return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr );
339  }
340 
341  // -------------------- convert from Chunk::Header to storage type
342 
343  uint16& operator << (uint16& val, const Chunk::Header& hdr);
344  Chunk::Header& operator << (Chunk::Header& hdr, const uint16 val);
345 
346 
347  // -------------------- type information
348 
349  template <typename T> bool is_float(const T&)
350  {
351 #if defined(OM_MISSING_HEADER_LIMITS)
352  return !Utils::NumLimitsT<T>::is_integer();
353 #else
354  return !std::numeric_limits<T>::is_integer;
355 #endif
356  }
357 
358  template <typename T> bool is_integer(const T)
359  {
360 #if defined(OM_MISSING_HEADER_LIMITS)
361  return Utils::NumLimitsT<T>::is_integer();
362 #else
363  return std::numeric_limits<T>::is_integer;
364 #endif
365  }
366 
367  template <typename T> bool is_signed(const T&)
368  {
369 #if defined(OM_MISSING_HEADER_LIMITS)
370  return Utils::NumLimitsT<T>::is_signed();
371 #else
372  return std::numeric_limits<T>::is_signed;
373 #endif
374  }
375 
376  // -------------------- conversions (format type <- type/value)
377 
378  template <typename VecType>
379  inline
380  Chunk::Dim dim( VecType )
381  {
382  assert( vector_traits< VecType >::size() < 9 );
383  return static_cast<Chunk::Dim>(vector_traits< VecType >::size() - 1);
384  }
385 
386  template <typename VecType>
387  inline
388  Chunk::Dim dim( const Chunk::Header& _hdr )
389  {
390  return static_cast<Chunk::Dim>( _hdr.dim_ );
391  }
392 
393  // calc minimum (power-of-2) number of bits needed
394  Chunk::Integer_Size needed_bits( size_t s );
395 
396  // Convert size of type to Integer_Size
397 #ifdef NDEBUG
398  template <typename T> Chunk::Integer_Size integer_size(const T&)
399 #else
400  template <typename T> Chunk::Integer_Size integer_size(const T& d)
401 #endif
402  {
403 #ifndef NDEBUG
404  assert( is_integer(d) );
405 #endif
406 
407  switch( sizeof(T) )
408  {
409  case 1: return OMFormat::Chunk::Integer_8;
410  case 2: return OMFormat::Chunk::Integer_16;
411  case 4: return OMFormat::Chunk::Integer_32;
412  case 8: return OMFormat::Chunk::Integer_64;
413  default:
414  std::cerr << "Invalid value in integer_size\n";
415  assert( false );
416  break;
417  }
418  return Chunk::Integer_Size(0);
419  }
420 
421 
422  // Convert size of type to FLoat_Size
423 #ifdef NDEBUG
424  template <typename T> Chunk::Float_Size float_size(const T&)
425 #else
426  template <typename T> Chunk::Float_Size float_size(const T& d)
427 #endif
428  {
429 #ifndef NDEBUG
430  assert( is_float(d) );
431 #endif
432 
433  switch( sizeof(T) )
434  {
435  case 4: return OMFormat::Chunk::Float_32;
436  case 8: return OMFormat::Chunk::Float_64;
437  case 16: return OMFormat::Chunk::Float_128;
438  default:
439  std::cerr << "Invalid value in float_size\n";
440  assert( false );
441  break;
442  }
443  return Chunk::Float_Size(0);
444  }
445 
446  // Return the storage type (Chunk::Header::bits_)
447  template <typename T>
448  inline
449  unsigned int bits(const T& val)
450  {
451  return is_integer(val)
452  ? (static_cast<unsigned int>(integer_size(val)))
453  : (static_cast<unsigned int>(float_size(val)));
454  }
455 
456  // -------------------- create/read version
457 
458  inline uint8 mk_version(const uint16 major, const uint16 minor)
459  { return (major & 0x07) << 5 | (minor & 0x1f); }
460 
461 
462  inline uint16 major_version(const uint8 version)
463  { return (version >> 5) & 0x07; }
464 
465 
466  inline uint16 minor_version(const uint8 version)
467  { return (version & 0x001f); }
468 
469 
470  // ---------------------------------------- convenience functions
471 
472  const char *as_string(Chunk::Type t);
473  const char *as_string(Chunk::Entity e);
474  const char *as_string(Chunk::Dim d);
475  const char *as_string(Chunk::Integer_Size d);
476  const char *as_string(Chunk::Float_Size d);
477 
478  std::ostream& operator << ( std::ostream& _os, const Header& _h );
479  std::ostream& operator << ( std::ostream& _os, const Chunk::Header& _c );
480 
482 } // namespace OMFormat
483 
484  // -------------------- (re-)store header
485 
486  template <> inline
487  size_t store( std::ostream& _os, const OMFormat::Header& _hdr, bool _swap)
488  { return _hdr.store( _os, _swap ); }
489 
490  template <> inline
491  size_t restore( std::istream& _is, OMFormat::Header& _hdr, bool _swap )
492  { return _hdr.restore( _is, _swap ); }
493 
494 
495  // -------------------- (re-)store chunk header
496 
497  template <> inline
498  size_t
499  store( std::ostream& _os, const OMFormat::Chunk::Header& _hdr, bool _swap)
500  {
501  OMFormat::uint16 val; val << _hdr;
502  return binary<uint16_t>::store( _os, val, _swap );
503  }
504 
505  template <> inline
506  size_t
507  restore( std::istream& _is, OMFormat::Chunk::Header& _hdr, bool _swap )
508  {
509  OMFormat::uint16 val;
510  size_t bytes = binary<uint16_t>::restore( _is, val, _swap );
511 
512  _hdr << val;
513 
514  return bytes;
515  }
516 
517  // -------------------- (re-)store integer with wanted number of bits (bytes)
518 
519  typedef GenProg::TrueType t_signed;
520  typedef GenProg::FalseType t_unsigned;
521 
522  // helper to store a an integer
523  template< typename T >
524  size_t
525  store( std::ostream& _os,
526  const T& _val,
527  OMFormat::Chunk::Integer_Size _b,
528  bool _swap,
529  t_signed);
530 
531  // helper to store a an unsigned integer
532  template< typename T >
533  size_t
534  store( std::ostream& _os,
535  const T& _val,
536  OMFormat::Chunk::Integer_Size _b,
537  bool _swap,
538  t_unsigned);
539 
541  template< typename T >
542  inline
543  size_t
544  store( std::ostream& _os,
545  const T& _val,
546  OMFormat::Chunk::Integer_Size _b,
547  bool _swap)
548  {
549  assert( OMFormat::is_integer( _val ) );
550 
551  if ( OMFormat::is_signed( _val ) )
552  return store( _os, _val, _b, _swap, t_signed() );
553  return store( _os, _val, _b, _swap, t_unsigned() );
554  }
555 
556  // helper to store a an integer
557  template< typename T > inline
558  size_t restore( std::istream& _is,
559  T& _val,
560  OMFormat::Chunk::Integer_Size _b,
561  bool _swap,
562  t_signed);
563 
564  // helper to store a an unsigned integer
565  template< typename T > inline
566  size_t restore( std::istream& _is,
567  T& _val,
568  OMFormat::Chunk::Integer_Size _b,
569  bool _swap,
570  t_unsigned);
571 
573  template< typename T >
574  inline
575  size_t
576  restore( std::istream& _is,
577  T& _val,
578  OMFormat::Chunk::Integer_Size _b,
579  bool _swap)
580  {
581  assert( OMFormat::is_integer( _val ) );
582 
583  if ( OMFormat::is_signed( _val ) )
584  return restore( _is, _val, _b, _swap, t_signed() );
585  return restore( _is, _val, _b, _swap, t_unsigned() );
586  }
587 
588 
589  //
590  // ---------------------------------------- storing vectors
591  template <typename VecT> inline
592  size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<2>,
593  bool _swap )
594  {
595  size_t bytes = store( _os, _vec[0], _swap );
596  bytes += store( _os, _vec[1], _swap );
597  return bytes;
598  }
599 
600  template <typename VecT> inline
601  size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<3>,
602  bool _swap )
603  {
604  size_t bytes = store( _os, _vec[0], _swap );
605  bytes += store( _os, _vec[1], _swap );
606  bytes += store( _os, _vec[2], _swap );
607  return bytes;
608  }
609 
610  template <typename VecT> inline
611  size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<4>,
612  bool _swap )
613  {
614  size_t bytes = store( _os, _vec[0], _swap );
615  bytes += store( _os, _vec[1], _swap );
616  bytes += store( _os, _vec[2], _swap );
617  bytes += store( _os, _vec[3], _swap );
618  return bytes;
619  }
620 
621  template <typename VecT> inline
622  size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<1>,
623  bool _swap )
624  {
625  return store( _os, _vec[0], _swap );
626  }
627 
629  template <typename VecT> inline
630  size_t vector_store( std::ostream& _os, const VecT& _vec, bool _swap )
631  {
632  return store( _os, _vec,
633  GenProg::Int2Type< vector_traits<VecT>::size_ >(),
634  _swap );
635  }
636 
637  // ---------------------------------------- restoring vectors
638  template <typename VecT>
639  inline
640  size_t
641  restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>,
642  bool _swap )
643  {
644  size_t bytes = restore( _is, _vec[0], _swap );
645  bytes += restore( _is, _vec[1], _swap );
646  return bytes;
647  }
648 
649  template <typename VecT>
650  inline
651  size_t
652  restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>,
653  bool _swap )
654  {
655  typedef typename vector_traits<VecT>::value_type scalar_type;
656  size_t bytes;
657 
658  bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
659  bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
660  bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
661  return bytes;
662  }
663 
664  template <typename VecT>
665  inline
666  size_t
667  restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>,
668  bool _swap )
669  {
670  typedef typename vector_traits<VecT>::value_type scalar_type;
671  size_t bytes;
672 
673  bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
674  bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
675  bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
676  bytes += binary<scalar_type>::restore( _is, _vec[3], _swap );
677  return bytes;
678  }
679 
680  template <typename VecT>
681  inline
682  size_t
683  restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>,
684  bool _swap )
685  {
686  return restore( _is, _vec[0], _swap );
687  }
688 
690  template <typename VecT>
691  inline
692  size_t
693  vector_restore( std::istream& _is, VecT& _vec, bool _swap )
694  {
695  return restore( _is, _vec,
696  GenProg::Int2Type< vector_traits<VecT>::size_ >(),
697  _swap );
698  }
699 
700 
701  // ---------------------------------------- storing property names
702 
703  template <>
704  inline
705  size_t store( std::ostream& _os, const OMFormat::Chunk::PropertyName& _pn,
706  bool _swap )
707  {
708  store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap ); // 1 byte
709  if ( _pn.size() )
710  _os.write( _pn.c_str(), _pn.size() ); // size bytes
711  return _pn.size() + 1;
712  }
713 
714  template <>
715  inline
716  size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn,
717  bool _swap )
718  {
719  size_t size;
720 
721  restore( _is, size, OMFormat::Chunk::Integer_8, _swap); // 1 byte
722 
723  assert( OMFormat::Chunk::PropertyName::is_valid( size ) );
724 
725  if ( size > 0 )
726  {
727  char buf[256];
728  _is.read( buf, size ); // size bytes
729  buf[size] = '\0';
730  _pn.resize(size);
731  _pn = buf;
732  }
733  return size+1;
734  }
735 
736 //=============================================================================
737 } // namespace IO
738 } // namespace OpenMesh
739 #endif
740 //=============================================================================
741 #if defined(OM_MISSING_HEADER_LIMITS)
742 # undef OM_MISSING_HEADER_LIMITS
743 #endif
744 //=============================================================================
745 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC)
746 # define OPENMESH_IO_OMFORMAT_TEMPLATES
747 # include "OMFormatT.cc"
748 #endif
749 //=============================================================================
750 #endif
751 //=============================================================================
unsigned char uchar
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:81
This file provides the streams omlog, omout, and omerr.
Temporary solution until std::numeric_limits is standard.
auto operator<<(std::ostream &os, const VectorT< Scalar, DIM > &_vec) -> typename std::enable_if< sizeof(decltype(os<< _vec[0])) >=0
output a vector by printing its space-separated compontens
static size_t size()
size/dimension of the vector
Definition: vector_traits.hh:105
short int16_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:86
T::value_type value_type
Type of the scalar value.
Definition: vector_traits.hh:99
int int32_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:90
long long int64_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:94
Contains all the mesh ingredients like the polygonal mesh, the triangle mesh, different mesh kernels ...
Definition: MeshItems.hh:64
float float32_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:97
unsigned int uint32_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:90
unsigned char uint8_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:85
signed char int8_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:85
unsigned long long uint64_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:94
static const size_t size_
size/dimension of the vector
Definition: vector_traits.hh:102
double float64_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:98
unsigned short uint16_t
Binary read a short from _is and perform byte swapping if _swap is true.
Definition: SR_types.hh:86

Project OpenMesh, ©  Computer Graphics Group, RWTH Aachen. Documentation generated using doxygen .