⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 omwriter.cc

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 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 =================================================================#include <OpenMesh/Core/System/config.hh>// -------------------- STL#if defined( OM_CC_MIPS )#  include <time.h>#  include <string.h>#else#  include <ctime>#  include <cstring>#endif#include <fstream>// -------------------- OpenMesh#include <OpenMesh/Core/IO/OMFormat.hh>#include <OpenMesh/Core/System/omstream.hh>#include <OpenMesh/Core/Utils/Endian.hh>#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>#include <OpenMesh/Core/IO/writer/OMWriter.hh>//=== NAMESPACES ==============================================================namespace OpenMesh {namespace IO {//=== INSTANCIATE =============================================================// register the OMLoader singleton with MeshLoader_OMWriter_  __OMWriterInstance;_OMWriter_& OMWriter() { return __OMWriterInstance; }//=== IMPLEMENTATION ==========================================================const OMFormat::uchar _OMWriter_::magic_[3] = "OM";const OMFormat::uint8 _OMWriter_::version_  = OMFormat::mk_version(1,2);_OMWriter_::_OMWriter_() {   IOManager().register_module(this); }bool_OMWriter_::write(const std::string& _filename, BaseExporter& _be,                   Options _opt) const{  // check whether exporter can give us an OpenMesh BaseKernel  if (!_be.kernel()) return false;  // check for om extension in filename, we can only handle OM    if (_filename.rfind(".om") == std::string::npos)      return false;  _opt += Options::Binary; // only binary format supported  std::ofstream ofs(_filename.c_str(), std::ios::binary);  // check if file is open  if (!ofs.is_open())  {    omerr() << "[OMWriter] : cannot open file " << _filename << std::endl;    return false;  }  // call stream save method  bool rc = write(ofs, _be, _opt);    // close filestream  ofs.close();  // return success/failure notice  return rc;}//-----------------------------------------------------------------------------bool_OMWriter_::write(std::ostream& _os, BaseExporter& _be, Options _opt) const{//   std::clog << "[OMWriter]::write( stream )\n";  // check exporter features  if ( !check( _be, _opt ) )  {    omerr() << "[OMWriter]: exporter does not support wanted feature!\n";    return false;  }  // Maybe an ascii version will be implemented in the future.  // For now, support only a binary format  if ( !_opt.check( Options::Binary ) )    _opt += Options::Binary;  // Ignore LSB/MSB bit. Always store in LSB (little endian)  _opt += Options::LSB;  _opt -= Options::MSB;//    if ( _opt.check(Options::Binary) )//    {  return write_binary(_os, _be, _opt);//    }//    else//    {//       return write_ascii(_os, _be, _opt);//    }}//-----------------------------------------------------------------------------// bool _OMWriter_::write_ascii(std::ostream& _os, BaseExporter& _be,//                               Options _opt) const// {//    return false;// }//-----------------------------------------------------------------------------#ifndef DOXY_IGNORE_THIStemplate <typename T> struct Enabler{  Enabler( T& obj ) : obj_(obj)  {}  ~Enabler() { obj_.enable(); }  T& obj_;};#endifbool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,                               Options _opt) const{  Enabler<mostream> enabler(omlog());  omlog() << "[OMWriter] : write binary file\n";  size_t bytes = 0;  bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);  unsigned int i, nV, nF;  Vec3f v;  Vec2f t;  std::vector<VertexHandle> vhandles;  // -------------------- write header  OMFormat::Header header;    header.magic_[0]   = 'O';  header.magic_[1]   = 'M';  header.mesh_       = _be.is_triangle_mesh() ? 'T' : 'P';  header.version_    = version_;  header.n_vertices_ = _be.n_vertices();  header.n_faces_    = _be.n_faces();  header.n_edges_    = _be.n_edges();    bytes += store( _os, header, swap );    // ---------------------------------------- write chunks    OMFormat::Chunk::Header chunk_header;      // -------------------- write vertex data    // ---------- write vertex position  if (_be.n_vertices())  {    v = _be.point(VertexHandle(0));    chunk_header.reserved_ = 0;    chunk_header.name_     = false;    chunk_header.entity_   = OMFormat::Chunk::Entity_Vertex;    chunk_header.type_     = OMFormat::Chunk::Type_Pos;    chunk_header.signed_   = OMFormat::is_signed(v[0]);    chunk_header.float_    = OMFormat::is_float(v[0]);    chunk_header.dim_      = OMFormat::dim(v);    chunk_header.bits_     = OMFormat::bits(v[0]);      bytes += store( _os, chunk_header, swap );    for (i=0, nV=_be.n_vertices(); i<nV; ++i)      bytes += vector_store( _os, _be.point(VertexHandle(i)), swap );  }  // ---------- write vertex normal  if (_be.n_vertices() && _opt.check( Options::VertexNormal ))  {    Vec3f n = _be.normal(VertexHandle(0));    chunk_header.name_     = false;    chunk_header.entity_   = OMFormat::Chunk::Entity_Vertex;    chunk_header.type_     = OMFormat::Chunk::Type_Normal;    chunk_header.signed_   = OMFormat::is_signed(n[0]);    chunk_header.float_    = OMFormat::is_float(n[0]);    chunk_header.dim_      = OMFormat::dim(n);    chunk_header.bits_     = OMFormat::bits(n[0]);      bytes += store( _os, chunk_header, swap );    for (i=0, nV=_be.n_vertices(); i<nV; ++i)      bytes += vector_store( _os, _be.normal(VertexHandle(i)), swap );  }  // ---------- write vertex color#if 1  if (_opt.check( Options::VertexColor ) && _be.has_vertex_colors() )  {      Vec3uc c = _be.color(VertexHandle(0));        chunk_header.name_     = false;    chunk_header.entity_   = OMFormat::Chunk::Entity_Vertex;    chunk_header.type_     = OMFormat::Chunk::Type_Color;    chunk_header.signed_   = OMFormat::is_signed( c );    chunk_header.float_    = OMFormat::is_float( c );    chunk_header.dim_      = OMFormat::dim( c );    chunk_header.bits_     = OMFormat::bits( c );        bytes += store( _os, chunk_header, swap );    for (i=0, nV=_be.n_vertices(); i<nV; ++i)      bytes += vector_store( _os, _be.color(VertexHandle(i)), swap );  }#endif  // ---------- write vertex texture coords  if (_be.n_vertices() && _opt.check(Options::VertexTexCoord))  {    t = _be.texcoord(VertexHandle(0));    chunk_header.name_     = false;    chunk_header.entity_   = OMFormat::Chunk::Entity_Vertex;    chunk_header.type_     = OMFormat::Chunk::Type_Texcoord;    chunk_header.signed_   = OMFormat::is_signed(t[0]);    chunk_header.float_    = OMFormat::is_float(t[0]);    chunk_header.dim_      = OMFormat::dim(t);    chunk_header.bits_     = OMFormat::bits(t[0]);      // std::clog << chunk_header << std::endl;    bytes += store( _os, chunk_header, swap );    for (i=0, nV=_be.n_vertices(); i<nV; ++i)      bytes += vector_store( _os, _be.texcoord(VertexHandle(i)), swap );  }  // -------------------- write face data  // ---------- write topology  {    chunk_header.name_     = false;    chunk_header.entity_   = OMFormat::Chunk::Entity_Face;    chunk_header.type_     = OMFormat::Chunk::Type_Topology;    chunk_header.signed_   = 0;    chunk_header.float_    = 0;    chunk_header.dim_      = OMFormat::Chunk::Dim_1D; // ignored    chunk_header.bits_     = OMFormat::needed_bits(_be.n_vertices());        bytes += store( _os, chunk_header, swap );    for (i=0, nF=_be.n_faces(); i<nF; ++i)    {      nV = _be.get_vhandles(FaceHandle(i), vhandles);      if ( header.mesh_ == 'P' )	bytes += store( _os, vhandles.size(), 			OMFormat::Chunk::Integer_16, swap );            for (size_t j=0; j < vhandles.size(); ++j)      {	using namespace OMFormat;	using namespace GenProg;		bytes += store( _os, vhandles[j].idx(),			Chunk::Integer_Size(chunk_header.bits_), swap );      }    }  }  // ---------- write face normals  if ( _be.has_face_normals() && _opt.check(Options::FaceNormal) )  {#define NEW_STYLE 0#if NEW_STYLE    const BaseProperty *bp = _be.kernel()._get_fprop("f:normals");    if (bp)    {#endif      Vec3f n = _be.normal(FaceHandle(0));      chunk_header.name_     = false;      chunk_header.entity_   = OMFormat::Chunk::Entity_Face;      chunk_header.type_     = OMFormat::Chunk::Type_Normal;      chunk_header.signed_   = OMFormat::is_signed(n[0]);      chunk_header.float_    = OMFormat::is_float(n[0]);      chunk_header.dim_      = OMFormat::dim(n);      chunk_header.bits_     = OMFormat::bits(n[0]);        bytes += store( _os, chunk_header, swap );#if !NEW_STYLE      for (i=0, nF=_be.n_faces(); i<nF; ++i)        bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );#else      bytes += bp->store(_os, swap );    }    else      return false;#endif#undef NEW_STYLE  }  // ---------- write face color  if (_be.has_face_colors() && _opt.check( Options::FaceColor ))  {  #define NEW_STYLE 0#if NEW_STYLE    const BaseProperty *bp = _be.kernel()._get_fprop("f:colors");        if (bp)    {#endif      Vec3uc c;            chunk_header.name_     = false;      chunk_header.entity_   = OMFormat::Chunk::Entity_Face;      chunk_header.type_     = OMFormat::Chunk::Type_Color;      chunk_header.signed_   = OMFormat::is_signed( c[0] );      chunk_header.float_    = OMFormat::is_float( c[0] );      chunk_header.dim_      = OMFormat::dim( c );      chunk_header.bits_     = OMFormat::bits( c[0] );            bytes += store( _os, chunk_header, swap );#if !NEW_STYLE      for (i=0, nF=_be.n_faces(); i<nF; ++i)        bytes += vector_store( _os, _be.color(FaceHandle(i)), swap );      #else      bytes += bp->store(_os, swap);    }    else      return false;#endif  }  // -------------------- write custom properties    BaseKernel::const_prop_iterator prop;    for (prop  = _be.kernel()->vprops_begin();       prop != _be.kernel()->vprops_end(); ++prop)  {    if ( !*prop ) continue;    if ( (*prop)->name()[1]==':') continue;    bytes += store_binary_custom_chunk(_os, **prop, 				       OMFormat::Chunk::Entity_Vertex, swap );  }  for (prop  = _be.kernel()->fprops_begin();       prop != _be.kernel()->fprops_end(); ++prop)  {    if ( !*prop ) continue;    if ( (*prop)->name()[1]==':') continue;    bytes += store_binary_custom_chunk(_os, **prop, 				       OMFormat::Chunk::Entity_Face, swap );  }  for (prop  = _be.kernel()->eprops_begin();       prop != _be.kernel()->eprops_end(); ++prop)  {    if ( !*prop ) continue;    if ( (*prop)->name()[1]==':') continue;    bytes += store_binary_custom_chunk(_os, **prop, 				       OMFormat::Chunk::Entity_Edge, swap );  }  for (prop  = _be.kernel()->hprops_begin();       prop != _be.kernel()->hprops_end(); ++prop)  {    if ( !*prop ) continue;    if ( (*prop)->name()[1]==':') continue;    bytes += store_binary_custom_chunk(_os, **prop, 				       OMFormat::Chunk::Entity_Halfedge, swap );  }  for (prop  = _be.kernel()->mprops_begin();       prop != _be.kernel()->mprops_end(); ++prop)  {    if ( !*prop ) continue;    if ( (*prop)->name()[1]==':') continue;    bytes += store_binary_custom_chunk(_os, **prop, 				       OMFormat::Chunk::Entity_Mesh, swap );  }// std::clog << "#bytes written: " << bytes << std::endl;  return true;}// ----------------------------------------------------------------------------size_t _OMWriter_::store_binary_custom_chunk(std::ostream& _os, 					     const BaseProperty& _bp,					     OMFormat::Chunk::Entity _entity,					     bool _swap) const{  omlog() << "Custom Property " << OMFormat::as_string(_entity) << " property ["	<< _bp.name() << "]" << std::endl;  // Don't store if   // 1. it is not persistent  // 2. it's name is empty  if ( !_bp.persistent() || _bp.name().empty() )  {    omlog() << "  skipped\n";    return 0;  }  size_t bytes = 0;  OMFormat::Chunk::esize_t element_size   = _bp.element_size();  OMFormat::Chunk::Header  chdr;  // set header  chdr.name_     = true;  chdr.entity_   = _entity;  chdr.type_     = OMFormat::Chunk::Type_Custom;  chdr.signed_   = 0;  chdr.float_    = 0;  chdr.dim_      = OMFormat::Chunk::Dim_1D; // ignored  chdr.bits_     = element_size;  // write custom chunk  // 1. chunk header         bytes += store( _os, chdr, _swap );  // 2. property name  bytes += store( _os, OMFormat::Chunk::PropertyName(_bp.name()), _swap );  // 3. block size  bytes += store( _os, _bp.size_of(), _swap );  omlog() << "  n_bytes = " << _bp.size_of() << std::endl;  // 4. data  {    size_t b;    bytes += ( b=_bp.store( _os, _swap ) );    omlog() << "  b       = " << b << std::endl;    assert( b == _bp.size_of() );  }  return bytes;}// ----------------------------------------------------------------------------size_t _OMWriter_::binary_size(BaseExporter& _be, Options _opt) const{  // std::clog << "[OMWriter]: binary_size()" << std::endl;  size_t bytes  = sizeof( OMFormat::Header );  // !!!TODO!!!  return bytes;}//=============================================================================} // namespace IO} // namespace OpenMesh//=============================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -