When rendering transparent objects whith python VTK lib, strange effects of the image display appear. At some points when we rotate objects, something happens with the transparency of objects. They disappear from the foreground. Sometimes it happens sometimes not. This greatly hinders the navigation in the viewport. Perhaps this is related to normals. Is it possible to solve this problem? Code:
import vtk
import numpy as np
data_matrix = np.zeros([75, 75, 75], dtype=np.uint8)
data_matrix[1:35, 1:35, 1:35] = 1
data_matrix[25:55, 25:55, 25:55] = 2
data_matrix[45:74, 45:74, 45:74] = 3
w, d, h = data_matrix.shape
dicom_images = vtk.vtkImageImport()
dicom_images.CopyImportVoidPointer(data_matrix.tostring(),
len(data_matrix.tostring()))
dicom_images.SetDataScalarTypeToUnsignedChar()
dicom_images.SetNumberOfScalarComponents(1)
dicom_images.SetDataExtent(0, h - 1, 0, d - 1, 0, w - 1)
dicom_images.SetWholeExtent(0, h - 1, 0, d - 1, 0, w - 1)
dicom_images.SetDataSpacing(1, 1, 1)
render = vtk.vtkRenderer()
render_window = vtk.vtkRenderWindow()
render_window.AddRenderer(render)
render_interact = vtk.vtkRenderWindowInteractor()
render_interact.SetRenderWindow(render_window)
threshold_dicom_image = vtk.vtkImageThreshold()
threshold_dicom_image.SetInputConnection(dicom_images.GetOutputPort())
threshold_dicom_image.Update()
discrete_marching_cubes = vtk.vtkDiscreteMarchingCubes()
discrete_marching_cubes.SetInputConnection(threshold_dicom_image.GetOutputPort())
discrete_marching_cubes.GenerateValues(3, 1, 3)
discrete_marching_cubes.ComputeNormalsOn()
discrete_marching_cubes.Update()
colorLookupTable = vtk.vtkLookupTable()
colorLookupTable.SetNumberOfTableValues(3)
colorLookupTable.Build()
colorLookupTable.SetTableValue(0, 1, 0, 0, 0.5)
colorLookupTable.SetTableValue(1, 0, 1, 0, 1)
colorLookupTable.SetTableValue(2, 0, 0, 1, 0.5)
dicom_data_mapper = vtk.vtkPolyDataMapper()
dicom_data_mapper.SetInputConnection(discrete_marching_cubes.GetOutputPort())
dicom_data_mapper.ScalarVisibilityOn()
dicom_data_mapper.SetLookupTable(colorLookupTable)
dicom_data_mapper.SetScalarRange(1, 3)
dicom_data_mapper.Update()
actor_dicom_3d = vtk.vtkActor()
actor_dicom_3d.SetMapper(dicom_data_mapper)
render.AddActor(actor_dicom_3d)
render.ResetCamera()
render_window.Render()
render_interact.Start()
You need to specify some algorithm to handle transparency rendering. VTK natively has depth peeling implemented and dual depth peeling since VTK 7.0 (and I think VTK 8.0 introduced something new, but I haven't checked that yet).
So the easiest way to "turn on" transparency is to enable depth peeling on the renderer:
render.SetUseDepthPeeling(1)
render.SetOcclusionRatio(0.1)
render.SetMaximumNumberOfPeels(100)
render_window.SetMultiSamples(0)
render_window.SetAlphaBitPlanes(1)
See https://www.vtk.org/Wiki/VTK/Examples/Cxx/Visualization/CorrectlyRenderTranslucentGeometry for some more details about the parameters. Note that it requires support of openGL version at least 3.2. If you are using VTK 7.0 or higher, the "dual depth peeling" will be used automatically if your graphic drivers support it, otherwise the standard depth peeling will be used.