Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 //=============================================================================
const std::string & pickMode() const
double focalDist_
Set eye distance for stereo.
QUdpSocket * socket_
socket used for synchronization
virtual void glMousePressEvent(QMouseEvent *_event)
handle mouse press events
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
Vec3d right() const
get right-vector w.r.t. camera coordinates
Definition: GLState.cc:914
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
bool synchronized_
synchronized with different viewer?
virtual void lightMouseEvent(QMouseEvent *)
optional: hande mouse events to rotate light
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
Definition: GLState.cc:513
std::vector< PickMode > pick_modes_
static void enable(GLenum _cap)
replaces glEnable, but supports locking
Definition: GLState.cc:1490
QToolBar * getToolBar()
Returns a pointer to the Toolbar.
virtual void toggleStereoMode()
toggle stereo mode
Namespace providing different geometric functions concerning angles.
Definition: DBSCANT.cc:51
void signalCustomContextMenuRequested(const QPoint &)
virtual void initializeGL()
initialize OpenGL states
virtual void showSceneGraphDialog()
show scenegraph widget
unsigned int glWidth() const
get width of QGLWidget
void moveForward()
First person navigation: Move forward.
bool pick(SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, Vec3d *_hitPointPtr=0)
Vec4f backgroundColor()
get background color
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
Definition: SceneGraph.hh:588
void setSceneCenter(const ACG::Vec3d &_center)
ACG::SceneGraph::DrawModes::DrawMode drawMode()
get current draw mode
void initialize()
initialize all state variables (called by constructor)
Definition: GLState.cc:162
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:924
bool containsAtomicDrawMode(DrawMode _atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
virtual void glMouseMoveEvent(QMouseEvent *_event)
handle mouse move events
bool skipNextSync_
Skips the next synch event.
NormalsMode normalsMode() const
get treatment of normals
FaceOrientation
orientation of the faces
void startDragEvent(QMouseEvent *_event)
pick any of the prior targets (should be implemented for all nodes)
Definition: BaseNode.hh:110
void strafeLeft()
First person navigation: Strafe left.
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:531
Show question button? Effect only if ShowToolBar!
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
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
virtual ~QtBaseViewer()
Destructor.
virtual void glMouseReleaseEvent(QMouseEvent *_event)
handle mouse release events
QtBaseViewer(QWidget *_parent=0, const char *_name=0, QStatusBar *_statusBar=0, const QGLFormat *_format=0, const QtBaseViewer *_share=0, Options _options=DefaultOptions)
void signalDrawScene(ACG::GLState *_state)
render callback
NavigationMode navigationMode() const
get current navigation mode
virtual void glContextMenuEvent(QContextMenuEvent *_event)
handle mouse press events
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:144
virtual QSize sizeHint() const
reimplemented
Definition: QtWheel.cc:432
virtual void home()
go to home pos
virtual void toggleProjectionMode()
toggle projection mode
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:127
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:794
void rotate(const Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:789
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
ProjectionMode
projection mode
QSize glSize() const
get size of QGLWIdget
void enablePopupMenu(bool _enable)
Enable/disable right button draw mode menu (default: enabled)
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
virtual void paintGL()
draw the scene. Triggered by updateGL().
virtual void sceneRectChanged(const QRectF &rect)
process graphics scene size changes
GLState & glState()
get OpenGL state
NormalsMode
Automatically normalize normals?
void update_lights()
update light position
void signalPickModeChanged(const std::string &)
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
Definition: GLState.cc:1953
void signalInitializeGL()
emitted when OpenGL stuff can be initialized
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:368
void translate(const Vec3d &trans)
translate the scene and update modelview matrix
virtual void resizeGL(int _w, int _h)
handle resize events
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:332
virtual void flyTo(const QPoint &_pos, bool _move_back)
Fly to. Get closer if _move_back=false, get more distant else.
virtual void viewWheelEvent(QWheelEvent *_event)=0
specialized viewer: handle wheel events
const Vec3d & bbMax() const
Returns maximum point of the bounding box.
Definition: SceneGraph.hh:409
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1700
void setStatusBar(QStatusBar *_sb)
virtual void glMouseDoubleClickEvent(QMouseEvent *_event)
handle mouse double click events
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
void initModelviewMatrix()
initialize modelview matrix to identity
void signalSetView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing (cf. slotSetView())
Show pick button? Effect only if ShowToolBar!
virtual void slotNodeChanged(ACG::SceneGraph::BaseNode *_node)
connected to scenegraph widget
bool animation() const
Is animation enabled?
SceneGraph::BaseNode * sceneGraph()
Returns: root node of scene graph.
virtual void questionMode()
calls actionMode() with QuestionMode (cf. ActionMode)
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
Definition: GLState.hh:814
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.cc:818
virtual void glMouseWheelEvent(QWheelEvent *_event)
handle mouse wheel events
bool add_sync_host(const QString &_name)
add host to synchronize with, given by its name
double eyeDist_
Set eye distance for stereo.
virtual void lightMode()
calls actionMode() with LightMode (cf. ActionMode)
void updateProjectionMatrix()
updates projection matrix
void updatePickMenu()
update pick mode menu
FaceOrientation faceOrientation() const
get face orientation
void signalMouseEventIdentify(QMouseEvent *)
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:400
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
Definition: GLMatrixT.cc:161
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
bool stereo_
Set eye distance for stereo.
const Vec3d & bbMin() const
Returns minimum point of the bounding box.
Definition: SceneGraph.hh:407
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
virtual void examineMode()
calls actionMode() with ExamineMode (cf. ActionMode)
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:851
ACG::SceneGraph::PickTarget pickRendererMode_
bool backFaceCulling() const
is backface culling enabled?
void signalActionModeChanged(ACG::QtWidgets::QtBaseViewer::ActionMode _m)
action mode was changed
void encodeView(QString &_view)
convert current view to text representation
bool synchronization()
synchronized with different viewer?
virtual void toggleNavigationMode()
toggle navigation mode
NavigationMode
Navigation mode.
void signalNodeChanged(ACG::SceneGraph::BaseNode *_node)
scene graph has changed
QToolBar * removeToolBar()
Returns a pointer to the toolbar and removes it from the default position in the examiner widget...
bool twoSidedLighting() const
is 2-sided lighing enabled?
void setState()
set the whole stored gl state
Definition: GLState.cc:209
virtual void setSynchronization(bool _b)
toggle global synchronization
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
void identity()
setup an identity matrix
Definition: Matrix4x4T.cc:256
void rotate_lights(Vec3d &_axis, double _angle)
rotete light sources
VectorT< T, 3 > transform_point(const VectorT< T, 3 > &_v) const
transform point (x',y',z',1) = M * (x,y,z,1)
Definition: Matrix4x4T.cc:202
static void disable(GLenum _cap)
replaces glDisable, but supports locking
Definition: GLState.cc:1504
virtual void unlockUpdate()
Unlock display locked by updateLock().
virtual void swapBuffers()
Swaps the screen contents with the off-screen buffer.
void moveBack()
First person navigation: Move back.
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
Definition: QtWheel.cc:447
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _setCenter=true)
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:731
virtual void setView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing
ProjectionMode projectionMode() const
get current projection mode
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 perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:446
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
Definition: GLState.hh:248
ActionMode
How to react on mouse events?
void signalMouseEvent(QMouseEvent *, const std::string &)
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
bool decodeView(const QString &_view)
Show wheel for rotation around y-axis (bottom)?
void viewChanged()
This signal is emitted whenever the view is changed by the user.
virtual void viewAll()
view the whole scene
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()).
virtual void startDrag()
drag & drop for modelview copying
void sync_send(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
synchronized with different viewer?
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
void setFovy(double _fovy)
set field of view y
void set_projection(const GLMatrixd &_m)
set projection
Definition: GLState.hh:694
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:143
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
void strafeRight()
First person navigation: Strafe Right.
void applyOptions(int _options)
Apply ORed Options _options.
unsigned int glHeight() const
get height of QGLWidget
static double clip(double _angle)
Definition: QtWheel.cc:443
virtual void setHome()
set home position
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:77
ActionMode actionMode() const
get action mode
Show wheel for rotation around x-axis (left)?
void copyToImage(QImage &_image, GLenum _buffer=GL_BACK)
copy current framebuffer to an QImage