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  QElapsedTimer 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 #if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
1361  QStringList split = temp.split(QRegExp("[\\n\\s]"),QString::SkipEmptyParts);
1362 #else
1363  QStringList split = temp.split(QRegExp("[\\n\\s]"),Qt::SkipEmptyParts);
1364 #endif
1365 
1366  ACG::GLMatrixd m, p;
1367  int w, h, pMode;
1368 
1369  // Check if the number of components matches the expected size
1370  if ( split.size() != 36 ) {
1371  std::cerr << "Unable to paste view ... wrong parameter count!! is" << split.size() << std::endl;
1372  return false;
1373  }
1374 
1375  // Parse the components
1376  bool ok = true;;
1377 
1378  m(0,0) = split[0].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1379  m(0,1) = split[1].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1380  m(0,2) = split[2].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1381  m(0,3) = split[3].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1382  m(1,0) = split[4].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1383  m(1,1) = split[5].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1384  m(1,2) = split[6].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1385  m(1,3) = split[7].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1386  m(2,0) = split[8].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1387  m(2,1) = split[9].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1388  m(2,2) = split[10].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1389  m(2,3) = split[11].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1390  m(3,0) = split[12].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1391  m(3,1) = split[13].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1392  m(3,2) = split[14].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1393  m(3,3) = split[15].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1394  p(0,0) = split[16].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1395  p(0,1) = split[17].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1396  p(0,2) = split[18].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1397  p(0,3) = split[19].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1398  p(1,0) = split[20].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1399  p(1,1) = split[21].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1400  p(1,2) = split[22].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1401  p(1,3) = split[23].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1402  p(2,0) = split[24].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1403  p(2,1) = split[25].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1404  p(2,2) = split[26].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1405  p(2,3) = split[27].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1406  p(3,0) = split[28].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1407  p(3,1) = split[29].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1408  p(3,2) = split[30].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1409  p(3,3) = split[31].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1410 
1411  w = split[32].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1412  h = split[33].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1413  pMode = split[34].toInt(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1414  orthoWidth_ = split[35].toDouble(&ok); if ( !ok ) { std::cerr << "Error in decoding View!" << std::endl; return false; }
1415 
1416  // Switch to our gl context
1417  makeCurrent();
1418 
1419  // set projection mode
1420  if (projectionMode_ != (ProjectionMode)pMode)
1422 
1423  // Apply new modelview matrix
1424  glstate_->set_modelview(m);
1425 
1426 
1427  if (w>0 && h>0 &&
1428  action_["PasteDropSize"]->isChecked() )
1429  {
1430  glstate_->set_projection(p);
1431  glView_->setFixedSize(w,h);
1432  updateGeometry();
1433  }
1434 
1435 
1436  updateGL();
1437 
1438 
1439  return true;
1440 }
1441 
1442 
1443 //-----------------------------------------------------------------------------
1444 
1445 
1446 void QtBaseViewer::actionDrawMenu( QAction * _action )
1447 {
1448  SceneGraph::DrawModes::DrawMode mode( _action->data().toUInt() );
1449 
1450  // combine draw modes
1451  if (qApp->keyboardModifiers() & Qt::ShiftModifier)
1452  {
1453  if (drawMode() & mode)
1454  drawMode(drawMode() & ~mode);
1455  else
1456  drawMode(drawMode() | mode);
1457  }
1458 
1459  // simply switch draw mode
1460  else
1461  {
1462  // clear all other checked items
1463  std::vector< QAction * >::iterator aIter, aEnd;
1464 
1465  aEnd = drawMenuActions_.end();
1466  for( aIter = drawMenuActions_.begin();
1467  aIter != aEnd;
1468  ++aIter )
1469  {
1470  if( SceneGraph::DrawModes::DrawMode((*aIter)->data().toUInt()) != mode )
1471  (*aIter)->setChecked( false );
1472  }
1473 
1474  drawMode(mode);
1475  }
1476 
1477  hidePopupMenus();
1478  updateGL();
1479 }
1480 
1481 
1482 //-----------------------------------------------------------------------------
1483 
1484 
1485 void QtBaseViewer::actionBackground()
1486 {
1487  const Vec4f bc = glstate_->clear_color() * 255.0f;
1488  QColor backCol((int)bc[0], (int)bc[1], (int)bc[2]);
1489  QColor c = QColorDialog::getColor(backCol,this);
1490  if (c != backCol && c.isValid())
1491  backgroundColor(Vec4f(((double) c.red()) / 255.0f,
1492  ((double) c.green()) / 255.0f,
1493  ((double) c.blue()) / 255.0f,
1494  1.0));
1495 
1496 }
1497 
1498 //-----------------------------------------------------------------------------
1499 
1500 
1501 void QtBaseViewer::actionCopyView()
1502 {
1503  QString view; encodeView(view);
1504  QApplication::clipboard()->setText(view);
1505 }
1506 
1507 
1508 //-----------------------------------------------------------------------------
1509 
1510 
1511 void QtBaseViewer::actionPasteView()
1512 {
1513  QString view; view=QApplication::clipboard()->text();
1514  decodeView(view);
1515 }
1516 
1517 
1518 //-----------------------------------------------------------------------------
1519 
1520 
1521 void QtBaseViewer::actionPasteDropSize()
1522 {
1523 }
1524 
1525 //-----------------------------------------------------------------------------
1526 
1527 
1528 void QtBaseViewer::actionSynchronize()
1529 {
1530  setSynchronization( action_["Synchronize"]->isChecked() );
1531 }
1532 
1533 //-----------------------------------------------------------------------------
1534 
1535 void QtBaseViewer::actionSynchronize(bool _enable)
1536 {
1537  setSynchronization( _enable );
1538 }
1539 
1541  return synchronized_;
1542 }
1543 
1544 //-----------------------------------------------------------------------------
1545 
1546 void QtBaseViewer::actionAnimation()
1547 {
1548  animation(!animation());
1549 }
1550 
1551 //-----------------------------------------------------------------------------
1552 
1553 void QtBaseViewer::actionAnimation(bool _enable)
1554 {
1555  animation(_enable);
1556 }
1557 
1558 //-----------------------------------------------------------------------------
1559 
1560 void QtBaseViewer::actionBackfaceCulling()
1561 {
1563 }
1564 
1565 //-----------------------------------------------------------------------------
1566 
1567 void QtBaseViewer::actionBackfaceCulling(bool _enable)
1568 {
1569  backFaceCulling(_enable);
1570 }
1571 
1572 //-----------------------------------------------------------------------------
1573 
1574 void QtBaseViewer::actionTwoSidedLighting()
1575 {
1577 }
1578 
1579 //-----------------------------------------------------------------------------
1580 
1581 void QtBaseViewer::actionTwoSidedLighting(bool _enable)
1582 {
1583  twoSidedLighting(_enable);
1584 }
1585 
1586 //-----------------------------------------------------------------------------
1587 
1588 
1589 void QtBaseViewer::updatePopupMenu()
1590 {
1591  //
1592  // Draw mode menu
1593  //
1594 
1595  if ( ! drawMenu_ )
1596  {
1597  drawMenu_ = new QMenu( this );
1598  connect( drawMenu_, SIGNAL( aboutToHide() ),
1599  this, SLOT( hidePopupMenus() ) );
1600 
1601  }
1602 
1603  QActionGroup * drawGroup = new QActionGroup( this );
1604  drawGroup->setExclusive( false );
1605  connect( drawGroup, SIGNAL( triggered( QAction * ) ),
1606  this, SLOT( actionDrawMenu( QAction * ) ) );
1607 
1608 
1609 
1610  drawMenuActions_.clear();
1611 
1612  std::vector< SceneGraph::DrawModes::DrawMode > draw_mode_id;
1613 
1614  draw_mode_id = availDrawModes_.getAtomicDrawModes();
1615 
1616  for ( unsigned int i = 0; i < draw_mode_id.size(); ++i )
1617  {
1618  SceneGraph::DrawModes::DrawMode id = draw_mode_id[i];
1619  std::string descr = id.description();
1620 
1621  QAction * action = new QAction( descr.c_str(), drawGroup );
1622  action->setData( QVariant( quint64(id.getIndex() ) ) );
1623  action->setCheckable( true );
1624  action->setChecked( curDrawMode_.containsAtomicDrawMode(id) );
1625  drawMenuActions_.push_back( action );
1626  }
1627 
1628 
1629  drawMenu_->clear();
1630  drawMenu_->addActions( drawGroup->actions() );
1631 
1632 
1633  // function menu
1634 
1635  if (!funcMenu_)
1636  {
1637  funcMenu_=new QMenu( this );
1638 
1639  funcMenu_->addAction( action_[ "Background" ] );
1640  funcMenu_->addSeparator();
1641  funcMenu_->addAction( action_[ "Snapshot" ] );
1642  funcMenu_->addAction( action_[ "SnapshotName" ] );
1643  funcMenu_->addAction( action_[ "SnapshotSavesView" ] );
1644  funcMenu_->addSeparator();
1645  funcMenu_->addAction( action_[ "CopyView" ] );
1646  funcMenu_->addAction( action_[ "PasteView" ] );
1647  funcMenu_->addAction( action_[ "PasteDropSize" ] );
1648  funcMenu_->addSeparator();
1649  funcMenu_->addAction( action_[ "Synchronize" ] );
1650  funcMenu_->addSeparator();
1651  funcMenu_->addAction( action_[ "Animation" ] );
1652  funcMenu_->addAction( action_[ "BackfaceCulling" ] );
1653  funcMenu_->addAction( action_[ "TwoSidedLighting" ] );
1654 
1655  connect( funcMenu_, SIGNAL( aboutToHide() ),
1656  this, SLOT( hidePopupMenus() ) );
1657  }
1658 
1659 
1660 }
1661 
1662 
1663 //-----------------------------------------------------------------------------
1664 
1665 
1666 void QtBaseViewer::hidePopupMenus()
1667 {
1668  if ( drawMenu_ )
1669  {
1670  drawMenu_->blockSignals(true);
1671  drawMenu_->hide();
1672  drawMenu_->blockSignals(false);
1673  }
1674 
1675  if ( funcMenu_ )
1676  {
1677  funcMenu_->blockSignals(true);
1678  funcMenu_->hide();
1679  funcMenu_->blockSignals(false);
1680  }
1681 
1682  if ( pickMenu_ )
1683  {
1684  pickMenu_->blockSignals(true);
1685  pickMenu_->hide();
1686  pickMenu_->blockSignals(false);
1687  }
1688 }
1689 
1690 
1691 //-----------------------------------------------------------------------------
1692 
1693 
1694 void QtBaseViewer::translate(const Vec3d& _trans)
1695 {
1696  makeCurrent();
1697  glstate_->translate(_trans[0], _trans[1], _trans[2], MULT_FROM_LEFT);
1698 }
1699 
1700 
1701 //-----------------------------------------------------------------------------
1702 
1703 
1705 {
1706  makeCurrent();
1707  glstate_->reset_modelview();
1708 }
1709 
1710 
1711 //-----------------------------------------------------------------------------
1712 
1713 
1714 void QtBaseViewer::rotate(const Vec3d& _axis,
1715  double _angle,
1716  const Vec3d& _center)
1717 {
1718  makeCurrent();
1719  Vec3d t = glstate_->modelview().transform_point(_center);
1720  glstate_->translate(-t[0], -t[1], -t[2], MULT_FROM_LEFT);
1721  glstate_->rotate(_angle, _axis[0], _axis[1], _axis[2], MULT_FROM_LEFT);
1722  glstate_->translate( t[0], t[1], t[2], MULT_FROM_LEFT);
1723 
1724  sync_send( glstate_->modelview(), glstate_->inverse_modelview() );
1725 }
1726 
1727 
1728 //-----------------------------------------------------------------------------
1729 
1730 
1731 unsigned int QtBaseViewer::glWidth() const {
1732  return glView_->width();
1733 }
1734 unsigned int QtBaseViewer::glHeight() const {
1735  return glView_->height();
1736 }
1737 QSize QtBaseViewer::glSize() const {
1738  return glView_->size();
1739 }
1740 QPoint QtBaseViewer::glMapFromGlobal( const QPoint& _pos ) const {
1741  return glView_->mapFromGlobal(_pos);
1742 }
1743 
1744 QPoint QtBaseViewer::glMapToGlobal( const QPoint& _pos ) const {
1745  return glView_->mapToGlobal(_pos);
1746 }
1747 
1748 
1749 //-----------------------------------------------------------------------------
1750 
1751 
1752 void
1754 {
1755  if (sceneGraphRoot_)
1756  {
1757  if (!sceneGraphDialog_)
1758  {
1759  sceneGraphDialog_ = new QtSceneGraphDialog( this, sceneGraphRoot_ );
1760 
1761  connect(this,
1763  sceneGraphDialog_,
1764  SLOT(update(ACG::SceneGraph::BaseNode*)));
1765 
1766  connect(sceneGraphDialog_,
1768  this,
1770  }
1771 
1772  sceneGraphDialog_->show();
1773  }
1774 }
1775 
1776 
1777 //-----------------------------------------------------------------------------
1778 
1779 
1780 void
1782 {
1783  emit(signalNodeChanged(_node));
1784  updateGL();
1785 }
1786 
1787 
1788 //-----------------------------------------------------------------------------
1789 
1790 
1791 void QtBaseViewer::slotWheelX(double _dAngle)
1792 {
1793  rotate(Vec3d(1,0,0),QtWheel::deg(QtWheel::clip(_dAngle)));
1794  updateGL();
1795 
1796  // sync
1797  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
1798 
1799  emit viewChanged();
1800 }
1801 
1802 void QtBaseViewer::slotWheelY(double _dAngle)
1803 {
1804  rotate(Vec3d(0,1,0),QtWheel::deg(QtWheel::clip(_dAngle)));
1805  updateGL();
1806 
1807  // sync
1808  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
1809 
1810  emit viewChanged();
1811 }
1812 
1813 void QtBaseViewer::slotWheelZ(double _dist)
1814 {
1815  double dz=_dist*0.5/M_PI*scene_radius_*2.0;
1816  translate(Vec3d(0,0,dz));
1817  updateGL();
1818 
1819  // sync
1820  emit(signalSetView(glstate_->modelview(), glstate_->inverse_modelview()));
1821 
1822  emit viewChanged();
1823 }
1824 
1825 
1826 //-----------------------------------------------------------------------------
1827 
1828 void QtBaseViewer::sceneRectChanged(const QRectF &rect)
1829 {
1830  glBase_->setGeometry (rect);
1831 }
1832 
1833 //-----------------------------------------------------------------------------
1834 
1835 
1836 void QtBaseViewer::grabGLArea()
1837 {
1838  glareaGrabbed_ = true;
1839 
1840  glView_->setCursor(Qt::BlankCursor);
1841  glBase_->setCursor(Qt::BlankCursor);
1842  glView_->grabMouse();
1843  glView_->grabKeyboard();
1844 }
1845 
1846 void QtBaseViewer::releaseGLArea()
1847 {
1848  glareaGrabbed_ = false;
1849 
1850  glView_->releaseMouse();
1851  glView_->releaseKeyboard();
1852  glView_->setCursor(Qt::ArrowCursor);
1853  glBase_->setCursor(Qt::ArrowCursor);
1854 }
1855 
1856 
1857 //-----------------------------------------------------------------------------
1858 
1859 
1860 void QtBaseViewer::glContextMenuEvent(QContextMenuEvent* _event)
1861 {
1862 
1863  if (popupEnabled_)
1864  {
1865  QPoint cpos(QCursor::pos()), dpos, fpos, ppos;
1866  int offset = 10, dw, dh, fw, fh, pw, ph;
1867  int minx, maxx, miny, maxy;
1868  int dx(0), dy(0);
1869 
1870 
1871 #ifdef ARCH_DARWIN
1872 # define WIDTH width()
1873 # define HEIGHT height()
1874 #else
1875 # define WIDTH sizeHint().width()
1876 # define HEIGHT sizeHint().height()
1877 #endif
1878 
1879 
1880 
1881  // drawing mode menu
1882  if (drawMenu_)//TODO: && drawMenu_->count()>0)
1883  {
1884  dw = drawMenu_->WIDTH;
1885  dh = drawMenu_->HEIGHT;
1886  dpos = cpos + QPoint(offset, offset);
1887  }
1888  else
1889  {
1890  dpos = cpos; dw=dh=0;
1891  }
1892 
1893 
1894  // function menu
1896  if (funcMenu_)
1897  {
1898  fw = funcMenu_->WIDTH;
1899  fh = funcMenu_->HEIGHT;
1900  fpos = cpos + QPoint(offset, -offset-fh);
1901  }
1902  else
1903  {
1904  fpos = cpos; fw=fh=0;
1905  }
1906 
1907 
1908  // pick mode menu
1910  if (pickMenu_)
1911  {
1912  pw = pickMenu_->WIDTH;
1913  ph = pickMenu_->HEIGHT;
1914  ppos = cpos + QPoint(-offset-pw, -ph/2);
1915  }
1916  else
1917  {
1918  ppos = cpos; pw=ph=0;
1919  }
1920 
1921 
1922 
1923  // handle screen boundaries
1924  minx = std::min(dpos.x(), std::min(fpos.x(), ppos.x()));
1925  maxx = std::max(dpos.x()+dw, std::max(fpos.x()+fw, ppos.x()+pw));
1926  miny = std::min(dpos.y(), std::min(fpos.y(), ppos.y()));
1927  maxy = std::max(dpos.y()+dh, std::max(fpos.y()+fh, ppos.y()+ph));
1928 
1929 
1930  if (minx < 0)
1931  {
1932  dx = -minx;
1933  }
1934  else if (maxx >= qApp->desktop()->width())
1935  {
1936  dx = qApp->desktop()->width() - maxx;
1937  }
1938 
1939  if (miny < 0)
1940  {
1941  dy = -miny;
1942  }
1943  else if (maxy >= qApp->desktop()->height())
1944  {
1945  dy = qApp->desktop()->height() - maxy;
1946  }
1947 
1948 
1949  dpos += QPoint(dx, dy);
1950  fpos += QPoint(dx, dy);
1951  ppos += QPoint(dx, dy);
1952 
1953 
1954 
1955  // popping up 3 menus only works w/o Qt menu fade/animate effects
1956  bool animate_menu = qApp->isEffectEnabled(Qt::UI_AnimateMenu);
1957  bool fade_menu = qApp->isEffectEnabled(Qt::UI_FadeMenu);
1958  if (animate_menu) qApp->setEffectEnabled(Qt::UI_AnimateMenu, false);
1959  if (fade_menu) qApp->setEffectEnabled(Qt::UI_FadeMenu, false);
1960 
1961 
1962  // popup the 3 menus
1963 
1964  if (drawMenu_)
1965  {
1966  // SceneGraph::DrawModes::setQPopupMenuChecked(drawMenu_, curDrawMode_);
1967  drawMenu_->popup(dpos);
1968  }
1969 
1970  if (funcMenu_)
1971  funcMenu_->popup(fpos);
1972 
1973  if (pickMenu_)
1974  pickMenu_->popup(ppos);
1975 
1976 
1977  // restore effect state
1978  if (animate_menu) qApp->setEffectEnabled(Qt::UI_AnimateMenu, true);
1979  if (fade_menu) qApp->setEffectEnabled(Qt::UI_FadeMenu, true);
1980 
1981 
1982  _event->accept();
1983  }
1984 }
1985 
1986 
1987 //-----------------------------------------------------------------------------
1988 
1989 
1990 void QtBaseViewer::glMousePressEvent(QMouseEvent* _event)
1991 {
1992  // right button pressed => popup menu (ignore here)
1993  if (_event->button() == Qt::RightButton && popupEnabled_)
1994  {
1995  return;
1996  }
1997  else
1998  {
1999  switch (actionMode_)
2000  {
2001  case ExamineMode:
2002  if ((_event->modifiers() & Qt::ControlModifier)) // drag&drop
2003  if ( externalDrag_ ) {
2004  emit startDragEvent( _event );
2005  } else {
2006  startDrag();
2007  }
2008  else
2009  viewMouseEvent(_event); // examine
2010  break;
2011 
2012  case LightMode:
2013  lightMouseEvent(_event);
2014  break;
2015 
2016  case PickingMode: // give event to application
2017  emit(signalMouseEvent(_event, pick_mode_name_));
2018  emit(signalMouseEvent(_event));
2019  break;
2020 
2021  case QuestionMode: // give event to application
2022  emit(signalMouseEventIdentify(_event));
2023  break;
2024  }
2025  }
2026 }
2027 
2028 
2029 //-----------------------------------------------------------------------------
2030 
2031 
2032 void QtBaseViewer::glMouseDoubleClickEvent(QMouseEvent* _event)
2033 {
2034  switch (actionMode_)
2035  {
2036  case ExamineMode:
2037  viewMouseEvent(_event);
2038  break;
2039 
2040  case LightMode:
2041  lightMouseEvent(_event);
2042  break;
2043 
2044  case PickingMode: // give event to application
2045  emit(signalMouseEvent(_event, pick_mode_name_));
2046  emit(signalMouseEvent(_event));
2047  break;
2048 
2049  case QuestionMode: // give event to application
2050  emit(signalMouseEventIdentify(_event));
2051  break;
2052  }
2053 }
2054 
2055 
2056 //-----------------------------------------------------------------------------
2057 
2058 
2059 void QtBaseViewer::glMouseMoveEvent(QMouseEvent* _event)
2060 {
2061  switch ( actionMode_ )
2062  {
2063  case ExamineMode:
2064  viewMouseEvent(_event);
2065  break;
2066 
2067  case LightMode:
2068  lightMouseEvent(_event);
2069  break;
2070 
2071  case PickingMode:
2072  // give event to application
2073  // deliver mouse moves with no button down, if tracking is enabled,
2074  if ((_event->buttons() & (Qt::LeftButton | Qt::MidButton | Qt::RightButton))
2075  || trackMouse_)
2076  {
2077  emit(signalMouseEvent(_event, pick_mode_name_));
2078  emit(signalMouseEvent(_event));
2079  }
2080  break;
2081 
2082  case QuestionMode: // give event to application
2083  emit(signalMouseEventIdentify(_event));
2084  break;
2085 
2086  default: // avoid warning
2087  break;
2088  }
2089 }
2090 
2091 
2092 //-----------------------------------------------------------------------------
2093 
2094 
2095 void QtBaseViewer::glMouseReleaseEvent(QMouseEvent* _event)
2096 {
2097 // if (_event->button() == Qt::RightButton )
2098 // hidePopupMenus();
2099 
2100  if (_event->button() != Qt::RightButton ||
2101  (actionMode_ == PickingMode && !popupEnabled_) )
2102  {
2103  switch ( actionMode_ )
2104  {
2105  case ExamineMode:
2106  viewMouseEvent(_event);
2107  break;
2108 
2109  case LightMode:
2110  lightMouseEvent(_event);
2111  break;
2112 
2113  case PickingMode: // give event to application
2114  emit(signalMouseEvent(_event, pick_mode_name_));
2115  emit(signalMouseEvent(_event));
2116  break;
2117 
2118  case QuestionMode: // give event to application
2119  emit(signalMouseEventIdentify(_event));
2120  break;
2121 
2122  default: // avoid warning
2123  break;
2124  }
2125  }
2126 
2127  isRotating_ = false;
2128 }
2129 
2130 
2131 //-----------------------------------------------------------------------------
2132 
2133 
2134 void QtBaseViewer::glMouseWheelEvent(QWheelEvent* _event)
2135 {
2136  switch ( actionMode_ )
2137  {
2138  case ExamineMode:
2139  viewWheelEvent(_event);
2140  break;
2141 
2142  case PickingMode: // give event to application
2143  emit(signalWheelEvent(_event, pick_mode_name_));
2144  break;
2145 
2146  default: // avoid warning
2147  break;
2148  }
2149 
2150  isRotating_ = false;
2151 }
2152 
2153 //-----------------------------------------------------------------------------
2154 
2155 
2157 {
2158  delete pickMenu_;
2159 
2160  pickMenu_ = new QMenu( 0 );
2161  connect( pickMenu_, SIGNAL( aboutToHide() ),
2162  this, SLOT( hidePopupMenus() ) );
2163 
2164  QActionGroup * ag = new QActionGroup( pickMenu_ );
2165  ag->setExclusive( true );
2166 
2167  for (unsigned int i=0; i<pick_modes_.size(); ++i) {
2168  if ( !pick_modes_[i].visible )
2169  continue;
2170 
2171  if (pick_modes_[i].name == "Separator")
2172  {
2173  if ((i > 0) && (i<pick_modes_.size()-1)) // not first, not last
2174  pickMenu_->addSeparator();
2175  }
2176  else
2177  {
2178  QAction * ac = new QAction( pick_modes_[i].name.c_str(), ag );
2179  ac->setData( QVariant( i ) );
2180  ac->setCheckable( true );
2181 
2182  if ((int)i == pick_mode_idx_)
2183  ac->setChecked( true );
2184 
2185  pickMenu_->addAction( ac );
2186  }
2187  }
2188 
2189  connect( ag, SIGNAL( triggered( QAction * ) ),
2190  this, SLOT( actionPickMenu( QAction * ) ));
2191 }
2192 
2193 //-----------------------------------------------------------------------------
2194 
2195 
2196 void QtBaseViewer::actionPickMenu( QAction * _action )
2197 {
2198  int _id = _action->data().toInt();
2199  if (_id < (int) pick_modes_.size() )
2200  {
2201  pickMode( _id );
2202  }
2203 
2205 
2206  hidePopupMenus();
2207 }
2208 
2209 //-----------------------------------------------------------------------------
2210 
2212  return buttonBar_;
2213 }
2214 
2216  glLayout_->removeWidget( buttonBar_ );
2217  return buttonBar_;
2218 }
2219 
2220 //-----------------------------------------------------------------------------
2221 
2222 
2224  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2225 
2226  ACG::Vec3d dir = glstate_->viewing_direction();
2227 
2228  dir *= -0.1;
2229 
2230  glstate_->translate(dir[0], dir[1], dir[2]);
2231 
2232  updateGL();
2233 
2234  emit viewChanged();
2235  }
2236 }
2237 
2239  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2240  ACG::Vec3d dir = glstate_->viewing_direction();
2241 
2242  dir *= 0.1;
2243 
2244  glstate_->translate(dir[0], dir[1], dir[2]);
2245 
2246  updateGL();
2247 
2248  emit viewChanged();
2249  }
2250 }
2251 
2253  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2254  ACG::Vec3d dir = glstate_->right();
2255 
2256  dir *= 0.1;
2257 
2258  glstate_->translate(dir[0], dir[1], dir[2]);
2259 
2260  updateGL();
2261 
2262  emit viewChanged();
2263  }
2264 }
2265 
2267  if(navigationMode_ == FIRSTPERSON_NAVIGATION) {
2268  ACG::Vec3d dir = glstate_->right();
2269 
2270  dir *= -0.1;
2271 
2272  glstate_->translate(dir[0], dir[1], dir[2]);
2273 
2274  updateGL();
2275 
2276  emit viewChanged();
2277  }
2278 }
2279 
2280 //=============================================================================
2281 } // namespace QtWidgets
2282 } // namespace ACG
2283 //=============================================================================
void trackMouse(bool _track)
Enable/disable mouse tracking (move events with no button press)
DrawModes::DrawMode drawModes() const
Get the collected draw modes.
Definition: SceneGraph.hh:582
const Vec3d & bbMax() const
Returns maximum point of the bounding box.
Definition: SceneGraph.hh:403
void rotate(Scalar angle, Scalar x, Scalar y, Scalar z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
static void enable(GLenum _cap, bool _warnRemoved=true)
replaces glEnable, but supports locking
Definition: GLState.cc:1507
ACG::SceneGraph::DrawModes::DrawMode drawMode()
get current draw mode
virtual void glContextMenuEvent(QContextMenuEvent *_event)
handle mouse press events
void reset_modelview()
reset modelview matrix (load identity)
Definition: GLState.cc:370
Vec3d viewing_direction() const
get viewing ray
Definition: GLState.hh:873
virtual void slotWheelX(double _dAngle)
process signals from wheelX_
void moveForward()
First person navigation: Move forward.
virtual void toggleNavigationMode()
toggle navigation mode
void set_clear_color(const Vec4f &_col)
set background color
Definition: GLState.cc:662
const std::string & pickMode() const
void signalSetView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing (cf. slotSetView())
static void shadeModel(GLenum _mode)
replaces glShadeModel, supports locking
Definition: GLState.cc:1729
virtual void slotWheelY(double _dAngle)
process signals from wheelX_
bool decodeView(const QString &_view)
void encodeView(QString &_view)
convert current view to text representation
virtual void resizeGL(int _w, int _h)
handle resize events
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
virtual void examineMode()
calls actionMode() with ExamineMode (cf. ActionMode)
virtual void startDrag()
drag & drop for modelview copying
void moveBack()
First person navigation: Move back.
virtual void slotNodeChanged(ACG::SceneGraph::BaseNode *_node)
connected to scenegraph widget
void updateProjectionMatrix()
updates projection matrix
ProjectionMode projectionMode() const
get current projection mode
Namespace providing different geometric functions concerning angles.
bool containsAtomicDrawMode(const DrawMode &_atomicDrawMode) const
Check whether an Atomic DrawMode is active in this draw Mode.
Definition: DrawModes.cc:512
virtual void showSceneGraphDialog()
show scenegraph widget
VectorT< float, 4 > Vec4f
Definition: VectorT.hh:138
GLState & glState()
get OpenGL state
QPoint glMapToGlobal(const QPoint &_pos) const
map glarea coords to global coords
void signalInitializeGL()
emitted when OpenGL stuff can be initialized
void identity()
setup an identity matrix
virtual void makeCurrent()
Makes this widget the current widget for OpenGL operations.
Show pick button? Effect only if ShowToolBar!
FaceOrientation
orientation of the faces
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)
bool animation() const
Is animation enabled?
void signalSceneGraphChanged(ACG::SceneGraph::BaseNode *_root)
scene graph has changed
virtual void orthographicProjection()
set orthographic view (projectionMode(ORTHOGRAPHIC_PROJECTION))
virtual void toggleProjectionMode()
toggle projection mode
NavigationMode navigationMode() const
get current navigation mode
virtual void paintGL()
draw the scene. Triggered by updateGL().
virtual void slotWheelZ(double _dist)
process signals from wheelZ_
ACG::SceneGraph::PickTarget pickRendererMode_
double focalDist_
Set eye distance for stereo.
virtual void sceneRectChanged(const QRectF &rect)
process graphics scene size changes
FaceOrientation faceOrientation() const
get face orientation
virtual void viewAll()
view the whole scene
virtual void perspectiveProjection()
set perspective view (projectionMode(PERSPECTIVE_PROJECTION))
void reset_projection()
reset projection matrix (load identity)
Definition: GLState.cc:334
void rotate(const Vec3d &axis, double angle)
rotate the scene (around its center) and update modelview matrix
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up)
set the viewing direction
Show question button? Effect only if ShowToolBar!
void set_modelview(const GLMatrixd &_m)
set modelview
Definition: GLState.hh:753
unsigned int glWidth() const
get width of QGLWidget
void perspective(double _fovY, double _aspect, double _near_plane, double _far_plane)
perspective projection
Definition: GLState.cc:448
Vec3d right() const
get right-vector w.r.t. camera coordinates
Definition: GLState.cc:918
void set_msSinceLastRedraw(unsigned int _ms)
set time passed since last redraw in milliseconds
Definition: GLState.hh:241
virtual void initializeGL()
initialize OpenGL states
const GLMatrixd & inverse_modelview() const
get inverse modelview matrix
Definition: GLState.hh:836
bool backFaceCulling() const
is backface culling enabled?
void viewChanged()
This signal is emitted whenever the view is changed by the user.
NormalsMode normalsMode() const
get treatment of normals
static void disable(GLenum _cap, bool _warnRemoved=true)
replaces glDisable, but supports locking
Definition: GLState.cc:1527
void setScenePos(const ACG::Vec3d &_center, double _radius, const bool _setCenter=true)
void enablePopupMenu(bool _enable)
Enable/disable right button draw mode menu (default: enabled)
virtual void viewWheelEvent(QWheelEvent *_event)=0
specialized viewer: handle wheel events
NormalsMode
Automatically normalize normals?
void sync_send(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
synchronized with different viewer?
virtual void flyTo(const QPoint &_pos, bool _move_back)
Fly to. Get closer if _move_back=false, get more distant else.
virtual void updateGL()
Redraw scene. Triggers paint event for updating the view (cf. drawNow()).
void signalMouseEvent(QMouseEvent *, const std::string &)
bool synchronized_
synchronized with different viewer?
void applyOptions(int _options)
Apply ORed Options _options.
ActionMode
How to react on mouse events?
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
void ortho(double _left, double _right, double _bottom, double _top, double _near_plane, double _far_plane)
orthographic projection
Definition: GLState.cc:402
virtual void swapBuffers()
Swaps the screen contents with the off-screen buffer.
virtual void glMouseWheelEvent(QWheelEvent *_event)
handle mouse wheel events
QPoint glMapFromGlobal(const QPoint &_pos) const
map global to glarea coords
void signalActionModeChanged(ACG::QtWidgets::QtBaseViewer::ActionMode _m)
action mode was changed
void rotate_lights(Vec3d &_axis, double _angle)
rotete light sources
bool synchronization()
synchronized with different viewer?
bool skipNextSync_
Skips the next synch event.
std::vector< PickMode > pick_modes_
Vec4f backgroundColor()
get background color
void startDragEvent(QMouseEvent *_event)
SceneGraph::BaseNode * sceneGraph()
Returns: root node of scene graph.
void updatePickMenu()
update pick mode menu
virtual void setView(const GLMatrixd &_modelview, const GLMatrixd &_inverse_modelview)
set view, used for synchronizing
void setStatusBar(QStatusBar *_sb)
NavigationMode
Navigation mode.
virtual void glMousePressEvent(QMouseEvent *_event)
handle mouse press events
void strafeRight()
First person navigation: Strafe Right.
std::vector< DrawMode > getAtomicDrawModes() const
Separates this drawMode into a list of all separate atomic draw modes.
Definition: DrawModes.cc:487
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:71
void signalMouseEventIdentify(QMouseEvent *)
QSize glSize() const
get size of QGLWIdget
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
static double deg(double _angle)
maps _angle from radiants to degrees (works also for clip()ped angles)
Definition: QtWheel.cc:440
void signalDrawScene(ACG::GLState *_state)
render callback
static double clip(double _angle)
Definition: QtWheel.cc:436
void update_lights()
update light position
virtual ~QtBaseViewer()
Destructor.
virtual void glMouseReleaseEvent(QMouseEvent *_event)
handle mouse release events
virtual void unlockUpdate()
Unlock display locked by updateLock().
virtual void viewMouseEvent(QMouseEvent *_event)=0
specialized viewer: hande mouse events
void setFovy(double _fovy)
set field of view y
bool add_sync_host(const QString &_name)
add host to synchronize with, given by its name
ActionMode actionMode() const
get action mode
void setSceneCenter(const ACG::Vec3d &_center)
void signalWheelEvent(QWheelEvent *, const std::string &)
Emitted in Pick mode. Uses pick mode.
const Vec3d & bbMin() const
Returns minimum point of the bounding box.
Definition: SceneGraph.hh:401
Show wheel for rotation around x-axis (left)?
Show wheel for rotation around y-axis (bottom)?
virtual void setHome()
set home position
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:816
void translate(const Vec3d &trans)
translate the scene and update modelview matrix
QUdpSocket * socket_
socket used for synchronization
virtual void home()
go to home pos
bool stereo_
Set eye distance for stereo.
QtBaseViewer(QWidget *_parent=0, const char *_name=0, QStatusBar *_statusBar=0, const QGLFormat *_format=0, const QtBaseViewer *_share=0, Options _options=DefaultOptions)
void set_projection(const GLMatrixd &_m)
set projection
Definition: GLState.hh:716
virtual void glMouseMoveEvent(QMouseEvent *_event)
handle mouse move events
bool pick(SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, unsigned int &_nodeIdx, unsigned int &_targetIdx, Vec3d *_hitPointPtr=0)
void set_twosided_lighting(bool _b)
set whether transparent or solid objects should be drawn
Definition: GLState.cc:822
void setState()
set the whole stored gl state
Definition: GLState.cc:209
static void drawBuffer(GLenum _mode)
replaces glDrawBuffer, supports locking
Definition: GLState.cc:2076
QToolBar * getToolBar()
Returns a pointer to the Toolbar.
void lookAt(const Vec3d &_eye, const Vec3d &_center, const Vec3d &_up)
set camera by lookAt
Definition: GLState.cc:515
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:811
void signalNodeChanged(ACG::SceneGraph::BaseNode *_node)
scene graph has changed
virtual void setSynchronization(bool _b)
toggle global synchronization
QToolBar * removeToolBar()
Returns a pointer to the toolbar and removes it from the default position in the examiner widget...
void initModelviewMatrix()
initialize modelview matrix to identity
virtual void lightMouseEvent(QMouseEvent *)
optional: hande mouse events to rotate light
bool twoSidedLighting() const
is 2-sided lighing enabled?
virtual void glMouseDoubleClickEvent(QMouseEvent *_event)
handle mouse double click events
const Vec4f & clear_color() const
get background color
Definition: GLState.hh:946
double eyeDist_
Set eye distance for stereo.
ProjectionMode
projection mode
void translate(double _x, double _y, double _z, MultiplyFrom _mult_from=MULT_FROM_RIGHT)
translate by (_x, _y, _z)
Definition: GLState.cc:533
void traverse(BaseNode *_node, Action &_action)
Definition: SceneGraph.hh:137
unsigned int glHeight() const
get height of QGLWidget
void initialize()
initialize all state variables (called by constructor)
Definition: GLState.cc:162
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
void signalPickModeChanged(const std::string &)
void strafeLeft()
First person navigation: Strafe left.