VTK/Tutorials/Widgets

From KitwarePublic
< VTK‎ | Tutorials
Revision as of 21:24, 23 March 2010 by Daviddoria (talk | contribs) (Created page with '==Introduction== A widget is an object that provides an interface to a complex operation. For example, vtkBoxWidget2 allows you to move a box around a scene. It provides a way to…')
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigationJump to search

Introduction

A widget is an object that provides an interface to a complex operation. For example, vtkBoxWidget2 allows you to move a box around a scene. It provides a way to translate the box, rotate the box, and scale the box. Of course this can all be achieved using a vtkCubeSource and a specialized vtkInteractorStyle, but the widget provides all of this in a "canned" way.

There are two main components to a widget - the interaction and the representation.

Interaction

The "interaction" is the class named vtk*Widget (for example, vtkBoxWidget2). It contains all of the options for the interaction, as well as the event handling.

Representation

The representation is the object that is drawn and interacted with. The class is named vtk*Representation, where the * is the same * from vtk*Widget.

Usage

To create the widget: <source lang="cpp">

 vtkSmartPointer<vtkBoxWidget2> boxWidget = 
   vtkSmartPointer<vtkBoxWidget2>::New();
 boxWidget->SetInteractor(renderWindowInteractor);

</source>

Most widgets will create a default representation automatically. If you wish to use several non-defaults, you should probably create the representation manually, and tell the widget to use it: <source lang="cpp">

 vtkSmartPointer<vtkBoxRepresentation> boxRepresentation = 
     vtkSmartPointer<vtkBoxRepresentation>::New();
 boxWidget->SetRepresentation(boxRepresentation);

</source>

Handling Events

Often you will want to do something in response to the user interacting with the widget. To do this, you should create a subclass of vtkCommand. The Execute function does the work.

<source lang="cpp"> class vtkBoxCallback : public vtkCommand {

 public:
   static vtkBoxCallback *New()
   {
     return new vtkBoxCallback;
   }
   
   virtual void Execute(vtkObject *caller, unsigned long, void*)
   {
     
     vtkBoxWidget2 *boxWidget = 
         reinterpret_cast<vtkBoxWidget2*>(caller);
     
     //get the actual box coordinates/planes
     vtkSmartPointer<vtkPolyData> polydata = 
         vtkSmartPointer<vtkPolyData>::New();
     static_cast<vtkBoxRepresentation*>(boxWidget->GetRepresentation())->GetPolyData (polydata);
     
     //display one of the points, just so we know it's working
     double p[3];
     polydata->GetPoint(0,p);
     cout << "P: " << p[0] << " " << p[1] << " " << p[2] << endl;
   }
   vtkBoxCallback(){}
   

}; </source>

The Execute function is similar to a vtkCallbackFunction in that the calling object can be obtain by casting "caller" to the appropriate type.

Putting It All Together

To attach this new class to the widget, instantiate the class and call AddObserver on the widget:

<source lang="cpp">

 vtkSmartPointer<vtkBoxCallback> boxCallback = 
     vtkSmartPointer<vtkBoxCallback>::New();

 boxWidget->AddObserver(vtkCommand::InteractionEvent,boxCallback);

</source>

Enabling the Widget

Widgets seem fussy about the order that things are done. The following order is appropriate: <source lang="cpp">

 renderWindow->Render();
 renderWindowInteractor->Initialize();
 renderWindow->Render();
 boxWidget->On();
 
 renderWindowInteractor->Start();

</source>