#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkSphereSource.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
//定义一个类,该类将是一个定时器回调函数
class vtkTimerCallback : public vtkCommand
{
public:
static vtkTimerCallback* New()
{
vtkTimerCallback* cb = new vtkTimerCallback;
cb->TimerCount = 0;
return cb;
}
//定义定时器回调函数
virtual void Execute(vtkObject* vtkNotUsed(caller), unsigned long eventId,
void* vtkNotUsed(callData))
{
if (vtkCommand::TimerEvent == eventId)
{
std::cout << "Timer count: " << this->TimerCount << std::endl;
++this->TimerCount;
}
}
private:
int TimerCount;
};
int main(int, char* [])
{
//创建一个球源,用来显示
vtkSmartPointer<vtkSphereSource> sphereSource =
vtkSmartPointer<vtkSphereSource>::New();
sphereSource->SetCenter(0.0, 0.0, 0.0);
sphereSource->SetRadius(5.0);
sphereSource->Update();
//将该球源放入一个Mapper
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(sphereSource->GetOutputPort());
//将Mapper放入一个Actor
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
//创建一个渲染窗口,并将Actor放入该窗口
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
//创建一个Interactor,并将渲染窗口放入该Interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
//创建一个定时器回调函数
vtkSmartPointer<vtkTimerCallback> timerCallback =
vtkSmartPointer<vtkTimerCallback>::New();
//添加一个定时器事件
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, timerCallback);
int timerId = renderWindowInteractor->CreateRepeatingTimer(1000); //1秒钟
renderWindow->Render();
//开始渲染
renderWindowInteractor->Start();
//删除定时器
renderWindowInteractor->DestroyTimer(timerId);
return EXIT_SUCCESS;
}
I use Linux, and TimerEvent works well. I see it counting:
Timer count: 0
Timer count: 1
Timer count: 2
Timer count: 3
But right now I tried on Windows. And it doesn’t work. So maybe the timers in vtkWin32RenderWindowInteractor are broken. That is bad, hopefully it will be fixed. One work-around is to use Qt, which has very good timers, but that increases the complexity of your application even more.
I will make a suggestion about callbacks in VTK: it is not necessary to derive your callback class from vtkCommand. The methods of any class can be used with AddObserver(). For example:
class MyClass
{
public:
// a simple callback method
void OnTimer() {
std::cout << "Timer count: " << this->TimerCount << std::endl;
++this->TimerCount;
}
/* // a callback method with arguments
void OnTimerWithArgs(vtkObject* caller, unsigned long event, void*) {
std::cout << caller->GetClassName() << " ";
std::cout << vtkCommand::GetStringFromEventId(event) << " ";
std::cout << this->TimerCount << std::endl;
++this->TimerCount;
}
*/
private:
int TimerCount = 0;
};
Using AddObserver with these callback methods:
MyClass o;
// simple callback
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, &o, &MyClass::OnTimer);
/* // callback with arguments
renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, &o, &MyClass::OnTimerWithArgs);
*/
Later, I solved the problem. The key is to initialize the interactor in advance. The timer will work only if the interactor is initialized early enough. I think it should be fixed. This is a bad way to use it.
WoW that works with python on windows too.
Thanks for your observation