50 #ifndef OPENMESH_IO_OMFORMAT_HH 51 #define OPENMESH_IO_OMFORMAT_HH 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> 64 #if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000) 66 # define OM_MISSING_HEADER_LIMITS 1 74 #ifndef DOXY_IGNORE_THIS 116 typedef unsigned char uchar;
137 size_t store( std::ostream& _os,
bool _swap )
const 139 _os.write( (
char*)
this, 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 );
147 size_t restore( std::istream& _is,
bool _swap )
149 if (_is.read( (
char*)
this, 4 ).eof())
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 );
165 typedef uint32 esize_t;
170 Type_Texcoord = 0x02,
178 Entity_Vertex = 0x00,
182 Entity_Halfedge = 0x06
209 static const int SIZE_RESERVED = 1;
210 static const int SIZE_NAME = 1;
211 static const int SIZE_ENTITY = 3;
212 static const int SIZE_TYPE = 4;
214 static const int SIZE_SIGNED = 1;
215 static const int SIZE_FLOAT = 1;
216 static const int SIZE_DIM = 3;
217 static const int SIZE_BITS = 2;
219 static const int OFF_RESERVED = 0;
220 static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED;
221 static const int OFF_ENTITY = SIZE_NAME + OFF_NAME;
222 static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY;
223 static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE;
224 static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED;
225 static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT;
226 static const int OFF_BITS = SIZE_DIM + OFF_DIM;
236 unsigned reserved_: SIZE_RESERVED;
237 unsigned name_ : SIZE_NAME;
238 unsigned entity_ : SIZE_ENTITY;
240 unsigned type_ : SIZE_TYPE;
242 unsigned signed_ : SIZE_SIGNED;
243 unsigned float_ : SIZE_FLOAT;
244 unsigned dim_ : SIZE_DIM;
245 unsigned bits_ : SIZE_BITS;
247 unsigned unused_ : 16;
251 class PropertyName :
public std::string
255 static const size_t size_max = 256;
259 PropertyName(
const std::string& _name ) { *
this = _name; }
261 bool is_valid()
const {
return is_valid( size() ); }
263 static bool is_valid(
size_t _s ) {
return _s <= size_max; }
265 PropertyName& operator = (
const std::string& _rhs )
267 assert( is_valid( _rhs.size() ) );
269 if ( is_valid( _rhs.size() ) )
270 std::string::operator = ( _rhs );
273 omerr() <<
"Warning! Property name too long. Will be shortened!\n";
274 this->std::string::operator = ( _rhs.substr(0, size_max) );
289 inline size_t header_size(
void) {
return sizeof(Header); }
293 inline size_t chunk_header_size(
void ) {
return sizeof(uint16); }
297 inline size_t scalar_size(
const Chunk::Header& _hdr )
299 return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_);
304 inline size_t dimensions(
const Chunk::Header& _chdr) {
return _chdr.dim_+1; }
308 inline size_t vector_size(
const Chunk::Header& _chdr )
310 return dimensions(_chdr)*scalar_size(_chdr);
315 inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr )
319 switch( _chunk_hdr.entity_ )
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_;
324 case Chunk::Entity_Edge: C += _hdr.n_edges_;
break;
325 case Chunk::Entity_Mesh: C = 1;
break;
327 std::cerr <<
"Invalid value in _chunk_hdr.entity_\n";
332 return C * vector_size( _chunk_hdr );
335 inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr )
337 return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr );
342 uint16&
operator << (uint16& val,
const Chunk::Header& hdr);
343 Chunk::Header&
operator << (Chunk::Header& hdr,
const uint16 val);
348 template <
typename T>
bool is_float(
const T&)
350 #if defined(OM_MISSING_HEADER_LIMITS) 351 return !Utils::NumLimitsT<T>::is_integer();
353 return !std::numeric_limits<T>::is_integer;
357 template <
typename T>
bool is_integer(
const T)
359 #if defined(OM_MISSING_HEADER_LIMITS) 360 return Utils::NumLimitsT<T>::is_integer();
362 return std::numeric_limits<T>::is_integer;
366 template <
typename T>
bool is_signed(
const T&)
368 #if defined(OM_MISSING_HEADER_LIMITS) 369 return Utils::NumLimitsT<T>::is_signed();
371 return std::numeric_limits<T>::is_signed;
377 template <
typename VecType>
379 Chunk::Dim dim( VecType )
385 template <
typename VecType>
387 Chunk::Dim dim(
const Chunk::Header& _hdr )
389 return static_cast<Chunk::Dim
>( _hdr.dim_ );
393 Chunk::Integer_Size needed_bits(
size_t s );
397 template <
typename T> Chunk::Integer_Size integer_size(
const T&)
399 template <
typename T> Chunk::Integer_Size integer_size(
const T& d)
402 assert( is_integer(d) );
406 case 1:
return OMFormat::Chunk::Integer_8;
407 case 2:
return OMFormat::Chunk::Integer_16;
408 case 4:
return OMFormat::Chunk::Integer_32;
409 case 8:
return OMFormat::Chunk::Integer_64;
411 std::cerr <<
"Invalid value in integer_size\n";
415 return Chunk::Integer_Size(0);
421 template <
typename T> Chunk::Float_Size float_size(
const T&)
423 template <
typename T> Chunk::Float_Size float_size(
const T& d)
426 assert( is_float(d) );
430 case 4:
return OMFormat::Chunk::Float_32;
431 case 8:
return OMFormat::Chunk::Float_64;
432 case 16:
return OMFormat::Chunk::Float_128;
434 std::cerr <<
"Invalid value in float_size\n";
438 return Chunk::Float_Size(0);
442 template <
typename T>
444 unsigned int bits(
const T& val)
446 return is_integer(val)
447 ? (
static_cast<unsigned int>(integer_size(val)))
448 : (
static_cast<unsigned int>(float_size(val)));
453 inline uint8 mk_version(
const uint16 major,
const uint16 minor)
454 {
return (major & 0x07) << 5 | (minor & 0x1f); }
457 inline uint16 major_version(
const uint8 version)
458 {
return (version >> 5) & 0x07; }
461 inline uint16 minor_version(
const uint8 version)
462 {
return (version & 0x001f); }
467 const char *as_string(Chunk::Type t);
468 const char *as_string(Chunk::Entity e);
469 const char *as_string(Chunk::Dim d);
470 const char *as_string(Chunk::Integer_Size d);
471 const char *as_string(Chunk::Float_Size d);
473 std::ostream&
operator << ( std::ostream& _os,
const Header& _h );
474 std::ostream&
operator << ( std::ostream& _os,
const Chunk::Header& _c );
482 size_t store( std::ostream& _os,
const OMFormat::Header& _hdr,
bool _swap)
483 {
return _hdr.store( _os, _swap ); }
486 size_t restore( std::istream& _is, OMFormat::Header& _hdr,
bool _swap )
487 {
return _hdr.restore( _is, _swap ); }
494 store( std::ostream& _os,
const OMFormat::Chunk::Header& _hdr,
bool _swap)
496 OMFormat::uint16 val; val << _hdr;
497 return binary<uint16_t>::store( _os, val, _swap );
502 restore( std::istream& _is, OMFormat::Chunk::Header& _hdr,
bool _swap )
504 OMFormat::uint16 val;
505 size_t bytes = binary<uint16_t>::restore( _is, val, _swap );
514 typedef GenProg::TrueType t_signed;
515 typedef GenProg::FalseType t_unsigned;
518 template<
typename T >
520 store( std::ostream& _os,
522 OMFormat::Chunk::Integer_Size _b,
527 template<
typename T >
529 store( std::ostream& _os,
531 OMFormat::Chunk::Integer_Size _b,
536 template<
typename T >
539 store( std::ostream& _os,
541 OMFormat::Chunk::Integer_Size _b,
544 assert( OMFormat::is_integer( _val ) );
546 if ( OMFormat::is_signed( _val ) )
547 return store( _os, _val, _b, _swap, t_signed() );
548 return store( _os, _val, _b, _swap, t_unsigned() );
552 template<
typename T >
inline 553 size_t restore( std::istream& _is,
555 OMFormat::Chunk::Integer_Size _b,
560 template<
typename T >
inline 561 size_t restore( std::istream& _is,
563 OMFormat::Chunk::Integer_Size _b,
568 template<
typename T >
571 restore( std::istream& _is,
573 OMFormat::Chunk::Integer_Size _b,
576 assert( OMFormat::is_integer( _val ) );
578 if ( OMFormat::is_signed( _val ) )
579 return restore( _is, _val, _b, _swap, t_signed() );
580 return restore( _is, _val, _b, _swap, t_unsigned() );
586 template <
typename VecT>
inline 587 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<2>,
590 size_t bytes = store( _os, _vec[0], _swap );
591 bytes += store( _os, _vec[1], _swap );
595 template <
typename VecT>
inline 596 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<3>,
599 size_t bytes = store( _os, _vec[0], _swap );
600 bytes += store( _os, _vec[1], _swap );
601 bytes += store( _os, _vec[2], _swap );
605 template <
typename VecT>
inline 606 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<4>,
609 size_t bytes = store( _os, _vec[0], _swap );
610 bytes += store( _os, _vec[1], _swap );
611 bytes += store( _os, _vec[2], _swap );
612 bytes += store( _os, _vec[3], _swap );
616 template <
typename VecT>
inline 617 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<1>,
620 return store( _os, _vec[0], _swap );
624 template <
typename VecT>
inline 625 size_t vector_store( std::ostream& _os,
const VecT& _vec,
bool _swap )
627 return store( _os, _vec,
633 template <
typename VecT>
636 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>,
639 size_t bytes = restore( _is, _vec[0], _swap );
640 bytes += restore( _is, _vec[1], _swap );
644 template <
typename VecT>
647 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>,
653 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
654 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
655 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
659 template <
typename VecT>
662 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>,
668 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
669 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
670 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
671 bytes += binary<scalar_type>::restore( _is, _vec[3], _swap );
675 template <
typename VecT>
678 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>,
681 return restore( _is, _vec[0], _swap );
685 template <
typename VecT>
688 vector_restore( std::istream& _is, VecT& _vec,
bool _swap )
690 return restore( _is, _vec,
700 size_t store( std::ostream& _os,
const OMFormat::Chunk::PropertyName& _pn,
703 store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap );
705 _os.write( _pn.c_str(), _pn.size() );
706 return _pn.size() + 1;
711 size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn,
716 restore( _is, size, OMFormat::Chunk::Integer_8, _swap);
718 assert( OMFormat::Chunk::PropertyName::is_valid( size ) );
723 _is.read( buf, size );
736 #if defined(OM_MISSING_HEADER_LIMITS) 737 # undef OM_MISSING_HEADER_LIMITS 740 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC) 741 # define OPENMESH_IO_OMFORMAT_TEMPLATES 742 # include "OMFormatT.cc" unsigned long long uint64_t
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
T::value_type value_type
Type of the scalar value.
static const size_t size_
size/dimension of the vector