3

I'm discovering VTK and want to use it to plot a 3D numpy array. So far, I've managed to convert a numpy array to a vtk.Volume and displaying it but from there I am having a hard time getting something pretty.
I get a very blocky rendering like this :
should have played more Minecraft

and I would like a smooth rendering, so I guess either this volume but smoothed, or the surface extracted from this volume smoothed.
I've tested a bunch of vtk mappers for this volume, like SmartVolumeMapper, and played around with the Shader and the Interpolation, but did not get great results.

Here is my code (in Python) :

import vtk
import numpy as np

npa= #some 3D numpy array
[h,w,z]=npa.shape

#importing the numpy array (comes from http://www.vtk.org/Wiki/VTK/Examples/Python/vtkWithNumpy) 
dataImporter = vtk.vtkImageImport()
data_string = npa.tostring()
dataImporter.CopyImportVoidPointer(data_string, len(data_string))
dataImporter.SetDataScalarTypeToUnsignedChar()
dataImporter.SetNumberOfScalarComponents(1)
dataImporter.SetDataExtent(0,z-1, 0, w-1, 0,h-1)
dataImporter.SetWholeExtent(0,z-1, 0,w-1, 0,h-1)

#Defining a transparency function
alphaChannelFunc = vtk.vtkPiecewiseFunction()
alphaChannelFunc.AddPoint(0, 0.0)
alphaChannelFunc.AddPoint(255, 1)

# Defining a color function
colorFunc = vtk.vtkColorTransferFunction()
colorFunc.AddRGBPoint(255, 1.0, 1.0, 1.0)
colorFunc.AddRGBPoint(128, 0.0, 0, 1.0)

#Creating the volume
volumeProperty = vtk.vtkVolumeProperty()
volumeProperty.SetColor(colorFunc)
volumeProperty.SetScalarOpacity(alphaChannelFunc)
volumeProperty.ShadeOn()
volumeProperty.SetInterpolationTypeToLinear()

#Creating the mapper
compositeFunction = vtk.vtkVolumeRayCastCompositeFunction()
volumeMapper = vtk.vtkVolumeRayCastMapper()
volumeMapper.SetVolumeRayCastFunction(compositeFunction)
volumeMapper.SetInputConnection(dataImporter.GetOutputPort())

#Creating the volume actor
volume = vtk.vtkVolume()
volume.SetMapper(volumeMapper)
volume.SetProperty(volumeProperty)

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

#Adding the actor
renderer.AddVolume(volume)
renderer.SetBackground(0, 0, 0)
renderWin.SetSize(400, 400)

#Launching the renderer
renderInteractor.Initialize()
renderWin.Render()
renderInteractor.Start()

I get the impression that a Volume actor is not the way to go to get something pretty, maybe I should go for a PolyData or something ? I went through the Marching Cubes example (in C++) which seems to take a volume and extract a surface out of it, but I can't get it to work for the moment (no errors but output is a completely white buggy window which won't close).
I could dive more into it to try and get it to work but first I would like to get input from you guys, since I'm a beginner in VTK and maybe I'm handling this all wrong.

I'm using Python 2.7.12 and vtk 5.10.1 on Ubuntu 14.

Soltius
  • 2,162
  • 1
  • 16
  • 28
  • So your data is a set of points in 3d, without any data attached to the individual points? Are the points representing a surface? Maybe you can triangulate the point cloud and include only tetrahedras up to a certain size criterion. – mululu Jun 06 '17 at 09:57
  • Yes exactly, it's only a set of points in 3D, nothing else. The points don't represent a surface, they represent a volume. Thanks for the triangulation idea, it might take a lot of computationnal power though... – Soltius Jun 06 '17 at 11:32

0 Answers0