Search code examples
python-3.xqtrenderingpyqt5vtk

VTK rendering not working as expected inside PyQt


I need to integrate a VTK visualization inside a PyQt application. However, when I put a model inside a QVTKRenderWindowInteractor the display shows some undesired transparency effect (see picture below). This happens for surfaces or point clouds, whatever I try to load.

Is there any way to achieve the proper representation inside a QVTKRenderWindowInteractor?

First picture is a cone from vtk.vtkConeSource().

Cone; Left: Without QVTKRenderWindowInteractor. Right: With QVTKRenderWindowInteractor

Second picture is a cturtle.pcd pointcloud from PCL Tests.

Cturtle; Left: Without QVTKRenderWindowInteractor. Right: With QVTKRenderWindowInteractor

Left: Without QVTKRenderWindowInteractor. Right: With QVTKRenderWindowInteractor

I attach an example code of the problem for reproduction. This is the code without Qt:

#!/usr/bin/env python

import vtk
from vtk.util.colors import tomato

"""This simple example shows how to do basic rendering and pipeline creation."""

cone = vtk.vtkConeSource()
cone.SetResolution(8)

coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInputConnection(cone.GetOutputPort())

coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
coneActor.GetProperty().SetColor(tomato)
coneActor.RotateX(30.0)
coneActor.RotateY(-45.0)

ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)


ren.AddActor(coneActor)
ren.SetBackground(0.1, 0.2, 0.4)

iren.Initialize()

ren.ResetCamera()
ren.GetActiveCamera().Zoom(1.5)
renWin.Render()

iren.Start()

And this is the equivalent display inside a QVTKRenderWindowInteractor:

#!/usr/bin/env python

import vtk
from PyQt5.QtWidgets import QApplication
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtk.util.colors import tomato

"""A simple example that uses the QVTKRenderWindowInteractor class."""


app = QApplication(['QVTKRenderWindowInteractor'])

cone = vtk.vtkConeSource()
cone.SetResolution(8)

coneMapper = vtk.vtkPolyDataMapper()
coneMapper.SetInputConnection(cone.GetOutputPort())

coneActor = vtk.vtkActor()
coneActor.SetMapper(coneMapper)
coneActor.GetProperty().SetColor(tomato)
coneActor.RotateX(30.0)
coneActor.RotateY(-45.0)

ren = vtk.vtkRenderer()
widget = QVTKRenderWindowInteractor()
widget.GetRenderWindow().AddRenderer(ren)

ren.AddActor(coneActor)
ren.SetBackground(0.1,0.2,0.4)

widget.Initialize()

ren.ResetCamera()
ren.GetActiveCamera().Zoom(1.5)
widget.GetRenderWindow().Render()

widget.Start()

widget.show()
app.exec_()

Solution

  • After trying several things, I got the solution reading the following Merge Request.

    I used QGLWidget as the base class of the QVTKRenderWindowInteractor, instead of QWidget. This change is because it is reported that sometimes QWidget can cause rendering problems.

    To do this I put the following code before importing QVTKRenderWindowInteractor:

    import vtk.qt
    vtk.qt.QVTKRWIBase = "QGLWidget"
    
    from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
    

    In order to use QGLWidget I had to install the following package:

    sudo apt-get install python3-pyqt5.qtopengl