VTK:在vtkRenderWindowInteractior处于活动状态时,以编程方式旋转actor



我正在尝试使用vtkActor::RotateZ旋转vtkActor,然后调用vtkRenderWindow::Render。它工作得很好(它旋转演员),但我不能移动、调整大小,甚至不能聚焦窗口。

我怀疑这是由于没有捕获操作系统事件引起的,所以我在混合中添加了一个vtkRenderWindowInteractor。现在我可以移动、调整窗口大小和聚焦窗口,但演员不再旋转了。

我已经在下面的代码片段中隔离了代码,注释行43可以看到这两种效果:

renderWindowInteractor->Start();

我正在使用mingw-w64(GCC 4.9.1)编译VTK 6.2,运行在Windows 8.1中。我已经在这个回购中上传了一个小的CMake设置的代码,所以你可以很容易地测试它。

谢谢你的帮助!


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(); // <-- Comment this line!
    // Render
    float rot = 0.0f;
    while(true)
    {
        texturedPlane->SetOrientation(0,0,0);
        texturedPlane->RotateZ(rot++);
        renWin->Render();
    }
}

使用asdfasdf的解决方案解决:(本回购中的代码)

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();
}

破解以解决部分问题。

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<CommandSubclass2> timerCallback =  vtkSmartPointer<CommandSubclass2>::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();
    }
}

如果我没有给你任何其他回复,我很抱歉,但由于这个解决方案很糟糕,我一直在等待其他人找到更好的解决方案,但似乎没有人回答你,所以我会这么做。

你几乎可以猜到它的作用。交互开始后每1ms,就会调用一个回调,停止交互并进行旋转。

最新更新