VDPMClientViewerWidget.hh 12 KB
Newer Older
1 2 3
/*===========================================================================*\
 *                                                                           *
 *                               OpenMesh                                    *
4
 *      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen      *
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
 *                           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 <http://www.gnu.org/licenses/>.                                      *
 *                                                                           *
\*===========================================================================*/ 

/*===========================================================================*\
 *                                                                           *             
 *   $Revision$                                                         *
 *   $Date$                   *
 *                                                                           *
\*===========================================================================*/

Jan Möbius's avatar
Jan Möbius committed
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361
#ifndef OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH
#define OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH

//== INCLUDES =================================================================

#include <qtimer.h>
#include <qsocket.h>
#include <qdatastream.h>
#include <iostream>
#include <string>

#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Geometry/Plane3d.hh>
#include <OpenMesh/Tools/Utils/Timer.hh>
#include <OpenMesh/Tools/VDPM/StreamingDef.hh>
#include <OpenMesh/Tools/VDPM/ViewingParameters.hh>
#include <OpenMesh/Tools/VDPM/VHierarchy.hh>
#include <OpenMesh/Tools/VDPM/VFront.hh>

#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MeshViewerWidgetT.hh>
#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/MyMesh.hh>
//#include <OpenMesh/Apps/VDProgMesh/Streaming/Client/VDPMClientSession.hh>



typedef MeshViewerWidgetT<MyMesh>                 MeshViewerWidget;



using OpenMesh::VDPM::VDPMStreamingPhase;
using OpenMesh::VDPM::kVSplitHeader;
using OpenMesh::VDPM::kVSplits;
using OpenMesh::VDPM::kBaseMesh;

using OpenMesh::VDPM::Plane3d;

using OpenMesh::VDPM::VFront;
using OpenMesh::VDPM::VHierarchy;
using OpenMesh::VDPM::VHierarchyNodeIndex;
using OpenMesh::VDPM::VHierarchyNodeHandle;
using OpenMesh::VDPM::ViewingParameters;
using OpenMesh::VDPM::set_debug_print;


//== CLASS DEFINITION =========================================================


class VDPMClientViewerWidget : public MeshViewerWidget
{

  Q_OBJECT

public:
  VDPMClientViewerWidget(QWidget *_parent=0, const char *_name=0)
    : MeshViewerWidget(_parent, _name)
  {
    set_debug_print(true);
    adaptive_mode_ = false;
    
    qSessionTimer_ = new QTimer(this);
    qSocket_ = new QSocket(this);
    streaming_phase_ = kBaseMesh;
    session_running_ = false;

    
    connect(qSessionTimer_, SIGNAL(timeout()),
      this, SLOT(session_timer_check()));

    connect(qSessionTimer_, SIGNAL(timeout()),
      this, SLOT(socketReadyRead()));
    
    // connect signal-slots about QSocket
    connect(qSocket_, SIGNAL(connected()), 
	    this, SLOT(socketConnected()));

    connect(qSocket_, SIGNAL(connectionClosed()), 
	    this, SLOT(socketConnectionClosed()));

    connect(qSocket_, SIGNAL(readyRead()), 
	    this, SLOT(socketReadyRead()));

    connect(qSocket_, SIGNAL(error(int)), 
	    this, SLOT(socketError(int)));


    look_around_mode_ = false;
    frame_ = 0;
    n_viewpoints_ = 60;

    global_timer_.reset();
    global_timer_.start();
    render_timer_.reset();
    refinement_timer_.reset();
    session_timer_.reset();

    qAnimationTimer_ = new QTimer(this);
   
    connect(qAnimationTimer_, SIGNAL(timeout()),
      this, SLOT(look_around()));
    //connect(qAnimationTimer_, SIGNAL(timeout()),
    //  this, SLOT(print_statistics()));


    uplink_file = fopen("uplink.txt", "w");
    downlink_file = fopen("downlink.txt", "w");

    render_file = fopen("render.txt", "w");
    refinement_file = fopen("refinement.txt", "w");
    session_file = fopen("session.txt", "w");

    vd_streaming_ = true;
    max_transmitted_datasize_ = 0;
    transmitted_datasize_ = 0;    
  }

  ~VDPMClientViewerWidget()
  {
    fclose(uplink_file);
    fclose(downlink_file);

    fclose(render_file);
    fclose(refinement_file);
    fclose(session_file);
  }


  void connectToServer( std::string& _server_name, 
			int _port= VDPM_STREAMING_PORT )
  {
    qSocket_->connectToHost( _server_name.c_str(), _port );
  }

  void openBaseMesh( std::string& _base_mesh )
  {
    open_vd_base_mesh( qFilename_ = _base_mesh.c_str() );
    std::cout << "spm file: " << qFilename_ << std::endl;
  }

// socket related slots
private slots:

  void closeConnection()
  {
    close();
    if (qSocket_->state() == QSocket::Closing)     // we have a delayed close.
    {      
      connect(this, SIGNAL(delayedCloseFinished()), SLOT(socketClosed()));
    }
    else                                 // the qSocket is closed.
    {      
      socketClosed();
    }
  }

  void socketReadyRead()
  {
    switch( streaming_phase_)
    {
      case kVSplits:      receive_vsplit_packets(); break;
      case kVSplitHeader: receive_vsplit_header();  break;
      case kBaseMesh:     receive_base_mesh();      break;
    }

  }

  void socketConnected()
  {
    std::cout << "Connected to server" << std::endl;
  }

  void socketConnectionClosed()
  {
    std::cout << "Connection closed by the server" << std::endl;
  }

  void socketClosed()
  {
    std::cout << "Connection closed" << std::endl;
  }

  void socketError(int e)
  {
    std::cout << "Error number " << e << " occurred" << std::endl;
  }

  void look_around();
  void print_statistics();


  void session_timer_check()
  {
    std::cout << "Session Timer works" << std::endl;
  }

// for view-dependent PM 
private:
  VHierarchy          vhierarchy_;
  //unsigned char       tree_id_bits_;
  VFront              vfront_;
  ViewingParameters   viewing_parameters_;
  float               kappa_square_;
  bool                adaptive_mode_;

  unsigned int        n_base_vertices_;
  unsigned int        n_base_edges_;
  unsigned int        n_base_faces_;
  unsigned int        n_details_;

private:

  bool outside_view_frustum(const OpenMesh::Vec3f &pos, float radius);
  bool oriented_away(float sin_square, float distance_square, 
		     float product_value);
  bool screen_space_error(float mue_square, float sigma_square, 
			  float distance_square, float product_value);
  void update_viewing_parameters();

  virtual void keyPressEvent(QKeyEvent *_event);

protected:

  /// inherited drawing method
  virtual void draw_scene(const std::string& _draw_mode);


public:

  void open_vd_prog_mesh(const char* _filename);
  
  unsigned int  num_base_vertices() const     { return  n_base_vertices_; }
  unsigned int  num_base_edges() const        { return  n_base_edges_; }
  unsigned int  num_base_faces() const        { return  n_base_faces_; }
  unsigned int  num_details() const           { return  n_details_; }  

  void adaptive_refinement();	
  bool qrefine(VHierarchyNodeHandle _node_handle);		
  void force_vsplit(VHierarchyNodeHandle _node_handle);
  bool ecol_legal(VHierarchyNodeHandle _parent_handle, MyMesh::HalfedgeHandle& v0v1);

  void get_active_cuts(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle &vl, MyMesh::VertexHandle &vr);
  void vsplit(VHierarchyNodeHandle _node_handle, MyMesh::VertexHandle vl, MyMesh::VertexHandle vr);
  void ecol(VHierarchyNodeHandle _parent_handle, const MyMesh::HalfedgeHandle& v0v1);

	void init_vfront(); 

  // streaming realted functions
private:
  QTimer              *qSessionTimer_;
  QSocket             *qSocket_;
  QString             qFilename_;
  bool                session_running_;
  VDPMStreamingPhase  streaming_phase_;
  unsigned int        n_vsplit_packets_;

public:
  void connect_to_server();
  bool request_base_mesh();
  bool receive_base_mesh();
  void send_viewing_information();
  void receive_vsplit_header();
  void receive_vsplit_packets();
  void open_vd_base_mesh(const char* _filename);
  void update_vhierarchy(
    const OpenMesh::Vec3f     &_pos,              // 3D position of v0
    const VHierarchyNodeIndex &_v,                // 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
    );

   
  // for example
private:
  QTimer              *qAnimationTimer_;
  QString             qCameraFileName_;
  MyMesh::Point       bbMin_, bbMax_;
  unsigned int        frame_;
  int                 max_transmitted_datasize_;
  int                 transmitted_datasize_;
  bool                vd_streaming_;

  unsigned int        nth_viewpoint_;
  unsigned int        n_viewpoints_;
  bool                look_around_mode_;
  GLdouble            reserved_modelview_matrix_[16];
  GLdouble            reserved_projection_matrix_[16];

  FILE  *uplink_file;
  FILE  *downlink_file;
  FILE  *render_file;
  FILE  *refinement_file;
  FILE  *session_file;

public:
  void save_screen(bool _flag);
  void save_views();
  void load_views(const char *camera_filename);
  void screen_capture(const char *_filename);
  void current_max_resolution();

  OpenMesh::Utils::Timer  global_timer_;
  OpenMesh::Utils::Timer  render_timer_;
  OpenMesh::Utils::Timer  refinement_timer_;
  OpenMesh::Utils::Timer  session_timer_;



#ifdef EXAMPLE_CREATION
  void increase_max_descendents(const VHierarchyNodeIndex &node_index);
  void increase_cur_descendents(VHierarchyNodeHandle _node_handle);
  void __add_children(const VHierarchyNodeIndex &node_index, bool update_current = true);
  void mesh_coloring();
#endif
};

#endif //OPENMESH_APPS_VDPMSTREAMING_CLIENT_VDPMCLIENTVIEWERWIDGET_HH defined