VTK/Tutorials/InteractorStyleSubclass

From KitwarePublic
< VTK‎ | Tutorials
Jump to navigationJump to search

Introduction

A typical way to handle events produced by a user (keypress, mouse events, etc) is to create a subclass of the chosen vtkInteractorStyle. Consider using the MouseEvents example for simply capturing mouse clicks.

Creating the Subclass

Suppose we are using vtkInteractorStyleTrackballCamera: <source lang="cpp">

 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
     vtkSmartPointer<vtkRenderWindowInteractor>::New();
 renderWindowInteractor->SetRenderWindow ( renderWindow );

 vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = 
   vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
 renderWindowInteractor->SetInteractorStyle( style );

</source>

and now we decide that we should do something when the user clicks the left mouse button. We create a subclass of vtkInteractorStyleTrackballCamera:

<source lang="cpp"> class MouseInteractorStyle : public vtkInteractorStyleTrackballCamera {

 public:
   static MouseInteractorStyle* New();
   vtkTypeRevisionMacro(MouseInteractorStyle,vtkInteractorStyleTrackballCamera);
   
   virtual void OnLeftButtonDown() 
   {
     cout << "Pressed left mouse button." << endl;
     // forward events
     vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
   }

}; vtkCxxRevisionMacro(MouseInteractorStyle, "$Revision: 1.1 $"); vtkStandardNewMacro(MouseInteractorStyle); </source>

and provide an implementation of the OnLeftButtonDown() function.

Using the Subclass

We now simply change our existing vtkInteractorStyleTrackballCamera instance to a MouseInteractorStyle instance: <source lang="cpp">

 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
     vtkSmartPointer<vtkRenderWindowInteractor>::New();
 renderWindowInteractor->SetRenderWindow ( renderWindow );

 vtkSmartPointer<MouseInteractorStyle> style = 
   vtkSmartPointer<MouseInteractorStyle>::New();
 renderWindowInteractor->SetInteractorStyle( style );

</source>

Writing the Function Implementation

We can perform any actions that we wish when the event happens (in this case, a simple output to the standard output stream when the left mouse button is clicked). We typically want to forward the event along to the superclass that we derived from so that everything that "usually" happens when using the chosen interactor style still happens after we are done with our new functionality. This is achieved by calling: <source lang="cpp"> vtkInteractorStyleTrackballCamera::OnLeftButtonDown(); </source>

Accessing Other Objects

A very common question is "That's great, now I know when the left button was pressed, but I don't have access to any of my objects in this class!?". For example, many times we wish to do something to the vtkRenderWindow that has been instantiated in main. The solution is to add a member variable and an accessor to the interactor style subclass:

<source lang="cpp"> class MouseInteractorStyle : public vtkInteractorStyleTrackballCamera {

 public:
   static MouseInteractorStyle* New();
   vtkTypeRevisionMacro(MouseInteractorStyle,vtkInteractorStyleTrackballCamera);
   
   virtual void OnLeftButtonDown() 
   {
     cout << "Pressed left mouse button." << endl;
     this->MyRenderWindow->Render();
     // forward events
     vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
   }
 void SetMyRenderWindow(vtkSmartPointer<vtkRenderWindow> renderWindow){this->MyRenderWindow = renderWindow;}
 private:
  vtkSmartPointer<vtkRenderWindow> MyRenderWindow;

}; vtkCxxRevisionMacro(MouseInteractorStyle, "$Revision: 1.1 $"); vtkStandardNewMacro(MouseInteractorStyle); </source>

We can now set the render window when we instantiate the interactor style subclass: <source lang="cpp">

 vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = 
     vtkSmartPointer<vtkRenderWindowInteractor>::New();
 renderWindowInteractor->SetRenderWindow ( renderWindow );

 vtkSmartPointer<MouseInteractorStyle> style = 
   vtkSmartPointer<MouseInteractorStyle>::New();
 style->SetMyRenderWindow(renderWindow);
 renderWindowInteractor->SetInteractorStyle( style );

</source>

As shown above, we can now access the render window from the OnLeftButtonDown() function.