/*===========================================================================*\ * * * OpenMesh * * Copyright (C) 2001-2012 by Computer Graphics Group, RWTH Aachen * * www.openmesh.org * * * *---------------------------------------------------------------------------* * This file is part of OpenMesh. * * * * OpenMesh is free software: you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version with the * * following exceptions: * * * * If other files instantiate templates or use macros * * or inline functions from this file, or you compile this file and * * link it with other files to produce an executable, this file does * * not by itself cause the resulting executable to be covered by the * * GNU Lesser General Public License. This exception does not however * * invalidate any other reasons why the executable file might be * * covered by the GNU Lesser General Public License. * * * * OpenMesh 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 Lesser General Public License for more details. * * * * You should have received a copy of the GNU LesserGeneral Public * * License along with OpenMesh. If not, * * see . * * * \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $Date$ * * * \*===========================================================================*/ //== INCLUDES ================================================================= #ifdef _MSC_VER # pragma warning(disable: 4267 4311) #endif #include #include #include #include #include #include #include #include #include #include #include #include #include // #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 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 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 index2handle_map; std::ifstream ifs(_filename, std::ios::binary); if (!ifs) { std::cerr << "Filename : " << _filename << std::endl; 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; ikey()) { case Qt::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 Qt::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 Qt::Key_A: adaptive_mode_ = !(adaptive_mode_); std::cout << "Adaptive refinement mode is " << ((adaptive_mode_ == true) ? "on" : "off") << std::endl; updateGL(); break; case Qt::Key_D: set_debug_print(!debug_print()); break; case Qt::Key_O: qFilename_ = QFileDialog::getOpenFileName(0,"","d:/data/models/spm/", "*.spm"); open_vd_base_mesh( qFilename_.toStdString().c_str() ); break; case Qt::Key_BracketLeft: max_transmitted_datasize_ -= 10000; std::cout << "Max transmitted data: " << max_transmitted_datasize_ << std::endl; break; case Qt::Key_BracketRight: max_transmitted_datasize_ += 10000; std::cout << "Max transmitted data: " << max_transmitted_datasize_ << std::endl; break; case Qt::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 Qt::Key_R: request_base_mesh(); break; case Qt::Key_S: save_views(); std::cout << "Saving view-points" << std::endl; break; case Qt::Key_F: frame_ = 0; std::cout << "Frame is set to 0" << std::endl; break; case Qt::Key_M: adaptive_mode_ = false; current_max_resolution(); updateGL(); std::cout << "Current max resolution mesh" << std::endl; break; case Qt::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 Qt::Key_C: adaptive_mode_ = false; qCameraFileName_ = QFileDialog::getOpenFileName(0, "","./", "*.cmr"); load_views( qCameraFileName_.toStdString().c_str() ); std::cout << "Loading view-points" << std::endl; updateGL(); break; case Qt::Key_9: save_screen(true); break; case Qt::Key_0: std::cout << "#faces: " << mesh_.n_faces() << std::endl; break; case Qt::Key_P: if (qAnimationTimer_->isActive()) { qAnimationTimer_->stop(); std::cout << "print_statistics mode is stopped!" << std::endl; } else { qAnimationTimer_->setSingleShot( true ); qAnimationTimer_->start(0); 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 Qt::Key_L: if (qAnimationTimer_->isActive()) { qAnimationTimer_->stop(); std::cout << "look_around mode is stopped!" << std::endl; } else { qAnimationTimer_->setSingleShot( true ); qAnimationTimer_->start(0); 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 Qt::Key_Q: case Qt::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_->bytesAvailable() < sizeof(int) ) qSocket_->waitForReadyRead(10); 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_->setSingleShot( true ); qSessionTimer_->start(300); } } 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_->setSingleShot( true ); qAnimationTimer_->start(500); } } 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_->setSingleShot( true ); qAnimationTimer_->start(3000); } } void VDPMClientViewerWidget::save_screen(bool _flag) { setCursor( Qt::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( Qt::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()); }