Search code examples
pythonvtk

How to choose the scalar used by vtkVolumeMapper


I have a volume with several data array and I render it using a vtkVolumeMapper (vtkFixedPointVolumeRayCastMapper).

How can I tell the mapper to use a specific array as scalar? (SelectColorArray is not a function of vtkVolumeMapper)

I'm using VTK 6

    # Create the reader for the data
    reader = vtk.vtkXMLImageDataReader()
    reader.SetFileName(self.scan_analysis.content.vtk_path)
    reader.GetOutput().GetPointData().SetActiveScalars('smooth')

    # Create transfer mapping scalar value to opacity
    opacityTransferFunction = vtk.vtkPiecewiseFunction()
    opacityTransferFunction.AddPoint(5, 0.0)
    opacityTransferFunction.AddPoint(80, 0.4)
    opacityTransferFunction.AddPoint(81, 0.0)
    opacityTransferFunction.AddPoint(100, 0.0)

    # Create transfer mapping scalar value to color
    lut = vtk.vtkColorTransferFunction()
    lut.AddRGBPoint(0.0, 0.0, 0.0, 1.0)
    lut.AddRGBPoint(50.0, 1.0, 1.0, 1.0)
    lut.AddRGBPoint(100.0, 1.0, 0.0, 0.0)

    # The property describes how the data will look
    volumeProperty = vtk.vtkVolumeProperty()
    volumeProperty.SetColor(lut)
    volumeProperty.SetScalarOpacity(opacityTransferFunction)
    volumeProperty.ShadeOn()
    volumeProperty.SetInterpolationTypeToLinear()

    # The mapper / ray cast function know how to render the data
    #volumeMapper = vtk.vtkGPUVolumeRayCastMapper()
    #volumeMapper = vtk.vtkSmartVolumeMapper()
    volumeMapper = vtk.vtkFixedPointVolumeRayCastMapper()
    volumeMapper.SetBlendModeToComposite()
    volumeMapper.SetInputConnection(reader.GetOutputPort())
    volumeMapper.SelectColorArray('smooth') ## -> exception

    # The volume holds the mapper and the property and
    # can be used to position/orient the volume
    volume = vtk.vtkVolume()
    volume.SetMapper(volumeMapper)
    volume.SetProperty(volumeProperty)

Also, is it possible to use cell scalars for volume mappers ?

Thanks

Update: I ended using different vtk files for each and every scalar. It works and does not consume more disk space... but I know it's not the right solution (frustrating)


Solution

  • I found the following solution, using SetScalarsName:

    from vtk import (vtkUnstructuredGridReader, vtkDataSetMapper, vtkActor,
                     vtkRenderer, vtkRenderWindow, vtkRenderWindowInteractor)
    
    # Read the source file.
    reader = vtkUnstructuredGridReader()
    reader.SetFileName("FileName")
    
    reader.SetScalarsName("ScalarNameYouWant")  ### this command should do it
    
    #reader.ReadAllScalarsOn()
    reader.Update()  # Needed because of GetScalarRange
    output = reader.GetOutput()
    output_port = reader.GetOutputPort()
    scalar_range = output.GetScalarRange()
    # Create the mapper that corresponds the objects of the vtk file
    # into graphics elements
    mapper = vtkDataSetMapper()
    mapper.SetInputConnection(output_port)
    mapper.SetScalarRange(scalar_range)
    # Create the Actor
    actor = vtkActor()
    actor.SetMapper(mapper)
    
    # Create the Renderer
    renderer = vtkRenderer()
    renderer.AddActor(actor)
    renderer.SetBackground(1, 1, 1) # Set background to white
    
    # Create the RendererWindow
    renderer_window = vtkRenderWindow()
    renderer_window.AddRenderer(renderer)
    
    # Create the RendererWindowInteractor and display the vtk_file
    interactor = vtkRenderWindowInteractor()
    interactor.SetRenderWindow(renderer_window)
    interactor.Initialize()
    interactor.Start()
    

    Solution found here:
    https://vtk.org/gitweb?p=VTK.git;a=blob;f=Examples/DataManipulation/Python/pointToCellData.py