|
|
(One intermediate revision by one other user not shown) |
Line 1: |
Line 1: |
| ==Introduction== | | = '''Examples are now hosted here: [https://kitware.github.io/vtk-examples/site/ VTKExamples website].''' = |
| 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.
| |
| | |
| Consider referencing the [[ VTK/Examples/Cxx#Widgets | Widgets examples page ]] for more examples.
| |
| | |
| 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>
| |