OpenMesh
|
00001 /*===========================================================================*\ 00002 * * 00003 * OpenMesh * 00004 * Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen * 00005 * www.openmesh.org * 00006 * * 00007 *---------------------------------------------------------------------------* 00008 * This file is part of OpenMesh. * 00009 * * 00010 * OpenMesh is free software: you can redistribute it and/or modify * 00011 * it under the terms of the GNU Lesser General Public License as * 00012 * published by the Free Software Foundation, either version 3 of * 00013 * the License, or (at your option) any later version with the * 00014 * following exceptions: * 00015 * * 00016 * If other files instantiate templates or use macros * 00017 * or inline functions from this file, or you compile this file and * 00018 * link it with other files to produce an executable, this file does * 00019 * not by itself cause the resulting executable to be covered by the * 00020 * GNU Lesser General Public License. This exception does not however * 00021 * invalidate any other reasons why the executable file might be * 00022 * covered by the GNU Lesser General Public License. * 00023 * * 00024 * OpenMesh is distributed in the hope that it will be useful, * 00025 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00026 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00027 * GNU Lesser General Public License for more details. * 00028 * * 00029 * You should have received a copy of the GNU LesserGeneral Public * 00030 * License along with OpenMesh. If not, * 00031 * see <http://www.gnu.org/licenses/>. * 00032 * * 00033 \*===========================================================================*/ 00034 00035 /*===========================================================================*\ 00036 * * 00037 * $Revision: 362 $ * 00038 * $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ * 00039 * * 00040 \*===========================================================================*/ 00041 00042 00043 #ifndef OPENMESH_IO_OMFORMAT_HH 00044 #define OPENMESH_IO_OMFORMAT_HH 00045 00046 00047 //=== INCLUDES ================================================================ 00048 00049 #include <OpenMesh/Core/System/config.h> 00050 #include <OpenMesh/Core/System/omstream.hh> 00051 #include <OpenMesh/Core/IO/SR_store.hh> 00052 #include <OpenMesh/Core/Utils/GenProg.hh> 00053 #include <OpenMesh/Core/Utils/Endian.hh> 00054 #include <OpenMesh/Core/Utils/vector_traits.hh> 00055 // -------------------- 00056 #include <iostream> 00057 #if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000) 00058 # include <OpenMesh/Tools/Utils/NumLimitsT.hh> 00059 # define OM_MISSING_HEADER_LIMITS 1 00060 #else 00061 # include <limits> 00062 #endif 00063 00064 00065 //== NAMESPACES ============================================================== 00066 00067 #ifndef DOXY_IGNORE_THIS 00068 namespace OpenMesh { 00069 namespace IO { 00070 namespace OMFormat { 00071 00072 00073 //=== IMPLEMENTATION ========================================================== 00074 00075 00079 00080 //----------------------------------------------------------------------------- 00081 00082 // <:Header> 00083 // <:Comment> 00084 // Chunk 0 00085 // <:ChunkHeader> 00086 // <:Comment> 00087 // data 00088 // Chunk 1 00089 // <:ChunkHeader> 00090 // <:Comment> 00091 // data 00092 // . 00093 // . 00094 // . 00095 // Chunk N 00096 00097 // 00098 // NOTICE! 00099 // 00100 // The usage of data types who differ in size 00101 // on different pc architectures (32/64 bit) and/or 00102 // operating systems, e.g. (unsigned) long, size_t, 00103 // is not recommended because of inconsistencies 00104 // in case of cross writing and reading. 00105 // 00106 // Basic types that are supported are: 00107 00108 00109 typedef unsigned char uchar; 00110 typedef uint8_t uint8; 00111 typedef uint16_t uint16; 00112 typedef uint32_t uint32; 00113 typedef uint64_t uint64; 00114 typedef int8_t int8; 00115 typedef int16_t int16; 00116 typedef int32_t int32; 00117 typedef int64_t int64; 00118 typedef float32_t float32; 00119 typedef float64_t float64; 00120 00121 struct Header 00122 { 00123 uchar magic_[2]; // OM 00124 uchar mesh_; // [T]riangles, [Q]uads, [P]olygonals 00125 uint8 version_; 00126 uint32 n_vertices_; 00127 uint32 n_faces_; 00128 uint32 n_edges_; 00129 00130 size_t store( std::ostream& _os, bool _swap ) const 00131 { 00132 _os.write( (char*)this, 4); // magic_, mesh_, version_ 00133 size_t bytes = 4; 00134 bytes += binary<uint32_t>::store( _os, n_vertices_, _swap ); 00135 bytes += binary<uint32_t>::store( _os, n_faces_, _swap ); 00136 bytes += binary<uint32_t>::store( _os, n_edges_, _swap ); 00137 return bytes; 00138 } 00139 00140 size_t restore( std::istream& _is, bool _swap ) 00141 { 00142 if (_is.read( (char*)this, 4 ).eof()) 00143 return 0; 00144 00145 size_t bytes = 4; 00146 bytes += binary<uint32_t>::restore( _is, n_vertices_, _swap ); 00147 bytes += binary<uint32_t>::restore( _is, n_faces_, _swap ); 00148 bytes += binary<uint32_t>::restore( _is, n_edges_, _swap ); 00149 return bytes; 00150 } 00151 00152 }; 00153 00154 struct Chunk 00155 { 00156 // Hardcoded this size to an uint32 to make the system 32/64 bit compatible. 00157 // Needs further investigation! 00158 typedef uint32 esize_t; // element size, used for custom properties 00159 00160 enum Type { 00161 Type_Pos = 0x00, 00162 Type_Normal = 0x01, 00163 Type_Texcoord = 0x02, 00164 Type_Status = 0x03, 00165 Type_Color = 0x04, 00166 Type_Custom = 0x06, 00167 Type_Topology = 0x07 00168 }; 00169 00170 enum Entity { 00171 Entity_Vertex = 0x00, 00172 Entity_Mesh = 0x01, 00173 Entity_Face = 0x02, 00174 Entity_Edge = 0x04, 00175 Entity_Halfedge = 0x06 00176 }; 00177 00178 enum Dim { 00179 Dim_1D = 0x00, 00180 Dim_2D = 0x01, 00181 Dim_3D = 0x02, 00182 Dim_4D = 0x03, 00183 Dim_5D = 0x04, 00184 Dim_6D = 0x05, 00185 Dim_7D = 0x06, 00186 Dim_8D = 0x07 00187 }; 00188 00189 enum Integer_Size { 00190 Integer_8 = 0x00, // 1 byte for (unsigned) char 00191 Integer_16 = 0x01, // 2 bytes for short 00192 Integer_32 = 0x02, // 4 bytes for long 00193 Integer_64 = 0x03 // 8 bytes for long long 00194 }; 00195 00196 enum Float_Size { 00197 Float_32 = 0x00, // 4 bytes for float 00198 Float_64 = 0x01, // 8 bytes for double 00199 Float_128 = 0x02 // 16 bytes for long double (an assumption!) 00200 }; 00201 00202 static const int SIZE_RESERVED = 1; // 1 00203 static const int SIZE_NAME = 1; // 2 00204 static const int SIZE_ENTITY = 3; // 5 00205 static const int SIZE_TYPE = 4; // 9 00206 00207 static const int SIZE_SIGNED = 1; // 10 00208 static const int SIZE_FLOAT = 1; // 11 00209 static const int SIZE_DIM = 3; // 14 00210 static const int SIZE_BITS = 2; // 16 00211 00212 static const int OFF_RESERVED = 0; // 0 00213 static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED; // 2 00214 static const int OFF_ENTITY = SIZE_NAME + OFF_NAME; // 3 00215 static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY; // 5 00216 static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE; // 9 00217 static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED; // 10 00218 static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT; // 11 00219 static const int OFF_BITS = SIZE_DIM + OFF_DIM; // 14 00220 00221 // !Attention! When changing the bit size, the operators 00222 // << (uint16, Header) and << (Header, uint16) must be changed as well 00223 // 00224 // Entries signed_, float_, dim_, bits_ are not used when type_ 00225 // equals Type_Custom 00226 // 00227 struct Header // 16 bits long 00228 { 00229 unsigned reserved_: SIZE_RESERVED; 00230 unsigned name_ : SIZE_NAME; // 1 named property, 0 anonymous 00231 unsigned entity_ : SIZE_ENTITY; // 0 vertex, 1 mesh, 2 edge, 00232 // 4 halfedge, 6 face 00233 unsigned type_ : SIZE_TYPE; // 0 pos, 1 normal, 2 texcoord, 00234 // 3 status, 4 color 6 custom 7 topology 00235 unsigned signed_ : SIZE_SIGNED; // bool 00236 unsigned float_ : SIZE_FLOAT; // bool 00237 unsigned dim_ : SIZE_DIM; // 0 1D, 1 2D, 2 3D, .., 7 8D 00238 unsigned bits_ : SIZE_BITS; // {8, 16, 32, 64} | {32, 64, 128} 00239 // (integer) (float) 00240 unsigned unused_ : 16; // fill up to 32 bits 00241 }; // struct Header 00242 00243 00244 class PropertyName : public std::string 00245 { 00246 public: 00247 00248 static const size_t size_max = 256; 00249 00250 PropertyName( ) { } 00251 00252 PropertyName( const std::string& _name ) { *this = _name; } 00253 00254 bool is_valid() const { return is_valid( size() ); } 00255 00256 static bool is_valid( size_t _s ) { return _s <= size_max; } 00257 00258 PropertyName& operator = ( const std::string& _rhs ) 00259 { 00260 assert( is_valid( _rhs.size() ) ); 00261 00262 if ( is_valid( _rhs.size() ) ) 00263 std::string::operator = ( _rhs ); 00264 else 00265 { 00266 omerr() << "Warning! Property name too long. Will be shortened!\n"; 00267 this->std::string::operator = ( _rhs.substr(0, size_max) ); 00268 } 00269 00270 return *this; 00271 } 00272 00273 }; 00274 00275 }; // Chunk 00276 00277 // ------------------------------------------------------------ Helper 00278 00279 // -------------------- get size information 00280 00282 inline size_t header_size(void) { return sizeof(Header); } 00283 00284 00286 inline size_t chunk_header_size( void ) { return sizeof(uint16); } 00287 00288 00290 inline size_t scalar_size( const Chunk::Header& _hdr ) 00291 { 00292 return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_); 00293 } 00294 00295 00297 inline size_t dimensions(const Chunk::Header& _chdr) { return _chdr.dim_+1; } 00298 00299 00301 inline size_t vector_size( const Chunk::Header& _chdr ) 00302 { 00303 return dimensions(_chdr)*scalar_size(_chdr); 00304 } 00305 00306 00308 inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr ) 00309 { 00310 size_t C = 0; 00311 00312 switch( _chunk_hdr.entity_ ) 00313 { 00314 case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break; 00315 case Chunk::Entity_Face: C = _hdr.n_faces_; break; 00316 case Chunk::Entity_Halfedge: C = _hdr.n_edges_; // no break! 00317 case Chunk::Entity_Edge: C += _hdr.n_edges_; break; 00318 case Chunk::Entity_Mesh: C = 1; break; 00319 default: 00320 std::cerr << "Invalid value in _chunk_hdr.entity_\n"; 00321 assert( false ); 00322 } 00323 00324 return C * vector_size( _chunk_hdr ); 00325 } 00326 00327 inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr ) 00328 { 00329 return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr ); 00330 } 00331 00332 // -------------------- convert from Chunk::Header to storage type 00333 00334 uint16& operator << (uint16& val, const Chunk::Header& hdr); 00335 Chunk::Header& operator << (Chunk::Header& hdr, const uint16 val); 00336 00337 00338 // -------------------- type information 00339 00340 template <typename T> bool is_float(const T&) 00341 { 00342 #if defined(OM_MISSING_HEADER_LIMITS) 00343 return !Utils::NumLimitsT<T>::is_integer(); 00344 #else 00345 return !std::numeric_limits<T>::is_integer; 00346 #endif 00347 } 00348 00349 template <typename T> bool is_integer(const T) 00350 { 00351 #if defined(OM_MISSING_HEADER_LIMITS) 00352 return Utils::NumLimitsT<T>::is_integer(); 00353 #else 00354 return std::numeric_limits<T>::is_integer; 00355 #endif 00356 } 00357 00358 template <typename T> bool is_signed(const T&) 00359 { 00360 #if defined(OM_MISSING_HEADER_LIMITS) 00361 return Utils::NumLimitsT<T>::is_signed(); 00362 #else 00363 return std::numeric_limits<T>::is_signed; 00364 #endif 00365 } 00366 00367 // -------------------- conversions (format type <- type/value) 00368 00369 template <typename VecType> 00370 inline 00371 Chunk::Dim dim( VecType ) 00372 { 00373 assert( vector_traits< VecType >::size() < 9 ); 00374 return static_cast<Chunk::Dim>(vector_traits< VecType >::size() - 1); 00375 } 00376 00377 template <typename VecType> 00378 inline 00379 Chunk::Dim dim( const Chunk::Header& _hdr ) 00380 { 00381 return static_cast<Chunk::Dim>( _hdr.dim_ ); 00382 } 00383 00384 // calc minimum (power-of-2) number of bits needed 00385 Chunk::Integer_Size needed_bits( size_t s ); 00386 00387 00388 // Return the storage type (Chunk::Header::bits_) 00389 template <typename T> 00390 inline 00391 unsigned int bits(const T& val) 00392 { 00393 return is_integer(val) 00394 ? (static_cast<unsigned int>(integer_size(val))) 00395 : (static_cast<unsigned int>(float_size(val))); 00396 } 00397 00398 // Convert size of type to Integer_Size 00399 #ifdef NDEBUG 00400 template <typename T> Chunk::Integer_Size integer_size(const T&) 00401 #else 00402 template <typename T> Chunk::Integer_Size integer_size(const T& d) 00403 #endif 00404 { 00405 assert( is_integer(d) ); 00406 00407 switch( sizeof(T) ) 00408 { 00409 case 1: return OMFormat::Chunk::Integer_8; 00410 case 2: return OMFormat::Chunk::Integer_16; 00411 case 4: return OMFormat::Chunk::Integer_32; 00412 case 8: return OMFormat::Chunk::Integer_64; 00413 } 00414 return Chunk::Integer_Size(0); 00415 } 00416 00417 00418 // Convert size of type to FLoat_Size 00419 #ifdef NDEBUG 00420 template <typename T> Chunk::Float_Size float_size(const T&) 00421 #else 00422 template <typename T> Chunk::Float_Size float_size(const T& d) 00423 #endif 00424 { 00425 assert( is_float(d) ); 00426 00427 switch( sizeof(T) ) 00428 { 00429 case 4: return OMFormat::Chunk::Float_32; 00430 case 8: return OMFormat::Chunk::Float_64; 00431 case 16: return OMFormat::Chunk::Float_128; 00432 } 00433 return Chunk::Float_Size(0); 00434 } 00435 00436 // -------------------- create/read version 00437 00438 inline uint8 mk_version(const uint16 major, const uint16 minor) 00439 { return (major & 0x07) << 5 | (minor & 0x1f); } 00440 00441 00442 inline uint16 major_version(const uint8 version) 00443 { return (version >> 5) & 0x07; } 00444 00445 00446 inline uint16 minor_version(const uint8 version) 00447 { return (version & 0x001f); } 00448 00449 00450 // ---------------------------------------- convenience functions 00451 00452 const char *as_string(Chunk::Type t); 00453 const char *as_string(Chunk::Entity e); 00454 const char *as_string(Chunk::Dim d); 00455 const char *as_string(Chunk::Integer_Size d); 00456 const char *as_string(Chunk::Float_Size d); 00457 00458 std::ostream& operator << ( std::ostream& _os, const Header& _h ); 00459 std::ostream& operator << ( std::ostream& _os, const Chunk::Header& _c ); 00460 00462 } // namespace OMFormat 00463 00464 // -------------------- (re-)store header 00465 00466 template <> inline 00467 size_t store( std::ostream& _os, const OMFormat::Header& _hdr, bool _swap) 00468 { return _hdr.store( _os, _swap ); } 00469 00470 template <> inline 00471 size_t restore( std::istream& _is, OMFormat::Header& _hdr, bool _swap ) 00472 { return _hdr.restore( _is, _swap ); } 00473 00474 00475 // -------------------- (re-)store chunk header 00476 00477 template <> inline 00478 size_t 00479 store( std::ostream& _os, const OMFormat::Chunk::Header& _hdr, bool _swap) 00480 { 00481 OMFormat::uint16 val; val << _hdr; 00482 return binary<uint16_t>::store( _os, val, _swap ); 00483 } 00484 00485 template <> inline 00486 size_t 00487 restore( std::istream& _is, OMFormat::Chunk::Header& _hdr, bool _swap ) 00488 { 00489 OMFormat::uint16 val; 00490 size_t bytes = binary<uint16_t>::restore( _is, val, _swap ); 00491 00492 _hdr << val; 00493 00494 return bytes; 00495 } 00496 00497 // -------------------- (re-)store integer with wanted number of bits (bytes) 00498 00499 typedef GenProg::True t_signed; 00500 typedef GenProg::False t_unsigned; 00501 00502 // helper to store a an integer 00503 template< typename T > 00504 size_t 00505 store( std::ostream& _os, 00506 const T& _val, 00507 OMFormat::Chunk::Integer_Size _b, 00508 bool _swap, 00509 t_signed); 00510 00511 // helper to store a an unsigned integer 00512 template< typename T > 00513 size_t 00514 store( std::ostream& _os, 00515 const T& _val, 00516 OMFormat::Chunk::Integer_Size _b, 00517 bool _swap, 00518 t_unsigned); 00519 00521 template< typename T > 00522 inline 00523 size_t 00524 store( std::ostream& _os, 00525 const T& _val, 00526 OMFormat::Chunk::Integer_Size _b, 00527 bool _swap) 00528 { 00529 assert( OMFormat::is_integer( _val ) ); 00530 00531 if ( OMFormat::is_signed( _val ) ) 00532 return store( _os, _val, _b, _swap, t_signed() ); 00533 return store( _os, _val, _b, _swap, t_unsigned() ); 00534 } 00535 00536 // helper to store a an integer 00537 template< typename T > inline 00538 size_t restore( std::istream& _is, 00539 T& _val, 00540 OMFormat::Chunk::Integer_Size _b, 00541 bool _swap, 00542 t_signed); 00543 00544 // helper to store a an unsigned integer 00545 template< typename T > inline 00546 size_t restore( std::istream& _is, 00547 T& _val, 00548 OMFormat::Chunk::Integer_Size _b, 00549 bool _swap, 00550 t_unsigned); 00551 00553 template< typename T > 00554 inline 00555 size_t 00556 restore( std::istream& _is, 00557 T& _val, 00558 OMFormat::Chunk::Integer_Size _b, 00559 bool _swap) 00560 { 00561 assert( OMFormat::is_integer( _val ) ); 00562 00563 if ( OMFormat::is_signed( _val ) ) 00564 return restore( _is, _val, _b, _swap, t_signed() ); 00565 return restore( _is, _val, _b, _swap, t_unsigned() ); 00566 } 00567 00568 00569 // 00570 // ---------------------------------------- storing vectors 00571 template <typename VecT> inline 00572 size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<2>, 00573 bool _swap ) 00574 { 00575 size_t bytes = store( _os, _vec[0], _swap ); 00576 bytes += store( _os, _vec[1], _swap ); 00577 return bytes; 00578 } 00579 00580 template <typename VecT> inline 00581 size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<3>, 00582 bool _swap ) 00583 { 00584 size_t bytes = store( _os, _vec[0], _swap ); 00585 bytes += store( _os, _vec[1], _swap ); 00586 bytes += store( _os, _vec[2], _swap ); 00587 return bytes; 00588 } 00589 00590 template <typename VecT> inline 00591 size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<4>, 00592 bool _swap ) 00593 { 00594 size_t bytes = store( _os, _vec[0], _swap ); 00595 bytes += store( _os, _vec[1], _swap ); 00596 bytes += store( _os, _vec[2], _swap ); 00597 bytes += store( _os, _vec[3], _swap ); 00598 return bytes; 00599 } 00600 00601 template <typename VecT> inline 00602 size_t store( std::ostream& _os, const VecT& _vec, GenProg::Int2Type<1>, 00603 bool _swap ) 00604 { 00605 return store( _os, _vec[0], _swap ); 00606 } 00607 00609 template <typename VecT> inline 00610 size_t vector_store( std::ostream& _os, const VecT& _vec, bool _swap ) 00611 { 00612 return store( _os, _vec, 00613 GenProg::Int2Type< vector_traits<VecT>::size_ >(), 00614 _swap ); 00615 } 00616 00617 // ---------------------------------------- restoring vectors 00618 template <typename VecT> 00619 inline 00620 size_t 00621 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<2>, 00622 bool _swap ) 00623 { 00624 size_t bytes = restore( _is, _vec[0], _swap ); 00625 bytes += restore( _is, _vec[1], _swap ); 00626 return bytes; 00627 } 00628 00629 template <typename VecT> 00630 inline 00631 size_t 00632 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<3>, 00633 bool _swap ) 00634 { 00635 typedef typename vector_traits<VecT>::value_type scalar_type; 00636 size_t bytes; 00637 00638 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap ); 00639 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap ); 00640 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap ); 00641 return bytes; 00642 } 00643 00644 template <typename VecT> 00645 inline 00646 size_t 00647 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<4>, 00648 bool _swap ) 00649 { 00650 typedef typename vector_traits<VecT>::value_type scalar_type; 00651 size_t bytes; 00652 00653 bytes = binary<scalar_type>::restore( _is, _vec[0], _swap ); 00654 bytes += binary<scalar_type>::restore( _is, _vec[1], _swap ); 00655 bytes += binary<scalar_type>::restore( _is, _vec[2], _swap ); 00656 bytes += binary<scalar_type>::restore( _is, _vec[3], _swap ); 00657 return bytes; 00658 } 00659 00660 template <typename VecT> 00661 inline 00662 size_t 00663 restore( std::istream& _is, VecT& _vec, GenProg::Int2Type<1>, 00664 bool _swap ) 00665 { 00666 return restore( _is, _vec[0], _swap ); 00667 } 00668 00670 template <typename VecT> 00671 inline 00672 size_t 00673 vector_restore( std::istream& _is, VecT& _vec, bool _swap ) 00674 { 00675 return restore( _is, _vec, 00676 GenProg::Int2Type< vector_traits<VecT>::size_ >(), 00677 _swap ); 00678 } 00679 00680 00681 // ---------------------------------------- storing property names 00682 00683 template <> 00684 inline 00685 size_t store( std::ostream& _os, const OMFormat::Chunk::PropertyName& _pn, 00686 bool _swap ) 00687 { 00688 store( _os, _pn.size(), OMFormat::Chunk::Integer_8, _swap ); // 1 byte 00689 if ( _pn.size() ) 00690 _os.write( _pn.c_str(), _pn.size() ); // size bytes 00691 return _pn.size() + 1; 00692 } 00693 00694 template <> 00695 inline 00696 size_t restore( std::istream& _is, OMFormat::Chunk::PropertyName& _pn, 00697 bool _swap ) 00698 { 00699 size_t size; 00700 00701 restore( _is, size, OMFormat::Chunk::Integer_8, _swap); // 1 byte 00702 00703 assert( OMFormat::Chunk::PropertyName::is_valid( size ) ); 00704 00705 if ( size > 0 ) 00706 { 00707 char buf[256]; 00708 _is.read( buf, size ); // size bytes 00709 buf[size] = '\0'; 00710 _pn.resize(size); 00711 _pn = buf; 00712 } 00713 return size+1; 00714 } 00715 00716 //============================================================================= 00717 } // namespace IO 00718 } // namespace OpenMesh 00719 #endif 00720 //============================================================================= 00721 #if defined(OM_MISSING_HEADER_LIMITS) 00722 # undef OM_MISSING_HEADER_LIMITS 00723 #endif 00724 //============================================================================= 00725 #if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC) 00726 # define OPENMESH_IO_OMFORMAT_TEMPLATES 00727 # include "OMFormatT.cc" 00728 #endif 00729 //============================================================================= 00730 #endif 00731 //=============================================================================