Developer Documentation
QtBaseViewer.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 <ACG/GL/acg_glew.hh>
62 
63 #include "QtBaseViewer.hh"
64 #include "QtGLGraphicsScene.hh"
65 #include "QtGLGraphicsView.hh"
66 #include "QtSceneGraphWidget.hh"
67 #include "QtWheel.hh"
68 
69 #include <QMimeData>
70 #include <QToolButton>
71 
72 #include <QClipboard>
73 #include <QApplication>
74 #include <QPushButton>
75 #include <QStatusBar>
76 #include <QColorDialog>
77 #include <QFileDialog>
78 #include <QTimer>
79 
80 #include <QDesktopWidget>
81 #include <QButtonGroup>
82 
83 #include <QGraphicsWidget>
84 #include <QGraphicsGridLayout>
85 #include <QGraphicsProxyWidget>
86 
87 #include "move.xpm"
88 #include "light.xpm"
89 #include "info.xpm"
90 #include "home.xpm"
91 #include "set_home.xpm"
92 #include "viewall.xpm"
93 #include "pick.xpm"
94 #include "persp.xpm"
95 #include "ortho.xpm"
96 #include "scenegraph.xpm"
97 #include "mono.xpm"
98 
99 
100 #define homeIcon home_xpm
101 #define sethomeIcon set_home_xpm
102 #define moveIcon move_xpm
103 #define lightIcon light_xpm
104 #define questionIcon info_xpm
105 #define viewallIcon viewall_xpm
106 #define pickIcon pick_xpm
107 #define perspectiveIcon persp_xpm
108 #define orthoIcon ortho_xpm
109 #define sceneGraphIcon scenegraph_xpm
110 #define monoIcon mono_xpm
111 
112 
113 #ifdef max
114 # undef max
115 #endif
116 
117 #ifdef min
118 # undef min
119 #endif
120 
121 
122 //== NAMESPACES ===============================================================
123 
124 namespace ACG {
125 namespace QtWidgets {
126 
127 
128 //== IMPLEMENTATION ==========================================================
129 
130 static const char VIEW_MAGIC[] =
131  "ACG::QtWidgets::QGLViewerWidget encoded view";
132 
133 //== IMPLEMENTATION ==========================================================
134 
135 
136 QtBaseViewer::QtBaseViewer( QWidget* _parent,
137  const char* /* _name */ ,
138  QStatusBar *_statusBar,
139  const QGLFormat* _format,
140  const QtBaseViewer* _share,
141  Options _options ) :
142  QWidget(_parent),
143  statusbar_(0),
144  glareaGrabbed_(false),
145  updateLocked_(false),
146  projectionUpdateLocked_(false),
147  blending_(true),
148  sceneGraphDialog_(0),
149  options_(_options),
150  privateStatusBar_(0),
151  disableKeyHandling_(false),
152  externalDrag_(false),
153  snapshotName_("snap.png"),
154  snapshotCounter_(0),
155  snapshot_(0),
156  pick_mode_name_(""),
157  pick_mode_idx_(-1),
158  renderPicking_(false),
159  pickRendererMode_(ACG::SceneGraph::PICK_ANYTHING)
160 
161 {
162  // check for OpenGL support
163  if ( !QGLFormat::hasOpenGL() )
164  {
165  std::cerr << "This system has no OpenGL support.\n";
166  exit(1);
167  }
168 
169 
170  // widget stuff
171  createWidgets(_format,_statusBar,_share);
172 
173 
174  // bind GL context to GL state class
175  glstate_ = new GLState();
176 
177 
178  // state
179  orthoWidth_ = 2.0;
180  isRotating_ = false;
181  near_ = 0.1;
182  far_ = 100.0;
183  fovy_ = 45.0;
184 
185  focalDist_ = 3.0;
186  eyeDist_ = 0.01;
187 
188  sceneGraphRoot_ = 0;
189  curDrawMode_ = SceneGraph::DrawModes::NONE;
190  availDrawModes_ = SceneGraph::DrawModes::NONE;
191 
192  normalsMode_ = DONT_TOUCH_NORMALS;
193  faceOrientation_ = CCW_ORIENTATION;
194  projectionMode_ = PERSPECTIVE_PROJECTION;
195  navigationMode_ = NORMAL_NAVIGATION;
196 
197 
198  backFaceCulling_ = false;
199  twoSidedLighting_ = false;
200  animation_ = false;
201 
202  light_matrix_.identity();
203 
204 
205  snapshot_=new QImage;
206 
207  trackMouse_ = false;
208  popupEnabled_ = true;
209 
210 
211  // stereo
212  stereo_ = false;
213 
214 
215  pickMenu_ = 0;
216  funcMenu_ = 0;
217  drawMenu_ = 0;
218 
219 
220  // init action modes: Examine & Pick
221  actionMode_ = PickingMode;
222  lastActionMode_ = PickingMode;
223  examineMode();
224 
225 
226  // clipboard sync stuff
227  synchronized_ = false;
228  skipNextSync_ = false;
229 
230  socket_ = new QUdpSocket();
231 
232  for (int i=6666; i<6676; ++i)
233  if ( socket_->bind( i ) )
234  {
235  std::cout << "listen on port " << i << "\n";
236  break;
237  }
238 
239  add_sync_host("127.0.0.1");
240 
241 
242 
243  // Note: we start locked (initialization of updateLocked_)
244  // will be unlocked in initializeGL()
245 
246 
247  // Actions
248 
249  action_.insert( "Background", new QAction( "Background color", this ) );
250  action_.insert( "Snapshot", new QAction( "Snapshot", this ) );
251  action_.insert( "SnapshotName", new QAction( "Set snapshot name", this ) );
252  action_.insert( "SnapshotSavesView", new QAction( "Snapshot saves view", this ) );
253  action_.insert( "CopyView", new QAction( "Copy view", this ) );
254  action_.insert( "PasteView", new QAction( "Paste view", this ) );
255  action_.insert( "PasteDropSize", new QAction( "Paste/Drop effects size", this ) );
256  action_.insert( "Synchronize", new QAction( "Synchronize", this ) );
257  action_.insert( "Animation", new QAction( "Animation", this ) );
258  action_.insert( "BackfaceCulling", new QAction( "Backface culling", this ) );
259  action_.insert( "TwoSidedLighting", new QAction( "Two-sided lighting", this ) );
260 
261  connect( action_["Background"], SIGNAL( triggered() ),
262  this, SLOT( actionBackground() ) );
263  connect( action_["Snapshot"], SIGNAL( triggered() ),
264  this, SLOT( actionSnapshot() ) );
265  connect( action_["SnapshotName"], SIGNAL( triggered() ),
266  this, SLOT( actionSnapshotName() ) );
267  connect( action_["SnapshotSavesView"], SIGNAL( triggered() ),
268  this, SLOT( actionSnapshotSavesView() ) );
269  connect( action_["CopyView"], SIGNAL( triggered() ),
270  this, SLOT( actionCopyView() ) );
271  connect( action_["PasteView"], SIGNAL( triggered() ),
272  this, SLOT( actionPasteView() ) );
273  connect( action_["PasteDropSize"], SIGNAL( triggered() ),
274  this, SLOT( actionPasteDropSize() ) );
275  connect( action_["Synchronize"], SIGNAL( triggered() ),
276  this, SLOT( actionSynchronize() ) );
277  connect( action_["Animation"], SIGNAL( triggered() ),
278  this, SLOT( actionAnimation() ) );
279  connect( action_["BackfaceCulling"], SIGNAL( triggered() ),
280  this, SLOT( actionBackfaceCulling() ) );
281  connect( action_["TwoSidedLighting"], SIGNAL( triggered() ),
282  this, SLOT( actionTwoSidedLighting() ) );
283 
284  action_["SnapshotSavesView"]->setCheckable( true );
285  action_["PasteDropSize"]->setCheckable( true );
286  action_["Synchronize"]->setCheckable( true );
287  action_["Animation"]->setCheckable( true );
288  action_["BackfaceCulling"]->setCheckable( true );
289  action_["TwoSidedLighting"]->setCheckable( true );
290 
291 
292  QSizePolicy sp = sizePolicy();
293  sp.setHorizontalPolicy( QSizePolicy::Expanding );
294  sp.setVerticalPolicy( QSizePolicy::Expanding );
295  sp.setHorizontalStretch( 1 );
296  sp.setVerticalStretch( 1 );
297  setSizePolicy( sp );
298 
299  redrawTime_.start ();
300 
301 }
302 
303 
304 //-----------------------------------------------------------------------------
305 
306 
308 {
309  delete privateStatusBar_;
310  delete snapshot_;
311  delete glstate_;
312  delete sceneGraphDialog_;
313  delete socket_;
314  // delete socket_notifier_;
315 }
316 
317 
318 //-----------------------------------------------------------------------------
319 
320 
321 QSize
322 QtBaseViewer::sizeHint() const
323 {
324  return QSize( 600, 600 );
325 }
326 
327 
328 //-----------------------------------------------------------------------------
329 
330 
331 void QtBaseViewer::setStatusBar(QStatusBar* _sb)
332 {
333  if (_sb==0)
334  {
335  if (privateStatusBar_==0)
336  privateStatusBar_=new QStatusBar(this);
337  statusbar_=privateStatusBar_;
338  if (options_ & ShowPrivateStatusBar)
339  privateStatusBar_->show();
340  else
341  privateStatusBar_->hide();
342  }
343  else {
344  statusbar_ = _sb;
345  }
346 }
347 
348 
349 //-----------------------------------------------------------------------------
350 
351 
352 void QtBaseViewer::applyOptions(int _options)
353 {
354  if (_options&ShowPrivateStatusBar)
355  setStatusBar(0);
356  else if (privateStatusBar_!=0)
357  privateStatusBar_->hide();
358 
359  if (_options&ShowToolBar) buttonBar_->show();
360  else buttonBar_->hide();
361  if (_options&ShowPickButton) pickButton_->show();
362  else pickButton_->hide();
363  if (_options&ShowQuestionButton) questionButton_->show();
364  else questionButton_->hide();
365  if (_options&ShowWheelX) wheelX_->show();
366  else wheelX_->hide();
367  if (_options&ShowWheelY) wheelY_->show();
368  else wheelY_->hide();
369  if (_options&ShowWheelZ) wheelZ_->show();
370  else wheelZ_->hide();
371 }
372 
373 
374 //-----------------------------------------------------------------------------
375 
376 
378  glWidget_->makeCurrent();
379 }
380 
382  glWidget_->swapBuffers();
383 }
384 
385 
386 //-----------------------------------------------------------------------------
387 
388 
390 {
391  sceneGraphRoot_ = _root;
392 
393  if (sceneGraphRoot_)
394  {
395  // get draw modes
397  SceneGraph::traverse(sceneGraphRoot_, action);
398  availDrawModes_ = action.drawModes();
399  updatePopupMenu();
400 
401  // get scene size
403  SceneGraph::traverse(sceneGraphRoot_, act);
404 
405  Vec3d bbmin = (Vec3d) act.bbMin();
406  Vec3d bbmax = (Vec3d) act.bbMax();
407 
408  if ( ( bbmin[0] > bbmax[0] ) ||
409  ( bbmin[1] > bbmax[1] ) ||
410  ( bbmin[2] > bbmax[2] ) )
411  setScenePos( Vec3d( 0.0,0.0,0.0 ) , 1.0 );
412  else
413  setScenePos( ( bbmin + bbmax ) * 0.5,
414  ( bbmax - bbmin ).norm() * 0.5 );
415  }
416 
417  updateGL();
418 
419  emit(signalSceneGraphChanged(sceneGraphRoot_));
420 }
421 
422 
423 //-----------------------------------------------------------------------------
424 
425 
427 {
428  updateLocked_ = true;
429  // QToolTip::add(moveButton_, "Switch to <b>move</b> mode (display locked)");
430 }
431 
432 
434 {
435  // QToolTip::add(moveButton_,"Switch to <b>move</b> mode");
436  updateLocked_ = false;
437 }
438 
439 
441 {
442  unlockUpdate();
443  updateGL();
444 }
445 
446 
447 //-----------------------------------------------------------------------------
448 
449 
450 void QtBaseViewer::trackMouse(bool _track)
451 {
452  trackMouse_ = _track;
453 }
454 
455 
456 //-----------------------------------------------------------------------------
457 
458 
460 {
461  popupEnabled_ = _enable;
462 
463  if ( popupEnabled_ ) {
464  glView_->setContextMenuPolicy( Qt::DefaultContextMenu );
465  } else {
466  glView_->setContextMenuPolicy( Qt::CustomContextMenu );
467  }
468 
469 }
470 
471 
472 //-----------------------------------------------------------------------------
473 
475 {
477  updateGL();
478 }
479 
480 
482 {
484  updateGL();
485 }
486 
487 
489 {
490  if (projectionMode_ == ORTHOGRAPHIC_PROJECTION)
492  else
494 
495  // sync
496  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
497 
498  emit viewChanged();
499 
500  updateGL();
501 }
502 
503 
505 {
506  if ((projectionMode_ = _p) == ORTHOGRAPHIC_PROJECTION)
507  projectionButton_->setIcon( QPixmap(orthoIcon) );
508  else
509  projectionButton_->setIcon( QPixmap(perspectiveIcon) );
510 
512 }
513 
515 {
516  if (navigationMode_ == NORMAL_NAVIGATION)
518  else
520 }
521 
522 
524 {
525  if ((navigationMode_ = _n) == NORMAL_NAVIGATION)
526  emit navigationModeChanged( true );
527  else
528  emit navigationModeChanged( false );
529 }
530 
531 
533 {
534  if( projectionUpdateLocked_ )
535  return;
536 
537  makeCurrent();
538 
539  glstate_->reset_projection();
540 
541  // In scereo mode we have to use a perspective matrix
542  if (stereo_ || projectionMode_ == PERSPECTIVE_PROJECTION)
543  {
544  double aspect;
545 
546  if (isVisible() && glWidth() && glHeight())
547  aspect = (double) glWidth() / (double) glHeight();
548  else
549  aspect = 1.0;
550 
551  glstate_->perspective(fovy_, (GLdouble) aspect,
552  near_, far_);
553  }
554  else
555  {
556  double aspect;
557 
558  if (isVisible() && glWidth() && glHeight())
559  aspect = (double) glWidth() / (double) glHeight();
560  else
561  aspect = 1.0;
562 
563  glstate_->ortho( -orthoWidth_, orthoWidth_,
564  -orthoWidth_/aspect, orthoWidth_/aspect,
565  near_, far_ );
566  }
567 
568 }
569 
570 
571 //-----------------------------------------------------------------------------
572 
573 
574 void QtBaseViewer::setScenePos(const ACG::Vec3d& _center, double _radius, const bool _setCenter)
575 {
576  if(_setCenter) {
577  scene_center_ = trackball_center_ = _center;
578  }
579 
580  scene_radius_ = trackball_radius_ = _radius;
581 
582  orthoWidth_ = 2.0 * scene_radius_;
583 
584  ACG::Vec3d c = glstate_->modelview().transform_point(scene_center_);
585 
586  // Set far plane
587  far_ = std::max(0.0002f * scene_radius_, -(c[2] - scene_radius_));
588 
589  // Set near plane
590  near_ = std::max(0.0001f * scene_radius_, -(c[2] + scene_radius_));
591 
592 
594  updateGL();
595 }
596 
597 //-----------------------------------------------------------------------------
598 
599 void QtBaseViewer::setSceneCenter( const ACG::Vec3d& _center ) {
600 
601  scene_center_ = trackball_center_ = _center;
602 }
603 
604 //----------------------------------------------------------------------------
605 
606 
607 void QtBaseViewer::viewingDirection( const Vec3d& _dir, const Vec3d& _up )
608 {
609  // calc eye point for this direction
610  ACG::Vec3d eye = scene_center_ - _dir*(3.0*scene_radius_);
611 
612  glstate_->reset_modelview();
613  glstate_->lookAt((ACG::Vec3d)eye, (ACG::Vec3d)scene_center_, (ACG::Vec3d)_up);
614 
615  emit viewChanged();
616 }
617 
618 
619 //-----------------------------------------------------------------------------
620 
621 void QtBaseViewer::setFovy( double _fovy )
622 {
623  // set new field of view
624  fovy_ = _fovy;
625 
626  emit viewChanged();
627 }
628 
629 //-----------------------------------------------------------------------------
630 
632 {
633  moveButton_->setDown(false);
634  lightButton_->setDown(false);
635  pickButton_->setDown(false);
636  questionButton_->setDown(false);
637 
638  trackMouse(false);
639 
640 
641  if (_am != actionMode_)
642  {
643  lastActionMode_ = actionMode_;
644  actionMode_ = _am;
645  }
646 
647 
648  switch (actionMode_)
649  {
650  case ExamineMode:
651  {
652  glView_->setCursor(Qt::PointingHandCursor);
653  glBase_->setCursor(Qt::PointingHandCursor);
654  moveButton_->setDown(true);
655  break;
656  }
657 
658 
659  case LightMode:
660  {
661  glView_->setCursor(Qt::PointingHandCursor);
662  glBase_->setCursor(Qt::PointingHandCursor);
663  lightButton_->setDown(true);
664  break;
665  }
666 
667 
668  case PickingMode:
669  {
670  glView_->setCursor(Qt::ArrowCursor);
671  glBase_->setCursor(Qt::ArrowCursor);
672  pickButton_->setDown(true);
673  if (pick_mode_idx_ != -1) {
675  glView_->setCursor(pick_modes_[pick_mode_idx_].cursor);
676  glBase_->setCursor(pick_modes_[pick_mode_idx_].cursor);
677  }
678 
679  break;
680  }
681 
682 
683  case QuestionMode:
684  {
685  glView_->setCursor(Qt::WhatsThisCursor);
686  glBase_->setCursor(Qt::WhatsThisCursor);
687  questionButton_->setDown(true);
688  break;
689  }
690  }
691 
692 
693  emit(signalActionModeChanged(actionMode_));
694 
695  //emit pickmodeChanged with either the name of the current pickmode or an empty string
696  if(actionMode_ == PickingMode)
698  else
699  emit(signalPickModeChanged(""));
700 }
701 
702 
703 //-----------------------------------------------------------------------------
704 
705 
707 {
708  makeCurrent();
709 
710  switch ( faceOrientation_ = _ori ) {
711  case CCW_ORIENTATION:
712  glFrontFace( GL_CCW );
713  break;
714 
715  case CW_ORIENTATION:
716  glFrontFace( GL_CW );
717  break;
718  }
719 
720  updateGL();
721 }
722 
723 
724 //-----------------------------------------------------------------------------
725 
726 
728 {
729  makeCurrent();
730  if (funcMenu_==0) updatePopupMenu();
731  if ( (backFaceCulling_ = _b) )
732  ACG::GLState::enable( GL_CULL_FACE );
733  else
734  ACG::GLState::disable( GL_CULL_FACE );
735 
736  action_["BackfaceCulling"]->setChecked( backFaceCulling_ );
737  updateGL();
738 }
739 
740 
742 {
743  makeCurrent();
744  if (funcMenu_==0) updatePopupMenu();
745  glstate_->set_twosided_lighting(twoSidedLighting_=_b);
746  action_["TwoSidedLighting"]->setChecked(twoSidedLighting_);
747  updateGL();
748 }
749 
750 
752 {
753  makeCurrent();
754  if (funcMenu_==0) updatePopupMenu();
755  animation_ = _b;
756  action_["Animation"]->setChecked( animation_ );
757  updateGL();
758 }
759 
760 
761 //-----------------------------------------------------------------------------
762 
763 
765 {
766  makeCurrent();
767 
768  switch(normalsMode_ = _mode)
769  {
770  case DONT_TOUCH_NORMALS:
771  ACG::GLState::disable(GL_NORMALIZE);
772  break;
773 
774  case NORMALIZE_NORMALS:
775  ACG::GLState::enable(GL_NORMALIZE);
776  break;
777  }
778 
779  updateGL();
780 }
781 
782 
783 //-----------------------------------------------------------------------------
784 
785 
786 void
788  unsigned int /* _l */ , unsigned int /* _t */ ,
789  unsigned int /* _w */ , unsigned int /* _h */ ,
790  GLenum /* _buffer */ )
791 {
792  makeCurrent();
793  _image = glWidget_->grabFrameBuffer(true);
794 }
795 
796 
797 //-----------------------------------------------------------------------------
798 
799 
801 {
802  makeCurrent();
803  paintGL();
804  swapBuffers();
805  glView_->repaint();
806 }
807 
809 {
810  if (!isUpdateLocked() && !isHidden() )
811  {
812  glScene_->update();
813  }
814 }
815 
816 
817 
818 //-----------------------------------------------------------------------------
819 
820 
821 void QtBaseViewer::drawScene()
822 {
823  QTime timer;
824  timer.start();
825 
826 
827  // *****************************************************************
828  // Adjust clipping planes
829  // *****************************************************************
830  // Far plane
831  ACG::Vec3d c = glstate_->modelview().transform_point(scene_center_);
832 
833  // Set far plane
834  far_ = std::max(0.0002f * scene_radius_, -(c[2] - scene_radius_));
835 
836  // Set near plane
837  near_ = std::max(0.0001f * scene_radius_, -(c[2] + scene_radius_));
838 
839 
841 
842  // store time since last repaint in gl state and restart timer
843  glstate_->set_msSinceLastRedraw (redrawTime_.restart ());
844 
845  // draw mono or stereo
846  makeCurrent();
847  if (stereo_) drawScene_stereo();
848  else drawScene_mono();
849 
850 
851  glFinish();
852  frame_time_ = timer.elapsed();
853 }
854 
855 
856 //-----------------------------------------------------------------------------
857 
858 
859 void QtBaseViewer::drawScene_mono()
860 {
861  emit(signalDrawScene(glstate_));
862 
863  if (sceneGraphRoot_)
864  {
865  if (! renderPicking_ ) {
866  SceneGraph::DrawAction action(curDrawMode_, *glstate_ , false);
867  SceneGraph::traverse(sceneGraphRoot_, action);
868 
869  if( blending_ )
870  {
871  SceneGraph::DrawAction action(curDrawMode_, *glstate_, true);
872  SceneGraph::traverse(sceneGraphRoot_, action);
873  }
874  } else {
875 
876  // prepare GL state
877  makeCurrent();
878 
879  ACG::GLState::disable(GL_LIGHTING);
880  glClear(GL_DEPTH_BUFFER_BIT);
881 
882  // do the picking
883  SceneGraph::PickAction action(*glstate_, pickRendererMode_, curDrawMode_);
884  SceneGraph::traverse(sceneGraphRoot_, action);
885 
886  ACG::GLState::enable(GL_LIGHTING);
887  }
888  }
889 }
890 
891 
892 //-----------------------------------------------------------------------------
893 
894 
895 void
896 QtBaseViewer::drawScene_stereo()
897 {
898  double l, r, t, b, w, h, a, radians, wd2, ndfl;
899 
900  w = glWidth();
901  h = glHeight();
902  a = w / h;
903 
904  radians = fovy_ * 0.5 / 180.0 * M_PI;
905  wd2 = near_ * tan(radians);
906  ndfl = near_ / focalDist_ * scene_radius_;
907 
908  l = -a*wd2;
909  r = a*wd2;
910  t = wd2;
911  b = -wd2;
912 
913  double offset = 0.5 * eyeDist_;
914  double offset2 = offset * ndfl;
915 
916 
917 
918  // left eye
919  glMatrixMode(GL_PROJECTION);
920  glLoadIdentity();
921  glFrustum(l+offset2, r+offset2, b, t, near_, far_);
922  glTranslatef(-offset, 0.0, 0.0);
923  glMatrixMode(GL_MODELVIEW);
924  ACG::GLState::drawBuffer(GL_BACK_LEFT);
925  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
926  drawScene_mono();
927 
928 
929  // right eye
930  glMatrixMode(GL_PROJECTION);
931  glLoadIdentity();
932  glFrustum(l-offset2, r-offset2, b, t, near_, far_);
933  glTranslatef(offset, 0.0, 0.0);
934  glMatrixMode(GL_MODELVIEW);
935  ACG::GLState::drawBuffer(GL_BACK_RIGHT);
936  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
937  drawScene_mono();
938  ACG::GLState::drawBuffer(GL_BACK);
939 }
940 
941 
942 
943 //-----------------------------------------------------------------------------
944 
945 
947 {
948  home_modelview_ = glstate_->modelview();
949  home_inverse_modelview_ = glstate_->inverse_modelview();
950  homeOrthoWidth_ = orthoWidth_;
951  home_center_ = trackball_center_;
952  home_radius_ = trackball_radius_;
953 }
954 
955 
957 {
958  makeCurrent();
959  glstate_->set_modelview(home_modelview_, home_inverse_modelview_);
960  orthoWidth_ = homeOrthoWidth_;
961  trackball_center_ = home_center_;
962  trackball_radius_ = home_radius_;
964  updateGL();
965 
966  // sync
967  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
968 
969  emit viewChanged();
970 }
971 
972 
973 //-----------------------------------------------------------------------------
974 
975 
977 {
978  makeCurrent();
979 
980  // move center (in camera coords) to origin and translate in -z dir
981  translate(-(glstate_->modelview().transform_point(scene_center_))
982  - Vec3d(0.0, 0.0, 3.0*scene_radius_ ));
983 
984  orthoWidth_ = 1.1*scene_radius_;
985  double aspect = (double) glWidth() / (double) glHeight();
986  if (aspect > 1.0) orthoWidth_ *= aspect;
988  updateGL();
989 
990  // sync
991  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
992 
993  emit viewChanged();
994 }
995 
996 
997 //-----------------------------------------------------------------------------
998 
999 
1000 void QtBaseViewer::flyTo(const QPoint& _pos, bool _move_back)
1001 {
1002  makeCurrent();
1003 
1004  unsigned int nodeIdx, targetIdx;
1005  Vec3d hitPoint;
1006 
1007  if (pick(SceneGraph::PICK_ANYTHING, _pos, nodeIdx, targetIdx, &hitPoint))
1008  {
1009  if (projectionMode_ == PERSPECTIVE_PROJECTION)
1010  {
1011  Vec3d eye(glState().eye());
1012  Vec3d t = hitPoint - eye;
1013  Vec3d e = eye + t * (_move_back ? -0.5f : 0.5f);
1014  flyTo(e, hitPoint, 300);
1015  }
1016  else
1017  {
1018  // Zoom in or out?
1019  orthoWidth_ *= _move_back ? 2.0 : 0.5;
1020 
1021  // Set the double click point as the new trackball center
1022  // Rotations will use this point as the center.
1023  trackball_center_ = hitPoint;
1024 
1026 
1027  // Update the projection matrix
1029 
1030  // Redraw scene
1031  updateGL();
1032  }
1033 
1034  // sync with external viewer
1035  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
1036 
1037  emit viewChanged();
1038  }
1039 }
1040 
1041 
1042 void QtBaseViewer::flyTo(const Vec3d& _position,
1043  const Vec3d& _center,
1044  double _time)
1045 {
1046  makeCurrent();
1047 
1048  // compute rotation
1049  Vec3d c = glstate_->modelview().transform_point(_center);
1050  Vec3d p = glstate_->modelview().transform_point(_position);
1051  Vec3d view =(p-c).normalize();
1052  Vec3d z(0,0,1);
1053  Vec3d axis = (z % -view).normalize();
1054  double angle = acos(std::max(-1.0,
1055  std::min(1.0,
1056  (z | view)))) / M_PI * 180.0;
1057 
1058  if (angle > 175)
1059  axis = Vec3d(0,1,0);
1060 
1061 
1062  // compute translation
1063  Vec3d target = glstate_->modelview().transform_point(_center);
1064  Vec3d trans ( -target[0],
1065  -target[1],
1066  -target[2] - (_position-_center).norm() );
1067 
1068 
1069 
1070  // how many frames in _time ms ?
1071  unsigned int frames = (unsigned int)(_time / frame_time_);
1072  if (frames > 1000) frames=1000;
1073 
1074 
1075 
1076 
1077  // animate it
1078  if (frames > 10)
1079  {
1080  Vec3d t = trans / (double)frames;
1081  double a = angle / (double)frames;
1082 
1083  for (unsigned int i=0; i<frames; ++i)
1084  {
1085  translate(t);
1086  if (fabs(a) > FLT_MIN)
1087  rotate(axis, a, _center);
1088 
1089  drawNow();
1090  }
1091  }
1092 
1093 
1094  // no animation
1095  else
1096  {
1097  translate(trans);
1098  if (fabs(angle) > FLT_MIN)
1099  rotate(axis, angle, _center);
1100 
1101  updateGL();
1102  }
1103 
1104 
1105  trackball_center_ = _center;
1106  trackball_radius_ = std::max(scene_radius_,
1107  (_center-_position).norm()*0.9f);
1108 }
1109 
1110 
1111 //-----------------------------------------------------------------------------
1112 
1113 
1114 void QtBaseViewer::setView(const GLMatrixd& _modelview,
1115  const GLMatrixd& _inverse_modelview)
1116 {
1117  makeCurrent();
1118  glstate_->set_modelview(_modelview, _inverse_modelview);
1119  updateGL();
1120 }
1121 
1122 
1123 //-----------------------------------------------------------------------------
1124 
1125 
1127 {
1128  // we use GLEW to manage extensions
1129  // initialize it first
1130  #ifndef __APPLE__
1131  glewInit();
1132  #endif
1133 
1134 
1135  // lock update
1136  lockUpdate();
1137 
1138  // init GL state
1139  glstate_->initialize();
1140 
1141  // OpenGL state
1142  ACG::GLState::enable(GL_DEPTH_TEST);
1143  ACG::GLState::enable(GL_LIGHTING);
1144  ACG::GLState::disable(GL_DITHER);
1145  ACG::GLState::shadeModel( GL_FLAT );
1146 
1147 
1148  projectionMode( projectionMode_ );
1149  normalsMode( normalsMode_ );
1150  faceOrientation( faceOrientation_ );
1151  backFaceCulling( backFaceCulling_ );
1152  twoSidedLighting( twoSidedLighting_ );
1153 
1154 
1155  // light sources
1156  light_matrix_.identity();
1157  update_lights();
1158 
1159 
1160  // scene pos and size
1161  scene_center_ = trackball_center_ = Vec3d( 0.0, 0.0, 0.0 );
1162  scene_radius_ = trackball_radius_ = 1.0;
1163  orthoWidth_ = 2.0;
1164 
1165 
1166  // modelview
1167  glstate_->translate(0.0, 0.0, -3.0);
1168  setHome();
1169 
1170 
1171  // pixel transfer
1172  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1173  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1174  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1175  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1176  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1177  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1178  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1179  glPixelStorei(GL_PACK_ALIGNMENT, 1);
1180 
1181 
1182  // emit initialization signal
1183  emit(signalInitializeGL());
1184 
1185 
1186  // unlock update (we started locked)
1187  unlockUpdate();
1188 }
1189 
1190 
1191 //-----------------------------------------------------------------------------
1192 
1193 
1195 {
1196  makeCurrent();
1197 
1198  glMatrixMode(GL_MODELVIEW);
1199  glPushMatrix();
1200  glLoadIdentity();
1201  glMultMatrixd(light_matrix_.data());
1202 
1203  GLfloat pos[4], col[4];
1204 
1205  col[0] = col[1] = col[2] = 0.7f;
1206  pos[3] = col[3] = 0.0f;
1207 
1208 #define SET_LIGHT(i,x,y,z) { \
1209  pos[0]=x; pos[1]=y; pos[2]=z; \
1210  glLightfv(GL_LIGHT##i, GL_POSITION, pos); \
1211  glLightfv(GL_LIGHT##i, GL_DIFFUSE, col); \
1212  glLightfv(GL_LIGHT##i, GL_SPECULAR, col); \
1213  ACG::GLState::enable(GL_LIGHT##i); \
1214  }
1215 
1216  SET_LIGHT(0, 0.0f, 0.0f, 1.0f);
1217  SET_LIGHT(1, -1.0f, 1.0f, 0.7f);
1218  SET_LIGHT(2, 1.0f, 1.0f, 0.7f);
1219 
1220  col[0] = col[1] = col[2] = 0.3f; col[3] = 1.0f;
1221  glLightModelfv(GL_LIGHT_MODEL_AMBIENT, col);
1222 
1223  glPopMatrix();
1224 }
1225 
1226 
1227 void QtBaseViewer::rotate_lights(Vec3d& _axis, double _angle)
1228 {
1229  light_matrix_.rotate(_angle, _axis[0], _axis[1], _axis[2], MULT_FROM_LEFT);
1230  update_lights();
1231 }
1232 
1233 
1234 //-----------------------------------------------------------------------------
1235 
1236 
1238 {
1239  static bool initialized = false;
1240  if (!initialized)
1241  {
1242  // we use GLEW to manage extensions
1243  // initialize it first
1244  #ifndef __APPLE__
1245  glewInit();
1246  #endif
1247 
1248  // lock update
1249  lockUpdate();
1250 
1251  // init GL state
1252  glstate_->initialize();
1253 
1254  // initialize lights
1255  light_matrix_.identity();
1256 
1257  // scene pos and size
1258  scene_center_ = trackball_center_ = Vec3d( 0.0, 0.0, 0.0 );
1259  scene_radius_ = trackball_radius_ = 1.0;
1260  orthoWidth_ = 2.0;
1261 
1262  // modelview
1263  glstate_->translate(0.0, 0.0, -3.0);
1264  setHome();
1265 
1266  // pixel transfer
1267  glPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
1268  glPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
1269  glPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
1270  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
1271  glPixelStorei(GL_PACK_ROW_LENGTH, 0);
1272  glPixelStorei(GL_PACK_SKIP_ROWS, 0);
1273  glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
1274  glPixelStorei(GL_PACK_ALIGNMENT, 1);
1275 
1276  // emit initialization signal
1277  emit(signalInitializeGL());
1278 
1279  // unlock update (we started locked)
1280  unlockUpdate();
1281 
1282  initialized = true;
1283  }
1284 
1285  if (!isUpdateLocked())
1286  {
1287  lockUpdate();
1288 
1289  glPushAttrib (GL_ALL_ATTRIB_BITS);
1290 
1291  ACG::GLState::enable(GL_DEPTH_TEST);
1292  ACG::GLState::enable(GL_LIGHTING);
1293  ACG::GLState::disable(GL_DITHER);
1294  ACG::GLState::shadeModel( GL_FLAT );
1295 
1296  glMatrixMode(GL_PROJECTION);
1297  glPushMatrix();
1298 
1299  glMatrixMode(GL_MODELVIEW);
1300  glPushMatrix();
1301 
1302 
1303  normalsMode( normalsMode_ );
1304  faceOrientation( faceOrientation_ );
1305  backFaceCulling( backFaceCulling_ );
1306 
1307  // light sources
1308  update_lights();
1309 
1310  glstate_->setState ();
1311 
1312  glColor4f(1.0,0.0,0.0,1.0);
1313 
1314  // clear (stereo mode clears buffers on its own)
1315  if (!stereo_)
1316  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
1317 
1318  unlockUpdate();
1319 
1320  // draw scene
1321  drawScene();
1322 
1323  glPopMatrix();
1324 
1325  glMatrixMode(GL_PROJECTION);
1326  glPopMatrix();
1327 
1328  glPopAttrib ();
1329  }
1330 }
1331 
1332 
1333 //-----------------------------------------------------------------------------
1334 
1335 
1336 void QtBaseViewer::resizeGL(int _w, int _h)
1337 {
1339  glstate_->viewport(0, 0, _w, _h);
1340  updateGL();
1341 }
1342 
1343 
1344 //-----------------------------------------------------------------------------
1345 
1346 void QtBaseViewer::encodeView(QString& _view)
1347 {
1348  // Get current matrices
1349  const ACG::GLMatrixd& m = glstate_->modelview();
1350  const ACG::GLMatrixd& p = glstate_->projection();
1351 
1352  // Add modelview matrix to output
1353  _view += QString(VIEW_MAGIC) + "\n";
1354  _view += QString::number(m(0,0)) + " " + QString::number(m(0,1)) + " " + QString::number(m(0,2)) + " " + QString::number(m(0,3)) + "\n";
1355  _view += QString::number(m(1,0)) + " " + QString::number(m(1,1)) + " " + QString::number(m(1,2)) + " " + QString::number(m(1,3)) + "\n";
1356  _view += QString::number(m(2,0)) + " " + QString::number(m(2,1)) + " " + QString::number(m(2,2)) + " " + QString::number(m(2,3)) + "\n";
1357  _view += QString::number(m(3,0)) + " " + QString::number(m(3,1)) + " " + QString::number(m(3,2)) + " " + QString::number(m(3,3)) + "\n";
1358 
1359  // Add projection matrix to output
1360  _view += QString::number(p(0,0)) + " " + QString::number(p(0,1)) + " " + QString::number(p(0,2)) + " " + QString::number(p(0,3)) + "\n";
1361  _view += QString::number(p(1,0)) + " " + QString::number(p(1,1)) + " " + QString::number(p(1,2)) + " " + QString::number(p(1,3)) + "\n";
1362  _view += QString::number(p(2,0)) + " " + QString::number(p(2,1)) + " " + QString::number(p(2,2)) + " " + QString::number(p(2,3)) + "\n";
1363  _view += QString::number(p(3,0)) + " " + QString::number(p(3,1)) + " " + QString::number(p(3,2)) + " " + QString::number(p(3,3)) + "\n";
1364 
1365  // add gl width/height, current projection Mode and the ortho mode width to output
1366  _view += QString::number(glWidth()) + " " + QString::number(glHeight()) + " " + QString::number(projectionMode_) + " " + QString::number(orthoWidth_) + "\n";
1367 }
1368 
1369 
1370 //----------------------------------------------------------------------------
1371 
1372 
1373 bool QtBaseViewer::decodeView(const QString& _view)
1374 {
1375  if (_view.left(sizeof(VIEW_MAGIC)-1) != QString(VIEW_MAGIC))
1376  return false;
1377 
1378  // Remove the magic from the string
1379  QString temp = _view;
1380  temp.remove(0,sizeof(VIEW_MAGIC));
1381 
1382  //Split it into its components
1383  QStringList split = temp.split(QRegExp("[\\n\\s]"),QString::SkipEmptyParts);
1384 
1385  ACG::GLMatrixd m, p;
1386  int w, h, pMode;
1387 
1388  // Check if the number of components matches the expected size
1389  if ( split.size() != 36 ) {
1390  std::cerr << "Unable to paste view ... wrong parameter count!! is" << split.size() << std::endl;
1391  return false;
1392  }
1393 
1394  // Parse the components
1395  bool ok = true;;
1396 
1397  m(0,0) = split[0].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1398  m(0,1) = split[1].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1399  m(0,2) = split[2].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1400  m(0,3) = split[3].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1401  m(1,0) = split[4].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1402  m(1,1) = split[5].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1403  m(1,2) = split[6].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1404  m(1,3) = split[7].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1405  m(2,0) = split[8].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1406  m(2,1) = split[9].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1407  m(2,2) = split[10].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1408  m(2,3) = split[11].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1409  m(3,0) = split[12].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1410  m(3,1) = split[13].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1411  m(3,2) = split[14].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1412  m(3,3) = split[15].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1413  p(0,0) = split[16].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1414  p(0,1) = split[17].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1415  p(0,2) = split[18].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1416  p(0,3) = split[19].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1417  p(1,0) = split[20].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1418  p(1,1) = split[21].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1419  p(1,2) = split[22].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1420  p(1,3) = split[23].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1421  p(2,0) = split[24].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1422  p(2,1) = split[25].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1423  p(2,2) = split[26].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1424  p(2,3) = split[27].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1425  p(3,0) = split[28].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1426  p(3,1) = split[29].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1427  p(3,2) = split[30].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1428  p(3,3) = split[31].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1429 
1430  w = split[32].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1431  h = split[33].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1432  pMode = split[34].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1433  orthoWidth_ = split[35].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1434 
1435  // Switch to our gl context
1436  makeCurrent();
1437 
1438  // set projection mode
1439  if (projectionMode_ != (ProjectionMode)pMode)
1441 
1442  // Apply new modelview matrix
1443  glstate_->set_modelview(m);
1444 
1445 
1446  if (w>0 && h>0 &&
1447  action_["PasteDropSize"]->isChecked() )
1448  {
1449  glstate_->set_projection(p);
1450  glView_->setFixedSize(w,h);
1451  updateGeometry();
1452  }
1453 
1454 
1455  updateGL();
1456 
1457 
1458  return true;
1459 }
1460 
1461 
1462 //-----------------------------------------------------------------------------
1463 
1464 
1465 void QtBaseViewer::actionDrawMenu( QAction * _action )
1466 {
1467  SceneGraph::DrawModes::DrawMode mode( _action->data().toUInt() );
1468 
1469  // combine draw modes
1470  if (qApp->keyboardModifiers() & Qt::ShiftModifier)
1471  {
1472  if (drawMode() & mode)
1473  drawMode(drawMode() & ~mode);
1474  else
1475  drawMode(drawMode() | mode);
1476  }
1477 
1478  // simply switch draw mode
1479  else
1480  {
1481  // clear all other checked items
1482  std::vector< QAction * >::iterator aIter, aEnd;
1483 
1484  aEnd = drawMenuActions_.end();
1485  for( aIter = drawMenuActions_.begin();
1486  aIter != aEnd;
1487  ++aIter )
1488  {
1489  if( SceneGraph::DrawModes::DrawMode((*aIter)->data().toUInt()) != mode )
1490  (*aIter)->setChecked( false );
1491  }
1492 
1493  drawMode(mode);
1494  }
1495 
1496  hidePopupMenus();
1497  updateGL();
1498 }
1499 
1500 
1501 //-----------------------------------------------------------------------------
1502 
1503 
1504 void QtBaseViewer::actionBackground()
1505 {
1506  const Vec4f bc = glstate_->clear_color() * 255.0;
1507  QColor backCol((int)bc[0], (int)bc[1], (int)bc[2]);
1508  QColor c = QColorDialog::getColor(backCol,this);
1509  if (c != backCol && c.isValid())
1510  backgroundColor(Vec4f(((double) c.red()) / 255.0,
1511  ((double) c.green()) / 255.0,
1512  ((double) c.blue()) / 255.0,
1513  1.0));
1514 
1515 }
1516 
1517 //-----------------------------------------------------------------------------
1518 
1519 
1520 void QtBaseViewer::actionCopyView()
1521 {
1522  QString view; encodeView(view);
1523  QApplication::clipboard()->setText(view);
1524 }
1525 
1526 
1527 //-----------------------------------------------------------------------------
1528 
1529 
1530 void QtBaseViewer::actionPasteView()
1531 {
1532  QString view; view=QApplication::clipboard()->text();
1533  decodeView(view);
1534 }
1535 
1536 
1537 //-----------------------------------------------------------------------------
1538 
1539 
1540 void QtBaseViewer::actionPasteDropSize()
1541 {
1542 }
1543 
1544 //-----------------------------------------------------------------------------
1545 
1546 
1547 void QtBaseViewer::actionSynchronize()
1548 {
1549  setSynchronization( action_["Synchronize"]->isChecked() );
1550 }
1551 
1552 //-----------------------------------------------------------------------------
1553 
1554 void QtBaseViewer::actionSynchronize(bool _enable)
1555 {
1556  setSynchronization( _enable );
1557 }
1558 
1560  return synchronized_;
1561 }
1562 
1563 //-----------------------------------------------------------------------------
1564 
1565 void QtBaseViewer::actionAnimation()
1566 {
1567  animation(!animation());
1568 }
1569 
1570 //-----------------------------------------------------------------------------
1571 
1572 void QtBaseViewer::actionAnimation(bool _enable)
1573 {
1574  animation(_enable);
1575 }
1576 
1577 //-----------------------------------------------------------------------------
1578 
1579 void QtBaseViewer::actionBackfaceCulling()
1580 {
1582 }
1583 
1584 //-----------------------------------------------------------------------------
1585 
1586 void QtBaseViewer::actionBackfaceCulling(bool _enable)
1587 {
1588  backFaceCulling(_enable);
1589 }
1590 
1591 //-----------------------------------------------------------------------------
1592 
1593 void QtBaseViewer::actionTwoSidedLighting()
1594 {
1596 }
1597 
1598 //-----------------------------------------------------------------------------
1599 
1600 void QtBaseViewer::actionTwoSidedLighting(bool _enable)
1601 {
1602  twoSidedLighting(_enable);
1603 }
1604 
1605 //-----------------------------------------------------------------------------
1606 
1607 void
1608 QtBaseViewer::createWidgets(const QGLFormat* _format,
1609  QStatusBar* _sb,
1610  const QtBaseViewer* _share)
1611 {
1612  statusbar_=privateStatusBar_=0;
1613  setStatusBar(_sb);
1614  drawMenu_=0;
1615  funcMenu_=0;
1616  pickMenu_=0;
1617 
1618 
1619  // contains splitter and eventually status bar
1620  // QT3: Q3VBoxLayout* layout=new Q3VBoxLayout(this,0,0,"toplevel layout");
1621  QVBoxLayout* layout=new QVBoxLayout(this);
1622  layout->setSpacing( 0 );
1623  layout->setMargin( 0 );
1624 
1625  // contains glarea and buttons
1626 
1627  // QT3: Q3Frame* work=new Q3Frame(this,"box-glarea-buttons");
1628  QFrame* work=new QFrame(this);
1629 
1630  layout->addWidget(work,1); // gets all stretch
1631 
1632 
1633  // private status bar
1634  assert(statusbar_!=0);
1635  if (privateStatusBar_!=0)
1636  layout->addWidget(privateStatusBar_,0); // no stretch
1637 
1638 
1639  // Construct GL context & widget
1640  QGLWidget* share = 0;
1641  if (_share) share = _share->glWidget_;
1642 
1643  QGLFormat format;
1644  format.setAlpha(true);
1645  if (_format!=0) format = *_format;
1646 
1647  glWidget_ = new QGLWidget(format, 0, share);
1648  glView_ = new QtGLGraphicsView(this, work);
1649  glScene_ = new QtGLGraphicsScene (this);
1650 
1651  glView_->setViewport(glWidget_);
1652  glView_->setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
1653  glView_->setScene(glScene_);
1654  glView_->setFrameStyle(QFrame::NoFrame);
1655 
1656  wheelZ_=new QtWheel( 0,"wheel-z",QtWheel::Vertical);
1657  wheelZ_->setMinimumSize(wheelZ_->sizeHint());
1658  wheelZ_->setMaximumSize(wheelZ_->sizeHint());
1659  connect(wheelZ_,SIGNAL(angleChangedBy(double)),
1660  this,SLOT(slotWheelZ(double)));
1661  wheelZ_->setToolTip( "Translate along <b>z-axis</b>.");
1662  wheelZ_->setWhatsThis( "Translate along <b>z-axis</b>.");
1663  if ((options_&ShowWheelZ)==0)
1664  wheelZ_->hide();
1665 
1666  wheelY_=new QtWheel( 0,"wheel-y",QtWheel::Horizontal);
1667  wheelY_->setMinimumSize(wheelY_->sizeHint());
1668  wheelY_->setMaximumSize(wheelY_->sizeHint());
1669  connect(wheelY_,SIGNAL(angleChangedBy(double)),
1670  this,SLOT(slotWheelY(double)));
1671  wheelY_->setToolTip("Rotate around <b>y-axis</b>.");
1672  wheelY_->setWhatsThis( "Rotate around <b>y-axis</b>.");
1673  if ((options_&ShowWheelY)==0)
1674  wheelY_->hide();
1675 
1676  wheelX_=new QtWheel( 0,"wheel-x",QtWheel::Vertical);
1677  wheelX_->setMinimumSize(wheelX_->sizeHint());
1678  wheelX_->setMaximumSize(wheelX_->sizeHint());
1679  connect(wheelX_,SIGNAL(angleChangedBy(double)),
1680  this,SLOT(slotWheelX(double)));
1681  wheelX_->setToolTip("Rotate around <b>x-axis</b>.");
1682  wheelX_->setWhatsThis( "Rotate around <b>x-axis</b>.");
1683  if ((options_&ShowWheelX)==0)
1684  wheelX_->hide();
1685 
1686 
1687  QGraphicsWidget *wheelX = glScene_->addWidget (wheelX_);
1688  QGraphicsWidget *wheelY = glScene_->addWidget (wheelY_);
1689  QGraphicsWidget *wheelZ = glScene_->addWidget (wheelZ_);
1690 
1691  wheelX_->setWindowOpacity (0.5);
1692  wheelY_->setWindowOpacity (0.5);
1693  wheelZ_->setWindowOpacity (0.5);
1694 
1695  wheelX->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1696  wheelY->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1697  wheelZ->setCacheMode(QGraphicsItem::DeviceCoordinateCache);
1698 
1699  glBaseLayout_ = new QGraphicsGridLayout;
1700  glBaseLayout_->addItem(wheelX, 1, 0);
1701  glBaseLayout_->addItem(wheelY, 2, 1);
1702  glBaseLayout_->addItem(wheelZ, 1, 3);
1703 
1704  glBaseLayout_->setColumnStretchFactor(0,0);
1705  glBaseLayout_->setColumnStretchFactor(1,0);
1706  glBaseLayout_->setColumnStretchFactor(2,1);
1707  glBaseLayout_->setColumnStretchFactor(3,0);
1708 
1709  glBaseLayout_->setRowStretchFactor(0,1);
1710  glBaseLayout_->setRowStretchFactor(1,0);
1711  glBaseLayout_->setRowStretchFactor(2,0);
1712 
1713  glBase_ = new QGraphicsWidget;
1714  glBase_->setLayout(glBaseLayout_);
1715  glScene_->addItem(glBase_);
1716  glBase_->setGeometry (glScene_->sceneRect ());
1717  //QRectF r = glScene_->sceneRect ();
1718 
1719  connect ( glScene_, SIGNAL( sceneRectChanged( const QRectF & ) ),
1720  this, SLOT( sceneRectChanged( const QRectF & ) ) );
1721 
1722  // If popupEnabled_ this signal will not be emitted!
1723  // If popupEnabled_ is set to false the Contextmenu Mode will be set to customContextMenuRequested
1724  // and this signal will be emitted on right click
1725  connect( glView_ , SIGNAL( customContextMenuRequested( const QPoint& ) ) ,
1726  this , SIGNAL( signalCustomContextMenuRequested( const QPoint& ) ) );
1727 
1728  // is stereo possible ?
1729  if (format.stereo())
1730  std::cerr << "Stereo buffer requested: "
1731  << (glWidget_->format().stereo() ? "ok\n" : "failed\n");
1732 
1733 
1734  // toolbar
1735  buttonBar_= new QToolBar( "Viewer Toolbar", work );
1736  buttonBar_->setOrientation(Qt::Vertical);
1737 
1738  moveButton_ = new QToolButton( buttonBar_ );
1739  moveButton_->setIcon( QPixmap(moveIcon) );
1740  moveButton_->setMinimumSize( 16, 16 );
1741  moveButton_->setMaximumSize( 32, 32 );
1742  moveButton_->setToolTip( "Switch to <b>move</b> mode." );
1743  moveButton_->setWhatsThis(
1744  "Switch to <b>move</b> mode.<br>"
1745  "<ul><li><b>Rotate</b> using <b>left</b> mouse button.</li>"
1746  "<li><b>Translate</b> using <b>middle</b> mouse button.</li>"
1747  "<li><b>Zoom</b> using <b>left+middle</b> mouse buttons.</li></ul>" );
1748  QObject::connect( moveButton_, SIGNAL( clicked() ),
1749  this, SLOT( examineMode() ) );
1750 
1751  buttonBar_->addWidget( moveButton_)->setText("Move");
1752 
1753  lightButton_ = new QToolButton( buttonBar_ );
1754  lightButton_->setIcon( QPixmap(lightIcon) );
1755  lightButton_->setMinimumSize( 16, 16 );
1756  lightButton_->setMaximumSize( 32, 32 );
1757  lightButton_->setToolTip("Switch to <b>light</b> mode.");
1758  lightButton_->setWhatsThis(
1759  "Switch to <b>light</b> mode.<br>"
1760  "Rotate lights using left mouse button.");
1761  QObject::connect( lightButton_, SIGNAL( clicked() ),
1762  this, SLOT( lightMode() ) );
1763  buttonBar_->addWidget( lightButton_)->setText("Light");
1764 
1765 
1766  pickButton_ = new QToolButton( buttonBar_ );
1767  pickButton_->setIcon( QPixmap(pickIcon) );
1768  pickButton_->setMinimumSize( 16, 16 );
1769  pickButton_->setMaximumSize( 32, 32 );
1770  pickButton_->setToolTip("Switch to <b>picking</b> mode.");
1771  pickButton_->setWhatsThis(
1772  "Switch to <b>picking</b> mode.<br>"
1773  "Use picking functions like flipping edges.<br>"
1774  "To change the mode use the right click<br>"
1775  "context menu in the viewer.");
1776  QObject::connect( pickButton_, SIGNAL( clicked() ),
1777  this, SLOT( pickingMode() ) );
1778  buttonBar_->addWidget( pickButton_)->setText("Pick");
1779 
1780 
1781  questionButton_ = new QToolButton( buttonBar_ );
1782  questionButton_->setIcon( QPixmap(questionIcon) );
1783  questionButton_->setMinimumSize( 16, 16 );
1784  questionButton_->setMaximumSize( 32, 32 );
1785  questionButton_->setToolTip("Switch to <b>identification</b> mode.");
1786  questionButton_->setWhatsThis(
1787  "Switch to <b>identification</b> mode.<br>"
1788  "Use identification mode to get information "
1789  "about objects. Click on an object and see "
1790  "the log output for information about the "
1791  "object.");
1792  QObject::connect( questionButton_, SIGNAL( clicked() ),
1793  this, SLOT( questionMode() ) );
1794  buttonBar_->addWidget( questionButton_)->setText("Question");
1795 
1796  buttonBar_->addSeparator();
1797 
1798  homeButton_ = new QToolButton( buttonBar_ );
1799  homeButton_->setIcon( QPixmap(homeIcon) );
1800  homeButton_->setMinimumSize( 16, 16 );
1801  homeButton_->setMaximumSize( 32, 32 );
1802  homeButton_->setCheckable( false );
1803  homeButton_->setToolTip("Restore <b>home</b> view.");
1804  homeButton_->setWhatsThis(
1805  "Restore home view<br><br>"
1806  "Resets the view to the home view");
1807  QObject::connect( homeButton_, SIGNAL( clicked() ),
1808  this, SLOT( home() ) );
1809  buttonBar_->addWidget( homeButton_)->setText("Home");
1810 
1811 
1812  setHomeButton_ = new QToolButton( buttonBar_ );
1813  setHomeButton_->setIcon( QPixmap(sethomeIcon) );
1814  setHomeButton_->setMinimumSize( 16, 16 );
1815  setHomeButton_->setMaximumSize( 32, 32 );
1816  setHomeButton_->setCheckable( false );
1817  setHomeButton_->setToolTip("Set <b>home</b> view");
1818  setHomeButton_->setWhatsThis(
1819  "Store home view<br><br>"
1820  "Stores the current view as the home view");
1821  QObject::connect( setHomeButton_, SIGNAL( clicked() ),
1822  this, SLOT( setHome() ) );
1823  buttonBar_->addWidget( setHomeButton_)->setText("Set Home");
1824 
1825 
1826  viewAllButton_ = new QToolButton( buttonBar_ );
1827  viewAllButton_->setIcon( QPixmap(viewallIcon) );
1828  viewAllButton_->setMinimumSize( 16, 16 );
1829  viewAllButton_->setMaximumSize( 32, 32 );
1830  viewAllButton_->setCheckable( false );
1831  viewAllButton_->setToolTip("View all.");
1832  viewAllButton_->setWhatsThis(
1833  "View all<br><br>"
1834  "Move the objects in the scene so that"
1835  " the whole scene is visible.");
1836  QObject::connect( viewAllButton_, SIGNAL( clicked() ),
1837  this, SLOT( viewAll() ) );
1838  buttonBar_->addWidget( viewAllButton_)->setText("View all");
1839 
1840 
1841  projectionButton_ = new QToolButton( buttonBar_ );
1842  projectionButton_->setIcon( QPixmap(perspectiveIcon) );
1843  projectionButton_->setMinimumSize( 16, 16 );
1844  projectionButton_->setMaximumSize( 32, 32 );
1845  projectionButton_->setCheckable( false );
1846  projectionButton_->setToolTip(
1847  "Switch between <b>perspective</b> and "
1848  "<b>parrallel</b> projection mode.");
1849  projectionButton_->setWhatsThis(
1850  "Switch projection modes<br><br>"
1851  "Switch between <b>perspective</b> and "
1852  "<b>parrallel</b> projection mode.");
1853  QObject::connect( projectionButton_, SIGNAL( clicked() ),
1854  this, SLOT( toggleProjectionMode() ) );
1855  buttonBar_->addWidget( projectionButton_)->setText( "Projection" );
1856 
1857 
1858  if (glWidget_->format().stereo())
1859  {
1860  stereoButton_ = new QToolButton( buttonBar_ );
1861  stereoButton_->setIcon( QPixmap(monoIcon) );
1862  stereoButton_->setMinimumSize( 16, 16 );
1863  stereoButton_->setMaximumSize( 32, 32 );
1864  stereoButton_->setCheckable( true );
1865  stereoButton_->setToolTip( "Toggle stereo viewing");
1866  stereoButton_->setWhatsThis(
1867  "Toggle stereo mode<br><br>"
1868  "Use this button to switch between stereo "
1869  "and mono view. To use this feature you need "
1870  "a stereo capable graphics card and a stereo "
1871  "display/projection system.");
1872  QObject::connect( stereoButton_, SIGNAL( clicked() ),
1873  this, SLOT( toggleStereoMode() ) );
1874  buttonBar_->addWidget( stereoButton_)->setText( "Stereo");
1875  }
1876 
1877  buttonBar_->addSeparator();
1878 
1879  sceneGraphButton_ = new QToolButton( buttonBar_ );
1880  sceneGraphButton_->setIcon( QPixmap(sceneGraphIcon) );
1881  sceneGraphButton_->setMinimumSize( 16, 16 );
1882  sceneGraphButton_->setMaximumSize( 32, 32 );
1883  sceneGraphButton_->setCheckable( false );
1884  sceneGraphButton_->setToolTip("Toggle scene graph viewer.");
1885  sceneGraphButton_->setWhatsThis(
1886  "Toggle scene graph viewer<br><br>"
1887  "The scene graph viewer enables you to examine the "
1888  "displayed scene graph and to modify certain nodes.<br><br>"
1889  "There are three modi for the scene graph viewer:"
1890  "<ul><li><b>hidden</b></li>"
1891  "<li><b>split</b>: share space</li>"
1892  "<li><b>dialog</b>: own dialog window</li></ul>"
1893  "This button toggles between these modi.");
1894  QObject::connect( sceneGraphButton_, SIGNAL( clicked() ),
1895  this, SLOT( showSceneGraphDialog() ) );
1896  buttonBar_->addWidget( sceneGraphButton_)->setText( "SceneGraph" );
1897 
1898  glLayout_ = new QGridLayout(work);
1899  glLayout_->setSpacing( 0 );
1900  glLayout_->setMargin( 0 );
1901 
1902  glLayout_->addWidget(glView_, 0,0);
1903  glLayout_->addWidget(buttonBar_, 0,1);
1904 
1905  glLayout_->setColumnStretch(0,1);
1906  glLayout_->setColumnStretch(1,0);
1907 
1908  if (!(options_ & ShowToolBar))
1909  buttonBar_->hide();
1910 
1911 }
1912 
1913 
1914 //-----------------------------------------------------------------------------
1915 
1916 
1917 void QtBaseViewer::updatePopupMenu()
1918 {
1919  //
1920  // Draw mode menu
1921  //
1922 
1923  if ( ! drawMenu_ )
1924  {
1925  drawMenu_ = new QMenu( this );
1926  connect( drawMenu_, SIGNAL( aboutToHide() ),
1927  this, SLOT( hidePopupMenus() ) );
1928 
1929  }
1930 
1931  QActionGroup * drawGroup = new QActionGroup( this );
1932  drawGroup->setExclusive( false );
1933  connect( drawGroup, SIGNAL( triggered( QAction * ) ),
1934  this, SLOT( actionDrawMenu( QAction * ) ) );
1935 
1936 
1937 
1938  drawMenuActions_.clear();
1939 
1940  std::vector< SceneGraph::DrawModes::DrawMode > draw_mode_id;
1941 
1942  draw_mode_id = availDrawModes_.getAtomicDrawModes();
1943 
1944  for ( unsigned int i = 0; i < draw_mode_id.size(); ++i )
1945  {
1946  SceneGraph::DrawModes::DrawMode id = draw_mode_id[i];
1947  std::string descr = id.description();
1948 
1949  QAction * action = new QAction( descr.c_str(), drawGroup );
1950  action->setData( QVariant( quint64(id.getIndex() ) ) );
1951  action->setCheckable( true );
1952  action->setChecked( curDrawMode_.containsAtomicDrawMode(id) );
1953  drawMenuActions_.push_back( action );
1954  }
1955 
1956 
1957  drawMenu_->clear();
1958  drawMenu_->addActions( drawGroup->actions() );
1959 
1960 
1961  // function menu
1962 
1963  if (!funcMenu_)
1964  {
1965  funcMenu_=new QMenu( this );
1966 
1967  funcMenu_->addAction( action_[ "Background" ] );
1968  funcMenu_->addSeparator();
1969  funcMenu_->addAction( action_[ "Snapshot" ] );
1970  funcMenu_->addAction( action_[ "SnapshotName" ] );
1971  funcMenu_->addAction( action_[ "SnapshotSavesView" ] );
1972  funcMenu_->addSeparator();
1973  funcMenu_->addAction( action_[ "CopyView" ] );
1974  funcMenu_->addAction( action_[ "PasteView" ] );
1975  funcMenu_->addAction( action_[ "PasteDropSize" ] );
1976  funcMenu_->addSeparator();
1977  funcMenu_->addAction( action_[ "Synchronize" ] );
1978  funcMenu_->addSeparator();
1979  funcMenu_->addAction( action_[ "Animation" ] );
1980  funcMenu_->addAction( action_[ "BackfaceCulling" ] );
1981  funcMenu_->addAction( action_[ "TwoSidedLighting" ] );
1982 
1983  connect( funcMenu_, SIGNAL( aboutToHide() ),
1984  this, SLOT( hidePopupMenus() ) );
1985  }
1986 
1987 
1988 }
1989 
1990 
1991 //-----------------------------------------------------------------------------
1992 
1993 
1994 void QtBaseViewer::hidePopupMenus()
1995 {
1996  if ( drawMenu_ )
1997  {
1998  drawMenu_->blockSignals(true);
1999  drawMenu_->hide();
2000  drawMenu_->blockSignals(false);
2001  }
2002 
2003  if ( funcMenu_ )
2004  {
2005  funcMenu_->blockSignals(true);
2006  funcMenu_->hide();
2007  funcMenu_->blockSignals(false);
2008  }
2009 
2010  if ( pickMenu_ )
2011  {
2012  pickMenu_->blockSignals(true);
2013  pickMenu_->hide();
2014  pickMenu_->blockSignals(false);
2015  }
2016 }
2017 
2018 
2019 //-----------------------------------------------------------------------------
2020 
2021 
2022 void QtBaseViewer::translate(const Vec3d& _trans)
2023 {
2024  makeCurrent();
2025  glstate_->translate(_trans[0], _trans[1], _trans[2], MULT_FROM_LEFT);
2026 }
2027 
2028 
2029 //-----------------------------------------------------------------------------
2030 
2031 
2033 {
2034  makeCurrent();
2035  glstate_->reset_modelview();
2036 }
2037 
2038 
2039 //-----------------------------------------------------------------------------
2040 
2041 
2042 void QtBaseViewer::rotate(const Vec3d& _axis,
2043  double _angle,
2044  const Vec3d& _center)
2045 {
2046  makeCurrent();
2047  Vec3d t = glstate_->modelview().transform_point(_center);
2048  glstate_->translate(-t[0], -t[1], -t[2], MULT_FROM_LEFT);
2049  glstate_->rotate(_angle, _axis[0], _axis[1], _axis[2], MULT_FROM_LEFT);
2050  glstate_->translate( t[0], t[1], t[2], MULT_FROM_LEFT);
2051 
2052  sync_send( glstate_->modelview(), glstate_->inverse_modelview() );
2053 }
2054 
2055 
2056 //-----------------------------------------------------------------------------
2057 
2058 
2059 unsigned int QtBaseViewer::glWidth() const {
2060  return glView_->width();
2061 }
2062 unsigned int QtBaseViewer::glHeight() const {
2063  return glView_->height();
2064 }
2065 QSize QtBaseViewer::glSize() const {
2066  return glView_->size();
2067 }
2068 QPoint QtBaseViewer::glMapFromGlobal( const QPoint& _pos ) const {
2069  return glView_->mapFromGlobal(_pos);
2070 }
2071 
2072 QPoint QtBaseViewer::glMapToGlobal( const QPoint& _pos ) const {
2073  return glView_->mapToGlobal(_pos);
2074 }
2075 
2076 
2077 //-----------------------------------------------------------------------------
2078 
2079 
2080 void
2082 {
2083  if (sceneGraphRoot_)
2084  {
2085  if (!sceneGraphDialog_)
2086  {
2087  sceneGraphDialog_ = new QtSceneGraphDialog( this, sceneGraphRoot_ );
2088 
2089  connect(this,
2091  sceneGraphDialog_,
2092  SLOT(update(ACG::SceneGraph::BaseNode*)));
2093 
2094  connect(sceneGraphDialog_,
2096  this,
2098  }
2099 
2100  sceneGraphDialog_->show();
2101  }
2102 }
2103 
2104 
2105 //-----------------------------------------------------------------------------
2106 
2107 
2108 void
2110 {
2111  emit(signalNodeChanged(_node));
2112  updateGL();
2113 }
2114 
2115 
2116 //-----------------------------------------------------------------------------
2117 
2118 
2119 void QtBaseViewer::slotWheelX(double _dAngle)
2120 {
2121  rotate(Vec3d(1,0,0),QtWheel::deg(QtWheel::clip(_dAngle)));
2122  updateGL();
2123 
2124  // sync
2125  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
2126 
2127  emit viewChanged();
2128 }
2129 
2130 void QtBaseViewer::slotWheelY(double _dAngle)
2131 {
2132  rotate(Vec3d(0,1,0),QtWheel::deg(QtWheel::clip(_dAngle)));
2133  updateGL();
2134 
2135  // sync
2136  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
2137 
2138  emit viewChanged();
2139 }
2140 
2141 void QtBaseViewer::slotWheelZ(double _dist)
2142 {
2143  double dz=_dist*0.5/M_PI*scene_radius_*2.0;
2144  translate(Vec3d(0,0,dz));
2145  updateGL();
2146 
2147  // sync
2148  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
2149 
2150  emit viewChanged();
2151 }
2152 
2153 
2154 //-----------------------------------------------------------------------------
2155 
2156 void QtBaseViewer::sceneRectChanged(const QRectF &rect)
2157 {
2158  glBase_->setGeometry (rect);
2159 }
2160 
2161 //-----------------------------------------------------------------------------
2162 
2163 
2164 void QtBaseViewer::grabGLArea()
2165 {
2166  glareaGrabbed_ = true;
2167 
2168  glView_->setCursor(Qt::BlankCursor);
2169  glBase_->setCursor(Qt::BlankCursor);
2170  glView_->grabMouse();
2171  glView_->grabKeyboard();
2172 }
2173 
2174 void QtBaseViewer::releaseGLArea()
2175 {
2176  glareaGrabbed_ = false;
2177 
2178  glView_->releaseMouse();
2179  glView_->releaseKeyboard();
2180  glView_->setCursor(Qt::ArrowCursor);
2181  glBase_->setCursor(Qt::ArrowCursor);
2182 }
2183 
2184 
2185 //-----------------------------------------------------------------------------
2186 
2187 
2188 void QtBaseViewer::glContextMenuEvent(QContextMenuEvent* _event)
2189 {
2190 
2191  if (popupEnabled_)
2192  {
2193  QPoint cpos(QCursor::pos()), dpos, fpos, ppos;
2194  int offset = 10, dw, dh, fw, fh, pw, ph;
2195  int minx, maxx, miny, maxy;
2196  int dx(0), dy(0);
2197 
2198 
2199 #ifdef ARCH_DARWIN
2200 # define WIDTH width()
2201 # define HEIGHT height()
2202 #else
2203 # define WIDTH sizeHint().width()
2204 # define HEIGHT sizeHint().height()
2205 #endif
2206 
2207 
2208 
2209  // drawing mode menu
2210  if (drawMenu_)//TODO: && drawMenu_->count()>0)
2211  {
2212  dw = drawMenu_->WIDTH;
2213  dh = drawMenu_->HEIGHT;
2214  dpos = cpos + QPoint(offset, offset);
2215  }
2216  else
2217  {
2218  dpos = cpos; dw=dh=0;
2219  }
2220 
2221 
2222  // function menu
2224  if (funcMenu_)
2225  {
2226  fw = funcMenu_->WIDTH;
2227  fh = funcMenu_->HEIGHT;
2228  fpos = cpos + QPoint(offset, -offset-fh);
2229  }
2230  else
2231  {
2232  fpos = cpos; fw=fh=0;
2233  }
2234 
2235 
2236  // pick mode menu
2238  if (pickMenu_)
2239  {
2240  pw = pickMenu_->WIDTH;
2241  ph = pickMenu_->HEIGHT;
2242  ppos = cpos + QPoint(-offset-pw, -ph/2);
2243  }
2244  else
2245  {
2246  ppos = cpos; pw=ph=0;
2247  }
2248 
2249 
2250 
2251  // handle screen boundaries
2252  minx = std::min(dpos.x(), std::min(fpos.x(), ppos.x()));
2253  maxx = std::max(dpos.x()+dw, std::max(fpos.x()+fw, ppos.x()+pw));
2254  miny = std::min(dpos.y(), std::min(fpos.y(), ppos.y()));
2255  maxy = std::max(dpos.y()+dh, std::max(fpos.y()+fh, ppos.y()+ph));
2256 
2257 
2258  if (minx < 0)
2259  {
2260  dx = -minx;
2261  }
2262  else if (maxx >= qApp->desktop()->width())
2263  {
2264  dx = qApp->desktop()->width() - maxx;
2265  }
2266 
2267  if (miny < 0)
2268  {
2269  dy = -miny;
2270  }
2271  else if (maxy >= qApp->desktop()->height())
2272  {
2273  dy = qApp->desktop()->height() - maxy;
2274  }
2275 
2276 
2277  dpos += QPoint(dx, dy);
2278  fpos += QPoint(dx, dy);
2279  ppos += QPoint(dx, dy);
2280 
2281 
2282 
2283  // popping up 3 menus only works w/o Qt menu fade/animate effects
2284  bool animate_menu = qApp->isEffectEnabled(Qt::UI_AnimateMenu);
2285  bool fade_menu = qApp->isEffectEnabled(Qt::UI_FadeMenu);
2286  if (animate_menu) qApp->setEffectEnabled(Qt::UI_AnimateMenu, false);
2287  if (fade_menu) qApp->setEffectEnabled(Qt::UI_FadeMenu, false);
2288 
2289 
2290  // popup the 3 menus
2291 
2292  if (drawMenu_)
2293  {
2294  // SceneGraph::DrawModes::setQPopupMenuChecked(drawMenu_, curDrawMode_);
2295  drawMenu_->popup(dpos);
2296  }
2297 
2298  if (funcMenu_)
2299  funcMenu_->popup(fpos);
2300 
2301  if (pickMenu_)
2302  pickMenu_->popup(ppos);
2303 
2304 
2305  // restore effect state
2306  if (animate_menu) qApp->setEffectEnabled(Qt::UI_AnimateMenu, true);
2307  if (fade_menu) qApp->setEffectEnabled(Qt::UI_FadeMenu, true);
2308 
2309 
2310  _event->accept();
2311  }
2312 }
2313 
2314 
2315 //-----------------------------------------------------------------------------
2316 
2317 
2318 void QtBaseViewer::glMousePressEvent(QMouseEvent* _event)
2319 {
2320  // right button pressed => popup menu (ignore here)
2321  if (_event->button() == Qt::RightButton && popupEnabled_)
2322  {
2323  return;
2324  }
2325  else
2326  {
2327  switch (actionMode_)
2328  {
2329  case ExamineMode:
2330  if ((_event->modifiers() & Qt::ControlModifier)) // drag&drop
2331  if ( externalDrag_ ) {
2332  emit startDragEvent( _event );
2333  } else {
2334  startDrag();
2335  }
2336  else
2337  viewMouseEvent(_event); // examine
2338  break;
2339 
2340  case LightMode:
2341  lightMouseEvent(_event);
2342  break;
2343 
2344  case PickingMode: // give event to application
2345  emit(signalMouseEvent(_event, pick_mode_name_));
2346  emit(signalMouseEvent(_event));
2347  break;
2348 
2349  case QuestionMode: // give event to application
2350  emit(signalMouseEventIdentify(_event));
2351  break;
2352  }
2353  }
2354 }
2355 
2356 
2357 //-----------------------------------------------------------------------------
2358 
2359 
2360 void QtBaseViewer::glMouseDoubleClickEvent(QMouseEvent* _event)
2361 {
2362  switch (actionMode_)
2363  {
2364  case ExamineMode:
2365  viewMouseEvent(_event);
2366  break;
2367 
2368  case LightMode:
2369  lightMouseEvent(_event);
2370  break;
2371 
2372  case PickingMode: // give event to application
2373  emit(signalMouseEvent(_event, pick_mode_name_));
2374  emit(signalMouseEvent(_event));
2375  break;
2376 
2377  case QuestionMode: // give event to application
2378  emit(signalMouseEventIdentify(_event));
2379  break;
2380  }
2381 }
2382 
2383 
2384 //-----------------------------------------------------------------------------
2385 
2386 
2387 void QtBaseViewer::glMouseMoveEvent(QMouseEvent* _event)
2388 {
2389  switch ( actionMode_ )
2390  {
2391  case ExamineMode:
2392  viewMouseEvent(_event);
2393  break;
2394 
2395  case LightMode:
2396  lightMouseEvent(_event);
2397  break;
2398 
2399  case PickingMode:
2400  // give event to application
2401  // deliver mouse moves with no button down, if tracking is enabled,
2402  if ((_event->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton))
2403  || trackMouse_)
2404  {
2405  emit(signalMouseEvent(_event, pick_mode_name_));
2406  emit(signalMouseEvent(_event));
2407  }
2408  break;
2409 
2410  case QuestionMode: // give event to application
2411  emit(signalMouseEventIdentify(_event));
2412  break;
2413 
2414  default: // avoid warning
2415  break;
2416  }
2417 }
2418 
2419 
2420 //-----------------------------------------------------------------------------
2421 
2422 
2423 void QtBaseViewer::glMouseReleaseEvent(QMouseEvent* _event)
2424 {
2425 // if (_event->button() == Qt::RightButton )
2426 // hidePopupMenus();
2427 
2428  if (_event->button() != Qt::RightButton ||
2429  (actionMode_ == PickingMode && !popupEnabled_) )
2430  {
2431  switch ( actionMode_ )
2432  {
2433  case ExamineMode:
2434  viewMouseEvent(_event);
2435  break;
2436 
2437  case LightMode:
2438  lightMouseEvent(_event);
2439  break;
2440 
2441  case PickingMode: // give event to application
2442  emit(signalMouseEvent(_event, pick_mode_name_));
2443  emit(signalMouseEvent(_event));
2444  break;
2445 
2446  case QuestionMode: // give event to application
2447  emit(signalMouseEventIdentify(_event));
2448  break;
2449 
2450  default: // avoid warning
2451  break;
2452  }
2453  }
2454 
2455  isRotating_ = false;
2456 }
2457 
2458 
2459 //-----------------------------------------------------------------------------
2460 
2461 
2462 void QtBaseViewer::glMouseWheelEvent(QWheelEvent* _event)
2463 {
2464  switch ( actionMode_ )
2465  {
2466  case ExamineMode:
2467  viewWheelEvent(_event);
2468  break;
2469 
2470  case PickingMode: // give event to application
2471  emit(signalWheelEvent(_event, pick_mode_name_));
2472  break;
2473 
2474  default: // avoid warning
2475  break;
2476  }
2477 
2478  isRotating_ = false;
2479 }
2480 
2481 //-----------------------------------------------------------------------------
2482 
2483 
2485 {
2486  delete pickMenu_;
2487 
2488  pickMenu_ = new QMenu( 0 );
2489  connect( pickMenu_, SIGNAL( aboutToHide() ),
2490  this, SLOT( hidePopupMenus() ) );
2491 
2492  QActionGroup * ag = new QActionGroup( pickMenu_ );
2493  ag->setExclusive( true );
2494 
2495  for (unsigned int i=0; i<pick_modes_.size(); ++i) {
2496  if ( !pick_modes_[i].visible )
2497  continue;
2498 
2499  if (pick_modes_[i].name == "Separator")
2500  {
2501  if ((i > 0) && (i<pick_modes_.size()-1)) // not first, not last
2502  pickMenu_->addSeparator();
2503  }
2504  else
2505  {
2506  QAction * ac = new QAction( pick_modes_[i].name.c_str(), ag );
2507  ac->setData( QVariant( i ) );
2508  ac->setCheckable( true );
2509 
2510  if ((int)i == pick_mode_idx_)
2511  ac->setChecked( true );
2512 
2513  pickMenu_->addAction( ac );
2514  }
2515  }
2516 
2517  connect( ag, SIGNAL( triggered( QAction * ) ),
2518  this, SLOT( actionPickMenu( QAction * ) ));
2519 }
2520 
2521 //-----------------------------------------------------------------------------
2522 
2523 
2524 void QtBaseViewer::actionPickMenu( QAction * _action )
2525 {
2526  int _id = _action->data().toInt();
2527  if (_id < (int) pick_modes_.size() )
2528  {
2529  pickMode( _id );
2530  }
2531 
2533 
2534  hidePopupMenus();
2535 }
2536 
2537 //-----------------------------------------------------------------------------
2538 
2540  return buttonBar_;
2541 }
2542 
2544  glLayout_->removeWidget( buttonBar_ );
2545  return buttonBar_;
2546 }
2547 
2548 //-----------------------------------------------------------------------------
2549 
2550 
2552  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2553 
2554  ACG::Vec3d dir = glstate_->viewing_direction();
2555 
2556  dir *= -0.1;
2557 
2558  glstate_->translate(dir[0], dir[1], dir[2]);
2559 
2560  updateGL();
2561 
2562  emit viewChanged();
2563  }
2564 }
2565 
2567  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2568  ACG::Vec3d dir = glstate_->viewing_direction();
2569 
2570  dir *= 0.1;
2571 
2572  glstate_->translate(dir[0], dir[1], dir[2]);
2573 
2574  updateGL();
2575 
2576  emit viewChanged();
2577  }
2578 }
2579 
2581  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2582  ACG::Vec3d dir = glstate_->right();
2583 
2584  dir *= 0.1;
2585 
2586  glstate_->translate(dir[0], dir[1], dir[2]);
2587 
2588  updateGL();
2589 
2590  emit viewChanged();
2591  }
2592 }
2593 
2595  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2596  ACG::Vec3d dir = glstate_->right();
2597 
2598  dir *= -0.1;
2599 
2600  glstate_->translate(dir[0], dir[1], dir[2]);
2601 
2602  updateGL();
2603 
2604  emit viewChanged();
2605  }
2606 }
2607 
2608 //=============================================================================
2609 } // namespace QtWidgets
2610 } // namespace ACG
2611 //=============================================================================
static void enable(GLenum _cap)
replaces glEnable, but supports locking
Definition: GLState.cc:1490
void sync_send(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
synchronized with different viewer?
virtual void viewWheelEvent(QWheelEvent *_event)=0
specialized viewer: handle wheel events
Vec4f backgroundColor()
get background color
std::vector< PickMode > pick_modes_
void viewChanged()
This signal is emitted whenever the view is changed by the user.
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:924
QToolBar * getToolBar()
Returns a pointer to the Toolbar.
GLState & glState()
get OpenGL state
virtual void toggleNavigationMode()
toggle navigation mode
void strafeLeft()
First person navigation: Strafe left.
void setState()
set the whole stored gl state
Definition: GLState.cc:209
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x&#39;,y&#39;,z&#39;,1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
double eyeDist_
Set eye distance for stereo.
ProjectionMode
projection mode
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
void initModelviewMatrix()
initialize modelview matrix to identity
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.cc:818
virtual void showSceneGraphDialog()
show scenegraph widget
virtual void questionMode()
calls actionMode() with QuestionMode (cf. ActionMode)
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
Definition: GLState.cc:513
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
virtual void sceneRectChanged(const QRectF &rect)
process graphics scene size changes
bool backFaceCulling() const
is backface culling enabled?
virtual void toggleStereoMode()
toggle stereo mode
void signalPickModeChanged(const std::string &)
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _setCenter=true)
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
NormalsMode
Automatically normalize normals?
void updateProjectionMatrix()
updates projection matrix
virtual void startDrag()
drag & drop for modelview copying
void encodeView(QString &_view)
convert current view to text representation
void translate(const Vec3d &trans)
translate the scene and update modelview matrix
void signalActionModeChanged(ACG::QtWidgets::QtBaseViewer::ActionMode _m)
action mode was changed
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
virtual void setSynchronization(bool _b)
toggle global synchronization
virtual void home()
go to home pos
virtual void glMouseWheelEvent(QWheelEvent *_event)
handle mouse wheel events
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:446
virtual void toggleProjectionMode()
toggle projection mode
void rotate_lights(Vec3d &_axis, double _angle)
rotete light sources
void strafeRight()
First person navigation: Strafe Right.
void enablePopupMenu(bool _enable)
Enable/disable right button draw mode menu (default: enabled)
virtual void resizeGL(int _w, int _h)
handle resize events
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
virtual void swapBuffers()
Swaps the screen contents with the off-screen buffer.
bool synchronized_
synchronized with different viewer?
QSize glSize() const
get size of QGLWIdget
bool twoSidedLighting() const
is 2-sided lighing enabled?
unsigned int glHeight() const
get height of QGLWidget
void setFovy(double _fovy)
set field of view y
unsigned int glWidth() const
get width of QGLWidget
virtual void initializeGL()
initialize OpenGL states
const Vec3d & bbMin() const
Returns minimum point of the bounding box.
Definition: SceneGraph.hh:407
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:400
virtual void glMouseMoveEvent(QMouseEvent *_event)
handle mouse move events
ProjectionMode projectionMode() const
get current projection mode
void signalInitializeGL()
emitted when OpenGL stuff can be initialized
void viewport(int _left, int _bottom, int _width, int _height, int _glwidth=0, int _glheight=0)
set viewport (lower left corner, width, height, glcontext width, height)
Definition: GLState.cc:468
void signalNodeChanged(ACG::SceneGraph::BaseNode *_node)
scene graph has changed
ACG::SceneGraph::PickTarget pickRendererMode_
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
Definition: GLMatrixT.cc:161
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
Definition: GLState.hh:814
void identity()
setup an identity matrix
Definition: Matrix4x4T.cc:256
void applyOptions(int _options)
Apply ORed Options _options.
Show pick button? Effect only if ShowToolBar!
void moveForward()
First person navigation: Move forward.
virtual void setHome()
set home position
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
Definition: QtWheel.cc:447
void signalMouseEvent(QMouseEvent *, const std::string &)
QtBaseViewer(QWidget *_parent=0, const char *_name=0, QStatusBar *_statusBar=0, const QGLFormat *_format=0, const QtBaseViewer *_share=0, Options _options=DefaultOptions)
NavigationMode navigationMode() const
get current navigation mode
virtual void viewMouseEvent(QMouseEvent *_event)=0
specialized viewer: hande mouse events
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:531
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
void signalCustomContextMenuRequested(const QPoint &)
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
Definition: GLState.hh:248
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
Definition: SceneGraph.hh:588
bool animation() const
Is animation enabled?
virtual void glMouseDoubleClickEvent(QMouseEvent *_event)
handle mouse double click events
QToolBar * removeToolBar()
Returns a pointer to the toolbar and removes it from the default position in the examiner widget...
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:731
void startDragEvent(QMouseEvent *_event)
virtual void slotNodeChanged(ACG::SceneGraph::BaseNode *_node)
connected to scenegraph widget
void setSceneCenter(const ACG::Vec3d &_center)
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
static double clip(double _angle)
Definition: QtWheel.cc:443
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:143
virtual void glMouseReleaseEvent(QMouseEvent *_event)
handle mouse release events
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
virtual void unlockUpdate()
Unlock display locked by updateLock().
virtual void lightMouseEvent(QMouseEvent *)
optional: hande mouse events to rotate light
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
bool pick(SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, Vec3d *_hitPointPtr=0)
bool synchronization()
synchronized with different viewer?
Show wheel for rotation around x-axis (left)?
virtual void glMousePressEvent(QMouseEvent *_event)
handle mouse press events
virtual void lightMode()
calls actionMode() with LightMode (cf. ActionMode)
void set_projection(const GLMatrixd &_m)
set projection
Definition: GLState.hh:694
void rotate(double _angle, double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
rotate around axis (_x, _y, _z) by _angle
Definition: GLState.cc:562
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Definition: GLState.cc:1504
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:77
virtual void flyTo(const QPoint &_pos, bool _move_back)
Fly to. Get closer if _move_back=false, get more distant else.
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:332
void signalDrawScene(ACG::GLState *_state)
render callback
const Vec3d & bbMax() const
Returns maximum point of the bounding box.
Definition: SceneGraph.hh:409
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
void signalMouseEventIdentify(QMouseEvent *)
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:789
FaceOrientation
orientation of the faces
ActionMode actionMode() const
get action mode
const std::string & pickMode() const
bool containsAtomicDrawMode(DrawMode _atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
bool add_sync_host(const QString &_name)
add host to synchronize with, given by its name
Show wheel for rotation around y-axis (bottom)?
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
FaceOrientation faceOrientation() const
get face orientation
virtual QSize sizeHint() const
reimplemented
Definition: QtWheel.cc:432
void moveBack()
First person navigation: Move back.
QUdpSocket * socket_
socket used for synchronization
bool decodeView(const QString &_view)
virtual void viewAll()
view the whole scene
void rotate(const Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
SceneGraph::BaseNode * sceneGraph()
Returns: root node of scene graph.
bool stereo_
Set eye distance for stereo.
void updatePickMenu()
update pick mode menu
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
NavigationMode
Navigation mode.
void copyToImage(QImage &_image, GLenum _buffer=GL_BACK)
copy current framebuffer to an QImage
NormalsMode normalsMode() const
get treatment of normals
virtual ~QtBaseViewer()
Destructor.
ACG::SceneGraph::DrawModes::DrawMode drawMode()
get current draw mode
Vec3d right() const
get right-vector w.r.t. camera coordinates
Definition: GLState.cc:914
void initialize()
initialize all state variables (called by constructor)
Definition: GLState.cc:162
virtual void glContextMenuEvent(QContextMenuEvent *_event)
handle mouse press events
void update_lights()
update light position
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
Definition: GLState.cc:1953
virtual void examineMode()
calls actionMode() with ExamineMode (cf. ActionMode)
virtual void setView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
void setStatusBar(QStatusBar *_sb)
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
Show question button? Effect only if ShowToolBar!
void signalSetView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing (cf. slotSetView())
double focalDist_
Set eye distance for stereo.
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:368
bool skipNextSync_
Skips the next synch event.
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
virtual void paintGL()
draw the scene. Triggered by updateGL().
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:851
ActionMode
How to react on mouse events?
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1700