Rendering a time sequence of volumes

#1

Hi All,
I’m new around here, and also new to VTK so bear with me. I have a series of vti files of an object. The series describes the movement of the object. I would like to render the series as an animation. So far I’ve been able to render only one at a time. Here’s what I have so far, and it’s not rendering the second volume:

reader = vtk.vtkXMLImageDataReader()
reader.SetFileName(’…/data/vtk/object_00.vti’)
reader.Update()

reader0 = vtk.vtkXMLImageDataReader()
reader0.SetFileName(’…/data/vtk/object_05.vti’)
reader0.Update()

alphaChannelFunc = vtk.vtkPiecewiseFunction()
alphaChannelFunc.AddPoint(0, 0.0)
alphaChannelFunc.AddPoint(50, 0.05)
alphaChannelFunc.AddPoint(51, 0.5)
alphaChannelFunc.AddPoint(255, 0.5)

colorFunc = vtk.vtkColorTransferFunction()
colorFunc.AddRGBPoint(0, 0.0, 0.0, 0.0)
colorFunc.AddRGBPoint(50, 0.1, 0.1, 0.1)
colorFunc.AddRGBPoint(51, 0.5, 0.5, 0.5)
colorFunc.AddRGBPoint(100, 0.7, 0.7, 0.7)
colorFunc.AddRGBPoint(150, 0.9, 0.9, 0.9)

volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetColor(colorFunc)
volumeProperty.SetScalarOpacity(alphaChannelFunc)

volumeMapper = vtk.vtkGPUVolumeRayCastMapper()
volumeMapper.SetInputConnection(reader.GetOutputPort())
volumeMapper.AddInputConnection(reader0.GetOutputPort())

volume = vtk.vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

renderer = vtk.vtkRenderer()
renderWin = vtk.vtkRenderWindow()
renderWin.AddRenderer(renderer)
renderInteractor = vtk.vtkRenderWindowInteractor()
renderInteractor.SetRenderWindow(renderWin)

renderer.AddVolume(volume)
renderer.SetBackground(0,0,0)
renderWin.SetSize(800, 600)

def exitCheck(obj, event):
if obj.GetEventPending() != 0:
obj.SetAbortRender(1)

renderWin.AddObserver(“AbortCheckEvent”, exitCheck)

renderInteractor.Initialize()
renderWin.Render()
renderInteractor.Start()

Any help appreciated!
-Guillaume

(Andrew Wilson) #2

Are you wanting to output the series of images as raw pngs? As video? Real time? Side by side?

#3

Hi Andrew,
I want to render the series in real time.
Thanks!
-G

(Andrew Wilson) #4

You could just manually switch the mappers image input to your next volume, at the next time point. To do this in “real time” you can setup a timer with the interactor to do this every x milliseconds (like 16ms). https://vtk.org/Wiki/VTK/Examples/Cxx/Utilities/Timer

(Marco Musy) #5

If you wish to use the vtkplotter library this becomes very easy:

from vtkplotter import *

img = loadImageData(datadir+'head.vti') # load vtkImageData obj

for i in range(9): # animation
    x, y, z = i*200, sin(i)*120, cos(i)*120

    vol = Volume(img, c=i) # vtkVolume
    vol.crop(back=0.4).pos(x,y,z) # crop 40% from the back (neg.y)
    vol.show(bg='white', interactive=0)
    #screenshot(str(i)+'.png')

printHistogram(img, logscale=True)
show(interactive=1)

Note that also another great tool exists which is vtki to achieve a similar result.

#6

I finally got around to trying this out. vtkplotter makes this very easy indeed, thanks! However I’m not using a typical rendering window. I’m using the vtkOpenVRRenderWindow. Is there a way to make vtkplotter work with OpenVR?
To give more context: I’m able to do something close to what I want with ParaView and its OpenVR plugin. However for some reason switching from one volume at time t to the next at time t+1 seems to be CPU bound, and therefore slow. I’d like to load all my volumes in the GPU at first and create a timer that toggles visibility on/off in a loop but I’d like for all of this to happen in the GPU, not involving the CPU to avoid the slowdowns I’ve been experienceing. Is this doable?
My apologies if this isn’t clear. I’m not too familiar with the world of 3D rendering and I’m learning as I go.

(Marco Musy) #7

i’m not sure if i can answer your questions, we need a real vtk expert here… :wink:
vtkplotter uses vtkGPUVolumeRayCastMapper so i guess everything should be happening on the gpu…
As the classes you mention inherit from the usual ones you might clone the vtkplotter and just change 2 lines in plotter.py (line 370, and 494) and see if that works…

#8

I’m a bit confused: following your link, line 370 is just title="", and line 494 is ############################. Did you reference the correct lines?

(Marco Musy) #9

… that’s because in the meanwhile I committed a new version… try
pip install -U vtkplotter
then lines are now 567
self.interactor = vtk.vtkRenderWindowInteractor()

and 443
self.window = vtk.vtkRenderWindow()