📄 omformat.hh
字号:
/*===========================================================================*\ * * * OpenMesh * * Copyright (C) 2001-2005 by Computer Graphics Group, RWTH Aachen * * www.openmesh.org * * * *---------------------------------------------------------------------------* * * * License * * * * This library is free software; you can redistribute it and/or modify it * * under the terms of the GNU Library General Public License as published * * by the Free Software Foundation, version 2. * * * * This library is distributed in the hope that it will be useful, but * * WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Library General Public License for more details. * * * * You should have received a copy of the GNU Library General Public * * License along with this library; if not, write to the Free Software * * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * *\*===========================================================================*/#ifndef OPENMESH_IO_OMFORMAT_HH#define OPENMESH_IO_OMFORMAT_HH//=== INCLUDES ================================================================#include <OpenMesh/Core/System/config.hh>#include <OpenMesh/Core/System/omstream.hh>#include <OpenMesh/Core/IO/SR_store.hh>#include <OpenMesh/Core/Utils/GenProg.hh>#include <OpenMesh/Core/Utils/Endian.hh>#include <OpenMesh/Core/Utils/vector_traits.hh>// --------------------#include <iostream>#if defined(OM_CC_GCC) && (OM_GCC_VERSION < 30000)# include <OpenMesh/Tools/Utils/NumLimitsT.hh># define OM_MISSING_HEADER_LIMITS 1#else# include <limits>#endif//== NAMESPACES ==============================================================#ifndef DOXY_IGNORE_THISnamespace OpenMesh {namespace IO {namespace OMFormat {//=== IMPLEMENTATION ==========================================================/** \name Mesh Reading / Writing*///@{//----------------------------------------------------------------------------- // <:Header> // <:Comment> // Chunk 0 // <:ChunkHeader> // <:Comment> // data // Chunk 1 // <:ChunkHeader> // <:Comment> // data // . // . // . // Chunk N typedef unsigned char uchar; typedef uint8_t uint8; typedef uint16_t uint16; typedef uint32_t uint32; typedef uint64_t uint64; typedef int8_t int8; typedef int16_t int16; typedef int32_t int32; typedef int64_t int64; typedef float32_t float32; typedef float64_t float64; struct Header { uchar magic_[2]; // OM uchar mesh_; // [T]riangles, [Q]uads, [P]olygonals uint8 version_; uint32 n_vertices_; uint32 n_faces_; uint32 n_edges_; size_t store( std::ostream& _os, bool _swap ) const { _os.write( (char*)this, 4); // magic_, mesh_, version_ size_t bytes = 4; bytes += binary<uint32_t>::store( _os, n_vertices_, _swap ); bytes += binary<uint32_t>::store( _os, n_faces_, _swap ); bytes += binary<uint32_t>::store( _os, n_edges_, _swap ); return bytes; } size_t restore( std::istream& _is, bool _swap ) { if (_is.read( (char*)this, 4 ).eof()) return 0; size_t bytes = 4; bytes += binary<uint32_t>::restore( _is, n_vertices_, _swap ); bytes += binary<uint32_t>::restore( _is, n_faces_, _swap ); bytes += binary<uint32_t>::restore( _is, n_edges_, _swap ); return bytes; } }; struct Chunk { typedef size_t esize_t; // element size, used for custom properties enum Type { Type_Pos = 0x00, Type_Normal = 0x01, Type_Texcoord = 0x02, Type_Status = 0x03, Type_Color = 0x04, Type_Custom = 0x06, Type_Topology = 0x07 }; enum Entity { Entity_Vertex = 0x00, Entity_Mesh = 0x01, Entity_Face = 0x02, Entity_Edge = 0x04, Entity_Halfedge = 0x06, }; enum Dim { Dim_1D = 0x00, Dim_2D = 0x01, Dim_3D = 0x02, Dim_4D = 0x03, Dim_5D = 0x04, Dim_6D = 0x05, Dim_7D = 0x06, Dim_8D = 0x07 }; enum Integer_Size { Integer_8 = 0x00, // 1 byte for (unsigned) char Integer_16 = 0x01, // 2 bytes for short Integer_32 = 0x02, // 4 bytes for long Integer_64 = 0x03 // 8 bytes for long long }; enum Float_Size { Float_32 = 0x00, // 4 bytes for float Float_64 = 0x01, // 8 bytes for double Float_128 = 0x02 // 16 bytes for long double (an assumption!) }; static const int SIZE_RESERVED = 1; // 1 static const int SIZE_NAME = 1; // 2 static const int SIZE_ENTITY = 3; // 5 static const int SIZE_TYPE = 4; // 9 static const int SIZE_SIGNED = 1; // 10 static const int SIZE_FLOAT = 1; // 11 static const int SIZE_DIM = 3; // 14 static const int SIZE_BITS = 2; // 16 static const int OFF_RESERVED = 0; // 0 static const int OFF_NAME = SIZE_RESERVED + OFF_RESERVED; // 2 static const int OFF_ENTITY = SIZE_NAME + OFF_NAME; // 3 static const int OFF_TYPE = SIZE_ENTITY + OFF_ENTITY; // 5 static const int OFF_SIGNED = SIZE_TYPE + OFF_TYPE; // 9 static const int OFF_FLOAT = SIZE_SIGNED + OFF_SIGNED; // 10 static const int OFF_DIM = SIZE_FLOAT + OFF_FLOAT; // 11 static const int OFF_BITS = SIZE_DIM + OFF_DIM; // 14 // !Attention! When changing the bit size, the operators // << (uint16, Header) and << (Header, uint16) must be changed as well // // Entries signed_, float_, dim_, bits_ are not used when type_ // equals Type_Custom // struct Header // 16 bits long { unsigned reserved_: SIZE_RESERVED; unsigned name_ : SIZE_NAME; // 1 named property, 0 anonymous unsigned entity_ : SIZE_ENTITY; // 0 vertex, 1 mesh, 2 edge, // 4 halfedge, 6 face unsigned type_ : SIZE_TYPE; // 0 pos, 1 normal, 2 texcoord, // 3 status, 4 color 6 custom 7 topology unsigned signed_ : SIZE_SIGNED; // bool unsigned float_ : SIZE_FLOAT; // bool unsigned dim_ : SIZE_DIM; // 0 1D, 1 2D, 2 3D, .., 7 8D unsigned bits_ : SIZE_BITS; // {8, 16, 32, 64} | {32, 64, 128} // (integer) (float) unsigned unused_ : 16; // fill up to 32 bits }; // struct Header class PropertyName : public std::string { public: static const size_t size_max = 256; PropertyName( ) { } PropertyName( const std::string& _name ) { *this = _name; } bool is_valid() const { return is_valid( size() ); } static bool is_valid( size_t _s ) { return _s <= size_max; } PropertyName& operator = ( const std::string& _rhs ) { assert( is_valid( _rhs.size() ) ); if ( is_valid( _rhs.size() ) ) std::string::operator = ( _rhs ); else { omerr() << "Warning! Property name too long. Will be shortened!\n"; this->std::string::operator = ( _rhs.substr(0, size_max) ); } return *this; } }; }; // Chunk // ------------------------------------------------------------ Helper // -------------------- get size information /// Return size of header in bytes. inline size_t header_size(void) { return sizeof(Header); } /// Return size of chunk header in bytes. inline size_t chunk_header_size( void ) { return sizeof(uint16); } /// Return the size of a scale in bytes. inline size_t scalar_size( const Chunk::Header& _hdr ) { return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_); } /// Return the dimension of the vector in a chunk inline size_t dimensions(const Chunk::Header& _chdr) { return _chdr.dim_+1; } /// Return the size of a vector in bytes. inline size_t vector_size( const Chunk::Header& _chdr ) { return dimensions(_chdr)*scalar_size(_chdr); } /// Return the size of chunk data in bytes inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr ) { size_t C = 0; switch( _chunk_hdr.entity_ ) { case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break; case Chunk::Entity_Face: C = _hdr.n_faces_; break; case Chunk::Entity_Halfedge: C = _hdr.n_edges_; // no break! case Chunk::Entity_Edge: C += _hdr.n_edges_; break; case Chunk::Entity_Mesh: C = 1; break; default: std::cerr << "Invalid value in _chunk_hdr.entity_\n"; assert( false ); } return C * vector_size( _chunk_hdr ); } inline size_t chunk_size( Header& _hdr, Chunk::Header& _chunk_hdr ) { return chunk_header_size() + chunk_data_size( _hdr, _chunk_hdr ); } // -------------------- convert from Chunk::Header to storage type uint16& operator << (uint16& val, const Chunk::Header& hdr); Chunk::Header& operator << (Chunk::Header& hdr, const uint16 val); // -------------------- type information template <typename T> bool is_float(const T&) { #if defined(OM_MISSING_HEADER_LIMITS) return !Utils::NumLimitsT<T>::is_integer();#else return !std::numeric_limits<T>::is_integer; #endif } template <typename T> bool is_integer(const T) { #if defined(OM_MISSING_HEADER_LIMITS) return Utils::NumLimitsT<T>::is_integer();#else return std::numeric_limits<T>::is_integer; #endif } template <typename T> bool is_signed(const T&) { #if defined(OM_MISSING_HEADER_LIMITS) return Utils::NumLimitsT<T>::is_signed();#else return std::numeric_limits<T>::is_signed; #endif } // -------------------- conversions (format type <- type/value) template <typename VecType> inline Chunk::Dim dim( VecType ) { assert( vector_traits< VecType >::size() < 9 ); return static_cast<Chunk::Dim>(vector_traits< VecType >::size() - 1); } template <> inline Chunk::Dim dim( const Chunk::Header& _hdr )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -