VTK/Tutorials/Callbacks: Difference between revisions

From KitwarePublic
< VTK‎ | Tutorials
Jump to navigationJump to search
No edit summary
(→‎Introduction: Add a note about the Execute function)
 
(3 intermediate revisions by 3 users not shown)
Line 14: Line 14:
       vtkSmartPointer<vtkCallbackCommand>::New();
       vtkSmartPointer<vtkCallbackCommand>::New();
   keypressCallback->SetCallback ( func );
   keypressCallback->SetCallback ( func );
</source>
OR
2. Create a vtkCallbackCommand and reimplement
<source lang="cpp">
virtual void Execute(vtkObject *caller, unsigned long, void*)
</source>
It will then automatically be the callback used when creating the CallbackCommand object with
<source lang="cpp">
  vtkSmartPointer<vtkCallbackCommand> keypressCallback =
      vtkSmartPointer<vtkCallbackCommand>::New();
</source>
</source>


Line 26: Line 38:
</source>
</source>


In this example, the vtkRenderWindowInteractor is listening for the command KeyPressEvent. A complete list of commands that are available can be found [here |http://www.vtk.org/doc/nightly/html/classvtkCommand.html].
In this example, the vtkRenderWindowInteractor is listening for the command KeyPressEvent. A complete list of commands that are available can be found [http://www.vtk.org/doc/nightly/html/classvtkCommand.html here].


==Writing the Callback Function==
==Writing the Callback Function==
Line 63: Line 75:
{
{
   vtkSmartPointer<vtkProgrammableFilter> programmableFilter =  
   vtkSmartPointer<vtkProgrammableFilter> programmableFilter =  
       static_cast<vtkProgrammableFilter*>(clientData);
       reinterpret_cast<vtkProgrammableFilter*>(clientData);
}
}
</source>
</source>
A full example is [http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/ClientData here].


===calldata===
===calldata===
calldata is data that may be sent with the callback. For example, when the ProgressEvent event is sent, it sends the progress value as calldata.
calldata is data that may be sent with the callback. For example, when the ProgressEvent event is sent, it sends the progress value as calldata. A full example is [http://www.vtk.org/Wiki/VTK/Examples/Cxx/Interaction/CallData here].

Latest revision as of 13:19, 28 May 2013

Introduction

A callback function is the "observer" in the "command/observer" design pattern. That is, there are times when VTK will know that something has happened and it will send out a command notifying all observers of the event.

To catch these commands, you must do three things:

1. Create a function with this signature: <source lang="cpp">

void func(vtkObject*, unsigned long eid, void* clientdata, void *calldata)

</source>

2. Create a vtkCallbackCommand and set its callback to the function you have just created: <source lang="cpp">

 vtkSmartPointer<vtkCallbackCommand> keypressCallback = 
     vtkSmartPointer<vtkCallbackCommand>::New();
 keypressCallback->SetCallback ( func );

</source>

OR

2. Create a vtkCallbackCommand and reimplement <source lang="cpp"> virtual void Execute(vtkObject *caller, unsigned long, void*) </source> It will then automatically be the callback used when creating the CallbackCommand object with <source lang="cpp">

 vtkSmartPointer<vtkCallbackCommand> keypressCallback = 
     vtkSmartPointer<vtkCallbackCommand>::New();

</source>

3. Register the callback that was just created with the object that is observing for the command: <source lang="cpp">

vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =

     vtkSmartPointer<vtkRenderWindowInteractor>::New();
 renderWindowInteractor->SetRenderWindow(renderWindow);
 renderWindowInteractor->AddObserver ( vtkCommand::KeyPressEvent, keypressCallback );

</source>

In this example, the vtkRenderWindowInteractor is listening for the command KeyPressEvent. A complete list of commands that are available can be found here.

Writing the Callback Function

caller

The vtkObject "caller" is a pointer to the observer. In this example, since we attached the vtkCallbackCommand to a vtkRenderWindowInteractor, we can successfully cast "caller" to a vtkRenderWindowInteractor.

<source lang="cpp"> void KeypressCallbackFunction ( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ) {

 cout << "Keypress callback" << endl;
 
 vtkRenderWindowInteractor *iren = 
     static_cast<vtkRenderWindowInteractor*>(caller);
 cout << "Pressed: " << iren->GetKeySym() << endl;

}

</source>

clientdata

clientdata provides a way to provide access to data that will be necessary in the callback function. You can set this data using the SetClientData function of vtkCallbackCommand. For example, if you want to have access to an instance of a vtkProgrammableFilter in the callback function, you can do:

<source lang="cpp">

 vtkSmartPointer<vtkProgrammableFilter> filter = 
     vtkSmartPointer<vtkProgrammableFilter>::New();
 vtkSmartPointer<vtkCallbackCommand> timerCallback = 
     vtkSmartPointer<vtkCallbackCommand>::New();
 timerCallback->SetCallback ( func );
 timerCallback->SetClientData(filter);

</source>

Then in the callback function, you can cast the clientdata to the expected type: <source lang="cpp"> void func ( vtkObject* caller, long unsigned int eventId, void* clientData, void* callData ) {

 vtkSmartPointer<vtkProgrammableFilter> programmableFilter = 
     reinterpret_cast<vtkProgrammableFilter*>(clientData);

} </source>

A full example is here.

calldata

calldata is data that may be sent with the callback. For example, when the ProgressEvent event is sent, it sends the progress value as calldata. A full example is here.