1 /* ========================================================================= * 2 * * 3 * OpenMesh * 4 * Copyright (c) 2001-2015, RWTH-Aachen University * 5 * Department of Computer Graphics and Multimedia * 6 * All rights reserved. * 7 * www.openmesh.org * 8 * * 9 *---------------------------------------------------------------------------* 10 * This file is part of OpenMesh. * 11 *---------------------------------------------------------------------------* 12 * * 13 * Redistribution and use in source and binary forms, with or without * 14 * modification, are permitted provided that the following conditions * 15 * are met: * 16 * * 17 * 1. Redistributions of source code must retain the above copyright notice, * 18 * this list of conditions and the following disclaimer. * 19 * * 20 * 2. Redistributions in binary form must reproduce the above copyright * 21 * notice, this list of conditions and the following disclaimer in the * 22 * documentation and/or other materials provided with the distribution. * 23 * * 24 * 3. Neither the name of the copyright holder nor the names of its * 25 * contributors may be used to endorse or promote products derived from * 26 * this software without specific prior written permission. * 27 * * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * 30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * 31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER * 32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * 33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * 34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * 35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * 36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING * 37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * 38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * 39 * * 40 * ========================================================================= */ 41 42 43 44 #ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH 45 #define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH 46 47 //== INCLUDES ================================================================= 48 49 #include <QTimer> 50 #include <QTcpSocket> 51 #include <QDataStream> 52 #include <iostream> 53 #include <string> 54 55 #include <OpenMesh/Core/IO/MeshIO.hh> 56 #include <OpenMesh/Core/Geometry/Plane3d.hh> 57 #include <OpenMesh/Tools/Utils/Timer.hh> 58 #include <OpenMesh/Tools/VDPM/StreamingDef.hh> 59 #include <OpenMesh/Tools/VDPM/ViewingParameters.hh> 60 #include <OpenMesh/Tools/VDPM/VHierarchy.hh> 61 #include <OpenMesh/Tools/VDPM/VFront.hh> 62 63 #include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh> 64 #include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MyMesh.hh> 65 //#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientSession.hh> 66 67 68 69 typedef MeshViewerWidgetT<MyMesh> MeshViewerWidget; 70 71 72 73 using OpenMesh::VDPM::VDPMStreamingPhase; 74 using OpenMesh::VDPM::kVSplitHeader; 75 using OpenMesh::VDPM::kVSplits; 76 using OpenMesh::VDPM::kBaseMesh; 77 78 using OpenMesh::VDPM::Plane3d; 79 80 using OpenMesh::VDPM::VFront; 81 using OpenMesh::VDPM::VHierarchy; 82 using OpenMesh::VDPM::VHierarchyNodeIndex; 83 using OpenMesh::VDPM::VHierarchyNodeHandle; 84 using OpenMesh::VDPM::ViewingParameters; 85 using OpenMesh::VDPM::set_debug_print; 86 87 88 //== CLASS DEFINITION ========================================================= 89 90 91 class VDPMClientViewerWidget : public MeshViewerWidget 92 { 93 94 Q_OBJECT 95 96 public: VDPMClientViewerWidget(QWidget * _parent=0,const char * _name=0)97 VDPMClientViewerWidget(QWidget *_parent=0, const char *_name=0) 98 : MeshViewerWidget(_parent, _name) 99 { 100 set_debug_print(true); 101 adaptive_mode_ = false; 102 103 qSessionTimer_ = new QTimer(this); 104 qSocket_ = new QTcpSocket(this); 105 streaming_phase_ = kBaseMesh; 106 session_running_ = false; 107 108 109 connect(qSessionTimer_, SIGNAL(timeout()), 110 this, SLOT(session_timer_check())); 111 112 connect(qSessionTimer_, SIGNAL(timeout()), 113 this, SLOT(socketReadyRead())); 114 115 // connect signal-slots about QSocket 116 connect(qSocket_, SIGNAL(connected()), 117 this, SLOT(socketConnected())); 118 119 connect(qSocket_, SIGNAL(connectionClosed()), 120 this, SLOT(socketConnectionClosed())); 121 122 connect(qSocket_, SIGNAL(readyRead()), 123 this, SLOT(socketReadyRead())); 124 125 connect(qSocket_, SIGNAL(error( QAbstractSocket::SocketError )), 126 this, SLOT(socketError( QAbstractSocket::SocketError ))); 127 128 129 look_around_mode_ = false; 130 frame_ = 0; 131 n_viewpoints_ = 60; 132 133 global_timer_.reset(); 134 global_timer_.start(); 135 render_timer_.reset(); 136 refinement_timer_.reset(); 137 session_timer_.reset(); 138 139 qAnimationTimer_ = new QTimer(this); 140 141 connect(qAnimationTimer_, SIGNAL(timeout()), 142 this, SLOT(look_around())); 143 //connect(qAnimationTimer_, SIGNAL(timeout()), 144 // this, SLOT(print_statistics())); 145 146 147 uplink_file = fopen("uplink.txt", "w"); 148 downlink_file = fopen("downlink.txt", "w"); 149 150 render_file = fopen("render.txt", "w"); 151 refinement_file = fopen("refinement.txt", "w"); 152 session_file = fopen("session.txt", "w"); 153 154 vd_streaming_ = true; 155 max_transmitted_datasize_ = 0; 156 transmitted_datasize_ = 0; 157 } 158 ~VDPMClientViewerWidget()159 ~VDPMClientViewerWidget() 160 { 161 fclose(uplink_file); 162 fclose(downlink_file); 163 164 fclose(render_file); 165 fclose(refinement_file); 166 fclose(session_file); 167 } 168 169 connectToServer(std::string & _server_name,int _port=VDPM_STREAMING_PORT)170 void connectToServer( std::string& _server_name, 171 int _port= VDPM_STREAMING_PORT ) 172 { 173 qSocket_->connectToHost( _server_name.c_str(), _port ); 174 } 175 openBaseMesh(std::string & _base_mesh)176 void openBaseMesh( std::string& _base_mesh ) 177 { 178 open_vd_base_mesh( _base_mesh.c_str() ); 179 std::cout << "spm file: " << _base_mesh << std::endl; 180 } 181 182 // socket related slots 183 private slots: 184 closeConnection()185 void closeConnection() 186 { 187 close(); 188 if (qSocket_->state() == QAbstractSocket::ClosingState) // we have a delayed close. 189 { 190 connect(this, SIGNAL(delayedCloseFinished()), SLOT(socketClosed())); 191 } 192 else // the qSocket is closed. 193 { 194 socketClosed(); 195 } 196 } 197 socketReadyRead()198 void socketReadyRead() 199 { 200 switch( streaming_phase_) 201 { 202 case kVSplits: receive_vsplit_packets(); break; 203 case kVSplitHeader: receive_vsplit_header(); break; 204 case kBaseMesh: receive_base_mesh(); break; 205 } 206 207 } 208 socketConnected()209 void socketConnected() 210 { 211 std::cout << "Connected to server" << std::endl; 212 } 213 socketConnectionClosed()214 void socketConnectionClosed() 215 { 216 std::cout << "Connection closed by the server" << std::endl; 217 } 218 socketClosed()219 void socketClosed() 220 { 221 std::cout << "Connection closed" << std::endl; 222 } 223 socketError(QAbstractSocket::SocketError e)224 void socketError(QAbstractSocket::SocketError e) 225 { 226 std::cout << "Error number " << e << " occurred" << std::endl; 227 } 228 229 void look_around(); 230 void print_statistics(); 231 232 session_timer_check()233 void session_timer_check() 234 { 235 std::cout << "Session Timer works" << std::endl; 236 } 237 238 // for view-dependent PM 239 private: 240 VHierarchy vhierarchy_; 241 //unsigned char tree_id_bits_; 242 VFront vfront_; 243 ViewingParameters viewing_parameters_; 244 float kappa_square_; 245 bool adaptive_mode_; 246 247 unsigned int n_base_vertices_; 248 unsigned int n_base_edges_; 249 unsigned int n_base_faces_; 250 unsigned int n_details_; 251 252 private: 253 254 bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius); 255 bool oriented_away(float sin_square, float distance_square, 256 float product_value); 257 bool screen_space_error(float mue_square, float sigma_square, 258 float distance_square, float product_value); 259 void update_viewing_parameters(); 260 261 virtual void keyPressEvent(QKeyEvent *_event); 262 263 protected: 264 265 /// inherited drawing method 266 virtual void draw_scene(const std::string& _draw_mode); 267 268 269 public: 270 271 void open_vd_prog_mesh(const char* _filename); 272 num_base_vertices() const273 unsigned int num_base_vertices() const { return n_base_vertices_; } num_base_edges() const274 unsigned int num_base_edges() const { return n_base_edges_; } num_base_faces() const275 unsigned int num_base_faces() const { return n_base_faces_; } num_details() const276 unsigned int num_details() const { return n_details_; } 277 278 void adaptive_refinement(); 279 bool qrefine(VHierarchyNodeHandle _node_handle); 280 void force_vsplit(VHierarchyNodeHandle _node_handle); 281 bool ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1); 282 283 void get_active_cuts(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr); 284 void vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr); 285 void ecol(VHierarchyNodeHandle _parent_handle, const MyMesh::HalfedgeHandle& v0v1); 286 287 void init_vfront(); 288 289 // streaming realted functions 290 private: 291 QTimer *qSessionTimer_; 292 QTcpSocket *qSocket_; 293 QString qFilename_; 294 bool session_running_; 295 VDPMStreamingPhase streaming_phase_; 296 unsigned int n_vsplit_packets_; 297 298 public: 299 void connect_to_server(); 300 bool request_base_mesh(); 301 bool receive_base_mesh(); 302 void send_viewing_information(); 303 void receive_vsplit_header(); 304 void receive_vsplit_packets(); 305 void open_vd_base_mesh(const char* _filename); 306 void update_vhierarchy( 307 const OpenMesh::Vec3f &_pos, // 3D position of v0 308 const VHierarchyNodeIndex &_v, // vhierarchy index of v1 309 const VHierarchyNodeIndex &_fund_lcut_index, // vhierarchy index of fundamental lcut 310 const VHierarchyNodeIndex &_fund_rcut_index, // vhierarchy index of fundamental rcut 311 const float _radius[2], // radius of lchild & rchild 312 const OpenMesh::Vec3f _normal[2], // normal of lchild & rchild 313 const float _sin_square[2], // sin_square of lchild & rchild 314 const float _mue_square[2], // mue_square of lchild & rchild 315 const float _sigma_square[2] // sigma_square of lchild & rchild 316 ); 317 318 319 // for example 320 private: 321 QTimer *qAnimationTimer_; 322 QString qCameraFileName_; 323 MyMesh::Point bbMin_, bbMax_; 324 unsigned int frame_; 325 int max_transmitted_datasize_; 326 int transmitted_datasize_; 327 bool vd_streaming_; 328 329 unsigned int nth_viewpoint_; 330 unsigned int n_viewpoints_; 331 bool look_around_mode_; 332 GLdouble reserved_modelview_matrix_[16]; 333 GLdouble reserved_projection_matrix_[16]; 334 335 FILE *uplink_file; 336 FILE *downlink_file; 337 FILE *render_file; 338 FILE *refinement_file; 339 FILE *session_file; 340 341 public: 342 void save_screen(bool _flag); 343 void save_views(); 344 void load_views(const char *camera_filename); 345 void screen_capture(const char *_filename); 346 void current_max_resolution(); 347 348 OpenMesh::Utils::Timer global_timer_; 349 OpenMesh::Utils::Timer render_timer_; 350 OpenMesh::Utils::Timer refinement_timer_; 351 OpenMesh::Utils::Timer session_timer_; 352 353 354 355 #ifdef EXAMPLE_CREATION 356 void increase_max_descendents(const VHierarchyNodeIndex &node_index); 357 void increase_cur_descendents(VHierarchyNodeHandle _node_handle); 358 void __add_children(const VHierarchyNodeIndex &node_index, bool update_current = true); 359 void mesh_coloring(); 360 #endif 361 }; 362 363 #endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH defined 364