소스 검색

Merge topic 'ctkVTKRenderView'

  ENH: ctkVTKRenderView - Add rock and spin animation feature
Jean-Christophe Fillion-Robin 14 년 전
부모
커밋
6886b2bc1b

+ 220 - 22
Libs/Visualization/VTK/Widgets/ctkVTKRenderView.cpp

@@ -21,6 +21,7 @@
 // Qt includes
 #include <QTimer>
 #include <QVBoxLayout>
+#include <QDebug>
 
 // CTK includes
 #include "ctkVTKRenderView.h"
@@ -51,10 +52,17 @@ ctkVTKRenderViewPrivate::ctkVTKRenderViewPrivate()
   this->RenderPending = false;
   this->RenderEnabled = false;
   this->ZoomFactor = 0.05;
-  this->RotateDegrees = 5;
+  this->PitchRollYawIncrement = 5;
   this->PitchDirection = ctkVTKRenderView::PitchUp;
   this->RollDirection = ctkVTKRenderView::RollRight;
   this->YawDirection = ctkVTKRenderView::YawLeft;
+  this->SpinDirection = ctkVTKRenderView::YawRight;
+  this->SpinEnabled = false;
+  this->AnimationIntervalMs = 5;
+  this->SpinIncrement = 2;
+  this->RockEnabled = false;
+  this->RockIncrement = 0;
+  this->RockLength = 200;
 }
 
 // --------------------------------------------------------------------------
@@ -118,6 +126,97 @@ void ctkVTKRenderViewPrivate::zoom(double zoomFactor)
 }
 
 //---------------------------------------------------------------------------
+void ctkVTKRenderViewPrivate::pitch(int rotateDegrees,
+                                    ctkVTKRenderView::RotateDirection pitchDirection)
+{
+  Q_ASSERT(this->Renderer->IsActiveCameraCreated());
+  Q_ASSERT(rotateDegrees >= 0);
+  vtkCamera *cam = this->Renderer->GetActiveCamera();
+  cam->Elevation(pitchDirection == ctkVTKRenderView::PitchDown ? rotateDegrees : -rotateDegrees);
+  cam->OrthogonalizeViewUp();
+  this->Renderer->UpdateLightsGeometryToFollowCamera();
+}
+
+//---------------------------------------------------------------------------
+void ctkVTKRenderViewPrivate::roll(int rotateDegrees,
+                                    ctkVTKRenderView::RotateDirection rollDirection)
+{
+  Q_ASSERT(this->Renderer->IsActiveCameraCreated());
+  Q_ASSERT(rotateDegrees >= 0);
+
+  vtkCamera *cam = this->Renderer->GetActiveCamera();
+  cam->Roll(rollDirection == ctkVTKRenderView::RollLeft ? rotateDegrees : -rotateDegrees);
+  cam->OrthogonalizeViewUp();
+  this->Renderer->UpdateLightsGeometryToFollowCamera();
+}
+
+//---------------------------------------------------------------------------
+void ctkVTKRenderViewPrivate::yaw(int rotateDegrees,
+                                    ctkVTKRenderView::RotateDirection yawDirection)
+{
+  Q_ASSERT(this->Renderer->IsActiveCameraCreated());
+  Q_ASSERT(rotateDegrees >= 0);
+  vtkCamera *cam = this->Renderer->GetActiveCamera();
+  cam->Azimuth(yawDirection == ctkVTKRenderView::YawLeft ? rotateDegrees : -rotateDegrees);
+  cam->OrthogonalizeViewUp();
+  this->Renderer->UpdateLightsGeometryToFollowCamera();
+}
+
+//---------------------------------------------------------------------------
+void ctkVTKRenderViewPrivate::doSpin()
+{
+  if (!this->SpinEnabled)
+    {
+    return;
+    }
+
+  switch (this->SpinDirection)
+    {
+    case ctkVTKRenderView::PitchUp:
+    case ctkVTKRenderView::PitchDown:
+      this->pitch(this->SpinIncrement, this->SpinDirection);
+      break;
+    case ctkVTKRenderView::RollLeft:
+    case ctkVTKRenderView::RollRight:
+      this->roll(this->SpinIncrement, this->SpinDirection);
+      break;
+    case ctkVTKRenderView::YawLeft:
+    case ctkVTKRenderView::YawRight:
+      this->yaw(this->SpinIncrement, this->SpinDirection);
+      break;
+    }
+
+  QTimer::singleShot(this->AnimationIntervalMs, this, SLOT(doSpin()));
+}
+
+//---------------------------------------------------------------------------
+void ctkVTKRenderViewPrivate::doRock()
+{
+  Q_ASSERT(this->Renderer->IsActiveCameraCreated());
+
+  if (!this->RockEnabled)
+    {
+    return;
+    }
+
+  vtkCamera *camera = this->Renderer->GetActiveCamera();
+
+  double frac = static_cast<double>(this->RockIncrement) / static_cast<double>(this->RockLength);
+  double az = 1.5 * cos (2.0 * 3.1415926 * (frac - floor(frac)));
+  this->RockIncrement = 1 + this->RockIncrement;
+  this->RockIncrement = this->RockIncrement % this->RockLength;
+
+  // Move the camera
+  camera->Azimuth(az);
+  camera->OrthogonalizeViewUp();
+
+  //Make the lighting follow the camera to avoid illumination changes
+  this->Renderer->UpdateLightsGeometryToFollowCamera();
+
+  QTimer::singleShot(this->AnimationIntervalMs, this, SLOT(doRock()));
+}
+
+//---------------------------------------------------------------------------
 // ctkVTKRenderView methods
 
 // --------------------------------------------------------------------------
@@ -288,26 +387,60 @@ CTK_SET_CXX(ctkVTKRenderView, bool, setRenderEnabled, RenderEnabled);
 CTK_GET_CXX(ctkVTKRenderView, bool, renderEnabled, RenderEnabled);
 
 //----------------------------------------------------------------------------
-CTK_GET_CXX(ctkVTKRenderView, int, rotateDegrees, RotateDegrees);
+CTK_GET_CXX(ctkVTKRenderView, int, pitchRollYawIncrement, PitchRollYawIncrement);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setPitchRollYawIncrement(int newPitchRollYawIncrement)
+{
+  CTK_D(ctkVTKRenderView);
+  d->PitchRollYawIncrement = qAbs(newPitchRollYawIncrement);
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RotateDirection, pitchDirection, PitchDirection);
 
 //----------------------------------------------------------------------------
-void ctkVTKRenderView::setRotateDegrees(int newRotateDegrees)
+void ctkVTKRenderView::setPitchDirection(ctkVTKRenderView::RotateDirection newPitchDirection)
 {
   CTK_D(ctkVTKRenderView);
-  d->RotateDegrees = qAbs(newRotateDegrees);
+  if (newPitchDirection != Self::PitchUp && newPitchDirection != Self::PitchDown)
+    {
+    return;
+    }
+  d->PitchDirection = newPitchDirection;
 }
 
 //----------------------------------------------------------------------------
-CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::PitchDirection, pitchDirection, PitchDirection);
-CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::PitchDirection, setPitchDirection, PitchDirection);
+CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RotateDirection, rollDirection, RollDirection);
 
 //----------------------------------------------------------------------------
-CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RollDirection, rollDirection, RollDirection);
-CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::RollDirection, setRollDirection, RollDirection);
+void ctkVTKRenderView::setRollDirection(ctkVTKRenderView::RotateDirection newRollDirection)
+{
+  CTK_D(ctkVTKRenderView);
+  if (newRollDirection != Self::RollLeft && newRollDirection != Self::RollRight)
+    {
+    return;
+    }
+  d->RollDirection = newRollDirection;
+}
 
 //----------------------------------------------------------------------------
-CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::YawDirection, yawDirection, YawDirection);
-CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::YawDirection, setYawDirection, YawDirection);
+CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RotateDirection, yawDirection, YawDirection);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setYawDirection(ctkVTKRenderView::RotateDirection newYawDirection)
+{
+  CTK_D(ctkVTKRenderView);
+  if (newYawDirection != Self::YawLeft && newYawDirection != Self::YawRight)
+    {
+    return;
+    }
+  d->YawDirection = newYawDirection;
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, ctkVTKRenderView::RotateDirection, spinDirection, SpinDirection);
+CTK_SET_CXX(ctkVTKRenderView, ctkVTKRenderView::RotateDirection, setSpinDirection, SpinDirection);
 
 //----------------------------------------------------------------------------
 void ctkVTKRenderView::pitch()
@@ -317,10 +450,7 @@ void ctkVTKRenderView::pitch()
     {
     return;
     }
-  vtkCamera *cam = d->Renderer->GetActiveCamera();
-  cam->Elevation(d->PitchDirection == Self::PitchDown ? d->RotateDegrees : -d->RotateDegrees);
-  cam->OrthogonalizeViewUp();
-  d->Renderer->UpdateLightsGeometryToFollowCamera();
+  d->pitch(d->PitchRollYawIncrement, d->PitchDirection);
 }
 
 //----------------------------------------------------------------------------
@@ -331,10 +461,7 @@ void ctkVTKRenderView::roll()
     {
     return;
     }
-  vtkCamera *cam = d->Renderer->GetActiveCamera();
-  cam->Roll(d->RollDirection == Self::RollLeft ? d->RotateDegrees : -d->RotateDegrees);
-  cam->OrthogonalizeViewUp();
-  d->Renderer->UpdateLightsGeometryToFollowCamera();
+  d->roll(d->PitchRollYawIncrement, d->RollDirection);
 }
 
 //----------------------------------------------------------------------------
@@ -345,13 +472,84 @@ void ctkVTKRenderView::yaw()
     {
     return;
     }
-  vtkCamera *cam = d->Renderer->GetActiveCamera();
-  cam->Azimuth(d->YawDirection == Self::YawLeft ? d->RotateDegrees : -d->RotateDegrees);
-  cam->OrthogonalizeViewUp();
-  d->Renderer->UpdateLightsGeometryToFollowCamera();
+  d->yaw(d->PitchRollYawIncrement, d->YawDirection);
+}
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setSpinEnabled(bool enabled)
+{
+  CTK_D(ctkVTKRenderView);
+  if (enabled == d->SpinEnabled)
+    {
+    return;
+    }
+  d->SpinEnabled = enabled;
+  d->RockEnabled = false;
+
+  QTimer::singleShot(0, d, SLOT(doSpin()));
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, bool, spinEnabled, SpinEnabled);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setSpinIncrement(int newSpinIncrement)
+{
+  CTK_D(ctkVTKRenderView);
+  d->SpinIncrement = qAbs(newSpinIncrement);
 }
 
 //----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, int, spinIncrement, SpinIncrement);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setAnimationIntervalMs(int newAnimationIntervalMs)
+{
+  CTK_D(ctkVTKRenderView);
+  d->AnimationIntervalMs = qAbs(newAnimationIntervalMs);
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, int, animationIntervalMs, AnimationIntervalMs);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setRockEnabled(bool enabled)
+{
+  CTK_D(ctkVTKRenderView);
+  if (enabled == d->RockEnabled)
+    {
+    return;
+    }
+  d->RockEnabled = enabled;
+  d->SpinEnabled = false;
+
+  QTimer::singleShot(0, d, SLOT(doRock()));
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, bool, rockEnabled, RockEnabled);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setRockLength(int newRockLength)
+{
+  CTK_D(ctkVTKRenderView);
+  d->RockLength = qAbs(newRockLength);
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, int, rockLength, RockLength);
+
+//----------------------------------------------------------------------------
+void ctkVTKRenderView::setRockIncrement(int newRockIncrement)
+{
+  CTK_D(ctkVTKRenderView);
+  d->RockIncrement = qAbs(newRockIncrement);
+}
+
+//----------------------------------------------------------------------------
+CTK_GET_CXX(ctkVTKRenderView, int, rockIncrement, RockIncrement);
+
+//----------------------------------------------------------------------------
 void ctkVTKRenderView::setZoomFactor(double newZoomFactor)
 {
   CTK_D(ctkVTKRenderView);

+ 71 - 27
Libs/Visualization/VTK/Widgets/ctkVTKRenderView.h

@@ -45,22 +45,23 @@ class CTK_VISUALIZATION_VTK_WIDGETS_EXPORT ctkVTKRenderView : public QWidget
   Q_PROPERTY(bool orientationWidgetVisible READ orientationWidgetVisible
              WRITE setOrientationWidgetVisible)
   Q_PROPERTY(double zoomFactor READ zoomFactor WRITE setZoomFactor)
-  Q_PROPERTY(int rotateDegrees READ rotateDegrees WRITE setRotateDegrees)
-  Q_ENUMS(PitchDirection)
-  Q_PROPERTY(PitchDirection pitchDirection READ pitchDirection WRITE setPitchDirection)
-  Q_ENUMS(RollDirection)
-  Q_PROPERTY(RollDirection rollDirection READ rollDirection WRITE setRollDirection)
-  Q_ENUMS(YawDirection)
-  Q_PROPERTY(YawDirection yawDirection READ yawDirection WRITE setYawDirection)
+  Q_PROPERTY(int pitchRollYawIncrement READ pitchRollYawIncrement WRITE setPitchRollYawIncrement)
+  Q_ENUMS(RotateDirection)
+  Q_PROPERTY(RotateDirection pitchDirection READ pitchDirection WRITE setPitchDirection)
+  Q_PROPERTY(RotateDirection rollDirection READ rollDirection WRITE setRollDirection)
+  Q_PROPERTY(RotateDirection yawDirection READ yawDirection WRITE setYawDirection)
+  Q_PROPERTY(RotateDirection spinDirection READ spinDirection WRITE setSpinDirection)
+  Q_PROPERTY(bool spinEnabled READ spinEnabled WRITE setSpinEnabled)
+  Q_PROPERTY(int spinIncrement READ spinIncrement WRITE setSpinIncrement)
+  Q_PROPERTY(int animationIntervalMs READ animationIntervalMs WRITE setAnimationIntervalMs)
+  Q_PROPERTY(bool rockEnabled READ rockEnabled WRITE setRockEnabled)
+  Q_PROPERTY(int rockLength READ rockLength WRITE setRockLength)
 
 public:
 
-  enum PitchDirection { PitchUp, PitchDown };
-  enum RollDirection {RollLeft, RollRight};
-  enum YawDirection {YawLeft, YawRight};
+  enum RotateDirection { PitchUp, PitchDown, RollLeft, RollRight, YawLeft, YawRight };
 
-  /// Constructors
-  typedef QWidget   Superclass;
+  typedef QWidget Superclass;
   explicit ctkVTKRenderView(QWidget* parent = 0);
   virtual ~ctkVTKRenderView(){}
 
@@ -87,20 +88,40 @@ public slots:
   /// Set absolute amount degrees the view should be either pitched, rolled or yawed with.
   /// \sa pitch setPitchDirection roll setRollDirection yaw setYawDirection
   /// \note The default is 5 degrees
-  void setRotateDegrees(int newRotateDegrees);
+  void setPitchRollYawIncrement(int newPitchRollYawIncrement);
 
-  /// Pitch view of X degrees. X been set using setRotateDegrees
-  /// \sa setRotateDegrees
+  /// Pitch view of X degrees. X been set using setPitchRollYawIncrement
+  /// \sa setPitchRollYawIncrement setPitchDirection
   void pitch();
 
-  /// Rool view of X degrees. X been set using setRotateDegrees
-  /// \sa setRotateDegrees
+  /// Rool view of X degrees. X been set using setPitchRollYawIncrement
+  /// \sa setPitchRollYawIncrement setRollDirection
   void roll();
 
-  /// Yaw view of X degrees. X been set using setRotateDegrees
-  /// \sa setRotateDegrees
+  /// Yaw view of X degrees. X been set using setPitchRollYawIncrement
+  /// \sa setPitchRollYawIncrement setYawDirection
   void yaw();
 
+  /// Enable or Disbled the animated spin of the view
+  void setSpinEnabled(bool enabled);
+
+  /// Set number of degrees in spin increment
+  /// \sa setSpinDirection setSpinIntervalMs
+  void setSpinIncrement(int newSpinIncrement);
+
+  /// Amount of wait time between spin or rock increments
+  /// \sa setSpinIncrement setRockIncrement
+  void setAnimationIntervalMs(int ms);
+
+  /// Enable or Disbled the animated rock of the view
+  void setRockEnabled(bool enabled);
+
+  /// Set length of the rock animation
+  void setRockLength(int newRockLength);
+
+  /// Set increment of animated rock
+  void setRockIncrement(int newRockIncrement);
+
   /// \brief Set zoom factor
   /// zoomFactor is a value between 0.0 and 1.0
   /// \note The default value is 0.05
@@ -153,17 +174,40 @@ public:
   /// Return if rendering is enabled
   bool renderEnabled() const;
 
-  /// Return amount of degrees used to either pitch, roll or yaw the view
-  int rotateDegrees()const;
+  /// Return pitch, roll or yaw increment (in degree)
+  int pitchRollYawIncrement()const;
+
+  /// Return if animated spin is enabled
+  bool spinEnabled() const;
+
+  /// Return spin increment (in degrees)
+  /// \sa setSpinIncrement
+  int spinIncrement()const;
+
+  /// Amount of waiting time between spin or rock increment
+  /// \sa setAnimationIntervalMs
+  int animationIntervalMs()const;
+
+  /// Return if animated rock is enabled
+  bool rockEnabled() const;
+
+  /// Return length of the rock animation
+  int rockLength() const;
+
+  /// Return increment of animated rock
+  int rockIncrement() const;
+
+  RotateDirection pitchDirection()const;
+  void setPitchDirection(RotateDirection newPitchDirection);
 
-  PitchDirection pitchDirection()const;
-  void setPitchDirection(PitchDirection newPitchDirection);
+  RotateDirection rollDirection()const;
+  void setRollDirection(RotateDirection newRollDirection);
 
-  RollDirection rollDirection()const;
-  void setRollDirection(RollDirection newRollDirection);
+  RotateDirection yawDirection()const;
+  void setYawDirection(RotateDirection newYawDirection);
 
-  YawDirection yawDirection()const;
-  void setYawDirection(YawDirection newYawDirection);
+  RotateDirection spinDirection()const;
+  void setSpinDirection(RotateDirection newSpinDirection);
 
   /// Return zoom factor
   double zoomFactor()const;

+ 23 - 6
Libs/Visualization/VTK/Widgets/ctkVTKRenderView_p.h

@@ -50,13 +50,23 @@ class ctkVTKRenderViewPrivate : public QObject,
 public:
   ctkVTKRenderViewPrivate();
 
-  void zoom(double zoomFactor);
-
   /// Convenient setup methods
   void setupCornerAnnotation();
   void setupRendering();
   void setupDefaultInteractor();
 
+  void zoom(double zoomFactor);
+
+  void pitch(int rotateDegrees, ctkVTKRenderView::RotateDirection pitchDirection);
+  void roll(int rotateDegrees, ctkVTKRenderView::RotateDirection rollDirection);
+  void yaw(int rotateDegrees, ctkVTKRenderView::RotateDirection yawDirection);
+
+public slots:
+  void doSpin();
+  void doRock();
+
+public:
+
   QVTKWidget*                                   VTKWidget;
   vtkSmartPointer<vtkRenderer>                  Renderer;
   vtkSmartPointer<vtkRenderWindow>              RenderWindow;
@@ -67,10 +77,17 @@ public:
   vtkSmartPointer<vtkOrientationMarkerWidget>   Orientation;
   vtkSmartPointer<vtkCornerAnnotation>          CornerAnnotation;
   double                                        ZoomFactor;
-  int                                           RotateDegrees;
-  ctkVTKRenderView::PitchDirection              PitchDirection;
-  ctkVTKRenderView::RollDirection               RollDirection;
-  ctkVTKRenderView::YawDirection                YawDirection;
+  int                                           PitchRollYawIncrement;
+  ctkVTKRenderView::RotateDirection             PitchDirection;
+  ctkVTKRenderView::RotateDirection             RollDirection;
+  ctkVTKRenderView::RotateDirection             YawDirection;
+  ctkVTKRenderView::RotateDirection             SpinDirection;
+  bool                                          SpinEnabled;
+  int                                           AnimationIntervalMs;
+  int                                           SpinIncrement;
+  bool                                          RockEnabled;
+  int                                           RockIncrement;
+  int                                           RockLength;
 
   vtkWeakPointer<vtkRenderWindowInteractor>     CurrentInteractor;