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