git-svn-id: http://www.openmesh.org/svnrepo/OpenMesh/trunk@58 fdac6126-5c0c-442c-9429-916003d36597
1341 lines
41 KiB
C++
1341 lines
41 KiB
C++
|
|
//== 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>
|
|
#include <GL/glut.h>
|
|
|
|
|
|
#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_.data(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(),
|
|
parent_handle = vhierarchy_.parent_handle(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_.data(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_.data(v0).set_vhierarchy_node_handle(lchild_handle);
|
|
mesh_.data(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_.data(v0).set_vhierarchy_node_handle(lchild_handle);
|
|
mesh_.data(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_.data(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, lchild_node_index, rchild_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);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, 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_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
|
|
|
|
vhierarchy_.node(node_handle).set_radius(radius);
|
|
vhierarchy_.node(node_handle).set_normal(normal);
|
|
vhierarchy_.node(node_handle).set_sin_square(sin_square);
|
|
vhierarchy_.node(node_handle).set_mue_square(mue_square);
|
|
vhierarchy_.node(node_handle).set_sigma_square(sigma_square);
|
|
mesh_.set_normal(vertex_handle, normal);
|
|
|
|
index2handle_map[node_index] = node_handle;
|
|
roots.push_back(node_handle);
|
|
}
|
|
vfront_.init(roots, n_details_);
|
|
|
|
for (i=0; i<n_base_faces_; ++i)
|
|
{
|
|
OpenMesh::IO::restore(ifs, fvi[0], swap);
|
|
OpenMesh::IO::restore(ifs, fvi[1], swap);
|
|
OpenMesh::IO::restore(ifs, fvi[2], swap);
|
|
|
|
mesh_.add_face(mesh_.vertex_handle(fvi[0]),
|
|
mesh_.vertex_handle(fvi[1]),
|
|
mesh_.vertex_handle(fvi[2]));
|
|
}
|
|
|
|
// load details
|
|
for (i=0; i<n_details_; ++i)
|
|
{
|
|
// position of v0
|
|
OpenMesh::IO::restore(ifs, p, swap);
|
|
|
|
// vsplit info.
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
node_index = VHierarchyNodeIndex(value);
|
|
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
fund_lcut_index = VHierarchyNodeIndex(value);
|
|
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
fund_rcut_index = VHierarchyNodeIndex(value);
|
|
|
|
node_handle = index2handle_map[node_index];
|
|
vhierarchy_.make_children(node_handle);
|
|
lchild_handle = vhierarchy_.node(node_handle).lchild_handle();
|
|
rchild_handle = vhierarchy_.node(node_handle).rchild_handle();
|
|
|
|
vhierarchy_.node(node_handle).set_fund_lcut(fund_lcut_index);
|
|
vhierarchy_.node(node_handle).set_fund_rcut(fund_rcut_index);
|
|
|
|
vertex_handle = mesh_.add_vertex(p);
|
|
vhierarchy_.node(lchild_handle).set_vertex_handle(vertex_handle);
|
|
vhierarchy_.node(rchild_handle).set_vertex_handle(vhierarchy_.node(node_handle).vertex_handle());
|
|
|
|
index2handle_map[vhierarchy_.node(lchild_handle).node_index()] = lchild_handle;
|
|
index2handle_map[vhierarchy_.node(rchild_handle).node_index()] = rchild_handle;
|
|
|
|
// view-dependent parameters
|
|
OpenMesh::IO::restore(ifs, radius, swap);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, swap);
|
|
|
|
vhierarchy_.node(lchild_handle).set_radius(radius);
|
|
vhierarchy_.node(lchild_handle).set_normal(normal);
|
|
vhierarchy_.node(lchild_handle).set_sin_square(sin_square);
|
|
vhierarchy_.node(lchild_handle).set_mue_square(mue_square);
|
|
vhierarchy_.node(lchild_handle).set_sigma_square(sigma_square);
|
|
|
|
|
|
OpenMesh::IO::restore(ifs, radius, swap);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, swap);
|
|
|
|
vhierarchy_.node(rchild_handle).set_radius(radius);
|
|
vhierarchy_.node(rchild_handle).set_normal(normal);
|
|
vhierarchy_.node(rchild_handle).set_sin_square(sin_square);
|
|
vhierarchy_.node(rchild_handle).set_mue_square(mue_square);
|
|
vhierarchy_.node(rchild_handle).set_sigma_square(sigma_square);
|
|
}
|
|
|
|
ifs.close();
|
|
|
|
// update face and vertex normals
|
|
mesh_.update_face_normals();
|
|
|
|
// bounding box
|
|
MyMesh::ConstVertexIter
|
|
vIt(mesh_.vertices_begin()),
|
|
vEnd(mesh_.vertices_end());
|
|
|
|
bbMin_ = bbMax_ = mesh_.point(vIt);
|
|
for (; vIt!=vEnd; ++vIt)
|
|
{
|
|
bbMin_.minimize(mesh_.point(vIt));
|
|
bbMax_.maximize(mesh_.point(vIt));
|
|
}
|
|
|
|
// set center and radius
|
|
set_scene_pos(0.5f*(bbMin_ + bbMax_), 0.5*(bbMin_ - bbMax_).norm());
|
|
|
|
// info
|
|
std::cerr << mesh_.n_vertices() << " vertices, "
|
|
<< mesh_.n_edges() << " edge, "
|
|
<< mesh_.n_faces() << " faces, "
|
|
<< n_details_ << " detail vertices\n";
|
|
|
|
updateGL();
|
|
}
|
|
|
|
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
open_vd_base_mesh(const char* _filename)
|
|
{
|
|
unsigned int i;
|
|
unsigned int fvi[3];
|
|
//int tree_id, node_id;
|
|
char fileformat[16];
|
|
OpenMesh::Vec3f p, normal;
|
|
float radius, sin_square, mue_square, sigma_square;
|
|
VHierarchyNodeHandleContainer roots;
|
|
OpenMesh::VertexHandle vertex_handle;
|
|
VHierarchyNodeIndex node_index, lchild_node_index, rchild_node_index, fund_lcut_index, fund_rcut_index;
|
|
VHierarchyNodeHandle node_handle, lchild_node_handle, rchild_node_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);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, 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_.data(vertex_handle).set_vhierarchy_node_handle(node_handle);
|
|
|
|
vhierarchy_.node(node_handle).set_radius(radius);
|
|
vhierarchy_.node(node_handle).set_normal(normal);
|
|
vhierarchy_.node(node_handle).set_sin_square(sin_square);
|
|
vhierarchy_.node(node_handle).set_mue_square(mue_square);
|
|
vhierarchy_.node(node_handle).set_sigma_square(sigma_square);
|
|
mesh_.set_normal(vertex_handle, normal);
|
|
|
|
index2handle_map[node_index] = node_handle;
|
|
roots.push_back(node_handle);
|
|
|
|
#ifdef EXAMPLE_CREATION
|
|
g_index2numdesc_map[node_index] = 1;
|
|
#endif
|
|
|
|
}
|
|
vfront_.init(roots, n_details_);
|
|
|
|
for (i=0; i<n_base_faces_; ++i)
|
|
{
|
|
OpenMesh::IO::restore(ifs, fvi[0], swap);
|
|
OpenMesh::IO::restore(ifs, fvi[1], swap);
|
|
OpenMesh::IO::restore(ifs, fvi[2], swap);
|
|
|
|
mesh_.add_face(mesh_.vertex_handle(fvi[0]),
|
|
mesh_.vertex_handle(fvi[1]),
|
|
mesh_.vertex_handle(fvi[2]));
|
|
}
|
|
|
|
|
|
|
|
#ifdef EXAMPLE_CREATION
|
|
int tree_id, node_id;
|
|
|
|
// load details
|
|
for (i=0; i<n_details_; ++i)
|
|
{
|
|
// position of v0
|
|
OpenMesh::IO::restore(ifs, p, swap);
|
|
|
|
// vsplit info.
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
node_index = vhierarchy_.generate_node_index(value);
|
|
|
|
// fundamental cut vertices
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
OpenMesh::IO::restore(ifs, value, swap);
|
|
|
|
// view-dependent parameters
|
|
OpenMesh::IO::restore(ifs, radius, swap);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, swap);
|
|
OpenMesh::IO::restore(ifs, radius, swap);
|
|
OpenMesh::IO::restore(ifs, normal, swap);
|
|
OpenMesh::IO::restore(ifs, sin_square, swap);
|
|
OpenMesh::IO::restore(ifs, mue_square, swap);
|
|
OpenMesh::IO::restore(ifs, sigma_square, swap);
|
|
|
|
__add_children(node_index, false);
|
|
}
|
|
|
|
// set max_descendents of root vertices
|
|
|
|
for (i=0; i<n_base_vertices_; ++i)
|
|
{
|
|
node_index = vhierarchy_.generate_node_index(i, 1);
|
|
VHierarchyNodeHandle node_handle = index2handle_map[node_index];
|
|
VertexHandle vh = vhierarchy_.node(node_handle).vertex_handle();
|
|
|
|
mesh_.set_color(vh, myYellow);
|
|
}
|
|
#endif
|
|
|
|
ifs.close();
|
|
|
|
// update face and vertex normals
|
|
mesh_.update_face_normals();
|
|
|
|
// bounding box
|
|
MyMesh::ConstVertexIter
|
|
vIt(mesh_.vertices_begin()),
|
|
vEnd(mesh_.vertices_end());
|
|
|
|
bbMin_ = bbMax_ = mesh_.point(vIt);
|
|
for (; vIt!=vEnd; ++vIt)
|
|
{
|
|
bbMin_.minimize(mesh_.point(vIt));
|
|
bbMax_.maximize(mesh_.point(vIt));
|
|
}
|
|
|
|
// set center and radius
|
|
set_scene_pos(0.5f*(bbMin_ + bbMax_), 0.5*(bbMin_ - bbMax_).norm());
|
|
|
|
save_views();
|
|
|
|
// info
|
|
std::cerr << mesh_.n_vertices() << " vertices, "
|
|
<< mesh_.n_edges() << " edge, "
|
|
<< mesh_.n_faces() << " faces, "
|
|
<< n_details_ << " detail vertices\n";
|
|
|
|
updateGL();
|
|
}
|
|
|
|
|
|
|
|
void VDPMClientViewerWidget::keyPressEvent(QKeyEvent* _event)
|
|
{
|
|
bool handled(false);
|
|
|
|
switch (_event->key())
|
|
{
|
|
case Key_Plus:
|
|
viewing_parameters_.increase_tolerance();
|
|
std::cout << "Scree-space error tolerance^2 is increased by "
|
|
<< viewing_parameters_.tolerance_square() << std::endl;
|
|
updateGL();
|
|
break;
|
|
|
|
case Key_Minus:
|
|
viewing_parameters_.decrease_tolerance();
|
|
std::cout << "Screen-space error tolerance^2 is decreased by "
|
|
<< viewing_parameters_.tolerance_square() << std::endl;
|
|
updateGL();
|
|
break;
|
|
|
|
case Key_A:
|
|
adaptive_mode_ = !(adaptive_mode_);
|
|
std::cout << "Adaptive refinement mode is "
|
|
<< ((adaptive_mode_ == true) ? "on" : "off") << std::endl;
|
|
updateGL();
|
|
break;
|
|
|
|
case Key_D:
|
|
set_debug_print(!debug_print());
|
|
break;
|
|
|
|
case Key_O:
|
|
qFilename_ = QFileDialog::getOpenFileName("d:/data/models/spm/", "*.spm");
|
|
open_vd_base_mesh(qFilename_);
|
|
break;
|
|
|
|
case Key_BracketLeft:
|
|
max_transmitted_datasize_ -= 10000;
|
|
std::cout << "Max transmitted data: " << max_transmitted_datasize_ << std::endl;
|
|
break;
|
|
|
|
case Key_BracketRight:
|
|
max_transmitted_datasize_ += 10000;
|
|
std::cout << "Max transmitted data: " << max_transmitted_datasize_ << std::endl;
|
|
break;
|
|
|
|
case Key_Space:
|
|
memcpy(reserved_modelview_matrix_, modelview_matrix(), 16*sizeof(GLdouble));
|
|
memcpy(reserved_projection_matrix_, projection_matrix(), 16*sizeof(GLdouble));
|
|
std::cout << "Reserving current view-point" << std::endl;
|
|
break;
|
|
|
|
case Key_R:
|
|
request_base_mesh();
|
|
break;
|
|
|
|
case Key_S:
|
|
save_views();
|
|
std::cout << "Saving view-points" << std::endl;
|
|
break;
|
|
|
|
case Key_F:
|
|
frame_ = 0;
|
|
std::cout << "Frame is set to 0" << std::endl;
|
|
break;
|
|
|
|
case Key_M:
|
|
adaptive_mode_ = false;
|
|
current_max_resolution();
|
|
updateGL();
|
|
std::cout << "Current max resolution mesh" << std::endl;
|
|
break;
|
|
|
|
case Key_V:
|
|
vd_streaming_ = !(vd_streaming_);
|
|
if (vd_streaming_)
|
|
std::cout << "View-dependent streaing mode" << std::endl;
|
|
else
|
|
std::cout << "Sequential streaming mode" << std::endl;
|
|
break;
|
|
|
|
case Key_C:
|
|
adaptive_mode_ = false;
|
|
qCameraFileName_ = QFileDialog::getOpenFileName("./", "*.cmr");
|
|
load_views(qCameraFileName_);
|
|
std::cout << "Loading view-points" << std::endl;
|
|
updateGL();
|
|
break;
|
|
|
|
case Key_9:
|
|
save_screen(true);
|
|
break;
|
|
|
|
case Key_0:
|
|
std::cout << "#faces: " << mesh_.n_faces() << std::endl;
|
|
break;
|
|
|
|
case Key_P:
|
|
if (qAnimationTimer_->isActive())
|
|
{
|
|
qAnimationTimer_->stop();
|
|
std::cout << "print_statistics mode is stopped!" << std::endl;
|
|
}
|
|
else
|
|
{
|
|
qAnimationTimer_->start(0, true);
|
|
std::cout << "print_statistics mode is started!" << std::endl;
|
|
|
|
adaptive_mode_ = true;
|
|
|
|
set_scene_pos(
|
|
Vec3f(0.5f*(bbMin_[0] + bbMax_[0]), 0.9f*bbMax_[1], 0.5f*(bbMin_[2] + bbMax_[2])),
|
|
0.15f*(bbMin_ - bbMax_).norm());
|
|
nth_viewpoint_ = 0;
|
|
print_statistics();
|
|
}
|
|
std::cout << "Frame: " << frame_ << std::endl;
|
|
break;
|
|
|
|
|
|
case Key_L:
|
|
if (qAnimationTimer_->isActive())
|
|
{
|
|
qAnimationTimer_->stop();
|
|
std::cout << "look_around mode is stopped!" << std::endl;
|
|
}
|
|
else
|
|
{
|
|
qAnimationTimer_->start(0, true);
|
|
std::cout << "look_around mode is started!" << std::endl;
|
|
|
|
adaptive_mode_ = true;
|
|
|
|
set_scene_pos(
|
|
Vec3f(0.5f*(bbMin_[0] + bbMax_[0]), 0.9f*bbMax_[1], 0.5f*(bbMin_[2] + bbMax_[2])),
|
|
0.15f*(bbMin_ - bbMax_).norm());
|
|
frame_ = 0;
|
|
nth_viewpoint_ = 0;
|
|
look_around();
|
|
}
|
|
|
|
break;
|
|
|
|
case Key_Q:
|
|
case Key_Escape:
|
|
qApp->quit();
|
|
|
|
default:
|
|
this->MeshViewerWidget::keyPressEvent( _event );
|
|
}
|
|
|
|
if (!handled)
|
|
_event->ignore();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
update_viewing_parameters()
|
|
{
|
|
viewing_parameters_.set_fovy(fovy());
|
|
viewing_parameters_.set_aspect((float) width() / (float) height());
|
|
viewing_parameters_.set_modelview_matrix(modelview_matrix());
|
|
|
|
viewing_parameters_.update_viewing_configurations();
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
// streaming related functions
|
|
/////////////////////////////////////////////////
|
|
|
|
|
|
|
|
bool
|
|
VDPMClientViewerWidget::
|
|
request_base_mesh()
|
|
{
|
|
if (streaming_phase_ != kBaseMesh)
|
|
return false;
|
|
|
|
if (qFilename_.isEmpty() == true)
|
|
{
|
|
std::cout << "Please, specify the base mesh filename." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
QDataStream qTcp(qSocket_);
|
|
|
|
qTcp << qFilename_.length();
|
|
qTcp << qFilename_;
|
|
qSocket_->flush();
|
|
|
|
return true;
|
|
}
|
|
|
|
bool
|
|
VDPMClientViewerWidget::
|
|
receive_base_mesh()
|
|
{
|
|
int status;
|
|
QDataStream qTcp(qSocket_);
|
|
|
|
while (qSocket_->waitForMore(10) < sizeof(int));
|
|
qTcp >> status;
|
|
if (status == 0)
|
|
{
|
|
std::cout << "There is no such a VDPM files in the server side." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
streaming_phase_ = kVSplitHeader;
|
|
|
|
std::cout << "A view-dependent streaming is ready." << std::endl;
|
|
return true;
|
|
}
|
|
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
send_viewing_information()
|
|
{
|
|
session_timer_.start();
|
|
QDataStream qTCP(qSocket_);
|
|
qTCP << modelview_matrix()[0] << modelview_matrix()[1]
|
|
<< modelview_matrix()[2] << modelview_matrix()[3]
|
|
<< modelview_matrix()[4] << modelview_matrix()[5]
|
|
<< modelview_matrix()[6] << modelview_matrix()[7]
|
|
<< modelview_matrix()[8] << modelview_matrix()[9]
|
|
<< modelview_matrix()[10] << modelview_matrix()[11]
|
|
<< modelview_matrix()[12] << modelview_matrix()[13]
|
|
<< modelview_matrix()[14] << modelview_matrix()[15]
|
|
<< viewing_parameters_.fovy()
|
|
<< viewing_parameters_.aspect()
|
|
<< viewing_parameters_.tolerance_square();
|
|
|
|
qSocket_->flush();
|
|
session_timer_.stop();
|
|
fprintf(session_file, "%d %d\n", frame_, (int) session_timer_.mseconds());
|
|
|
|
|
|
global_timer_.stop();
|
|
fprintf(uplink_file, "%d %ld\n", (int) global_timer_.mseconds(), 16*sizeof(double) + 3*sizeof(float));
|
|
global_timer_.cont();
|
|
}
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
receive_vsplit_header()
|
|
{
|
|
if (qSocket_->bytesAvailable() < sizeof(unsigned int))
|
|
return;
|
|
|
|
QDataStream qTcp(qSocket_);
|
|
|
|
// while (qSocket_->waitForMore(10) < sizeof(unsigned int));
|
|
|
|
qTcp >> n_vsplit_packets_;
|
|
|
|
if (n_vsplit_packets_ > 0)
|
|
{
|
|
streaming_phase_ = kVSplits;
|
|
|
|
if (debug_print() == true)
|
|
{
|
|
std::cout << "Server will transmit " << n_vsplit_packets_
|
|
<< " of vsplit packets to me" << std::endl;
|
|
}
|
|
|
|
receive_vsplit_packets();
|
|
}
|
|
else
|
|
{
|
|
session_running_ = false;
|
|
}
|
|
}
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
receive_vsplit_packets()
|
|
{
|
|
static unsigned int n_vsplits = 0;
|
|
static unsigned int len = (int) (17 * sizeof(float) + 3 * sizeof(int));
|
|
|
|
if (qSocket_->bytesAvailable() < len)
|
|
return;
|
|
|
|
QString str;
|
|
OpenMesh::Vec3f pos;
|
|
VHierarchyNodeIndex node_index, fund_lcut_index, fund_rcut_index;
|
|
float radius[2];
|
|
OpenMesh::Vec3f normal[2];
|
|
float sin_square[2];
|
|
float mue_square[2];
|
|
float sigma_square[2];
|
|
unsigned int value[3];
|
|
|
|
global_timer_.stop();
|
|
fprintf(downlink_file, "%d %ld\n", (int) global_timer_.mseconds(), qSocket_->bytesAvailable());
|
|
global_timer_.cont();
|
|
|
|
session_timer_.start();
|
|
|
|
while ( qSocket_->bytesAvailable() >= len )
|
|
{
|
|
if (vd_streaming_) transmitted_datasize_ += (int) len;
|
|
//if (vd_streaming_) transmitted_datasize_ += (int) 3*sizeof(int) + 3*sizeof(float); // only for non-refinement cliet
|
|
else transmitted_datasize_ += (int) 3*sizeof(int) + 3*sizeof(float);
|
|
|
|
if (max_transmitted_datasize_ > 0)
|
|
{
|
|
if (transmitted_datasize_ > max_transmitted_datasize_)
|
|
{
|
|
if (vd_streaming_) transmitted_datasize_ -= (int) len;
|
|
//if (vd_streaming_) transmitted_datasize_ -= (int) 3*sizeof(int) + 3*sizeof(float); // only for non-refinement cliet
|
|
else transmitted_datasize_ -= (int) 3*sizeof(int) + 3*sizeof(float);
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
QDataStream qTcp(qSocket_);
|
|
qTcp >> pos[0] >> pos[1] >> pos[2]
|
|
>> value[0]
|
|
>> value[1]
|
|
>> value[2]
|
|
>> radius[0]
|
|
>> (normal[0])[0] >> (normal[0])[1] >> (normal[0])[2]
|
|
>> sin_square[0]
|
|
>> mue_square[0] >> sigma_square[0]
|
|
>> radius[1]
|
|
>> (normal[1])[0] >> (normal[1])[1] >> (normal[1])[2]
|
|
>> sin_square[1]
|
|
>> mue_square[1] >> sigma_square[1];
|
|
|
|
node_index = VHierarchyNodeIndex(value[0]);
|
|
fund_lcut_index = VHierarchyNodeIndex(value[1]);
|
|
fund_rcut_index = VHierarchyNodeIndex(value[2]);
|
|
|
|
update_vhierarchy(pos,
|
|
node_index, fund_lcut_index, fund_rcut_index,
|
|
radius, normal, sin_square, mue_square, sigma_square);
|
|
|
|
|
|
std::cout << "transmitted datasize: " << transmitted_datasize_ << std::endl;
|
|
|
|
if (debug_print() == true)
|
|
{
|
|
std::cout << "Pkg #" << n_vsplits << std::endl;
|
|
}
|
|
|
|
++n_vsplits;
|
|
|
|
if (n_vsplits >= n_vsplit_packets_)
|
|
{
|
|
n_vsplits = 0;
|
|
streaming_phase_ = kVSplitHeader;
|
|
session_running_ = false;
|
|
|
|
if (debug_print() == true)
|
|
{
|
|
std::cout << "transmission of vsplit packets is complete" << std::endl;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
session_timer_.stop();
|
|
fprintf(session_file, "%d %d\n", frame_, (int) session_timer_.mseconds());
|
|
|
|
updateGL();
|
|
|
|
if (n_vsplits != n_vsplit_packets_)
|
|
qSessionTimer_->start(300, true);
|
|
}
|
|
|
|
|
|
void
|
|
VDPMClientViewerWidget::
|
|
update_vhierarchy(
|
|
const OpenMesh::Vec3f &_pos, // 3D position of v0
|
|
const VHierarchyNodeIndex &_node_index, // vhierarchy index of v1
|
|
const VHierarchyNodeIndex &_fund_lcut_index, // vhierarchy index of fundamental lcut
|
|
const VHierarchyNodeIndex &_fund_rcut_index, // vhierarchy index of fundamental rcut
|
|
const float _radius[2], // radius of lchild & rchild
|
|
const OpenMesh::Vec3f _normal[2], // normal of lchild & rchild
|
|
const float _sin_square[2], // sin_square of lchild & rchild
|
|
const float _mue_square[2], // mue_square of lchild & rchild
|
|
const float _sigma_square[2] // sigma_square of lchild & rchild
|
|
)
|
|
{
|
|
OpenMesh::VertexHandle vertex_handle;
|
|
VHierarchyNodeHandle node_handle, lchild_handle, rchild_handle;
|
|
|
|
node_handle = vhierarchy_.node_handle(_node_index);
|
|
vhierarchy_.make_children(node_handle);
|
|
|
|
|
|
lchild_handle = vhierarchy_.lchild_handle(node_handle);
|
|
rchild_handle = vhierarchy_.rchild_handle(node_handle);
|
|
|
|
vhierarchy_.node(node_handle).set_fund_lcut(_fund_lcut_index);
|
|
vhierarchy_.node(node_handle).set_fund_rcut(_fund_rcut_index);
|
|
|
|
vertex_handle = mesh_.add_vertex(_pos);
|
|
vhierarchy_.node(lchild_handle).set_vertex_handle(vertex_handle);
|
|
vhierarchy_.node(rchild_handle).set_vertex_handle(vhierarchy_.node(node_handle).vertex_handle());
|
|
|
|
vhierarchy_.node(lchild_handle).set_radius(_radius[0]);
|
|
vhierarchy_.node(lchild_handle).set_normal(_normal[0]);
|
|
vhierarchy_.node(lchild_handle).set_sin_square(_sin_square[0]);
|
|
vhierarchy_.node(lchild_handle).set_mue_square(_mue_square[0]);
|
|
vhierarchy_.node(lchild_handle).set_sigma_square(_sigma_square[0]);
|
|
|
|
vhierarchy_.node(rchild_handle).set_radius(_radius[1]);
|
|
vhierarchy_.node(rchild_handle).set_normal(_normal[1]);
|
|
vhierarchy_.node(rchild_handle).set_sin_square(_sin_square[1]);
|
|
vhierarchy_.node(rchild_handle).set_mue_square(_mue_square[1]);
|
|
vhierarchy_.node(rchild_handle).set_sigma_square(_sigma_square[1]);
|
|
|
|
#ifdef EXAMPLE_CREATION
|
|
__add_children(_node_index);
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////
|
|
// example related functions
|
|
/////////////////////////////////////////////////
|
|
|
|
void VDPMClientViewerWidget::save_views()
|
|
{
|
|
FILE *camera_file = fopen("camera.cmr", "w");
|
|
|
|
GLdouble current_modelview_matrix[16], current_projection_matrix[16];
|
|
|
|
memcpy(current_modelview_matrix, modelview_matrix(), 16*sizeof(GLdouble));
|
|
memcpy(current_projection_matrix, projection_matrix(), 16*sizeof(GLdouble));
|
|
|
|
|
|
fprintf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
current_modelview_matrix[0], current_modelview_matrix[1], current_modelview_matrix[2], current_modelview_matrix[3],
|
|
current_modelview_matrix[4], current_modelview_matrix[5], current_modelview_matrix[6], current_modelview_matrix[7],
|
|
current_modelview_matrix[8], current_modelview_matrix[9], current_modelview_matrix[10], current_modelview_matrix[11],
|
|
current_modelview_matrix[12], current_modelview_matrix[13], current_modelview_matrix[14], current_modelview_matrix[15]);
|
|
|
|
fprintf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
current_projection_matrix[0], current_projection_matrix[1], current_projection_matrix[2], current_projection_matrix[3],
|
|
current_projection_matrix[4], current_projection_matrix[5], current_projection_matrix[6], current_projection_matrix[7],
|
|
current_projection_matrix[8], current_projection_matrix[9], current_projection_matrix[10], current_projection_matrix[11],
|
|
current_projection_matrix[12], current_projection_matrix[13], current_projection_matrix[14], current_projection_matrix[15]);
|
|
|
|
|
|
fprintf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
reserved_modelview_matrix_[0], reserved_modelview_matrix_[1], reserved_modelview_matrix_[2], reserved_modelview_matrix_[3],
|
|
reserved_modelview_matrix_[4], reserved_modelview_matrix_[5], reserved_modelview_matrix_[6], reserved_modelview_matrix_[7],
|
|
reserved_modelview_matrix_[8], reserved_modelview_matrix_[9], reserved_modelview_matrix_[10], reserved_modelview_matrix_[11],
|
|
reserved_modelview_matrix_[12], reserved_modelview_matrix_[13], reserved_modelview_matrix_[14], reserved_modelview_matrix_[15]);
|
|
|
|
fprintf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
reserved_projection_matrix_[0], reserved_projection_matrix_[1], reserved_projection_matrix_[2], reserved_projection_matrix_[3],
|
|
reserved_projection_matrix_[4], reserved_projection_matrix_[5], reserved_projection_matrix_[6], reserved_projection_matrix_[7],
|
|
reserved_projection_matrix_[8], reserved_projection_matrix_[9], reserved_projection_matrix_[10], reserved_projection_matrix_[11],
|
|
reserved_projection_matrix_[12], reserved_projection_matrix_[13], reserved_projection_matrix_[14], reserved_projection_matrix_[15]);
|
|
|
|
fclose(camera_file);
|
|
}
|
|
|
|
|
|
void VDPMClientViewerWidget::load_views(const char *camera_filename)
|
|
{
|
|
FILE *camera_file = fopen(camera_filename, "r");
|
|
|
|
GLdouble current_modelview_matrix[16], current_projection_matrix[16];
|
|
|
|
|
|
fscanf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
&(current_modelview_matrix[0]), &(current_modelview_matrix[1]), &(current_modelview_matrix[2]), &(current_modelview_matrix[3]),
|
|
&(current_modelview_matrix[4]), &(current_modelview_matrix[5]), &(current_modelview_matrix[6]), &(current_modelview_matrix[7]),
|
|
&(current_modelview_matrix[8]), &(current_modelview_matrix[9]), &(current_modelview_matrix[10]), &(current_modelview_matrix[11]),
|
|
&(current_modelview_matrix[12]), &(current_modelview_matrix[13]), &(current_modelview_matrix[14]), &(current_modelview_matrix[15]));
|
|
|
|
|
|
fscanf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
&(current_projection_matrix[0]), &(current_projection_matrix[1]), &(current_projection_matrix[2]), &(current_projection_matrix[3]),
|
|
&(current_projection_matrix[4]), &(current_projection_matrix[5]), &(current_projection_matrix[6]), &(current_projection_matrix[7]),
|
|
&(current_projection_matrix[8]), &(current_projection_matrix[9]), &(current_projection_matrix[10]), &(current_projection_matrix[11]),
|
|
&(current_projection_matrix[12]), &(current_projection_matrix[13]), &(current_projection_matrix[14]), &(current_projection_matrix[15]));
|
|
|
|
|
|
fscanf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
&(reserved_modelview_matrix_[0]), &(reserved_modelview_matrix_[1]), &(reserved_modelview_matrix_[2]), &(reserved_modelview_matrix_[3]),
|
|
&(reserved_modelview_matrix_[4]), &(reserved_modelview_matrix_[5]), &(reserved_modelview_matrix_[6]), &(reserved_modelview_matrix_[7]),
|
|
&(reserved_modelview_matrix_[8]), &(reserved_modelview_matrix_[9]), &(reserved_modelview_matrix_[10]), &(reserved_modelview_matrix_[11]),
|
|
&(reserved_modelview_matrix_[12]), &(reserved_modelview_matrix_[13]), &(reserved_modelview_matrix_[14]), &(reserved_modelview_matrix_[15]));
|
|
|
|
|
|
fscanf(camera_file, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
|
|
&(reserved_projection_matrix_[0]), &(reserved_projection_matrix_[1]), &(reserved_projection_matrix_[2]), &(reserved_projection_matrix_[3]),
|
|
&(reserved_projection_matrix_[4]), &(reserved_projection_matrix_[5]), &(reserved_projection_matrix_[6]), &(reserved_projection_matrix_[7]),
|
|
&(reserved_projection_matrix_[8]), &(reserved_projection_matrix_[9]), &(reserved_projection_matrix_[10]), &(reserved_projection_matrix_[11]),
|
|
&(reserved_projection_matrix_[12]), &(reserved_projection_matrix_[13]), &(reserved_projection_matrix_[14]), &(reserved_projection_matrix_[15]));
|
|
|
|
fclose(camera_file);
|
|
|
|
set_modelview_matrix(current_modelview_matrix);
|
|
set_projection_matrix(current_projection_matrix);
|
|
|
|
adaptive_mode_ = false;
|
|
}
|
|
|
|
void VDPMClientViewerWidget::print_statistics()
|
|
{
|
|
const float angle = 360.0/(float)n_viewpoints_;
|
|
Vec3f axis = Vec3f(0,1,0);
|
|
Vec3f delta = Vec3f(0, 0.7f*(bbMin_[1] - bbMax_[1])/n_viewpoints_, 0);
|
|
|
|
rotate(axis, -angle);
|
|
set_scene_pos(center() + delta, 1.0f * radius() );
|
|
|
|
updateGL();
|
|
|
|
if (++nth_viewpoint_ < n_viewpoints_)
|
|
qAnimationTimer_->start(500, true);
|
|
}
|
|
|
|
void VDPMClientViewerWidget::look_around()
|
|
{
|
|
const float angle = 360.0/(float)n_viewpoints_;
|
|
Vec3f axis = Vec3f(0,1,0);
|
|
Vec3f delta = Vec3f(0, 0.7f*(bbMin_[1] - bbMax_[1])/n_viewpoints_, 0);
|
|
|
|
rotate(axis, -angle);
|
|
set_scene_pos(center() + delta, 1.0f * radius() );
|
|
|
|
updateGL();
|
|
|
|
save_screen(true);
|
|
|
|
if (++nth_viewpoint_ < n_viewpoints_)
|
|
qAnimationTimer_->start(3000, true);
|
|
}
|
|
|
|
|
|
void VDPMClientViewerWidget::save_screen(bool _flag)
|
|
{
|
|
setCursor( waitCursor );
|
|
|
|
if (_flag == true) // shot from the reserved view-point
|
|
{
|
|
GLdouble current_modelview_matrix[16];
|
|
GLdouble current_projection_matrix[16];
|
|
bool current_adaptive_mode = adaptive_mode_;
|
|
|
|
memcpy(current_modelview_matrix, modelview_matrix(), 16*sizeof(GLdouble));
|
|
memcpy(current_projection_matrix, projection_matrix(), 16*sizeof(GLdouble));
|
|
|
|
set_modelview_matrix(reserved_modelview_matrix_);
|
|
set_projection_matrix(reserved_projection_matrix_);
|
|
adaptive_mode_ = false;
|
|
|
|
updateGL();
|
|
|
|
// shot from the reserved view-point
|
|
char rfilename[256];
|
|
sprintf(rfilename, "rview%03d.bmp", nth_viewpoint_);
|
|
screen_capture(rfilename);
|
|
std::cout << "shot from the reserved view-point" << std::endl;
|
|
|
|
|
|
set_modelview_matrix(current_modelview_matrix);
|
|
set_projection_matrix(current_projection_matrix);
|
|
adaptive_mode_ = current_adaptive_mode;
|
|
}
|
|
|
|
updateGL();
|
|
|
|
// shot from the current view-point
|
|
char cfilename[256];
|
|
sprintf(cfilename, "cview%03d.bmp", nth_viewpoint_);
|
|
screen_capture(cfilename);
|
|
std::cout << "shot from the current view-point" << std::endl;
|
|
|
|
|
|
setCursor( pointingHandCursor );
|
|
}
|
|
|
|
void VDPMClientViewerWidget::screen_capture(const char * /* _filename */)
|
|
{
|
|
// CImageData image(width(), height());
|
|
|
|
// glReadBuffer(GL_BACK);
|
|
// glReadPixels(0, 0, width(), height(), GL_RGB, GL_UNSIGNED_BYTE, (GLvoid*) image.rgbMap());
|
|
|
|
// image.SaveBMP(_filename, width(), height());
|
|
}
|
|
|