Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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_()
like image 578
Ribes Avatar asked Dec 24 '22 05:12

Ribes


2 Answers

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

like image 131
Ribes Avatar answered Jan 26 '23 00:01

Ribes


The solution for newer version of vtk:

# this should be done before importing vtk
import vtkmodules.qt
vtkmodules.qt.QVTKRWIBase = 'QGLWidget'

import vtk
like image 44
2man Avatar answered Jan 26 '23 01:01

2man