Scipy cookbook example not compatible with vtk 8

Hello everyone,

I’m trying to get familiar with vtk in python.
I’d like to do ray tracing using vtk 8.

So I found the following example at https://vtk.org/Wiki/VTK/Examples/Python/vtkWithNumpy

(reproducing it to freeze it in time)

# An example from scipy cookbook demonstrating the use of numpy arrys in vtk 

import vtk
from numpy import *

# We begin by creating the data we want to render.
# For this tutorial, we create a 3D-image containing three overlaping cubes.
# This data can of course easily be replaced by data from a medical CT-scan or anything else three dimensional.
# The only limit is that the data must be reduced to unsigned 8 bit or 16 bit integers.
data_matrix = zeros([75, 75, 75], dtype=uint8)
data_matrix[0:35, 0:35, 0:35] = 50
data_matrix[25:55, 25:55, 25:55] = 100
data_matrix[45:74, 45:74, 45:74] = 150

# For VTK to be able to use the data, it must be stored as a VTK-image. This can be done by the vtkImageImport-class which
# imports raw data and stores it.
dataImporter = vtk.vtkImageImport()
# The preaviusly created array is converted to a string of chars and imported.
data_string = data_matrix.tostring()
dataImporter.CopyImportVoidPointer(data_string, len(data_string))
# The type of the newly imported data is set to unsigned char (uint8)
dataImporter.SetDataScalarTypeToUnsignedChar()
# Because the data that is imported only contains an intensity value (it isnt RGB-coded or someting similar), the importer
# must be told this is the case.
dataImporter.SetNumberOfScalarComponents(1)
# The following two functions describe how the data is stored and the dimensions of the array it is stored in. For this
# simple case, all axes are of length 75 and begins with the first element. For other data, this is probably not the case.
# I have to admit however, that I honestly dont know the difference between SetDataExtent() and SetWholeExtent() although
# VTK complains if not both are used.
dataImporter.SetDataExtent(0, 74, 0, 74, 0, 74)
dataImporter.SetWholeExtent(0, 74, 0, 74, 0, 74)

# The following class is used to store transparencyv-values for later retrival. In our case, we want the value 0 to be
# completly opaque whereas the three different cubes are given different transperancy-values to show how it works.
alphaChannelFunc = vtk.vtkPiecewiseFunction()
alphaChannelFunc.AddPoint(0, 0.0)
alphaChannelFunc.AddPoint(50, 0.05)
alphaChannelFunc.AddPoint(100, 0.1)
alphaChannelFunc.AddPoint(150, 0.2)

# This class stores color data and can create color tables from a few color points. For this demo, we want the three cubes
# to be of the colors red green and blue.
colorFunc = vtk.vtkColorTransferFunction()
colorFunc.AddRGBPoint(50, 1.0, 0.0, 0.0)
colorFunc.AddRGBPoint(100, 0.0, 1.0, 0.0)
colorFunc.AddRGBPoint(150, 0.0, 0.0, 1.0)

# The preavius two classes stored properties. Because we want to apply these properties to the volume we want to render,
# we have to store them in a class that stores volume prpoperties.
volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetColor(colorFunc)
volumeProperty.SetScalarOpacity(alphaChannelFunc)

# This class describes how the volume is rendered (through ray tracing).
compositeFunction = vtk.vtkVolumeRayCastCompositeFunction()
# We can finally create our volume. We also have to specify the data for it, as well as how the data will be rendered.
volumeMapper = vtk.vtkVolumeRayCastMapper()
volumeMapper.SetVolumeRayCastFunction(compositeFunction)
volumeMapper.SetInputConnection(dataImporter.GetOutputPort())

# The class vtkVolume is used to pair the preaviusly declared volume as well as the properties to be used when rendering that volume.
volume = vtk.vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

# With almost everything else ready, its time to initialize the renderer and window, as well as creating a method for exiting the application
renderer = vtk.vtkRenderer()
renderWin = vtk.vtkRenderWindow()
renderWin.AddRenderer(renderer)
renderInteractor = vtk.vtkRenderWindowInteractor()
renderInteractor.SetRenderWindow(renderWin)

# We add the volume to the renderer ...
renderer.AddVolume(volume)
# ... set background color to white ...
renderer.SetBackground(0,0,0)
# ... and set window size.
renderWin.SetSize(400, 400)

# A simple function to be called when the user decides to quit the application.
def exitCheck(obj, event):
    if obj.GetEventPending() != 0:
        obj.SetAbortRender(1)

# Tell the application to use the function as an exit check.
renderWin.AddObserver("AbortCheckEvent", exitCheck)

renderInteractor.Initialize()
# Because nothing will be rendered without any input, we order the first render manually before control is handed over to the main-loop.
renderWin.Render()
renderInteractor.Start()

I have the following here surely related to API changes :slightly_smiling_face:

module 'vtk' has no attribute 'vtkVolumeRayCastCompositeFunction'
module 'vtk' has no attribute 'vtkVolumeRayCastMapper'

Maybe this line is problematic too, but cannot affirm because I could not find the relevant new way to do this.

volumeMapper.SetVolumeRayCastFunction(compositeFunction)

Here is the result of

pip freeze

apptools==4.4.0
attrs==19.1.0
backcall==0.1.0
bleach==3.1.0
configobj==5.0.6
cycler==0.10.0
decorator==4.4.0
defusedxml==0.6.0
entrypoints==0.3
envisage==4.7.2
fenics==2019.1.0
fenics-dijitso==2019.1.0
fenics-ffc==2019.1.0.post0
fenics-fiat==2019.1.0
fenics-ufl==2019.1.0
ipykernel==5.1.1
ipython==7.5.0
ipython-genutils==0.2.0
ipywidgets==7.4.2
jedi==0.13.3
Jinja2==2.10.1
jsonschema==3.0.1
jupyter==1.0.0
jupyter-client==5.2.4
jupyter-console==6.0.0
jupyter-core==4.4.0
jupyterlab==0.35.6
jupyterlab-server==0.2.0
kiwisolver==1.1.0
MarkupSafe==1.1.1
matplotlib==3.1.0
mayavi==4.6.2
mistune==0.8.4
mpmath==1.1.0
nbconvert==5.5.0
nbformat==4.4.0
notebook==5.7.8
numpy==1.16.4
pandocfilters==1.4.2
parso==0.4.0
pexpect==4.7.0
pickleshare==0.7.5
prometheus-client==0.7.0
prompt-toolkit==2.0.9
ptyprocess==0.6.0
pyface==6.1.0
Pygments==2.4.2
pyparsing==2.4.0
PyQt5==5.12.2
PyQt5-sip==4.19.17
pyrsistent==0.15.2
python-dateutil==2.8.0
pyzmq==18.0.1
qtconsole==4.5.1
Send2Trash==1.5.0
six==1.12.0
sympy==1.4
terminado==0.8.2
testpath==0.4.2
tornado==6.0.2
traitlets==4.3.2
traits==5.1.1
traitsui==6.1.1
vtk==8.1.2
wcwidth==0.1.7
webencodings==0.5.1
widgetsnbextension==3.4.2

I would be really grateful if someone could help me figure out what is the new way of doing this. I really need the ray tracer quality !

Thank you very much,
Joachim

It was deprecated in https://gitlab.kitware.com/vtk/vtk/commit/bc6c71ea79dc7bd7523b81aa1d1b5e6a98d57daf in https://gitlab.kitware.com/vtk/vtk/merge_requests/639. Following that, the tests were updated to use the new pattern here: https://gitlab.kitware.com/vtk/vtk/merge_requests/1307. However, I believe that all of the Wiki examples have been ported over to @lorensen’s repository. That one seems to now live here: https://github.com/lorensen/VTKExamples/blob/master/src/Python/Utilities/VTKWithNumpy.py

Hello Ben,

Thank you very much for your quick answer !
Seems like the problem is solved , thank you for pointing me to the right source of info.

Joachim

Hello Joachim,

I got the same questions with you. Could you please tell me what vtkVolumeRayCastCompositeFunction, vtkVolumeRayCastMapper and SetVolumeRayCastFunction are changed to? There was a problem fetching the pipeline stages when I view Ben’s link. Thanks a lot.

Fan