VTK: rotacione o ator programaticamente enquanto o vtkRenderWindowInteractor está ativo

Eu estou tentando rodar um vtkActor usando vtkActor::RotateZ e, em seguida, chamando vtkRenderWindow::Render . Ele funciona bem (gira o ator), mas não consigo mover, resize nem focar a janela.

Eu suspeitava que isso foi causado devido a algo não capturar os events do sistema operacional, então adicionei um vtkRenderWindowInteractor à mistura. Agora posso mover, resize e focar a janela, mas o ator não está mais girando.

Eu isolei o código no snippet abaixo, comente a linha 43 para ver os dois efeitos:

 renderWindowInteractor->Start(); 

Estou compilando o VTK 6.2 com o mingw-w64 (GCC 4.9.1), em execução no Windows 8.1. Eu carreguei o código neste repository com uma pequena configuração do CMake para que você possa testá-lo facilmente.

Obrigado pela ajuda!


 constexpr float planeWidth = 200.0f; constexpr float planeHeight = 100.0f; int main() { auto renderer = vtkRenderer::New(); // Create render window auto renWin = vtkRenderWindow::New(); renWin->AddRenderer(renderer); renWin->SetSize(600,600); // Create a plane auto texturedPlane = vtkActor::New(); auto plane = vtkPlaneSource::New(); plane->SetOrigin(0, planeHeight, 0); plane->SetPoint1(planeWidth, planeHeight, 0); plane->SetPoint2(0, 0, 0); auto planeMapper = vtkPolyDataMapper::New(); planeMapper->SetInputConnection(plane->GetOutputPort()); texturedPlane->SetMapper(planeMapper); texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0); renderer->AddActor(texturedPlane); renderer->ResetCamera(); // Create a RenderWindowInteractor auto renderWindowInteractor = vtkRenderWindowInteractor::New(); renderWindowInteractor->SetRenderWindow(renWin); renderWindowInteractor->Start(); // SetOrientation(0,0,0); texturedPlane->RotateZ(rot++); renWin->Render(); } } 

Resolvido usando a solução do asdfasdf: (Código neste repo )

 constexpr float planeWidth = 200.0f; constexpr float planeHeight = 100.0f; vtkActor * texturedPlane; vtkRenderWindowInteractor * renderWindowInteractor; vtkRenderWindow * renWin; float rot = 0.0f; class RotateCommand : public vtkCommand { public: vtkTypeMacro(RotateCommand, vtkCommand); static RotateCommand * New() { return new RotateCommand; } void Execute(vtkObject * vtkNotUsed(caller), unsigned long vtkNotUsed(eventId), void * vtkNotUsed(callData)) { texturedPlane->SetOrientation(0,0,0); texturedPlane->RotateZ(rot++); renWin->Render(); } }; int main() { auto renderer = vtkRenderer::New(); // Create render window renWin = vtkRenderWindow::New(); renWin->AddRenderer(renderer); renWin->SetSize(600,600); // Create a plane texturedPlane = vtkActor::New(); auto plane = vtkPlaneSource::New(); plane->SetOrigin(0, planeHeight, 0); plane->SetPoint1(planeWidth, planeHeight, 0); plane->SetPoint2(0, 0, 0); auto planeMapper = vtkPolyDataMapper::New(); planeMapper->SetInputConnection(plane->GetOutputPort()); texturedPlane->SetMapper(planeMapper); texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0); renderer->AddActor(texturedPlane); renderer->ResetCamera(); // Create a RenderWindowInteractor renderWindowInteractor = vtkRenderWindowInteractor::New(); renderWindowInteractor->SetRenderWindow(renWin); renderWindowInteractor->Initialize(); renderWindowInteractor->CreateRepeatingTimer(1); RotateCommand * rotateCallback = RotateCommand::New(); renderWindowInteractor->AddObserver(vtkCommand::TimerEvent, rotateCallback ); renderWindowInteractor->Start(); } 

Hack para contornar parte do problema.

 vtkRenderWindowInteractor * renderWindowInteractor; constexpr float planeWidth = 200.0f; constexpr float planeHeight = 100.0f; class CommandSubclass2 : public vtkCommand { public: vtkTypeMacro(CommandSubclass2, vtkCommand); static CommandSubclass2 *New() { return new CommandSubclass2; } void Execute(vtkObject *vtkNotUsed(caller), unsigned long vtkNotUsed(eventId), void *vtkNotUsed(callData)) { std::cout << "timer callback" << std::endl; renderWindowInteractor->ExitCallback(); } }; int main() { auto renderer = vtkRenderer::New(); // Create render window auto renWin = vtkRenderWindow::New(); renWin->AddRenderer(renderer); renWin->SetSize(600,600); // Create a plane auto texturedPlane = vtkActor::New(); auto plane = vtkPlaneSource::New(); plane->SetOrigin(0, planeHeight, 0); plane->SetPoint1(planeWidth, planeHeight, 0); plane->SetPoint2(0, 0, 0); auto planeMapper = vtkPolyDataMapper::New(); planeMapper->SetInputConnection(plane->GetOutputPort()); texturedPlane->SetMapper(planeMapper); texturedPlane->SetOrigin(planeWidth / 2, planeHeight, 0); renderer->AddActor(texturedPlane); renderer->ResetCamera(); // Create a RenderWindowInteractor renderWindowInteractor = vtkRenderWindowInteractor::New(); renderWindowInteractor->SetRenderWindow(renWin); renderWindowInteractor->Initialize(); renderWindowInteractor->CreateRepeatingTimer(1); vtkSmartPointer timerCallback = vtkSmartPointer::New(); renderWindowInteractor->AddObserver ( vtkCommand::TimerEvent, timerCallback ); // Render float rot = 0.0f; while(true) { renderWindowInteractor->Start(); // <-- Comment this line! texturedPlane->SetOrientation(0,0,0); texturedPlane->RotateZ(rot++); renWin->Render(); } } 

Me desculpe se eu não te dei nenhuma outra resposta, mas como essa solução é muito ruim, eu estava esperando alguém encontrar uma solução melhor, mas parece que ninguém te respondeu, então aqui está o que eu faria Faz.

Você pode adivinhar o que faz. Cada 1 ms depois de iniciar a interação, é chamado um retorno de chamada que interromperá a interação e fará uma rotação.