VTK:在vtkRenderWindowInteractor处于活动状态时,以编程方式旋转actor [英] VTK: Rotate actor programmatically while vtkRenderWindowInteractor is active

查看:1561
本文介绍了VTK:在vtkRenderWindowInteractor处于活动状态时,以编程方式旋转actor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用 vtkActor :: RotateZ 旋转 vtkActor ,然后调用 vtkRenderWindow :: Render 。它工作正常(它旋转actor),但我不能移动,调整大小,甚至聚焦窗口。

I'm trying to rotate a vtkActor using vtkActor::RotateZ and then calling vtkRenderWindow::Render. It works fine (it rotates the actor) but I can't move, resize, or even focus the window.

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

I suspected this was caused due to something not catching operating system events, so I added a vtkRenderWindowInteractor to the mix. Now I can move, resize and focus the window, but the actor is not rotating anymore.

我已隔离下面的代码段,注释行43两个效果:

I've isolated the code in the snippet below, comment line 43 to see both effects:

renderWindowInteractor->Start();

我正在使用mingw-w64(GCC 4.9.1)编译VTK 6.2,运行在Windows 8.1 。我已使用小型CMake设置上传此库中的代码,以便您可以

I'm compiling VTK 6.2 with mingw-w64 (GCC 4.9.1), running in Windows 8.1. I've uploaded the code in this repo with a small CMake setup so you can test it easily.

感谢您的帮助!

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的解决方案:
this 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();
}


推荐答案

问题。

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

对不起,如果我没有给你任何其他回复,但由于这个解决方案是相当不好,我在等待别人找到一个更好的解决方案,但似乎没有人回答你,所以这里是我会做的。

I'm sorry if I didn't give you any other reply, but since this solution is quite bad, I was waiting for someone else to find a better solution, but it seems that no one answered you, so here is what I would do.

你可以猜测它是做什么的。在开始互动后的每1毫秒,将调用一个回调函数来停止互动,并进行轮换。

You can pretty much guess what it does. Each 1 ms after starting the interaction, a callback is called that will stop the interaction, and do a rotation.

这篇关于VTK:在vtkRenderWindowInteractor处于活动状态时,以编程方式旋转actor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆