📄 vdpmanalyzer.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#include <iostream>#include <fstream>#include <algorithm>#include <limits>#include <exception>#include <cmath>// -------------------- OpenMesh#include <OpenMesh/Core/IO/MeshIO.hh>#include <OpenMesh/Core/Mesh/Types/TriMesh_ArrayKernelT.hh>#include <OpenMesh/Core/Utils/Endian.hh>#include <OpenMesh/Tools/Utils/Timer.hh>#include <OpenMesh/Tools/Utils/getopt.h>// -------------------- OpenMesh VDPM#include <OpenMesh/Tools/VDPM/StreamingDef.hh>#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>#include <OpenMesh/Tools/VDPM/VHierarchy.hh>#include <OpenMesh/Tools/VDPM/VFront.hh>// ----------------------------------------------------------------------------// ----------------------------------------------------------------------------using namespace OpenMesh;// ----------------------------------------------------------------------------// using view dependent progressive meshusing VDPM::Plane3d;using VDPM::VFront;using VDPM::VHierarchy;using VDPM::VHierarchyNode;using VDPM::VHierarchyNodeIndex;using VDPM::VHierarchyNodeHandle;using VDPM::VHierarchyNodeHandleContainer;using VDPM::ViewingParameters;// ------------------------------------------------------------- mesh type ----// Generate an OpenMesh suitable for the analyzing taskstruct AnalyzerTraits : public DefaultTraits{ VertexTraits { public: VHierarchyNodeHandle vhierarchy_node_handle() { return node_handle_; } void set_vhierarchy_node_handle(VHierarchyNodeHandle _node_handle) { node_handle_ = _node_handle; } bool is_ancestor(const VHierarchyNodeIndex &_other) { return false; } private: VHierarchyNodeHandle node_handle_; }; HalfedgeTraits { public: VHierarchyNodeHandle vhierarchy_leaf_node_handle() { return leaf_node_handle_; } void set_vhierarchy_leaf_node_handle(VHierarchyNodeHandle _leaf_node_handle) { leaf_node_handle_ = _leaf_node_handle; } private: VHierarchyNodeHandle leaf_node_handle_; }; VertexAttributes(Attributes::Status | Attributes::Normal); HalfedgeAttributes(Attributes::PrevHalfedge); EdgeAttributes(Attributes::Status); FaceAttributes(Attributes::Status | Attributes::Normal);};typedef TriMesh_ArrayKernelT<AnalyzerTraits> Mesh;// ----------------------------------------------------------------- types ----struct PMInfo{ Mesh::Point p0; Mesh::VertexHandle v0, v1, vl, vr;};typedef std::vector<PMInfo> PMInfoContainer;typedef PMInfoContainer::iterator PMInfoIter;typedef std::vector<VertexHandle> VertexHandleContainer;typedef std::vector<Vec3f> ResidualContainer;// -------------------------------------------------------------- forwards ----/// open progressive meshvoid open_prog_mesh(const std::string &_filename);/// save view-dependent progressive meshvoid save_vd_prog_mesh(const std::string &_filename);/// locate fundamental cut verticesvoid locate_fund_cut_vertices();void create_vertex_hierarchy();/// refine mesh up to _n verticesvoid refine(unsigned int _n);/// coarsen mesh down to _n verticesvoid coarsen(unsigned int _n);void vdpm_analysis();void get_leaf_node_handles(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes);void compute_bounding_box(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes);void compute_cone_of_normals(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes);void compute_screen_space_error(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes);void compute_mue_sigma(VHierarchyNodeHandle node_handle, ResidualContainer &residuals);Vec3fpoint2triangle_residual(const Vec3f &p, const Vec3f tri[3], float &s, float &t);void PrintOutFundCuts();void PrintVertexNormals();// --------------------------------------------------------------- globals ----// mesh dataMesh mesh_;PMInfoContainer pminfos_;PMInfoIter pmiter_;VHierarchy vhierarchy_;unsigned int n_base_vertices_, n_base_faces_, n_details_;unsigned int n_current_res_;unsigned int n_max_res_;bool verbose = false;// ----------------------------------------------------------------------------void usage_and_exit(int xcode){ using namespace std; cout << "Usage: vdpmanalyzer [-h] [-o output.spm] input.pm\n"; exit(xcode);}// ----------------------------------------------------------------------------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));}// ----------------------------------------------------------------------------// just for debuggingtypedef std::vector<OpenMesh::Vec3f> MyPoints;typedef MyPoints::iterator MyPointsIter;MyPoints projected_points;MyPoints original_points;// ------------------------------------------------------------------ main ----int main(int argc, char **argv){ int c; std::string ifname; std::string ofname; while ( (c=getopt(argc, argv, "o:"))!=-1 ) { switch(c) { case 'v': verbose = true; break; case 'o': ofname = optarg; break; case 'h': usage_and_exit(0); default: usage_and_exit(1); } } if (optind >= argc) usage_and_exit(1); ifname = argv[optind]; if (ofname == "." || ofname == ".." ) ofname += "/" + basename(ifname); std::string spmfname = ofname.empty() ? ifname : ofname; replace_extension(spmfname, "spm"); if ( ifname.empty() || spmfname.empty() ) { usage_and_exit(1); } try { open_prog_mesh(ifname); vdpm_analysis(); save_vd_prog_mesh(spmfname.c_str()); } catch( std::bad_alloc& ) { std::cerr << "Error: out of memory!\n" << std::endl; return 1; } catch( std::exception& x ) { std::cerr << "Error: " << x.what() << std::endl; return 1; } catch( ... ) { std::cerr << "Fatal! Unknown error!\n"; return 1; } return 0;}// ----------------------------------------------------------------------------void open_prog_mesh(const std::string& _filename){ Mesh::Point p; unsigned int i, i0, i1, i2; unsigned int v1, vl, vr; char c[10]; VertexHandle vertex_handle; VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle; VHierarchyNodeIndex node_index; std::ifstream ifs(_filename.c_str(), std::ios::binary); if (!ifs) { std::cerr << "read error\n"; exit(1); } // bool swap = Endian::local() != Endian::LSB; // read header ifs.read(c, 8); c[8] = '\0'; if (std::string(c) != std::string("ProgMesh")) { std::cerr << "Wrong file format.\n"; ifs.close(); exit(1); } IO::restore(ifs, n_base_vertices_, swap); IO::restore(ifs, n_base_faces_, swap); IO::restore(ifs, n_details_, swap); vhierarchy_.set_num_roots(n_base_vertices_); for (i=0; i<n_base_vertices_; ++i) { IO::restore(ifs, p, swap); vertex_handle = mesh_.add_vertex(p); node_index = vhierarchy_.generate_node_index(i, 1); node_handle = vhierarchy_.add_node(); vhierarchy_.node(node_handle).set_index(node_index); vhierarchy_.node(node_handle).set_vertex_handle(vertex_handle); mesh_.vertex(vertex_handle).set_vhierarchy_node_handle(node_handle); } for (i=0; i<n_base_faces_; ++i) { IO::restore(ifs, i0, swap); IO::restore(ifs, i1, swap); IO::restore(ifs, i2, swap); mesh_.add_face(mesh_.vertex_handle(i0), mesh_.vertex_handle(i1), mesh_.vertex_handle(i2)); } // load progressive detail for (i=0; i<n_details_; ++i) { IO::restore(ifs, p, swap); IO::restore(ifs, v1, swap); IO::restore(ifs, vl, swap); IO::restore(ifs, vr, swap); PMInfo pminfo; pminfo.p0 = p; pminfo.v0 = mesh_.add_vertex(p); pminfo.v1 = Mesh::VertexHandle(v1); pminfo.vl = Mesh::VertexHandle(vl); pminfo.vr = Mesh::VertexHandle(vr); pminfos_.push_back(pminfo); node_handle = mesh_.vertex(pminfo.v1).vhierarchy_node_handle(); vhierarchy_.make_children(node_handle); lchild_handle = vhierarchy_.lchild_handle(node_handle); rchild_handle = vhierarchy_.rchild_handle(node_handle); mesh_.vertex(pminfo.v0).set_vhierarchy_node_handle(lchild_handle); mesh_.vertex(pminfo.v1).set_vhierarchy_node_handle(rchild_handle); vhierarchy_.node(lchild_handle).set_vertex_handle(pminfo.v0); vhierarchy_.node(rchild_handle).set_vertex_handle(pminfo.v1); } ifs.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -