Developer Documentation
QtBaseViewerSynchronization.cc
1 /*===========================================================================*\
2  * *
3  * OpenFlipper *
4  * Copyright (c) 2001-2015, RWTH-Aachen University *
5  * Department of Computer Graphics and Multimedia *
6  * All rights reserved. *
7  * www.openflipper.org *
8  * *
9  *---------------------------------------------------------------------------*
10  * This file is part of OpenFlipper. *
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 
45 
46 //=============================================================================
47 //
48 // CLASS QtBaseViewer - IMPLEMENTATION
49 //
50 //=============================================================================
51 
52 
53 //== INCLUDES =================================================================
54 #include <ACG/GL/acg_glew.hh>
55 #include "QtBaseViewer.hh"
56 #include "QtGLGraphicsScene.hh"
57 #include "QtGLGraphicsView.hh"
58 #include <QHostInfo>
59 
60 #include "../GL/GLState.hh"
61 
62 //== NAMESPACES ===============================================================
63 
64 namespace ACG {
65 namespace QtWidgets {
66 
67 
68 //== IMPLEMENTATION ==========================================================
69 
70 
72 {
73  connect(_other,
74  SIGNAL(signalSetView(const GLMatrixd&, const GLMatrixd&)),
75  this,
76  SLOT(setView(const GLMatrixd&, const GLMatrixd&)));
77 }
78 
79 
80 //-----------------------------------------------------------------------------
81 
82 
84 {
85  disconnect(_other,
86  SIGNAL(signalSetView(const GLMatrixd&, const GLMatrixd&)),
87  this,
88  SLOT(setView(const GLMatrixd&, const GLMatrixd&)));
89 }
90 
91 
92 //-----------------------------------------------------------------------------
93 
94 
96 {
97  const GLMatrixd& m = glstate_->modelview();
98  const GLMatrixd& p = glstate_->projection();
99 
100  QByteArray datagram;
101  QDataStream out(&datagram, QIODevice::WriteOnly);
102  out.setVersion(5);
103 
104  quint64 myId = (quint64) winId();
105 
106  out << myId
107  << m(0,0) << m(0,1) << m(0,2) << m(0,3)
108  << m(1,0) << m(1,1) << m(1,2) << m(1,3)
109  << m(2,0) << m(2,1) << m(2,2) << m(2,3)
110  << m(3,0) << m(3,1) << m(3,2) << m(3,3)
111  << p(0,0) << p(0,1) << p(0,2) << p(0,3)
112  << p(1,0) << p(1,1) << p(1,2) << p(1,3)
113  << p(2,0) << p(2,1) << p(2,2) << p(2,3)
114  << p(3,0) << p(3,1) << p(3,2) << p(3,3)
115  << glWidth() << glHeight()
116  << projectionMode_
117  << orthoWidth_;
118 
119  for (int h=0, n=sync_hosts_.size(); h<n; ++h)
120  for (int i=6666; i<6676; ++i)
121  if (i != socket_->localPort() || h != 0)
122  socket_->writeDatagram( datagram, datagram.size(),sync_hosts_[h], i);
123 }
124 
125 
127 {
128 GLMatrixd m, p;
129  int w, h, pMode;
130  quint64 id, myId = (quint64) winId();
131 
132 
133  QByteArray datagram( socket_->pendingDatagramSize(), 'x' );
134  socket_->readDatagram( datagram.data(), datagram.size() );
135 
136 
137  if (datagram.size() < 280)
138  return;
139 
140  QDataStream in( & datagram, QIODevice::ReadOnly);
141  in.setVersion(5);
142 
143 
144  in >> id;
145  if (id == myId)
146  return;
147 
148  in >> m(0,0) >> m(0,1) >> m(0,2) >> m(0,3)
149  >> m(1,0) >> m(1,1) >> m(1,2) >> m(1,3)
150  >> m(2,0) >> m(2,1) >> m(2,2) >> m(2,3)
151  >> m(3,0) >> m(3,1) >> m(3,2) >> m(3,3)
152  >> p(0,0) >> p(0,1) >> p(0,2) >> p(0,3)
153  >> p(1,0) >> p(1,1) >> p(1,2) >> p(1,3)
154  >> p(2,0) >> p(2,1) >> p(2,2) >> p(2,3)
155  >> p(3,0) >> p(3,1) >> p(3,2) >> p(3,3)
156  >> w >> h >> pMode >> orthoWidth_;
157 
158 
159  blockSignals(true);
160 
161  makeCurrent();
162 
163  if (projectionMode_ != (ProjectionMode)pMode)
165 
166  glstate_->set_modelview(m);
167 
168  if (w>0 && h>0 &&
169  action_["PasteDropSize"]->isChecked() )
170  {
171  glstate_->set_projection(p);
172  glView_->setFixedSize(w,h);
173  updateGeometry();
174  }
175 
176  blockSignals(false);
177 
178  updateGL();
179 }
180 
181 
182 //-----------------------------------------------------------------------------
183 
184 
186 {
187  synchronized_ = _b;
188  action_["Synchronize"]->setChecked( synchronized_ );
189 
190  if (synchronized_)
191  {
192  connect(socket_,
193  SIGNAL(readyRead()),
194  this,
195  SLOT(sync_receive()));
196 
197  connect(this,
198  SIGNAL(signalSetView(const GLMatrixd&, const GLMatrixd&)),
199  this,
200  SLOT(sync_send(const GLMatrixd&, const GLMatrixd&)));
201  }
202  else
203  {
204  disconnect(socket_,
205  SIGNAL( readyRead() ),
206  this,
207  SLOT(sync_receive()));
208 
209  disconnect(this,
210  SIGNAL(signalSetView(const GLMatrixd&, const GLMatrixd&)),
211  this,
212  SLOT(sync_send(const GLMatrixd&, const GLMatrixd&)));
213  }
214 
215 }
216 
217 
218 //----------------------------------------------------------------------------
219 
220 
221 bool QtBaseViewer::add_sync_host(const QString& _name)
222 {
223  QHostAddress adr;
224  if (adr.setAddress(_name))
225  {
226  add_sync_host(adr);
227  return true;
228  }
229 
230  // QT4
231 
232  // use DNS otherwise
233  QHostInfo hi = QHostInfo::fromName( _name );
234  QList<QHostAddress> list = hi.addresses();
235  if (!list.empty())
236  {
237  add_sync_host(list.front());
238  return true;
239  }
240 
241 
242  return false;
243 }
244 
245 
246 void QtBaseViewer::add_sync_host(QHostAddress& _adr)
247 {
248  sync_hosts_.push_back(_adr);
249 }
250 
251 //=============================================================================
252 } // namespace QtWidgets
253 } // namespace ACG
254 //=============================================================================
void signalSetView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing (cf. slotSetView())
ProjectionMode projectionMode() const
get current projection mode
Namespace providing different geometric functions concerning angles.
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
std::vector< QHostAddress > sync_hosts_
List of hosts which should receive sync information.
void sync_receive()
synchronized with different viewer?
void sync_connect(const QtBaseViewer *)
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:753
unsigned int glWidth() const
get width of QGLWidget
void sync_send(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
synchronized with different viewer?
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
bool synchronized_
synchronized with different viewer?
virtual void setView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing
bool add_sync_host(const QString &_name)
add host to synchronize with, given by its name
void sync_disconnect(const QtBaseViewer *)
unsync two sync_connect()ed QtBaseViewer&#39;s
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:816
QUdpSocket * socket_
socket used for synchronization
void set_projection(const GLMatrixd &_m)
set projection
Definition: GLState.hh:716
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:811
virtual void setSynchronization(bool _b)
toggle global synchronization
ProjectionMode
projection mode
unsigned int glHeight() const
get height of QGLWidget