Rendering an actor created within a vtkCommand (callback)

老子叫甜甜 提交于 2021-01-29 06:25:42

问题


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

回答1:


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

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


来源:https://stackoverflow.com/questions/54337397/rendering-an-actor-created-within-a-vtkcommand-callback

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!