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

Project OpenMesh, ©  Visual Computing Institute, RWTH Aachen. Documentation generated using doxygen .