渲染在 vtkCommand 中创建的 actor(回调) [英] Rendering an actor created within a vtkCommand (callback)

查看:31
本文介绍了渲染在 vtkCommand 中创建的 actor(回调)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个程序,该程序在按下箭头键时显示和循环显示不同文件格式的图像.我发现设置我的 reader->mapper->actor 管道然后启动我的 RenderWindowInteractor 允许渲染 actor,但是将此代码移动到 RenderWindowInteractor 的 KeyPressEvent 的回调不允许渲染 actor.一旦事件循环开始,是否还需要额外的步骤来设置新的 actor,或者我犯了其他错误?

I am attempting to write a program that displays and cycles through images of different file formats when the arrow keys are pressed. I have found that setting up my reader->mapper->actor pipeline and then starting my RenderWindowInteractor allows the actor to be rendered, but moving this code to a callback for the RenderWindowInteractor's KeyPressEvent does not allow the actor to be rendered. Are there additional steps required to set up a new actor once the event loop has started, or have I made some other mistake?

import vtk

#Create the renderer that will display our actors
ren = vtk.vtkRenderer()

actor = None

#Maps the data from the Nifti file 'filename' onto a vtkImageSlice actor
def LoadNifti():
    # load head MRI in NIFTI format
    reader = vtk.vtkNIFTIImageReader()
    reader.SetFileName("head.nii")
    reader.Update()

    # Add an ImageSliceMapper, which maps data to an ImageSlice Actor
    mapper = vtk.vtkImageSliceMapper()
    #Set the slice position to the camera focal point
    mapper.SliceAtFocalPointOn()
    mapper.SetInputConnection(reader.GetOutputPort())

    # Add an ImageSlice actor, which represents a slice as an image
    global actor
    actor = vtk.vtkImageSlice()
    actor.SetMapper(mapper)

#Placeholder for when I have DICOM working
def ShowDICOM(filename):
    pass


#Create a RenderWindow to display images from the Renderer
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)

#Wrap the RenderWindow in a RenderWindowInteractor to catch key and mouse events
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

def foo():
    LoadNifti()
    ren.AddActor(actor)

##Extend the default functionality of the interactor and its style with custom listeners
def KeyPressEvent(obj, ev):
    foo()
    print("This verifies that the callback is triggered")
iren.AddObserver("KeyPressEvent", KeyPressEvent)        

#Start the program
###########################################################################
# WHEN foo() IS PRESENT BELOW, THE ACTOR WILL RENDER IMMEDIATELY.
# WHEN foo() IS ABSENT BELOW, CALLING foo() BY TRIGGERING THE KeyPressEvent
# IS NOT SUFFICIENT TO HAVE THE ACTOR RENDER.
###########################################################################
foo()
#According to the docs, the Start method will initialize iren and render renWin automatically
iren.Start()

推荐答案

好吧,您绝对可以在回调中添加或删除 actor.要立即再次渲染场景,只需调用 iren.Render().

Well, you definitely can add or remove actors inside a callback. To render the scene again immediately, simply call iren.Render().

当您在没有任何可见演员和明确定义的相机的情况下启动渲染器时,通常需要 ResetCamera.自动 ResetCamera 在初始化期间只调用一次,这就是为什么在 iren.Start() 之前调用 foo() 使得对象可见.

When you start a renderer without any visible actors and without an explicitly defined camera, then ResetCamera is typically required. Automatic ResetCamera is only called once during the initialization, and this is the reason, why calling foo() before iren.Start() makes the object visible.

def foo():
    LoadNifti()
    ren.AddActor(actor)
    ren.ResetCamera() # should that be necessary
    iren.Render()

这篇关于渲染在 vtkCommand 中创建的 actor(回调)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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