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

📄 mkbalancedpm.cc

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 CC
字号:
// -------------------- STL#include <iostream>#include <sstream>#include <cmath>// -------------------- OpenMesh#include <OpenMesh/Core/IO/MeshIO.hh>#include <OpenMesh/Core/Mesh/Types/TriMesh_ArrayKernelT.hh>#include <OpenMesh/Tools/Utils/getopt.h>#include <OpenMesh/Tools/Utils/Timer.hh>#include <OpenMesh/Tools/Decimater/DecimaterT.hh>#include <OpenMesh/Tools/Decimater/ModBaseT.hh>#include <OpenMesh/Tools/Decimater/ModQuadricT.hh>#include <OpenMesh/Tools/Decimater/ModNormalFlippingT.hh>#include <OpenMesh/Tools/Decimater/ModProgMeshT.hh>#include <OpenMesh/Tools/Decimater/ModIndependentSetsT.hh>typedef OpenMesh::TriMesh_ArrayKernelT<> Mesh;typedef OpenMesh::Decimater::DecimaterT<Mesh> Decimater;typedef OpenMesh::Decimater::ModNormalFlippingT<Decimater>  ModNormalFlipping;typedef OpenMesh::Decimater::ModQuadricT<Decimater>         ModQuadric;typedef OpenMesh::Decimater::ModProgMeshT<Decimater>        ModProgMesh;typedef OpenMesh::Decimater::ModIndependentSetsT<Decimater> ModIndependentSets;// ----------------------------------------------------------------------------using namespace OpenMesh::Decimater;template <class D>class ModBalancerT : public OpenMesh::Decimater::ModQuadricT<D>{public:  typedef OpenMesh::Decimater::ModQuadricT<D> BaseModQ;  DECIMATING_MODULE( ModBalancerT, D, Balancer );public:  typedef size_t level_t;public:   /// Constructor  ModBalancerT( D &_dec )    : BaseModQ( _dec ),      max_level_(0), n_vertices_(0)  {    BaseModQ::mesh().add_property( level_ );  }  /// Destructor  virtual ~ModBalancerT()  {    BaseModQ::mesh().remove_property( level_ );  }public:  static level_t calc_bits_for_roots( size_t _n_vertices )  {    return level_t(std::ceil(std::log((double)_n_vertices)*inv_log2_));  }public: // inherited  void initialize(void)  {    BaseModQ::initialize();    n_vertices_ = BaseModQ::mesh().n_vertices();    n_roots_    = calc_bits_for_roots(n_vertices_);  }  virtual float collapse_priority(const CollapseInfo& _ci)  {    level_t newlevel = std::max( BaseModQ::mesh().property( level_, _ci.v0 ),                                 BaseModQ::mesh().property( level_, _ci.v1 ) )+1;    level_t newroots = calc_bits_for_roots(n_vertices_-1);    if ( (newroots + newlevel) < 32 )    {      double err = BaseModQ::collapse_priority( _ci );      if (err!=BaseModQ::ILLEGAL_COLLAPSE)      {        return float(newlevel + err/(err+1.0));      }    }    return BaseModQ::ILLEGAL_COLLAPSE;  }  /// post-process halfedge collapse (accumulate quadrics)  void postprocess_collapse(const CollapseInfo& _ci)  {    BaseModQ::postprocess_collapse( _ci );    BaseModQ::mesh().property( level_, _ci.v1 ) =      std::max( BaseModQ::mesh().property( level_, _ci.v0 ),		BaseModQ::mesh().property( level_, _ci.v1 ) ) + 1;    max_level_ = std::max( BaseModQ::mesh().property( level_, _ci.v1 ), max_level_ );    n_roots_   = calc_bits_for_roots(--n_vertices_);  }public:  level_t max_level(void) const       { return max_level_; }  level_t bits_for_roots(void) const  { return n_roots_; }private:  OpenMesh::VPropHandleT<level_t> level_;  level_t max_level_; // maximum level reached  level_t n_roots_;   // minimum bits for root nodes  size_t  n_vertices_;// number of potential root nodes  static const double inv_log2_;};template <typename D>const double ModBalancerT<D>::inv_log2_ = 1.0/std::log(2.0);typedef ModBalancerT<Decimater>  ModBalancer;// ----------------------------------------------------------------------------inlinestd::string&replace_extension( std::string& _s, const std::string& _e ){  std::string::size_type dot = _s.rfind(".");  if (dot == std::string::npos)  { _s += "." + _e; }  else  { _s = _s.substr(0,dot+1)+_e; }  return _s;}inlinestd::stringbasename(const std::string& _f){  std::string::size_type dot = _f.rfind("/");  if (dot == std::string::npos)    return _f;  return _f.substr(dot+1, _f.length()-(dot+1));}// ----------------------------------------------------------------------------void usage_and_exit(int xcode){  using namespace std;  cout << endl       << "Usage: mkbalancedpm [-n <decimation-steps>] [-o <output>] "       << "<input.ext>\n"       << endl       << "  Create a balanced progressive mesh from an input file.\n"       << "  By default decimate as much as possible and write the result\n"       << "  to <input>.pm\n"       << endl       << "Options:\n"       << endl       << "  -n <decimation-steps>\n"       << "\tDetermines the maximum number of decimation steps.\n"       << "\tDecimate as much as possible if the value is equal zero\n"       << "\tDefault value: 0\n"       << endl       << "  -o <output>\n"       << "\tWrite resulting progressive mesh to the file named <output>\n"       << endl       << "  -N\n"       << "\tEnable Normal Flipping\n"       << endl       << "  -I\n"       << "\tEnable Independent Sets\n"       << endl;      exit(xcode);}// ----------------------------------------------------------------------------int main(int argc, char **argv){  Mesh mesh;  int  c;  std::string ifname, ofname;  size_t      decstep=0;  bool enable_modNF = false;  bool enable_modIS = false;  while ((c=getopt(argc, argv, "n:o:NIh"))!=-1)  {    switch (c)    {      case 'o': ofname = optarg; break;      case 'n': { std::stringstream str; str << optarg; str >> decstep; } break;      case 'N': enable_modNF = true; break;      case 'I': enable_modIS = true; break;      case 'h':        usage_and_exit(0);      default:	usage_and_exit(1);    }  }  if (optind >= argc)    usage_and_exit(1);     ifname = argv[optind];  if (!OpenMesh::IO::read_mesh(mesh, ifname))  {    std::cerr << "Error loading mesh from file '" << ifname << "'!\n";    return 1;  }  {    OpenMesh::Utils::Timer t;    Decimater decimater(mesh);    ModProgMesh::Handle        modPM;    ModBalancer::Handle        modB;    ModNormalFlipping::Handle  modNF;    ModIndependentSets::Handle modIS;        decimater.add_binary(modPM);    std::cout << "w/  progressive mesh module\n";    decimater.add_priority(modB);    std::cout << "w/  balancer module\n";    if ( enable_modNF )      decimater.add_binary(modNF);    std::cout << "w/" << (modNF.is_valid() ? ' ' : 'o')              << " normal flipping module\n";    if ( enable_modIS )      decimater.add_binary(modIS);    std::cout << "w/" << (modIS.is_valid() ? ' ' : 'o')              << " independent sets module\n";    std::cout << "Initialize decimater\n";    t.start();    if ( !decimater.initialize() )    {      std::cerr << "  Initialization failed!\n";      return 1;    }    t.stop();    std::cout << "  done [" << t.as_string() << "]\n";    t.reset();    int    rc;    size_t nv = mesh.n_vertices();    std::cout << "Begin decimation (#V " << nv << ")\n";    t.start();    do     {      if (modIS.is_valid())      {        Mesh::VertexIter  v_it;        Mesh::FaceIter    f_it;        for (f_it = mesh.faces_begin(); f_it != mesh.faces_end(); ++f_it)          if ( !mesh.status(f_it).deleted() )            mesh.update_normal(f_it);              for (v_it = mesh.vertices_begin(); v_it != mesh.vertices_end(); ++v_it)          if ( !mesh.status(v_it).deleted() )          {            mesh.status(v_it).set_locked(false);            mesh.update_normal(v_it);          }             }      rc = decimater.decimate(decstep);      t.stop();      std::cout << '\r'                 << (nv-=rc) << " (-" << rc << ")                " << std::flush;      t.cont();    } while (rc > 0);    t.stop();    std::cout << "\n  done [" << t.as_string() << "]\n";    std::cout << "Bits for <tree-id, node-id>: <"              << decimater.module(modB).bits_for_roots() << ", "              << decimater.module(modB).max_level()  << ">"              << std::endl;    std::cout << "Maximum level reached: "	      << decimater.module(modB).max_level() << std::endl;    if (ofname == "." || ofname == ".." )      ofname += "/" + basename(ifname);    std::string pmfname = ofname.empty() ? ifname : ofname;    replace_extension(pmfname, "pm");    std::cout << "Write progressive mesh data to file "              << pmfname << std::endl;    decimater.module(modPM).write( pmfname );  }  return 0;}

⌨️ 快捷键说明

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