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