如何使用VTK创建自定义事件?

3
我正在使用VTK制作一个线程软件,需要在实时更新模型本身的同时更改其渲染方式。一切都正常运作,但是问题出现在interactor->start(); ,模型数据得到了很好的更新,但只有当我移动摄像头时才会在屏幕上显示。此外,我选择了一些从imagedata文件生成3D数据的方法,为此需要关闭vtk窗口(交互式窗口),然后代码将重新打开它并将新生成的数据发送给它...。
我需要类似这样的东西:
int force close_window = false; int refresh_interactor = false;

我成功让窗口关闭了,但只能使用vtkcommand :: Keypressed命令,但我不知道如何使用新命令:S,我尝试过vtkcommand :: UserEvent,但我没有找到任何有关如何处理该数据的好信息(如一些调用它的方法)。
我处理VTK的方式是使用两个线程,第一个线程只和vtk iren循环有关,第二个线程则处理模型并检查iren是否需要更新。
在我的理想代码中,应该是这样的:
=======================================================
bool VTKWindow()
{ 
    ... 
    vtkSmartPointer ator = vtkSmartPointer::New(); 
    iren = vtkSmartPointer::New(); 
    RenWindow = vtkSmartPointer::New(); 
    render->SetBackground(.1, .2, .3); 
    RenWindow->AddRenderer(renderer); 
    iren->SetRenderWindow(RenWindow);

    if(data_type == voxel_type)
    { 
        Render->AddViewProp(VoxelData); 
    }
    else
    { 
        actor->SetMapper(PolyData);
        Render->AddActor(Actor); 
    }

    RenWindow->Render(); 
    iren->Start();
}

void ManageVTK()
{ 
    while true loop... 
            if(force close_window == true)
                do some command to exit the iren loop 
            if(refresh_interactor == true)
                do some command to refresh iren 
}

抱歉我的母语不是英语,对于问题的格式还请见谅,这是我第一次使用stackoverflow

1个回答

1

这可能听起来很蠢,但我找到了一种解决问题的方法。在相关链接中,我看到了这个人 vtkRenderWindowInteractor事件循环和线程 ,它几乎是相同的问题...

class VTKNewEvent : public vtkCommand{
    public:
        vtkTypeMacro(VTKNewEvent , vtkCommand);

        static VTKNewEvent * New(){
            return new VTKNewEvent ;
        }
        void Execute(vtkObject * caller, unsigned long vtkNotUsed(eventId), void * vtkNotUsed(callData)){
            vtkRenderWindowInteractor *iren = static_cast<vtkRenderWindowInteractor*>(caller);
            if (iren_close == true){
                iren->GetRenderWindow()->Finalize                   // Stop the interactor
                iren->TerminateApp();
                iren_close = false;
            }
            if (iren_update== true){
                renderJanela->Render();
                iren_update= false;
            }           
        }
};


bool VTKWindow(){
    vtkSmartPointer<VTKNewEvent > IrenRefresh= vtkSmartPointer<VTKNewEvent>::New();
...
    iren->CreateRepeatingTimer(1);//this makes that IrenRefresh will be called at every 1ms
    iren->AddObserver(vtkCommand::TimerEvent, IrenRefresh);
    iren->Start();
...
}

虽然也许不是最好的方法,但这很简单,确实完成了工作。我希望这个链接能够帮助那些刚进入VTK世界的人,因为线程和渲染循环并不是一件容易理解正在发生什么的事情。


1
我不确定你是否真的在这段代码中创建了一个新事件。因为你使用 vtkCommand::TimerEvent 作为触发观察者的事件。创建新事件的正确方法是使用 vtkCommand::UserEvent + intShift,其中 intShift 是一个整数,可以允许创建更多的新事件。可以通过更新 vtkAllEventsMacro 来注册这些新事件。在这个示例中,文件 vtkTestFilter.h 显示了如何创建一个未注册的新事件。 - gallo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接