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