VTK渲染在PyQt中无法按预期工作

时间:2018-07-16 08:31:57

标签: python-3.x qt rendering pyqt5 vtk

我需要在PyQt应用程序中集成VTK可视化。但是,当我将模型放入QVTKRenderWindowInteractor时,显示会显示一些不希望的透明效果(请参见下图)。无论我尝试加载什么,都会发生于表面或点云。

有什么方法可以在QVTKRenderWindowInteractor内部实现正确的表示吗?

第一张图片是vtk.vtkConeSource()的圆锥形。

Cone; Left: Without QVTKRenderWindowInteractor. Right: With QVTKRenderWindowInteractor

第二张图片是PCL测试公司的 cturtle.pcd 点云。

Cturtle; Left: Without QVTKRenderWindowInteractor. Right: With QVTKRenderWindowInteractor

左: 没有QVTKRenderWindowInteractor。 :使用QVTKRenderWindowInteractor

我附上该问题的示例代码以供复制。 这是没有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()

这是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_()

3 个答案:

答案 0 :(得分:3)

尝试了几件事之后,我得到了阅读以下Merge Request的解决方案。

我使用QGLWidget作为QVTKRenderWindowInteractor的基类,而不是QWidget。发生这种变化是因为据报道,有时QWidget可能会导致呈现问题。

为此,我在导入QVTKRenderWindowInteractor之前放置了以下代码:

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

from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

为了使用QGLWidget,我必须安装以下软件包:

  

sudo apt-get install python3-pyqt5.qtopengl

答案 1 :(得分:0)

正如我在评论中所写,我无法在MacOS 10.11.6上重现VTK 8.1的问题。如果您运行的是旧版本,请考虑升级。

下面是另一个示例,其中QVTKRenderWindowInteractor小部件被嵌入到QMainWindow中。问题仍然存在吗?

如果是,请比较我在下面附加的print(self.ren)的输出。我会在vtk issue tracker上进行举报。

#!/usr/bin/env python
import sys
import vtk
from PyQt5 import QtWidgets
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from vtk.util.colors import tomato

class MainWindow(QtWidgets.QMainWindow):

    def __init__(self, parent = None):
        super(MainWindow, self,).__init__(parent)

        self.frame = QtWidgets.QFrame()
        self.vl = QtWidgets.QVBoxLayout()
        self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
        self.vl.addWidget(self.vtkWidget)
        self.ren = vtk.vtkRenderer()
        self.ren.SetBackground(0.5,0.5,0.5)
        self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
        self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()

        source = vtk.vtkConeSource()
        source.SetResolution(8)
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputConnection(source.GetOutputPort())
        actor = vtk.vtkActor()
        actor.SetMapper(mapper)
        actor.GetProperty().SetColor(tomato)
        actor.RotateX(30.0)
        actor.RotateY(-45.0)

        self.ren.AddActor(actor)
        self.ren.SetBackground(0.1, 0.2, 0.4)
        self.ren.ResetCamera()
        self.ren.GetActiveCamera().Zoom(1.5)
        self.frame.setLayout(self.vl)
        self.setCentralWidget(self.frame)

        # Print the renderer.
        print(self.ren)

        self.show()
        self.iren.Initialize()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    window = MainWindow()
    sys.exit(app.exec_())

控制台输出:

vtkOpenGLRenderer (0x7ff4c3d8a5f0)
  Debug: Off
  Modified Time: 1159
  Reference Count: 2
  Registered Events: (none)
  Aspect: (1, 1)
  PixelAspect: (1, 1)
  Background: (0.1, 0.2, 0.4)
  Background2: (0.2, 0.2, 0.2)
  BackgroundAlpha: 0
  GradientBackground: Off
  Viewport: (0, 0, 1, 1)
  Displaypoint: (0, 0, 0)
  Viewpoint: (0, 0, 0)
  Worldpoint: (0, 0, 0, 0)
  Pick Position X1 Y1: -1 -1
  Pick Position X2 Y2: -1 -1
  IsPicking boolean: 0
  Props:
    Debug: Off
    Modified Time: 923
    Reference Count: 1
    Registered Events: (none)
    Number Of Items: 1
  PickResultProps:
  nullptr
  Near Clipping Plane Tolerance: 0.001
  ClippingRangeExpansion: 0.5
  Ambient: (1, 1, 1)
  Backing Store: Off
  Display Point: (0, 0, 0)
  Lights:
    Debug: Off
    Modified Time: 806
    Reference Count: 1
    Registered Events: (none)
    Number Of Items: 0
  Light Follow Camera: On
  View Point: (0, 0, 0)
  Two Sided Lighting: On
  Automatic Light Creation: On
  Layer = 0
  PreserveDepthBuffer: Off
  PreserveColorBuffer: Off
  Interactive = On
  Allocated Render Time: 10000
  Last Time To Render (Seconds): -1
  TimeFactor: 1
  Erase: On
  Draw: On
  UseDepthPeeling: Off
  OcclusionRation: 0
  MaximumNumberOfPeels: 4
  LastRenderingUsedDepthPeeling: Off
  Delegate:null
  Selector: 0x0
  TexturedBackground: Off
  BackgroundTexture:null
  Pass:null
  PickedId0
  NumPicked0
  PickedZ 0

答案 2 :(得分:0)

vtk较新版本的解决方案:

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

import vtk