QtBaseViewer.cc 72.1 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
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
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper 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.                         *
*                                                                            *
*  OpenFlipper 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 OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
33
34
35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36
37
38
39
40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42
43
44
45
46
47




//=============================================================================
//
Jan Möbius's avatar
   
Jan Möbius committed
48
//  CLASS glViewer - IMPLEMENTATION
Jan Möbius's avatar
 
Jan Möbius committed
49
50
51
52
53
54
55
//
//=============================================================================


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

#include "QtBaseViewer.hh"
Jan Möbius's avatar
Jan Möbius committed
56
#include "QtGLViewerLayout.hh"
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
57
#include "CursorPainter.hh"
Jan Möbius's avatar
Jan Möbius committed
58

Jan Möbius's avatar
 
Jan Möbius committed
59
60
#include <ACG/QtWidgets/QtWheel.hh>
#include <ACG/Scenegraph/DrawModes.hh>
61
#include <ACG/Scenegraph/CoordsysNode.hh>
Jan Möbius's avatar
Jan Möbius committed
62
#include <ACG/Scenegraph/SceneGraphAnalysis.hh>
Jan Möbius's avatar
 
Jan Möbius committed
63
64
65
66
#include <ACG/GL/gl.hh>

#include <iostream>
#include <string>
67
#include <cassert>
Jan Möbius's avatar
 
Jan Möbius committed
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

#include <QMimeData>
#include <QToolButton>
#include <QFrame>

#include <QClipboard>
#include <QApplication>
#include <QSplitter>
#include <QLayout>
#include <QPushButton>
#include <QLabel>
#include <QImage>
#include <QColorDialog>
#include <QToolTip>
#include <QTextStream>
#include <QDateTime>
#include <QTimer>

#include <QDesktopWidget>
#include <QMouseEvent>
#include <QVBoxLayout>
#include <QKeyEvent>
#include <QGridLayout>
#include <QContextMenuEvent>
#include <QWheelEvent>
#include <QDropEvent>
#include <QPixmap>
#include <QMenu>
#include <QVariant>
#include <QButtonGroup>
#include <QToolBar>

100
101
#include <QGraphicsView>
#include <QGraphicsScene>
Jan Möbius's avatar
 
Jan Möbius committed
102
103
104
#include <QGraphicsWidget>
#include <QGraphicsGridLayout>
#include <QGraphicsProxyWidget>
Jan Möbius's avatar
   
Jan Möbius committed
105
106
#include <QPainter>
#include <QPaintEngine>
Jan Möbius's avatar
 
Jan Möbius committed
107

108
109
#include <QImageWriter>

110
111
112
113
114
115
116
117
#if QT_VERSION < 0x050000
  #include <QGLFramebufferObject>
#else // QT_VERSION > 0x050000
  #undef QT_NO_OPENGL
  #include <QOpenGLFramebufferObject>
  #define QT_NO_OPENGL
#endif //QT_VERSION < 0x050000

Jan Möbius's avatar
 
Jan Möbius committed
118
119
120
121
122
123
124
125
#ifdef max
#  undef max
#endif

#ifdef min
#  undef min
#endif

126
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Jan Möbius's avatar
Jan Möbius committed
127
#include <OpenFlipper/common/ViewObjectMarker.hh>
Jan Möbius's avatar
 
Jan Möbius committed
128

Jan Möbius's avatar
Dennis:    
Jan Möbius committed
129
130
#include <OpenFlipper/common/GlobalOptions.hh>

131
132
#include <QGLFramebufferObject>

133
#include <OpenFlipper/common/RendererInfo.hh>
134
135
#include <OpenFlipper/BasePlugin/PostProcessorInterface.hh>

Jan Möbius's avatar
 
Jan Möbius committed
136
137
138
139
140
141
//== NAMESPACES ===============================================================



//== IMPLEMENTATION ==========================================================

142
static const char          COPY_PASTE_VIEW_START_STRING[] =
Jan Möbius's avatar
 
Jan Möbius committed
143
144
145
146
147
  "ACG::QtWidgets::QGLViewerWidget encoded view";

//== IMPLEMENTATION ==========================================================


148
glViewer::glViewer( QGraphicsScene* _scene,
149
                    QGLWidget* _glWidget,
150
                    Viewer::ViewerProperties& _properties,
151
                    QGraphicsWidget* _parent) :
Jan Möbius's avatar
   
Jan Möbius committed
152
  QGraphicsWidget(_parent),
Jan Möbius's avatar
 
Jan Möbius committed
153
154
  glareaGrabbed_(false),
  projectionUpdateLocked_(false),
Jan Möbius's avatar
   
Jan Möbius committed
155
156
  glScene_(_scene),
  glWidget_(_glWidget),
Jan Möbius's avatar
Jan Möbius committed
157
158
159
  pickCache_(0),
  updatePickCache_(true),
  pickCacheSupported_(true),
160
  constrainedRotationAxis_(std::numeric_limits<double>::quiet_NaN(), 0, 0),
161
  clickEvent_(QEvent::MouseButtonPress, QPoint (), Qt::NoButton, Qt::NoButton, Qt::NoModifier),
Dirk Wilden's avatar
Dirk Wilden committed
162
  properties_(_properties),
163
  glstate_(0),
Jan Möbius's avatar
Jan Möbius committed
164
165
166
167
168
  initialized_(false),
  flyAnimationPerspective_(0),
  flyAnimationOrthogonal_(0),
  flyAngle_(0.0),
  currentAnimationPos_(0.0),
Jan Möbius's avatar
Jan Möbius committed
169
170
  flyMoveBack_(false),
  sceneTexReadBackWidth_(0), sceneTexReadBackHeight_(0)
Jan Möbius's avatar
 
Jan Möbius committed
171
172
173
{

  // widget stuff
174
  createWidgets();
Jan Möbius's avatar
 
Jan Möbius committed
175
176
177

  // bind GL context to GL state class
  glstate_ = new ACG::GLState();
178
179
  properties_.setglState( glstate_ );

Jan Möbius's avatar
 
Jan Möbius committed
180
181
  // state
  isRotating_       = false;
Mike Kremer's avatar
Mike Kremer committed
182
  lookAround_       = false;
Jan Möbius's avatar
 
Jan Möbius committed
183
184
185

  sceneGraphRoot_   = 0;

186
  normalsMode_      = NORMALIZE_NORMALS;
Jan Möbius's avatar
 
Jan Möbius committed
187
  projectionMode_   = PERSPECTIVE_PROJECTION;
Jan Möbius's avatar
Jan Möbius committed
188
  navigationMode_   = NORMAL_NAVIGATION;
189

Jan Möbius's avatar
 
Jan Möbius committed
190
191
192
193
194
195
196
197
198
199
200
201
202
203
  trackMouse_ = false;

  // Note: we start locked (initialization of updateLocked_)
  // will be unlocked in initializeGL()

  QSizePolicy sp = sizePolicy();
  sp.setHorizontalPolicy( QSizePolicy::Expanding );
  sp.setVerticalPolicy( QSizePolicy::Expanding );
  sp.setHorizontalStretch( 1 );
  sp.setVerticalStretch( 1 );
  setSizePolicy( sp );

  redrawTime_.start ();

204
205
206
207
  // timer for animation
  timer_ = new QTimer( this );
  connect( timer_, SIGNAL(timeout()), this, SLOT( slotAnimation()) );

208
209
  fovyModifier_ = 1.0;

210
211
212
  allowRotation_ = true;


Jan Möbius's avatar
   
Jan Möbius committed
213
214
215
  connect( &properties_,SIGNAL(updated()), this, SLOT( slotPropertiesUpdated() ) );


Dirk Wilden's avatar
Dirk Wilden committed
216
217
218
  //check for updated properties once
  slotPropertiesUpdated();

Jan Möbius's avatar
   
Jan Möbius committed
219
  setAcceptDrops(true);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
220

221
  setHome();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
222

223
224
  clickTimer_.setSingleShot (true);
  connect (&clickTimer_, SIGNAL(timeout ()), this, SLOT(slotClickTimeout ()));
Jan Möbius's avatar
 
Jan Möbius committed
225
226
227
228
229
230
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
231
glViewer::~glViewer()
Jan Möbius's avatar
 
Jan Möbius committed
232
233
234
235
236
237
238
239
{
  delete glstate_;
}


//-----------------------------------------------------------------------------


240
241
242
243
244
//QSizeF
//glViewer::sizeHint(Qt::SizeHint which, const QSizeF & constraint) const
//{
//  return QSizeF( 600, 600 );
//}
Jan Möbius's avatar
 
Jan Möbius committed
245
246
247
248

//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
249
void glViewer::makeCurrent() {
Jan Möbius's avatar
 
Jan Möbius committed
250
251
252
  glWidget_->makeCurrent();
}

Jan Möbius's avatar
   
Jan Möbius committed
253
void glViewer::swapBuffers() {
Jan Möbius's avatar
 
Jan Möbius committed
254
255
256
257
258
259
  glWidget_->swapBuffers();
}


//-----------------------------------------------------------------------------

Jan Möbius's avatar
Jan Möbius committed
260
261
262
263
264
void glViewer::sceneGraph(ACG::SceneGraph::BaseNode* _root,
                          unsigned int               _maxPasses,
                          ACG::Vec3d                 _bbmin,
                          ACG::Vec3d                 _bbmax,
                          const bool _resetTrackBall)
Jan Möbius's avatar
 
Jan Möbius committed
265
266
267
{
  sceneGraphRoot_ = _root;

Jan Möbius's avatar
Jan Möbius committed
268
  if (sceneGraphRoot_ )
Jan Möbius's avatar
 
Jan Möbius committed
269
270
  {

Jan Möbius's avatar
Jan Möbius committed
271
272
    // set max number of render pass
    glstate_->set_max_render_passes(_maxPasses);
Jan Möbius's avatar
Jan Möbius committed
273
    
Jan Möbius's avatar
Jan Möbius committed
274
275
276
    if ( ( _bbmin[0] > _bbmax[0] ) ||
         ( _bbmin[1] > _bbmax[1] ) ||
         ( _bbmin[2] > _bbmax[2] )   ) {
277
278
      
      // Invalid bounding box, try to recover
279
      setScenePos( properties_.sceneCenter() , properties_.sceneRadius(), _resetTrackBall );
280
281
    
      // Update bounding box to match the scene geometry after recovery
Jan Möbius's avatar
Jan Möbius committed
282
283
      _bbmin = ACG::Vec3d(-1.0,-1.0,-1.0);
      _bbmax = ACG::Vec3d( 1.0, 1.0, 1.0);
Jan Möbius's avatar
Jan Möbius committed
284
285
    } else {
      
286
      // For very small scenes, we set the scene radius to 0.1
Jan Möbius's avatar
Jan Möbius committed
287
      // otherwise we take the real radius
Jan Möbius's avatar
Jan Möbius committed
288
289
      if ( ( _bbmax - _bbmin ).max() < OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble() )  {
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
290
                     OpenFlipperSettings().value("Core/Gui/glViewer/minimalSceneSize",0.1).toDouble(),
Jan Möbius's avatar
Jan Möbius committed
291
292
293
                     _resetTrackBall);
                   
      } else {
Jan Möbius's avatar
Jan Möbius committed
294
295
        setScenePos( ( _bbmin + _bbmax )        * 0.5,
                     ( _bbmax - _bbmin ).norm() * 0.5,
Jan Möbius's avatar
Jan Möbius committed
296
297
298
299
                     _resetTrackBall); 
      }
                   
    }
300
301
                   
    // remember the new bounding box for the state
Jan Möbius's avatar
Jan Möbius committed
302
    glstate_->set_bounding_box(_bbmin,_bbmax);
303
    
Jan Möbius's avatar
 
Jan Möbius committed
304
  }
305
  
Jan Möbius's avatar
 
Jan Möbius committed
306
307
308
309
310
311
312
313
314
315

  updateGL();

  emit(signalSceneGraphChanged(sceneGraphRoot_));
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
316
void glViewer::trackMouse(bool _track)
Jan Möbius's avatar
 
Jan Möbius committed
317
318
319
320
321
322
323
{
  trackMouse_ = _track;
}


//-----------------------------------------------------------------------------

324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
void glViewer::setCoordSysProjection(ProjectionMode _mode) {
  // Find coordsys node
  ACG::SceneGraph::BaseNode* node = 0;
  node = PluginFunctions::getSceneGraphRootNode()->find("Core Coordsys Node");

  // set the projection mode for the coordinate system node
  if (node != 0) {
    ACG::SceneGraph::CoordsysNode* cnode = dynamic_cast<ACG::SceneGraph::CoordsysNode*> (node);
    if (_mode ==  ORTHOGRAPHIC_PROJECTION) {
      cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::ORTHOGRAPHIC_PROJECTION);
    } else {
      cnode->setProjectionMode(ACG::SceneGraph::CoordsysNode::PERSPECTIVE_PROJECTION);
    }
  }
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
344
void glViewer::perspectiveProjection()
Jan Möbius's avatar
 
Jan Möbius committed
345
346
347
348
349
350
{
  projectionMode(PERSPECTIVE_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
351
void glViewer::orthographicProjection()
Jan Möbius's avatar
 
Jan Möbius committed
352
353
354
355
356
357
{
  projectionMode(ORTHOGRAPHIC_PROJECTION);
  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
358
void glViewer::toggleProjectionMode()
Jan Möbius's avatar
 
Jan Möbius committed
359
360
361
362
363
364
365
366
367
368
{
  if (projectionMode_ == ORTHOGRAPHIC_PROJECTION)
    projectionMode(PERSPECTIVE_PROJECTION);
  else
    projectionMode(ORTHOGRAPHIC_PROJECTION);

  updateGL();
}


Jan Möbius's avatar
   
Jan Möbius committed
369
void glViewer::projectionMode(ProjectionMode _p)
Jan Möbius's avatar
 
Jan Möbius committed
370
371
{
  if ((projectionMode_ = _p) == ORTHOGRAPHIC_PROJECTION)
372
    emit projectionModeChanged( true );
Jan Möbius's avatar
 
Jan Möbius committed
373
  else
374
    emit projectionModeChanged( false );
Jan Möbius's avatar
 
Jan Möbius committed
375
376

  updateProjectionMatrix();
377

378
379
  setCoordSysProjection(_p);

380
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
381
382
}

383
384
385
void glViewer::toggleNavigationMode()
{
  if (navigationMode_ == NORMAL_NAVIGATION)
Mike Kremer's avatar
Mike Kremer committed
386
    navigationMode(FIRSTPERSON_NAVIGATION);
387
388
389
390
391
392
393
394
395
396
397
398
399
  else
    navigationMode(NORMAL_NAVIGATION);
}


void glViewer::navigationMode(NavigationMode _n)
{
  if ((navigationMode_ = _n) == NORMAL_NAVIGATION)
    emit navigationModeChanged( true );
  else
    emit navigationModeChanged( false );
}

400
401
402
403
404
405
406
407
408
409
410
void glViewer::setFOVY(double _fovy) {
    
  if(_fovy <= 0.0 || _fovy >= 180) {
    std::cerr << "Error: Minimum or maximum fovy angle exceeded!" << std::endl;
    return;
  }
  
  OpenFlipperSettings().setValue("Core/Projection/FOVY", _fovy);
  updateProjectionMatrix();
}

Jan Möbius's avatar
 
Jan Möbius committed
411

Jan Möbius's avatar
   
Jan Möbius committed
412
void glViewer::updateProjectionMatrix()
Jan Möbius's avatar
 
Jan Möbius committed
413
414
415
416
417
418
419
420
{
  if( projectionUpdateLocked_ )
    return;

  makeCurrent();

  glstate_->reset_projection();

421
  // In stereo mode we have to use a perspective matrix
422
  if ( projectionMode_ == PERSPECTIVE_PROJECTION)
Jan Möbius's avatar
 
Jan Möbius committed
423
  {
424
425
426
427
428
429
430
    double aspect;

    if (isVisible() && glWidth() && glHeight())
      aspect = (double) glWidth() / (double) glHeight();
    else
      aspect = 1.0;

431
    // Get fovy
432
    double fovy = OpenFlipperSettings().value("Core/Projection/FOVY", 45.0).toDouble() + fovyModifier_;
433
434

    glstate_->perspective(fovy, (GLdouble) aspect,
435
                          properties_.nearPlane(), properties_.farPlane());
Jan Möbius's avatar
Jan Möbius committed
436
437
438
439
  }
  else
  {
    double aspect;
Jan Möbius's avatar
Jan Möbius committed
440

441
    if (isVisible() && glWidth() && glHeight())
Jan Möbius's avatar
Jan Möbius committed
442
443
      aspect = (double) glWidth() / (double) glHeight();
    else
444
      aspect = 1.0;
Jan Möbius's avatar
 
Jan Möbius committed
445

446
447
448
    glstate_->ortho( -properties_.orthoWidth(), properties_.orthoWidth(),
                     -properties_.orthoWidth()/aspect, properties_.orthoWidth()/aspect,
                      properties_.nearPlane(), properties_.farPlane() );
Jan Möbius's avatar
 
Jan Möbius committed
449
  }
450

Jan Möbius's avatar
 
Jan Möbius committed
451
452
453
454
455
456
}


//-----------------------------------------------------------------------------


457
void glViewer::setScenePos(const ACG::Vec3d& _center, double _radius, const bool _resetTrackBall)
Jan Möbius's avatar
 
Jan Möbius committed
458
{
459
  if(_resetTrackBall) {
460
    properties_.trackballCenter(_center);
461
462
  }

463
  properties_.sceneCenter(_center);
464

465
466
  properties_.sceneRadius(_radius);
  properties_.trackballRadius(_radius);
467

468
  ACG::Vec3d c = glstate_->modelview().transform_point(properties_.sceneCenter());
469

Jan Möbius's avatar
Jan Möbius committed
470
471
  double nearPlane = std::max(0.0001f * properties_.sceneRadius(),  -(c[2] + properties_.sceneRadius()));
  double farPlane  = std::max(0.0002f * properties_.sceneRadius(),  -(c[2] - properties_.sceneRadius()));
472
473

   // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
474
   if ( nearPlane <= 0.0 ) {
475
     std::cerr << "Error in BaseViewer drawScene, nearplane <= 0.0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
476
     nearPlane = 0.000000000000001;
477
478
479
   }

  // Safety check. Make sure that they are in the right order
Jan Möbius's avatar
Typo    
Jan Möbius committed
480
  if ( nearPlane > farPlane ) {
481
    std::cerr << "Error in BaseViewer setScenePos, Nearplane > Farplane" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
482
    std::swap(nearPlane,farPlane);
483
484
  }

Jan Möbius's avatar
Jan Möbius committed
485
  properties_.setPlanes(nearPlane,farPlane);
486
  properties_.orthoWidth(_radius);
Jan Möbius's avatar
 
Jan Möbius committed
487

488
489
490
491
  updateProjectionMatrix();
  updateGL();

  emit viewChanged();
492
493
494
495
496
497
}


//----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
498
void glViewer::viewingDirection( const ACG::Vec3d& _dir, const ACG::Vec3d& _up )
Jan Möbius's avatar
 
Jan Möbius committed
499
500
{
  // calc eye point for this direction
501
  ACG::Vec3d eye = properties_.sceneCenter() - _dir * ( 3.0 * properties_.sceneRadius());
Jan Möbius's avatar
 
Jan Möbius committed
502
503

  glstate_->reset_modelview();
504
  glstate_->lookAt((ACG::Vec3d)eye, (ACG::Vec3d)properties_.sceneCenter(), (ACG::Vec3d)_up);
505

506
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
507
508
}

509
510
511
512
513
514
515
//-----------------------------------------------------------------------------

void glViewer::lookAt(const ACG::Vec3d& _eye, const ACG::Vec3d& _center, const ACG::Vec3d& _up) {
    
    glstate_->reset_modelview();
    glstate_->lookAt(_eye, _center, _up);
    
516
517
    properties_.sceneCenter( _center );
    properties_.sceneRadius( (properties_.sceneCenter() - _eye).norm() );
518
519
520
    
    emit viewChanged();
}
Jan Möbius's avatar
 
Jan Möbius committed
521
522
523

//-----------------------------------------------------------------------------

Jan Möbius's avatar
   
Jan Möbius committed
524
void glViewer::normalsMode(NormalsMode _mode)
Jan Möbius's avatar
 
Jan Möbius committed
525
526
527
528
529
530
{
  makeCurrent();

  switch(normalsMode_ = _mode)
  {
    case DONT_TOUCH_NORMALS:
531
      ACG::GLState::disable(GL_NORMALIZE);
Jan Möbius's avatar
 
Jan Möbius committed
532
533
534
      break;

    case NORMALIZE_NORMALS:
535
      ACG::GLState::enable(GL_NORMALIZE);
Jan Möbius's avatar
 
Jan Möbius committed
536
537
538
539
540
541
542
543
544
545
546
      break;
  }

  updateGL();
}


//-----------------------------------------------------------------------------


void
Jan Möbius's avatar
   
Jan Möbius committed
547
glViewer::copyToImage( QImage& _image,
Jan Möbius's avatar
Jan Möbius committed
548
549
		       unsigned int _l, unsigned int _t,
		       unsigned int _w, unsigned int _h,
550
			     GLenum /* _buffer */ )
Jan Möbius's avatar
 
Jan Möbius committed
551
{
552
553
554

//    makeCurrent();

Jan Möbius's avatar
Jan Möbius committed
555
  _image = glWidget_->grabFrameBuffer(true).copy (_l, _t, _w, _h).convertToFormat (QImage::Format_RGB32);
Jan Möbius's avatar
 
Jan Möbius committed
556
557
558
559
560
561
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
562
void glViewer::updateGL()
Jan Möbius's avatar
 
Jan Möbius committed
563
{
Jan Möbius's avatar
   
Jan Möbius committed
564
  if (!properties_.updateLocked() && isVisible() )
Jan Möbius's avatar
 
Jan Möbius committed
565
  {
Jan Möbius's avatar
Jan Möbius committed
566
    updatePickCache_ = true;
Jan Möbius's avatar
   
Jan Möbius committed
567
    update();
568
569

    emit viewUpdated();
Jan Möbius's avatar
 
Jan Möbius committed
570
571
572
573
574
575
576
577
  }
}



//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
578
void glViewer::drawScene()
Jan Möbius's avatar
 
Jan Möbius committed
579
{
580
581
582
583
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(true);
  
Jan Möbius's avatar
 
Jan Möbius committed
584
585
586
  QTime  timer;
  timer.start();

Jan Möbius's avatar
   
Jan Möbius committed
587
588
589
590
  // *****************************************************************
  // Adjust clipping planes
  // *****************************************************************
  // Far plane
591
  ACG::Vec3d c = glstate_->modelview().transform_point(properties_.sceneCenter());
Jan Möbius's avatar
   
Jan Möbius committed
592

Jan Möbius's avatar
Jan Möbius committed
593
594
  double nearPlane = std::max(0.0001f * properties_.sceneRadius(),  -(c[2] + properties_.sceneRadius()));
  double farPlane  = std::max(0.0002f * properties_.sceneRadius(),  -(c[2] - properties_.sceneRadius()));
595
596

  // Safety check, if near < 0
Jan Möbius's avatar
Jan Möbius committed
597
  if ( nearPlane <= 0.0 ) {
598
    std::cerr << "Error in BaseViewer drawScene, nearplane < 0" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
599
    nearPlane = 0.000000000000001;
600
601
602
  }

  // Safety check. Make sure that they are in the right order
Jan Möbius's avatar
Jan Möbius committed
603
  if ( nearPlane > farPlane ) {
604
    std::cerr << "Error in BaseViewer drawScene, Nearplane > Farplane" << std::endl;
Jan Möbius's avatar
Jan Möbius committed
605
    std::swap(nearPlane,farPlane);
606
  }
Jan Möbius's avatar
   
Jan Möbius committed
607

Jan Möbius's avatar
Jan Möbius committed
608
  properties_.setPlanes(nearPlane,farPlane);
Jan Möbius's avatar
   
Jan Möbius committed
609

Jan Möbius's avatar
 
Jan Möbius committed
610
611
612
613
614
615
  updateProjectionMatrix();

  // store time since last repaint in gl state and restart timer
  glstate_->set_msSinceLastRedraw (redrawTime_.restart ());

  makeCurrent();
616

Jan Möbius's avatar
Jan Möbius committed
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
  // draw mono or stereo
  // If stereo mode is selected, we have to provide multiple ways of rendering.

  // 1. Default internal pipeline : Directly to output buffer (no stereo support!)
  // 2. Non default : Non-stereo Directly to output buffer (no stereo support!)
  //
  //

//  if (OpenFlipper::Options::stereoMode () == OpenFlipper::Options::OpenGL && OpenFlipper::Options::glStereo ())
//  {
//    // Stereo      : Hardware support (OpenGL stereo : left and right buffer with offset eyes)
//
//    return;
//  }
//  else if (OpenFlipper::Options::stereoMode () == OpenFlipper::Options::AnaglyphCustom && customAnaglyphSupported_)
//  {
//    //Stereo      : No Hardware support (Left and right frame buffer with offset eyes)
//  } else {
//
//  }


//  QGLFramebufferObject fbo( glstate_->viewport_width(),glstate_->viewport_height(),QGLFramebufferObject::CombinedDepthStencil );
//
//  fbo.bind();

Jan Möbius's avatar
Jan Möbius committed
643
644
645
646
647
  updatePostProcessingBufs(glstate_->viewport_width(),glstate_->viewport_height());


//  glBindFramebuffer(GL_FRAMEBUFFER, postProcessFBO_);

648
  // Check if we use build in default renderer
Jan Möbius's avatar
Jan Möbius committed
649
  if ( renderManager().activeId( properties_.viewerId() ) == 0 ) {
650
    drawScene_mono();
Jan Möbius's avatar
Jan Möbius committed
651
  } else {
652
    renderManager().active( properties_.viewerId() )->plugin->render(glstate_,properties_);
Jan Möbius's avatar
Jan Möbius committed
653
  }
Jan Möbius's avatar
Jan Möbius committed
654

Jan Möbius's avatar
Jan Möbius committed
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
//  glBindFramebuffer(GL_FRAMEBUFFER, 0);






  // =================================================================================
  // Post-Processing pipeline

  readBackBuffer(glstate_);

  int numPostProcessors = postProcessorManager().numActive(properties_.viewerId());

//   // DEBUG testing post processor chain
//   if (numPostProcessors == 1)
//   {
//     postProcessorManager().append("Grayscale Postprocessor Plugin", properties_.viewerId());
//     postProcessorManager().append("Red Postprocessor Plugin", properties_.viewerId());
// 
//     numPostProcessors += 2;
//   }

  // 1st post processing source: back buffer
  int postProcSrc = 1;
  PostProcessorInput postProcInput;
  postProcInput.colorTex_ = sceneTexReadBack_.id();
  postProcInput.depthTex_ = depthTexReadBack_.id();
  postProcInput.width     = sceneTexReadBackWidth_;
  postProcInput.height    = sceneTexReadBackHeight_;


  // execute post processing chain with 2 FBOs
  for (int i = 0; i < numPostProcessors; ++i)  {

    int postProcTarget = 1 - postProcSrc;
Jan Möbius's avatar
Jan Möbius committed
691

Jan Möbius's avatar
Jan Möbius committed
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
    GLuint targetFBO = postProcessFBO_[postProcTarget].getFboID();

    // write to back buffer in last step
    if (i + 1 == numPostProcessors)
      targetFBO = 0;

    // apply post processor
    PostProcessorInfo* proc = postProcessorManager().active( properties_.viewerId(), i );
    if (proc && proc->plugin)
      proc->plugin->postProcess(glstate_, postProcInput, targetFBO);


    // swap target/source fbo
    postProcSrc = postProcTarget;

    postProcInput.colorTex_ = postProcessFBO_[postProcSrc].getAttachment(GL_COLOR_ATTACHMENT0);
708
  }
Jan Möbius's avatar
Jan Möbius committed
709
710
711
712
713
714

  // =================================================================================

  // unbind vbo for qt log window
  glBindBuffer(GL_ARRAY_BUFFER, 0);

715
716
717
  glActiveTexture(GL_TEXTURE0);
  glBindTexture(GL_TEXTURE_2D, 0);

Jan Möbius's avatar
Jan Möbius committed
718
719
720
721
722
723
724
725
726
727
//  fbo.release();
//
//  QRect blitRect(0,0,glstate_->viewport_width(),glstate_->viewport_height());
//
//  //
//  //QTime time;
//  //time.restart();
//  QGLFramebufferObject::blitFramebuffer( 0 , blitRect, &fbo, blitRect , GL_COLOR_BUFFER_BIT );
//  //std::cerr << "Elapsed for blit: " << time.elapsed() << std::endl;

Jan Möbius's avatar
 
Jan Möbius committed
728
  glFinish();
Jan Möbius's avatar
Jan Möbius committed
729

Jan Möbius's avatar
 
Jan Möbius committed
730
  frame_time_ = timer.elapsed();
Jan Möbius's avatar
Jan Möbius committed
731

732
733
734
  
  // Inside the glWidget rendering, the system should not send extra updates
  properties_.blockSignals(false);
Jan Möbius's avatar
Jan Möbius committed
735

Jan Möbius's avatar
 
Jan Möbius committed
736
737
738
739
740
741
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
742
void glViewer::drawScene_mono()
Jan Möbius's avatar
 
Jan Möbius committed
743
{
744
745
746
747
  if (sceneGraphRoot_) {
    ViewObjectMarker *oM = properties_.objectMarker();
    GLuint refBits = 0;
    QSet<GLuint> references;
748

749
750
751
    if (oM)
    {
      glClear (GL_STENCIL_BUFFER_BIT);
752
      ACG::GLState::enable (GL_STENCIL_TEST);
753
754
      glStencilOp (GL_KEEP, GL_KEEP, GL_ZERO);
      glStencilFunc (GL_ALWAYS, 0, ~0);
755

756
757
      for (PluginFunctions::ObjectIterator o_it(PluginFunctions::ALL_OBJECTS, DATA_ALL) ;
          o_it != PluginFunctions::objectsEnd(); ++o_it)
758
      {
759
760
761
762
        bool ok;
        GLuint ref;

        ok = oM->stencilRefForObject(*o_it, ref);
763

764
        if (ok)
765
        {
766
767
768
769
          o_it->stencilRefNode ()->setReference (ref);
          o_it->stencilRefNode ()->show ();
          refBits |= ref;
          references << ref;
770
        }
771
772
        else
          o_it->stencilRefNode ()->hide ();
773
      }
774
775
    }

Jan Möbius's avatar
Jan Möbius committed
776
777
778
    // First pass
    ACG::SceneGraph::DrawAction pass1( properties_.drawMode(), *glstate_ , false);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass1, *glstate_, properties_.drawMode() );
779

Jan Möbius's avatar
Jan Möbius committed
780
781
782
    // Second Pass for Blending operations
    ACG::SceneGraph::DrawAction pass2(properties_.drawMode(), *glstate_, true);
    ACG::SceneGraph::traverse_multipass(sceneGraphRoot_, pass2, *glstate_, properties_.drawMode());
Jan Möbius's avatar
 
Jan Möbius committed
783

784
785
786
    if (oM)
    {
      if (oM->type() == ViewObjectMarker::PerBit)
Jan Möbius's avatar
 
Jan Möbius committed
787
      {
788
789
790
791
        references.clear ();
        for (unsigned int i = 0; i < sizeof (GLuint) * 8; i++)
          if (refBits & (1 << i))
            references << (1 << i);
Jan Möbius's avatar
 
Jan Möbius committed
792
      }
793

794
      glPushAttrib(GL_ALL_ATTRIB_BITS);
795

796
      ACG::GLState::enable(GL_BLEND);
797
798
799
      ACG::GLState::disable(GL_DEPTH_TEST);
      ACG::GLState::disable(GL_LIGHTING);
      ACG::GLState::disable(GL_DITHER);
800

801
802
      int vp_l, vp_b, vp_w, vp_h;
      glstate_->get_viewport (vp_l, vp_b, vp_w, vp_h);
803

804
805
806
807
808
809
810
      glMatrixMode(GL_PROJECTION);
      glPushMatrix ();
      glLoadIdentity();
      glOrtho(0, vp_w, vp_h, 0, 0, 1.0);
      glMatrixMode(GL_MODELVIEW);
      glPushMatrix ();
      glLoadIdentity();
811

812
      glStencilOp (GL_KEEP, GL_KEEP, GL_KEEP);
813

814
815
816
817
818
819
820
      foreach (unsigned int ref, references)
      {
        bool ok;
        GLenum sfactor;
        GLenum dfactor;
        ACG::Vec4f color;
        unsigned int mask = ~0;
821

822
        if (oM->type() == ViewObjectMarker::PerBit)
823
        {
824
825
          ok = oM->blendForStencilRefBit (ref, sfactor, dfactor, color);
          mask = ref;
826
        }
827
828
        else
          ok = oM->blendForStencilRefNumber (ref, sfactor, dfactor, color);
829

830
831
        if (!ok)
          continue;
832

833
        glStencilFunc (GL_EQUAL, ref, mask);
Jan Möbius's avatar
 
Jan Möbius committed
834

835
        ACG::GLState::blendFunc (sfactor, dfactor);
836
        glColor4f (color[0], color [1], color [2], color[3]);
Jan Möbius's avatar
 
Jan Möbius committed
837

838
839
840
841
842
843
844
845
        glBegin (GL_QUADS);
        glVertex2i(0, 0);
        glVertex2i(0, vp_h);
        glVertex2i(vp_w, vp_h);
        glVertex2i(vp_w, 0);
        glEnd ();

      }
Jan Möbius's avatar
 
Jan Möbius committed
846

847
848
849
850
      glMatrixMode(GL_PROJECTION);
      glPopMatrix ();
      glMatrixMode(GL_MODELVIEW);
      glPopMatrix ();
Jan Möbius's avatar
 
Jan Möbius committed
851

852
      glPopAttrib ();
853
      ACG::GLState::disable (GL_STENCIL_TEST);
Jan Möbius's avatar
 
Jan Möbius committed
854
    }
855
856


Jan Möbius's avatar
 
Jan Möbius committed
857
  }
Jan Möbius's avatar
Jan Möbius committed
858

859
  if (properties_.cursorPainter() && properties_.cursorPainter()->enabled () && properties_.cursorPositionValid() )
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
860
861
862
863
864
  {
    glstate_->push_modelview_matrix ();
    // reset view transformation
    glstate_->reset_modelview ();
    // translate cursor position to 0,0
865
    glstate_->translate ( properties_.cursorPoint3D() );
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
866
    // paint cursor
867
    properties_.cursorPainter()->paintCursor (glstate_);
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
868
869
    glstate_->pop_modelview_matrix ();
  }
870

Jan Möbius's avatar
 
Jan Möbius committed
871
872
}

Jan Möbius's avatar
   
Jan Möbius committed
873
void glViewer::setHome()
Jan Möbius's avatar
 
Jan Möbius committed
874
875
876
{
  home_modelview_          = glstate_->modelview();
  home_inverse_modelview_  = glstate_->inverse_modelview();
877
  homeOrthoWidth_          = properties_.orthoWidth();
878
879
  home_center_             = properties_.trackballCenter();
  home_radius_             = properties_.trackballRadius();
Jan Möbius's avatar
 
Jan Möbius committed
880
881
882
}


Jan Möbius's avatar
   
Jan Möbius committed
883
void glViewer::home()
Jan Möbius's avatar
 
Jan Möbius committed
884
885
886
{
  makeCurrent();
  glstate_->set_modelview(home_modelview_, home_inverse_modelview_);
887
  properties_.orthoWidth( homeOrthoWidth_ );
888
889
  properties_.trackballCenter( home_center_ );
  properties_.trackballRadius(home_radius_);
Jan Möbius's avatar
 
Jan Möbius committed
890
891
  updateProjectionMatrix();
  updateGL();
892

893
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
894
895
896
897
898

}

//-----------------------------------------------------------------------------

Jan Möbius's avatar
   
Jan Möbius committed
899
void glViewer::viewAll()
Jan Möbius's avatar
 
Jan Möbius committed
900
{
901
  makeCurrent();
Jan Möbius's avatar
 
Jan Möbius committed
902

903
904
  // update scene graph (get new bounding box and set projection right, including near and far plane)
  properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
905

906
907
908
  // move center (in camera coords) to origin and translate in -z dir
  translate(-(glstate_->modelview().transform_point(properties_.sceneCenter()))
            - ACG::Vec3d(0.0, 0.0, 3.0 * properties_.sceneRadius()));
909

910
911
912
913
  properties_.orthoWidth( 1.1 * properties_.sceneRadius() );
  double aspect = (double) glWidth() / (double) glHeight();
  if (aspect > 1.0)
    properties_.orthoWidth( aspect * properties_.orthoWidth() ) ;
914

Jan Möbius's avatar
Jan Möbius committed
915
916
917
918
919
  unsigned int maxPases = 1;
  ACG::Vec3d bbmin,bbmax;
  ACG::SceneGraph::analyzeSceneGraph(PluginFunctions::getSceneGraphRootNode(),maxPases,bbmin,bbmax);

  sceneGraph ( PluginFunctions::getSceneGraphRootNode(), maxPases,bbmin,bbmax,true);
920

921
922
923
  properties_.unLockUpdate();
  updateProjectionMatrix();
  updateGL();
924

925
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
926
927
928
929
930
931
932

}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
933
void glViewer::setView(const ACG::GLMatrixd& _modelview,
Jan Möbius's avatar
 
Jan Möbius committed
934
935
936
937
938
			                  const ACG::GLMatrixd& _inverse_modelview)
{
  makeCurrent();
  glstate_->set_modelview(_modelview, _inverse_modelview);
  updateGL();
939

940
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
941
942
943
944
945
946
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
947
void glViewer::initializeGL()
Jan Möbius's avatar
 
Jan Möbius committed
948
949
950
{

  // lock update
951
  properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
952
953
954
955
956

  // init GL state
  glstate_->initialize();

  // OpenGL state
957
958
  ACG::GLState::enable(GL_DEPTH_TEST);
  ACG::GLState::enable(GL_LIGHTING);
959
  ACG::GLState::disable(GL_DITHER);
960
  ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
961
962
963
964
965


  projectionMode(   projectionMode_   );
  normalsMode(      normalsMode_      );

966
  // Update all settings which would require a redraw
967
  applyProperties();
Jan Möbius's avatar
 
Jan Möbius committed
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985

  // modelview
  glstate_->translate(0.0, 0.0, -3.0);
  setHome();


  // pixel transfer
  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
  glPixelStorei(GL_PACK_ALIGNMENT, 1);


  // unlock update (we started locked)
986
  properties_.unLockUpdate();
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
987

988
989
990
991
  initialized_ = true;

  if (sceneGraphRoot_)
  {
Jan Möbius's avatar
Jan Möbius committed
992
993
994
995
996
997
998
    unsigned int maxPases = 1;
    ACG::Vec3d bbmin,bbmax;
    ACG::SceneGraph::analyzeSceneGraph(sceneGraphRoot_,maxPases,bbmin,bbmax);

    sceneGraph ( sceneGraphRoot_, maxPases,bbmin,bbmax,true);

    viewAll();
999
  }
Jan Möbius's avatar
 
Jan Möbius committed
1000
1001
1002
1003
1004
1005
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
1006
void glViewer::paintGL()
Jan Möbius's avatar
 
Jan Möbius committed
1007
{
1008
1009
  if (!initialized_)
    initializeGL ();
Jan Möbius's avatar
 
Jan Möbius committed
1010

1011
  if (!properties_.updateLocked())
Jan Möbius's avatar
 
Jan Möbius committed
1012
  {
Jan Möbius's avatar
Dennis:    
Jan Möbius committed
1013
1014
    ACG::Vec4f clear_color;

1015
    properties_.lockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
1016
1017
1018

    glPushAttrib (GL_ALL_ATTRIB_BITS);

1019
1020
    ACG::GLState::enable(GL_DEPTH_TEST);
    ACG::GLState::enable(GL_LIGHTING);
1021
    ACG::GLState::disable(GL_DITHER);
1022
    ACG::GLState::shadeModel( GL_FLAT );
Jan Möbius's avatar
 
Jan Möbius committed
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

    glMatrixMode(GL_PROJECTION);
    glPushMatrix();

    glMatrixMode(GL_MODELVIEW);
    glPushMatrix();


    normalsMode(      normalsMode_      );

1033
    applyProperties();
1034

1035
    glstate_->setState();
Jan Möbius's avatar
 
Jan Möbius committed
1036
1037
1038

    glColor4f(1.0,0.0,0.0,1.0);

1039
    glstate_->clearBuffers ();
Jan Möbius's avatar
 
Jan Möbius committed
1040

1041
    properties_.unLockUpdate();
Jan Möbius's avatar
 
Jan Möbius committed
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052

    // draw scene
    drawScene();

    glPopMatrix();

    glMatrixMode(GL_PROJECTION);
    glPopMatrix();

    glPopAttrib ();
  }
1053

Jan Möbius's avatar
 
Jan Möbius committed
1054
1055
1056
1057
1058
1059
}


//-----------------------------------------------------------------------------


Jan Möbius's avatar
   
Jan Möbius committed
1060
void glViewer::resizeEvent(QGraphicsSceneResizeEvent *)
Jan Möbius's avatar
 
Jan Möbius committed
1061
1062
{
  updateProjectionMatrix();
Jan Möbius's avatar
   
Jan Möbius committed
1063
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1064
1065
1066
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1067
  update();
1068

1069
  emit viewChanged();
Jan Möbius's avatar
 
Jan Möbius committed
1070
1071
}

Jan Möbius's avatar
   
Jan Möbius committed
1072
1073
1074
void glViewer::moveEvent (QGraphicsSceneMoveEvent *)
{
  glstate_->viewport(scenePos().x(),
Jan Möbius's avatar
Jan Möbius committed
1075
1076
1077
                     scene()->height () - scenePos().y() - size().height (),
                     size().width (), size().height (),
                     scene()->width (), scene()->height ());
Jan Möbius's avatar
   
Jan Möbius committed
1078
  update();
1079

1080
  emit viewChanged();
Jan Möbius's avatar
   
Jan Möbius committed
1081
}
Jan Möbius's avatar
 
Jan Möbius committed
1082
1083
1084

//-----------------------------------------------------------------------------

1085
void glViewer::encodeView(QString& _view, const QSize& _windowSize /*= QSize()*/, const int _splitterWidth /*=-1*/)
Jan Möbius's avatar
 
Jan Möbius committed
1086
{
1087
  // Get current matrices
Jan Möbius's avatar
 
Jan Möbius committed
1088
1089
1090
  const ACG::GLMatrixd m = glstate_->modelview();
  const ACG::GLMatrixd p = glstate_->projection();

1091
  // Add modelview matrix to output
1092
  _view += QString(COPY_PASTE_VIEW_START_STRING) + "\n";
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
  _view += QString::number(m(0,0)) + " " + QString::number(m(0,1)) + " " + QString::number(m(0,2)) + " " + QString::number(m(0,3)) + "\n";
  _view += QString::number(m(1,0)) + " " + QString::number(m(1,1)) + " " + QString::number(m(1,2)) + " " + QString::number(m(1,3)) + "\n";
  _view += QString::number(m(2,0)) + " " + QString::number(m(2,1)) + " " + QString::number(m(2,2)) + " " + QString::number(m(2,3)) + "\n";
  _view += QString::number(m(3,0)) + " " + QString::number(m(3,1)) + " " + QString::number(m(3,2)) + " " + QString::number(m(3,3)) + "\n";

  // Add projection matrix to output
  _view += QString::number(p(0,0)) + " " + QString::number(p(0,1)) + " " + QString::number(p(0,2)) + " " + QString::number(p(0,3)) + "\n";
  _view += QString::number(p(1,0)) + " " + QString::number(p(1,1)) + " " + QString::number(p(1,2)) + " " + QString::number(p(1,3)) + "\n";
  _view += QString::number(p(2,0)) + " " + QString::number(p(2,1)) + " " + QString::number(p(2,2)) + " " + QString::number(p(2,3)) + "\n";
  _view += QString::number(p(3,0)) + " " + QString::number(p(3,1)) + " " + QString::number(p(3,2)) + " " + QString::number(p(3,3)) + "\n";

  // add gl width/height, current projection Mode and the ortho mode width to output
1105
  _view += QString::number(_windowSize.width()) + " " +  QString::number(_windowSize.height()) + " "  + QString::number(_splitterWidth)+ " " + QString::number(projectionMode_) + " " + QString::number(properties_.orthoWidth()) + "\n";
Jan Möbius's avatar
 
Jan Möbius committed
1106
1107
1108
1109
1110
1111
}


//----------------------------------------------------------------------------


1112
bool glViewer::decodeView(const QString& _view, QSize *_windowSize /*= NULL*/, int* _splitterWidth /*= NULL*/)
Jan Möbius's avatar
 
Jan Möbius committed
1113
{
1114
1115
1116
  if (_view.left(sizeof(COPY_PASTE_VIEW_START_STRING)-1) != QString(COPY_PASTE_VIEW_START_STRING))
  {
    std::cerr << "No View was copied." << std::endl;
Jan Möbius's avatar
 
Jan Möbius committed
1117
    return false;
1118
  }
Jan Möbius's avatar
 
Jan Möbius committed
1119

1120
1121
  // Remove the magic from the string
  QString temp = _view;
1122
  temp.remove(0,sizeof(COPY_PASTE_VIEW_START_STRING));
Jan Möbius's avatar
 
Jan Möbius committed
1123

1124
1125
  //Split it into its components
  QStringList split = temp.split(QRegExp("[\\n\\s]"),QString::SkipEmptyParts);
Jan Möbius's avatar
 
Jan Möbius committed
1126
1127

  ACG::GLMatrixd m, p;
Jan Möbius's avatar
Jan Möbius committed
1128
  int            pMode;
Jan Möbius's avatar
 
Jan Möbius committed
1129

1130
1131
1132
1133
1134
1135
1136
1137