43 #ifndef OPENMESH_IO_OMFORMAT_HH
44 #define OPENMESH_IO_OMFORMAT_HH
49 #include <OpenMesh/Core/System/config.h>
51 #include <OpenMesh/Core/IO/SR_store.hh>
52 #include <OpenMesh/Core/Utils/GenProg.hh>
53 #include <OpenMesh/Core/Utils/Endian.hh>
54 #include <OpenMesh/Core/Utils/vector_traits.hh>
57 #if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000)
59 # define OM_MISSING_HEADER_LIMITS 1
67 #ifndef DOXY_IGNORE_THIS
109 typedef unsigned char uchar;
130 size_t store( std::ostream& _os,
bool _swap )
const
132 _os.write( (
char*)
this, 4);
134 bytes += binary<uint32_t>::store( _os, n_vertices_, _swap );
135 bytes += binary<uint32_t>::store( _os, n_faces_, _swap );
136 bytes += binary<uint32_t>::store( _os, n_edges_, _swap );
140 size_t restore( std::istream& _is,
bool _swap )
142 if (_is.read( (
char*)
this, 4 ).eof())
146 bytes += binary<uint32_t>::restore( _is, n_vertices_, _swap );
147 bytes += binary<uint32_t>::restore( _is, n_faces_, _swap );
148 bytes += binary<uint32_t>::restore( _is, n_edges_, _swap );
158 typedef uint32 esize_t;
163 Type_Texcoord = 0x02,
171 Entity_Vertex = 0x00,
175 Entity_Halfedge = 0x06
202 static const int SIZE_RESERVED = 1;
203 static const int SIZE_NAME = 1;
204 static const int SIZE_ENTITY = 3;
205 static const int SIZE_TYPE = 4;
207 static const int SIZE_SIGNED = 1;
208 static const int SIZE_FLOAT = 1;
209 static const int SIZE_DIM = 3;
210 static const int SIZE_BITS = 2;
212 static const int OFF_RESERVED = 0;
213 static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED;
214 static const int OFF_ENTITY = SIZE_NAME + OFF_NAME;
215 static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY;
216 static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE;
217 static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED;
218 static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT;
219 static const int OFF_BITS = SIZE_DIM + OFF_DIM;
229 unsigned reserved_: SIZE_RESERVED;
230 unsigned name_ : SIZE_NAME;
231 unsigned entity_ : SIZE_ENTITY;
233 unsigned type_ : SIZE_TYPE;
235 unsigned signed_ : SIZE_SIGNED;
236 unsigned float_ : SIZE_FLOAT;
237 unsigned dim_ : SIZE_DIM;
238 unsigned bits_ : SIZE_BITS;
240 unsigned unused_ : 16;
244 class PropertyName :
public std::string
248 static const size_t size_max = 256;
252 PropertyName(
const std::string& _name ) { *
this = _name; }
254 bool is_valid()
const {
return is_valid( size() ); }
256 static bool is_valid(
size_t _s ) {
return _s <= size_max; }
258 PropertyName& operator = (
const std::string& _rhs )
260 assert( is_valid( _rhs.size() ) );
262 if ( is_valid( _rhs.size() ) )
263 std::string::operator = ( _rhs );
266 omerr() <<
"Warning! Property name too long. Will be shortened!\n";
267 this->std::string::operator = ( _rhs.substr(0, size_max) );
282 inline size_t header_size(
void) {
return sizeof(Header); }
286 inline size_t chunk_header_size(
void ) {
return sizeof(uint16); }
290 inline size_t scalar_size(
const Chunk::Header& _hdr )
292 return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_);
297 inline size_t dimensions(
const Chunk::Header& _chdr) {
return _chdr.dim_+1; }
301 inline size_t vector_size(
const Chunk::Header& _chdr )
303 return dimensions(_chdr)*scalar_size(_chdr);
308 inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr )
312 switch( _chunk_hdr.entity_ )
314 case Chunk::Entity_Vertex: C = _hdr.n_vertices_;
break;
315 case Chunk::Entity_Face: C = _hdr.n_faces_;
break;
316 case Chunk::Entity_Halfedge: C = _hdr.n_edges_;
317 case Chunk::Entity_Edge: C += _hdr.n_edges_;
break;
318 case Chunk::Entity_Mesh: C = 1;
break;
320 std::cerr <<
"Invalid value in _chunk_hdr.entity_\n";
324 return C * vector_size( _chunk_hdr );
327 inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr )
329 return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr );
334 uint16&
operator << (uint16& val,
const Chunk::Header& hdr);
335 Chunk::Header&
operator << (Chunk::Header& hdr,
const uint16 val);
340 template <
typename T>
bool is_float(
const T&)
342 #if defined(OM_MISSING_HEADER_LIMITS)
343 return !Utils::NumLimitsT<T>::is_integer();
345 return !std::numeric_limits<T>::is_integer;
349 template <
typename T>
bool is_integer(
const T)
351 #if defined(OM_MISSING_HEADER_LIMITS)
352 return Utils::NumLimitsT<T>::is_integer();
354 return std::numeric_limits<T>::is_integer;
358 template <
typename T>
bool is_signed(
const T&)
360 #if defined(OM_MISSING_HEADER_LIMITS)
361 return Utils::NumLimitsT<T>::is_signed();
363 return std::numeric_limits<T>::is_signed;
369 template <
typename VecType>
371 Chunk::Dim dim( VecType )
373 assert( vector_traits< VecType >::size() < 9 );
374 return static_cast<Chunk::Dim
>(vector_traits< VecType >::size() - 1);
377 template <
typename VecType>
379 Chunk::Dim dim(
const Chunk::Header& _hdr )
381 return static_cast<Chunk::Dim
>( _hdr.dim_ );
385 Chunk::Integer_Size needed_bits(
size_t s );
389 template <
typename T> Chunk::Integer_Size integer_size(
const T&)
391 template <
typename T> Chunk::Integer_Size integer_size(
const T& d)
394 assert( is_integer(d) );
398 case 1:
return OMFormat::Chunk::Integer_8;
399 case 2:
return OMFormat::Chunk::Integer_16;
400 case 4:
return OMFormat::Chunk::Integer_32;
401 case 8:
return OMFormat::Chunk::Integer_64;
403 return Chunk::Integer_Size(0);
409 template <
typename T> Chunk::Float_Size float_size(
const T&)
411 template <
typename T> Chunk::Float_Size float_size(
const T& d)
414 assert( is_float(d) );
418 case 4:
return OMFormat::Chunk::Float_32;
419 case 8:
return OMFormat::Chunk::Float_64;
420 case 16:
return OMFormat::Chunk::Float_128;
422 return Chunk::Float_Size(0);
426 template <
typename T>
428 unsigned int bits(
const T& val)
430 return is_integer(val)
431 ? (
static_cast<unsigned int>(integer_size(val)))
432 : (
static_cast<unsigned int>(float_size(val)));
437 inline uint8 mk_version(
const uint16 major,
const uint16 minor)
438 {
return (major & 0x07) << 5 | (minor & 0x1f); }
441 inline uint16 major_version(
const uint8 version)
442 {
return (version >> 5) & 0x07; }
445 inline uint16 minor_version(
const uint8 version)
446 {
return (version & 0x001f); }
451 const char *as_string(Chunk::Type t);
452 const char *as_string(Chunk::Entity e);
453 const char *as_string(Chunk::Dim d);
454 const char *as_string(Chunk::Integer_Size d);
455 const char *as_string(Chunk::Float_Size d);
457 std::ostream&
operator << ( std::ostream& _os,
const Header& _h );
458 std::ostream&
operator << ( std::ostream& _os,
const Chunk::Header& _c );
466 size_t store( std::ostream& _os,
const OMFormat::Header& _hdr,
bool _swap)
467 {
return _hdr.store( _os, _swap ); }
470 size_t restore( std::istream& _is, OMFormat::Header& _hdr,
bool _swap )
471 {
return _hdr.restore( _is, _swap ); }
478 store( std::ostream& _os,
const OMFormat::Chunk::Header& _hdr,
bool _swap)
480 OMFormat::uint16 val; val << _hdr;
481 return binary<uint16_t>::store( _os, val, _swap );
486 restore( std::istream& _is, OMFormat::Chunk::Header& _hdr,
bool _swap )
488 OMFormat::uint16 val;
489 size_t bytes = binary<uint16_t>::restore( _is, val, _swap );
498 typedef GenProg::True t_signed;
499 typedef GenProg::False t_unsigned;
502 template<
typename T >
504 store( std::ostream& _os,
506 OMFormat::Chunk::Integer_Size _b,
511 template<
typename T >
513 store( std::ostream& _os,
515 OMFormat::Chunk::Integer_Size _b,
520 template<
typename T >
523 store( std::ostream& _os,
525 OMFormat::Chunk::Integer_Size _b,
528 assert( OMFormat::is_integer( _val ) );
530 if ( OMFormat::is_signed( _val ) )
531 return store( _os, _val, _b, _swap, t_signed() );
532 return store( _os, _val, _b, _swap, t_unsigned() );
536 template<
typename T >
inline
537 size_t restore( std::istream& _is,
539 OMFormat::Chunk::Integer_Size _b,
544 template<
typename T >
inline
545 size_t restore( std::istream& _is,
547 OMFormat::Chunk::Integer_Size _b,
552 template<
typename T >
555 restore( std::istream& _is,
557 OMFormat::Chunk::Integer_Size _b,
560 assert( OMFormat::is_integer( _val ) );
562 if ( OMFormat::is_signed( _val ) )
563 return restore( _is, _val, _b, _swap, t_signed() );
564 return restore( _is, _val, _b, _swap, t_unsigned() );
570 template <
typename VecT>
inline
571 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<2>,
574 size_t bytes = store( _os, _vec[0], _swap );
575 bytes += store( _os, _vec[1], _swap );
579 template <
typename VecT>
inline
580 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<3>,
583 size_t bytes = store( _os, _vec[0], _swap );
584 bytes += store( _os, _vec[1], _swap );
585 bytes += store( _os, _vec[2], _swap );
589 template <
typename VecT>
inline
590 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<4>,
593 size_t bytes = store( _os, _vec[0], _swap );
594 bytes += store( _os, _vec[1], _swap );
595 bytes += store( _os, _vec[2], _swap );
596 bytes += store( _os, _vec[3], _swap );
600 template <
typename VecT>
inline
601 size_t store( std::ostream& _os,
const VecT& _vec, GenProg::Int2Type<1>,
604 return store( _os, _vec[0], _swap );
608 template <
typename VecT>
inline
609 size_t vector_store( std::ostream& _os,
const VecT& _vec,
bool _swap )
611 return store( _os, _vec,
612 GenProg::Int2Type< vector_traits<VecT>::size_ >(),
617 template <
typename VecT>
620 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>,
623 size_t bytes = restore( _is, _vec[0], _swap );
624 bytes += restore( _is, _vec[1], _swap );
628 template <
typename VecT>
631 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>,
634 typedef typename vector_traits<VecT>::value_type scalar_type;
637 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
638 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
639 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
643 template <
typename VecT>
646 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>,
649 typedef typename vector_traits<VecT>::value_type scalar_type;
652 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap );
653 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap );
654 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap );
655 bytes += binary<scalar_type>::restore( _is, _vec[3], _swap );
659 template <
typename VecT>
662 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>,
665 return restore( _is, _vec[0], _swap );
669 template <
typename VecT>
672 vector_restore( std::istream& _is, VecT& _vec,
bool _swap )
674 return restore( _is, _vec,
675 GenProg::Int2Type< vector_traits<VecT>::size_ >(),
684 size_t store( std::ostream& _os,
const OMFormat::Chunk::PropertyName& _pn,
687 store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap );
689 _os.write( _pn.c_str(), _pn.size() );
690 return _pn.size() + 1;
695 size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn,
700 restore( _is, size, OMFormat::Chunk::Integer_8, _swap);
702 assert( OMFormat::Chunk::PropertyName::is_valid( size ) );
707 _is.read( buf, size );
720 #if defined(OM_MISSING_HEADER_LIMITS)
721 # undef OM_MISSING_HEADER_LIMITS
724 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC)
725 # define OPENMESH_IO_OMFORMAT_TEMPLATES
726 # include "OMFormatT.cc"