📄 omreader.cc
字号:
/*===========================================================================*\ * * * 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. * * *\*===========================================================================*///== INCLUDES =================================================================//STL#include <fstream>// OpenMesh#include <OpenMesh/Core/System/config.hh>#include <OpenMesh/Core/System/omstream.hh>#include <OpenMesh/Core/Utils/Endian.hh>#include <OpenMesh/Core/IO/OMFormat.hh>#include <OpenMesh/Core/IO/reader/OMReader.hh>//=== NAMESPACES ==============================================================namespace OpenMesh {namespace IO {//=== INSTANCIATE =============================================================// register the OMReader singleton with MeshReader_OMReader_ __OMReaderInstance;_OMReader_& OMReader() { return __OMReaderInstance; }//=== IMPLEMENTATION ==========================================================_OMReader_::_OMReader_(){ IOManager().register_module(this); }//-----------------------------------------------------------------------------bool _OMReader_::read(const std::string& _filename, BaseImporter& _bi, Options& _opt){ // check whether importer can give us an OpenMesh BaseKernel if (!_bi.kernel()) return false; _opt += Options::Binary; // only binary format supported! // clear vhandles vhandles_.clear(); // Open file std::ifstream ifs( _filename.c_str(), std::ios::binary ); if (!ifs.is_open()) { omerr() << "[OMReader] : cannot not open file " << _filename << std::endl; return false; } // Pass stream to read method, remember result bool result = read(ifs, _bi, _opt); // clean up vhandles BaseImporter::VHandles().swap(vhandles_); // close input stream ifs.close(); return result;}//-----------------------------------------------------------------------------bool _OMReader_::read(std::istream& _is, BaseImporter& _bi, Options& _opt ){ // currently only binary file format is supported _opt += Options::Binary; return read_binary( _is, _bi, _opt );}//-----------------------------------------------------------------------------bool _OMReader_::read_ascii( std::istream& _is, BaseImporter& _bi, Options& _opt){ // not supported yet! return false;}//-----------------------------------------------------------------------------bool _OMReader_::read_binary( std::istream& _is, BaseImporter& _bi, Options& _opt){ bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB); // intialize byte counter bytes_ = 0; bytes_ += restore( _is, header_, swap ); size_t data_bytes; while( !_is.eof() ) { bytes_ += restore( _is, chunk_header_, swap ); if ( _is.eof() ) break; // Is this a named property restore the name if ( chunk_header_.name_ ) { OMFormat::Chunk::PropertyName pn; bytes_ += restore( _is, property_name_, swap ); } // Read in the property data. If it is an anonymous or unknown named // property, then skip data. data_bytes = bytes_; switch( chunk_header_.entity_ ) { case OMFormat::Chunk::Entity_Vertex: if (!read_binary_vertex_chunk( _is, _bi, _opt, swap )) return false; break; case OMFormat::Chunk::Entity_Face: if (!read_binary_face_chunk( _is, _bi, _opt, swap )) return false; break; case OMFormat::Chunk::Entity_Edge: if (!read_binary_edge_chunk( _is, _bi, _opt, swap )) return false; break; case OMFormat::Chunk::Entity_Halfedge: if (!read_binary_halfedge_chunk( _is, _bi, _opt, swap )) return false; break; case OMFormat::Chunk::Entity_Mesh: if (!read_binary_mesh_chunk( _is, _bi, _opt, swap )) return false; break; default: return false; } data_bytes = bytes_ - data_bytes; } // File was successfully parsed. return true;}//-----------------------------------------------------------------------------bool_OMReader_::can_u_read(const std::string& _filename) const{ // !!! Assuming BaseReader::can_u_parse( std::string& ) // does not call BaseReader::read_magic()!!! if ( this->BaseReader::can_u_read( _filename ) ) { std::ifstream ifile( _filename.c_str() ); if ( ifile && can_u_read( ifile ) ) return true; } return false;}//----------------------------------------------------------------------------- bool_OMReader_::can_u_read(std::istream& _is) const{ std::vector<char> evt; evt.reserve(20); // read first 4 characters into a buffer while( evt.size() < 4 ) evt.push_back( static_cast<char>(_is.get()) ); // put back all read characters std::vector<char>::reverse_iterator it = evt.rbegin(); while (it != evt.rend() ) _is.putback( *it++ ); // evaluate header information OMFormat::Header *hdr = (OMFormat::Header*)&evt[0]; // first two characters must be 'OM' if (hdr->magic_[0] != 'O' || hdr->magic_[1] != 'M') return false; // 3rd characters defines the mesh type: switch(hdr->mesh_) { case 'T': // Triangle Mesh case 'Q': // Quad Mesh case 'P': // Polygonal Mesh break; default: // ? return false; } // 4th characters encodes the version return supports( hdr->version_ );}//-----------------------------------------------------------------------------bool _OMReader_::supports( const OMFormat::uint8 version ) const{ return true;}//-----------------------------------------------------------------------------bool _OMReader_::read_binary_vertex_chunk( std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap){ using OMFormat::Chunk; assert( chunk_header_.entity_ == Chunk::Entity_Vertex ); OpenMesh::Vec3f v3f; OpenMesh::Vec2f v2f; OpenMesh::Vec3uc v3uc; // rgb OMFormat::Chunk::PropertyName custom_prop; size_t vidx=0; switch (chunk_header_.type_) { case Chunk::Type_Pos: assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()) ); for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { bytes_ += vector_restore( _is, v3f, _swap ); vhandles_.push_back( _bi.add_vertex(v3f) ); } break; case Chunk::Type_Normal: assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()) ); _opt += Options::VertexNormal; for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { bytes_ += vector_restore( _is, v3f, _swap ); _bi.set_normal(VertexHandle(vidx), v3f); } break; case Chunk::Type_Texcoord: assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec2f::dim()) ); _opt += Options::VertexTexCoord; for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) { bytes_ += vector_restore( _is, v2f, _swap ); _bi.set_texcoord(VertexHandle(vidx), v2f); } break;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -