【问题标题】:VTK rendering not working as expected inside PyQtVTK 渲染在 PyQt 中无法按预期工作
【发布时间】:2018-07-16 08:31:56
【问题描述】:

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

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

第一张图片是来自vtk.vtkConeSource()的圆锥体。

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

左: 没有 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_()

【问题讨论】:

  • 我无法在 Mac OS 10.11.6 和 VTK 8.1 上重现该问题。你用的是什么版本的VTK?

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


【解决方案1】:

在尝试了几件事后,我得到了阅读以下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

【讨论】:

  • 此解决方案不再有效。我的环境设置:Manjaro==20.1.2;蟒蛇==3.8.5; VTK==8.2.0; PyQt==5.15.1
  • 我在 Ubuntu 20.04、qt 5.12.8 和 vtk 7.1.1 上遇到了这个问题。除了奇怪的伪透明效果之外,我注意到的第一件事是,无论场景中的真实深度如何,一个演员总是会在另一个演员面前渲染。这个解决方案对我有用。
【解决方案2】:

vtk较新版本的解决方案:

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

import vtk

【讨论】:

    【解决方案3】:

    正如我在评论中所写,我无法在 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
    

    【讨论】:

    • 我使用的是 Ubuntu 16.04,VTK 的版本是 8.1.1。我试过你的代码,问题仍然存在。 self.ren 的输出看起来和你的一样。
    • 好的。我倾向于将您的问题归类为错误。最后,您可以使用演员的面部剔除选项。见vtkProperty。这有什么改变吗?
    • 如果我添加coneActor.GetProperty().SetBackfaceCulling(1),锥体显示正确(可能是因为它是一个表面)。但是例如在点云中,背景的点仍然显示在前面的点之上。
    • 你能在多台机器上重现这个吗?由于涉及到OpenGL,所以问题可能与驱动问题有关。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多