📄 vdpmclientviewerwidget.cc
字号:
//== INCLUDES =================================================================
#ifdef _MSC_VER
# pragma warning(disable: 4267 4311)
#endif
#include <iostream>
#include <fstream>
#include <map>
#include <qapplication.h>
#include <qdatetime.h>
#include <qfiledialog.h>
#include <qdatastream.h>
#ifdef ARCH_DARWIN# include <glut.h>#else# include <GL/glut.h>#endif
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientViewerWidget.hh>
#include <OpenMesh/Core/IO/BinaryHelper.hh>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Utils/Endian.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
// #include "ImageData.h"
using OpenMesh::VDPM::debug_print;
using OpenMesh::VDPM::set_debug_print;
using OpenMesh::VDPM::VHierarchyNode;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::VHierarchyNodeHandleContainer;
#ifdef EXAMPLE_CREATION
static OpenMesh::Vec3uc myYellow = OpenMesh::Vec3uc(255, 255, 0);
static OpenMesh::Vec3uc myBlue = OpenMesh::Vec3uc(0, 0, 255);
std::map<VHierarchyNodeIndex, unsigned int> g_index2numdesc_map;
void VDPMClientViewerWidget::increase_max_descendents(const VHierarchyNodeIndex &_node_index)
{
g_index2numdesc_map[_node_index] = 2 + g_index2numdesc_map[_node_index];
unsigned char tree_id_bits = vhierarchy_.tree_id_bits();
VHierarchyNodeIndex parent_index
= VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), _node_index.node_id(tree_id_bits) / 2, tree_id_bits);
if (parent_index.is_valid(tree_id_bits) == true)
increase_max_descendents(parent_index);
}
void VDPMClientViewerWidget::increase_cur_descendents(VHierarchyNodeHandle _node_handle)
{
unsigned int cur_desc = vhierarchy_.node(_node_handle).cur_descendents();
vhierarchy_.node(_node_handle).set_cur_descendents(2 + cur_desc);
VHierarchyNodeHandle parent_handle = vhierarchy_.parent_handle(_node_handle);
if (parent_handle.is_valid())
increase_cur_descendents(parent_handle);
}
void VDPMClientViewerWidget::__add_children(const VHierarchyNodeIndex &_node_index, bool update_current)
{
if (update_current == true)
{
increase_cur_descendents(vhierarchy_.node_handle(_node_index));
}
else
{
unsigned char tree_id_bits = vhierarchy_.tree_id_bits();
VHierarchyNodeIndex lchild_index
= VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), 2*_node_index.node_id(tree_id_bits), tree_id_bits);
VHierarchyNodeIndex rchild_index
= VHierarchyNodeIndex(_node_index.tree_id(tree_id_bits), 1+2*_node_index.node_id(tree_id_bits), tree_id_bits);
g_index2numdesc_map[lchild_index] = 1;
g_index2numdesc_map[rchild_index] = 1;
increase_max_descendents(_node_index);
}
}
void VDPMClientViewerWidget::mesh_coloring()
{
MyMesh::VertexIter vIt(mesh_.vertices_begin()),
vEnd(mesh_.vertices_end());
VHierarchyNodeHandle node_handle;
float ratio;
unsigned char r, g, b;
for (; vIt!=vEnd; ++vIt)
{
node_handle = mesh_.vertex(vIt.handle()).vhierarchy_node_handle();
ratio = vhierarchy_.node(node_handle).ratio();
r = (unsigned char) ((1.0f - ratio) * myYellow[0] + ratio * myBlue[0]);
g = (unsigned char) ((1.0f - ratio) * myYellow[1] + ratio * myBlue[1]);
b = (unsigned char) ((1.0f - ratio) * myYellow[2] + ratio * myBlue[2]);
mesh_.set_color(vIt.handle(), OpenMesh::Vec3uc(r,g,b));
}
}
#endif
void
VDPMClientViewerWidget::
draw_scene(const std::string &_draw_mode)
{
//std::cout << frame_ << "-th frame statistics" << std::endl;
if (adaptive_mode_ == true)
{
refinement_timer_.start();
adaptive_refinement();
refinement_timer_.stop();
fprintf(refinement_file, "%d %d\n", frame_, (int) refinement_timer_.mseconds());
#ifdef EXAMPLE_CREATION
mesh_coloring();
#endif
}
render_timer_.start();
MeshViewerWidget::draw_scene(_draw_mode);
render_timer_.stop();
fprintf(render_file, "%d %d %d\n", frame_, (int) render_timer_.mseconds(), mesh_.n_faces());
++frame_;
}
void
VDPMClientViewerWidget::
adaptive_refinement()
{
update_viewing_parameters();
MyMesh::HalfedgeHandle v0v1;
float fovy = viewing_parameters_.fovy();
float tolerance_square = viewing_parameters_.tolerance_square();
float tan_value = tanf(fovy / 2.0f);
kappa_square_ = 4.0f * tan_value * tan_value * tolerance_square;
for (vfront_.begin(); vfront_.end() != true;)
{
VHierarchyNodeHandle
node_handle = vfront_.node_handle(),
parent_handle = vhierarchy_.parent_handle(node_handle);
if (qrefine(node_handle) == true)
{
if (vhierarchy_.is_leaf_node(node_handle) != true)
{
force_vsplit(node_handle);
}
else
{
//if (qSocket_->bytesAvailable() == 0)
if (session_running_ != true)
{
session_running_ = true;
send_viewing_information();
}
vfront_.next();
}
}
else if (vhierarchy_.is_root_node(node_handle) != true &&
ecol_legal(parent_handle, v0v1) == true &&
qrefine(parent_handle) != true)
{
ecol(parent_handle, v0v1);
}
else
{
vfront_.next();
}
}
// free memories taged as 'deleted'
mesh_.garbage_collection(false, true, true);
mesh_.update_face_normals();
}
void
VDPMClientViewerWidget::
current_max_resolution()
{
for (vfront_.begin(); vfront_.end() != true;)
{
VHierarchyNodeHandle
node_handle = vfront_.node_handle();
if (vhierarchy_.is_leaf_node(node_handle) != true)
force_vsplit(node_handle);
else
vfront_.next();
}
// free memories taged as 'deleted'
mesh_.garbage_collection(false, true, true);
mesh_.update_face_normals();
}
bool
VDPMClientViewerWidget::
qrefine(VHierarchyNodeHandle _node_handle)
{
VHierarchyNode &node = vhierarchy_.node(_node_handle);
OpenMesh::Vec3f p = mesh_.point(node.vertex_handle());
OpenMesh::Vec3f eye_dir = p - viewing_parameters_.eye_pos();
float distance = eye_dir.length();
float distance2 = distance * distance;
float product_value = dot(eye_dir, node.normal());
if (outside_view_frustum(p, node.radius()) == true)
return false;
if (oriented_away(node.sin_square(), distance2, product_value) == true)
return false;
if (screen_space_error(node.mue_square(),
node.sigma_square(), distance2, product_value) == true)
return false;
return true;
}
void
VDPMClientViewerWidget::
force_vsplit(VHierarchyNodeHandle node_handle)
{
MyMesh::VertexHandle vl, vr;
get_active_cuts(node_handle, vl, vr);
while (vl == vr) {
force_vsplit(mesh_.vertex(vl).vhierarchy_node_handle());
get_active_cuts(node_handle, vl, vr);
}
vsplit(node_handle, vl, vr);
}
void
VDPMClientViewerWidget::
vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr)
{
// refine
VHierarchyNodeHandle lchild_handle = vhierarchy_.lchild_handle(_node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_.rchild_handle(_node_handle);
MyMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
MyMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
mesh_.vertex_split(v0, v1, vl, vr);
mesh_.set_normal(v0, vhierarchy_.normal(lchild_handle));
mesh_.set_normal(v1, vhierarchy_.normal(rchild_handle));
mesh_.vertex(v0).set_vhierarchy_node_handle(lchild_handle);
mesh_.vertex(v1).set_vhierarchy_node_handle(rchild_handle);
mesh_.status(v0).set_deleted(false);
mesh_.status(v1).set_deleted(false);
vfront_.remove(_node_handle);
vfront_.add(lchild_handle);
vfront_.add(rchild_handle);
}
void
VDPMClientViewerWidget::
ecol(VHierarchyNodeHandle _node_handle, const MyMesh::HalfedgeHandle& v0v1)
{
VHierarchyNodeHandle lchild_handle = vhierarchy_.lchild_handle(_node_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_.rchild_handle(_node_handle);
MyMesh::VertexHandle v0 = vhierarchy_.vertex_handle(lchild_handle);
MyMesh::VertexHandle v1 = vhierarchy_.vertex_handle(rchild_handle);
// coarsen
mesh_.collapse(v0v1);
mesh_.set_normal(v1, vhierarchy_.normal(_node_handle));
mesh_.vertex(v0).set_vhierarchy_node_handle(lchild_handle);
mesh_.vertex(v1).set_vhierarchy_node_handle(_node_handle);
mesh_.status(v0).set_deleted(false);
mesh_.status(v1).set_deleted(false);
vfront_.add(_node_handle);
vfront_.remove(lchild_handle);
vfront_.remove(rchild_handle);
}
bool
VDPMClientViewerWidget::
ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1)
{
VHierarchyNodeHandle lchild_handle = vhierarchy_.lchild_handle(_parent_handle);
VHierarchyNodeHandle rchild_handle = vhierarchy_.rchild_handle(_parent_handle);
// test whether lchild & rchild present in the current vfront
if (vfront_.is_active(lchild_handle) != true || vfront_.is_active(rchild_handle) != true)
return false;
MyMesh::VertexHandle v0, v1;
v0 = vhierarchy_.vertex_handle(lchild_handle);
v1 = vhierarchy_.vertex_handle(rchild_handle);
v0v1 = mesh_.find_halfedge(v0, v1);
return mesh_.is_collapse_ok(v0v1);
}
void
VDPMClientViewerWidget::
get_active_cuts(const VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr)
{
MyMesh::VertexVertexIter vv_it;
VHierarchyNodeHandle nnode_handle;
VHierarchyNodeIndex nnode_index;
VHierarchyNodeIndex fund_lcut_index = vhierarchy_.fund_lcut_index(_node_handle);
VHierarchyNodeIndex fund_rcut_index = vhierarchy_.fund_rcut_index(_node_handle);
vl = MyMesh::InvalidVertexHandle;
vr = MyMesh::InvalidVertexHandle;
for (vv_it=mesh_.vv_iter(vhierarchy_.vertex_handle(_node_handle)); vv_it; ++vv_it)
{
nnode_handle = mesh_.vertex(vv_it.handle()).vhierarchy_node_handle();
nnode_index = vhierarchy_.node_index(nnode_handle);
if (vl == MyMesh::InvalidVertexHandle && vhierarchy_.is_ancestor(nnode_index, fund_lcut_index) == true)
vl = vv_it.handle();
if (vr == MyMesh::InvalidVertexHandle && vhierarchy_.is_ancestor(nnode_index, fund_rcut_index) == true)
vr = vv_it.handle();
/*if (vl == MyMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_lcut_index) == true)
vl = vv_it.handle();
if (vr == MyMesh::InvalidVertexHandle && nnode_index.is_ancestor_index(fund_rcut_index) == true)
vr = vv_it.handle();*/
if (vl != MyMesh::InvalidVertexHandle && vr != MyMesh::InvalidVertexHandle)
break;
}
}
bool
VDPMClientViewerWidget::
outside_view_frustum(const OpenMesh::Vec3f &pos, float radius)
{
Plane3d frustum_plane[4];
viewing_parameters_.frustum_planes(frustum_plane);
for (int i = 0; i < 4; i++) {
if (frustum_plane[i].signed_distance(pos) < -radius)
return true;
}
return false;
}
bool
VDPMClientViewerWidget::
oriented_away(float sin_square, float distance_square, float product_value)
{
if (product_value > 0 && product_value*product_value > distance_square * sin_square)
return true;
else
return false;
}
bool
VDPMClientViewerWidget::
screen_space_error(float mue_square, float sigma_square, float distance_square, float product_value)
{
if ((mue_square >= kappa_square_ * distance_square) ||
(sigma_square * (distance_square - product_value * product_value) >= kappa_square_ * distance_square * distance_square))
return false;
else
return true;
}
void
VDPMClientViewerWidget::
open_vd_prog_mesh(const char* _filename)
{
unsigned int i;
unsigned int value;
unsigned int fvi[3];
char fileformat[16];
OpenMesh::Vec3f p, normal;
float radius, sin_square, mue_square, sigma_square;
VHierarchyNodeHandleContainer roots;
OpenMesh::VertexHandle vertex_handle;
VHierarchyNodeIndex node_index, fund_lcut_index, fund_rcut_index;
VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle;
std::map<VHierarchyNodeIndex, VHierarchyNodeHandle> index2handle_map;
std::ifstream ifs(_filename, std::ios::binary);
if (!ifs)
{
std::cerr << "read error\n";
exit(1);
}
//
bool swap = OpenMesh::Endian::local() != OpenMesh::Endian::LSB;
// read header
ifs.read(fileformat, 10); fileformat[10] = '\0';
if (std::string(fileformat) != std::string("VDProgMesh"))
{
std::cerr << "Wrong file format.\n";
ifs.close();
exit(1);
}
OpenMesh::IO::restore(ifs, n_base_vertices_, swap);
OpenMesh::IO::restore(ifs, n_base_faces_, swap);
OpenMesh::IO::restore(ifs, n_details_, swap);
mesh_.clear();
vfront_.clear();
vhierarchy_.clear();
vhierarchy_.set_num_roots(n_base_vertices_);
// load base mesh
for (i=0; i<n_base_vertices_; ++i)
{
OpenMesh::IO::restore(ifs, p, swap);
OpenMesh::IO::restore(ifs, radius, swap);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -