📄 vdpmanalyzer.cc
字号:
// recover mapping between basemesh vertices to roots of vertex hierarchy for (i=0; i<n_base_vertices_; ++i) { node_handle = vhierarchy_.root_handle(i); vertex_handle = vhierarchy_.node(node_handle).vertex_handle(); mesh_.vertex(vertex_handle).set_vhierarchy_node_handle(node_handle); } pmiter_ = pminfos_.begin(); n_current_res_ = 0; n_max_res_ = n_details_; // update face and vertex normals mesh_.update_face_normals(); mesh_.update_vertex_normals(); // bounding box Mesh::ConstVertexIter vIt(mesh_.vertices_begin()), vEnd(mesh_.vertices_end()); Mesh::Point bbMin, bbMax; bbMin = bbMax = mesh_.point(vIt); for (; vIt!=vEnd; ++vIt) { bbMin.minimize(mesh_.point(vIt)); bbMax.maximize(mesh_.point(vIt)); } // info std::cerr << mesh_.n_vertices() << " vertices, " << mesh_.n_edges() << " edge, " << mesh_.n_faces() << " faces, " << n_details_ << " detail vertices\n";}// ----------------------------------------------------------------------------voidsave_vd_prog_mesh(const std::string &_filename){ unsigned i; int fvi[3]; Mesh::Point p; Vec3f normal; float radius, sin_square, mue_square, sigma_square; Mesh::FaceIter f_it; Mesh::HalfedgeHandle hh; Mesh::VertexHandle vh; VHierarchyNodeIndex node_index; VHierarchyNodeIndex fund_lcut_index, fund_rcut_index; VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle; std::map<VertexHandle, unsigned int> handle2index_map; std::ofstream ofs(_filename.c_str(), std::ios::binary); if (!ofs) { std::cerr << "write error\n"; exit(1); } // bool swap = Endian::local() != Endian::LSB; // write header ofs << "VDProgMesh"; IO::store(ofs, n_base_vertices_, swap); IO::store(ofs, n_base_faces_, swap); IO::store(ofs, n_details_, swap); // write base mesh coarsen(0); mesh_.garbage_collection( false, true, true ); for (i=0; i<n_base_vertices_; ++i) { node_handle = vhierarchy_.root_handle(i); vh = vhierarchy_.node(node_handle).vertex_handle(); p = mesh_.point(vh); radius = vhierarchy_.node(node_handle).radius(); normal = vhierarchy_.node(node_handle).normal(); sin_square = vhierarchy_.node(node_handle).sin_square(); mue_square = vhierarchy_.node(node_handle).mue_square(); sigma_square = vhierarchy_.node(node_handle).sigma_square(); IO::store(ofs, p, swap); IO::store(ofs, radius, swap); IO::store(ofs, normal, swap); IO::store(ofs, sin_square, swap); IO::store(ofs, mue_square, swap); IO::store(ofs, sigma_square, swap); handle2index_map[vh] = i; } for (f_it=mesh_.faces_begin(); f_it!=mesh_.faces_end(); ++f_it) { hh = mesh_.halfedge_handle(f_it.handle()); vh = mesh_.to_vertex_handle(hh); fvi[0] = handle2index_map[vh]; hh = mesh_.next_halfedge_handle(hh); vh = mesh_.to_vertex_handle(hh); fvi[1] = handle2index_map[vh]; hh = mesh_.next_halfedge_handle(hh); vh = mesh_.to_vertex_handle(hh); fvi[2] = handle2index_map[vh]; IO::store(ofs, fvi[0], swap); IO::store(ofs, fvi[1], swap); IO::store(ofs, fvi[2], swap); } // write progressive detail (vertex hierarchy) for (i=0; i<n_details_; ++i) { PMInfo pminfo = *pmiter_; p = mesh_.point(pminfo.v0); IO::store(ofs, p, swap); node_handle = mesh_.vertex(pminfo.v1).vhierarchy_node_handle(); lchild_handle = vhierarchy_.lchild_handle(node_handle); rchild_handle = vhierarchy_.rchild_handle(node_handle); node_index = vhierarchy_.node(node_handle).node_index(); fund_lcut_index = vhierarchy_.node(node_handle).fund_lcut_index(); fund_rcut_index = vhierarchy_.node(node_handle).fund_rcut_index(); IO::store(ofs, node_index.value(), swap); IO::store(ofs, fund_lcut_index.value(), swap); IO::store(ofs, fund_rcut_index.value(), swap); radius = vhierarchy_.node(lchild_handle).radius(); normal = vhierarchy_.node(lchild_handle).normal(); sin_square = vhierarchy_.node(lchild_handle).sin_square(); mue_square = vhierarchy_.node(lchild_handle).mue_square(); sigma_square = vhierarchy_.node(lchild_handle).sigma_square(); IO::store(ofs, radius, swap); IO::store(ofs, normal, swap); IO::store(ofs, sin_square, swap); IO::store(ofs, mue_square, swap); IO::store(ofs, sigma_square, swap); radius = vhierarchy_.node(rchild_handle).radius(); normal = vhierarchy_.node(rchild_handle).normal(); sin_square = vhierarchy_.node(rchild_handle).sin_square(); mue_square = vhierarchy_.node(rchild_handle).mue_square(); sigma_square = vhierarchy_.node(rchild_handle).sigma_square(); IO::store(ofs, radius, swap); IO::store(ofs, normal, swap); IO::store(ofs, sin_square, swap); IO::store(ofs, mue_square, swap); IO::store(ofs, sigma_square, swap); refine(i); } ofs.close(); std::cout << "save view-dependent progressive mesh" << std::endl;}//-----------------------------------------------------------------------------void refine(unsigned int _n){ while (n_current_res_ < _n && pmiter_ != pminfos_.end()) { mesh_.vertex_split(pmiter_->v0, pmiter_->v1, pmiter_->vl, pmiter_->vr); VHierarchyNodeHandle parent_handle = mesh_.vertex(pmiter_->v1).vhierarchy_node_handle(); VHierarchyNodeHandle lchild_handle = vhierarchy_.lchild_handle(parent_handle), rchild_handle = vhierarchy_.rchild_handle(parent_handle); mesh_.vertex(pmiter_->v0).set_vhierarchy_node_handle(lchild_handle); mesh_.vertex(pmiter_->v1).set_vhierarchy_node_handle(rchild_handle); ++pmiter_; ++n_current_res_; }}//-----------------------------------------------------------------------------void coarsen(unsigned int _n){ while (n_current_res_ > _n && pmiter_ != pminfos_.begin()) { --pmiter_; Mesh::HalfedgeHandle hh = mesh_.find_halfedge(pmiter_->v0, pmiter_->v1); mesh_.collapse(hh); VHierarchyNodeHandle rchild_handle = mesh_.vertex(pmiter_->v1).vhierarchy_node_handle(); VHierarchyNodeHandle parent_handle = vhierarchy_.parent_handle(rchild_handle); mesh_.vertex(pmiter_->v1).set_vhierarchy_node_handle(parent_handle); --n_current_res_; }}//-----------------------------------------------------------------------------void vdpm_analysis(){ unsigned int i; Mesh::VertexHandle vh; Mesh::VertexIter v_it; Mesh::HalfedgeIter h_it; Mesh::HalfedgeHandle h, o, hn, op, hpo, on, ono; VHierarchyNodeHandleContainer leaf_nodes; OpenMesh::Utils::Timer tana; tana.start(); refine(n_max_res_); mesh_.update_face_normals(); mesh_.update_vertex_normals(); std::cout << "Init view-dependent PM analysis" << std::endl; // initialize for (h_it=mesh_.halfedges_begin(); h_it!=mesh_.halfedges_end(); ++h_it) { vh = mesh_.to_vertex_handle(h_it.handle()); h_it->set_vhierarchy_leaf_node_handle(mesh_.vertex(vh).vhierarchy_node_handle()); } for (v_it=mesh_.vertices_begin(); v_it!=mesh_.vertices_end(); ++v_it) { VHierarchyNodeHandle node_handle = mesh_.vertex(v_it.handle()).vhierarchy_node_handle(); vhierarchy_.node(node_handle).set_normal(mesh_.normal(v_it.handle())); } std::cout << "Start view-dependent PM analysis" << std::endl; // locate fundamental cut vertices in each edge collapse OpenMesh::Utils::Timer t; for (i=n_max_res_; i>0; --i) { t.start(); PMInfo pminfo = pminfos_[i-1]; if (verbose) std::cout << "Analyzing " << i << "-th detail vertex" << std::endl; // maintain leaf node pointers & locate fundamental cut vertices h = mesh_.find_halfedge(pminfo.v0, pminfo.v1); o = mesh_.opposite_halfedge_handle(h); hn = mesh_.next_halfedge_handle(h); hpo = mesh_.opposite_halfedge_handle(mesh_.prev_halfedge_handle(h)); op = mesh_.prev_halfedge_handle(o); on = mesh_.next_halfedge_handle(o); ono = mesh_.opposite_halfedge_handle(on); VHierarchyNodeHandle rchild_handle = mesh_.vertex(pminfo.v1).vhierarchy_node_handle(); VHierarchyNodeHandle parent_handle = vhierarchy_.parent_handle(rchild_handle); if (pminfo.vl != Mesh::InvalidVertexHandle) { VHierarchyNodeHandle fund_lcut_handle = mesh_.halfedge(hn).vhierarchy_leaf_node_handle(); VHierarchyNodeHandle left_leaf_handle = mesh_.halfedge(hpo).vhierarchy_leaf_node_handle(); mesh_.halfedge(hn).set_vhierarchy_leaf_node_handle(left_leaf_handle); vhierarchy_.node(parent_handle). set_fund_lcut(vhierarchy_.node_index(fund_lcut_handle)); } if (pminfo.vr != Mesh::InvalidVertexHandle) { VHierarchyNodeHandle fund_rcut_handle = mesh_.halfedge(on).vhierarchy_leaf_node_handle(), right_leaf_handle = mesh_.halfedge(ono).vhierarchy_leaf_node_handle(); mesh_.halfedge(op).set_vhierarchy_leaf_node_handle(right_leaf_handle); vhierarchy_.node(parent_handle). set_fund_rcut(vhierarchy_.node_index(fund_rcut_handle)); } coarsen(i-1); leaf_nodes.clear(); get_leaf_node_handles(parent_handle, leaf_nodes); compute_bounding_box(parent_handle, leaf_nodes); compute_cone_of_normals(parent_handle, leaf_nodes); compute_screen_space_error(parent_handle, leaf_nodes); t.stop(); if (verbose) { std::cout << " radius of bounding sphere: " << vhierarchy_.node(parent_handle).radius() << std::endl; std::cout << " direction of cone of normals: " << vhierarchy_.node(parent_handle).normal() << std::endl; std::cout << " sin(semi-angle of cone of normals) ^2: " << vhierarchy_.node(parent_handle).sin_square() << std::endl; std::cout << " (mue^2, sigma^2) : (" << vhierarchy_.node(parent_handle).mue_square() << ", " << vhierarchy_.node(parent_handle).sigma_square() << ")" << std::endl; std::cout << "- " << t.as_string() << std::endl; } } // end for all collapses tana.stop(); std::cout << "Analyzing step completed in " << tana.as_string() << std::endl;}// ----------------------------------------------------------------------------void get_leaf_node_handles(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes){ if (vhierarchy_.node(node_handle).is_leaf()) { leaf_nodes.push_back(node_handle); } else { get_leaf_node_handles(vhierarchy_.node(node_handle).lchild_handle(), leaf_nodes); get_leaf_node_handles(vhierarchy_.node(node_handle).rchild_handle(), leaf_nodes); }}// ----------------------------------------------------------------------------void compute_bounding_box(VHierarchyNodeHandle node_handle, VHierarchyNodeHandleContainer &leaf_nodes){ float max_distance; Vec3f p, lp; VHierarchyNodeHandleContainer::iterator n_it, n_end(leaf_nodes.end()); max_distance = 0.0f; VertexHandle vh = vhierarchy_.node(node_handle).vertex_handle(); p = mesh_.point(vh); for ( n_it = leaf_nodes.begin(); n_it != n_end; ++n_it ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -