渲染在 vtkCommand 中创建的角色(回调)

Rendering an actor created within a vtkCommand (callback)

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

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

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

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

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