VTK 渲染在 PyQt 中没有按预期工作
VTK rendering not working as expected inside PyQt
我需要在 PyQt 应用程序中集成 VTK 可视化。但是,当我将模型放入 QVTKRenderWindowInteractor 时,显示会显示出一些不需要的透明效果(见下图)。无论我尝试加载什么,表面或点云都会发生这种情况。
有什么方法可以在 QVTKRenderWindowInteractor 中实现正确的表示吗?
第一张图片是 vtk.vtkConeSource()
的圆锥体。
第二张图片是 cturtle.pcd 来自 PCL 测试的点云。
左:没有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_()
正如我在评论中所写,我无法在 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
尝试了几种方法后,我得到了以下解决方案 Merge Request。
我使用 QGLWidget 作为 QVTKRenderWindowInteractor 的基础 class,而不是 QWidget。此更改是因为据报道有时 QWidget 会导致渲染问题。
为此,我在导入 QVTKRenderWindowInteractor 之前添加了以下代码:
import vtk.qt
vtk.qt.QVTKRWIBase = "QGLWidget"
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
为了使用 QGLWidget,我必须安装以下包:
sudo apt-get install python3-pyqt5.qtopengl
新版vtk解决方案:
# this should be done before importing vtk
import vtkmodules.qt
vtkmodules.qt.QVTKRWIBase = 'QGLWidget'
import vtk
我需要在 PyQt 应用程序中集成 VTK 可视化。但是,当我将模型放入 QVTKRenderWindowInteractor 时,显示会显示出一些不需要的透明效果(见下图)。无论我尝试加载什么,表面或点云都会发生这种情况。
有什么方法可以在 QVTKRenderWindowInteractor 中实现正确的表示吗?
第一张图片是 vtk.vtkConeSource()
的圆锥体。
第二张图片是 cturtle.pcd 来自 PCL 测试的点云。
左:没有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_()
正如我在评论中所写,我无法在 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
尝试了几种方法后,我得到了以下解决方案 Merge Request。
我使用 QGLWidget 作为 QVTKRenderWindowInteractor 的基础 class,而不是 QWidget。此更改是因为据报道有时 QWidget 会导致渲染问题。
为此,我在导入 QVTKRenderWindowInteractor 之前添加了以下代码:
import vtk.qt
vtk.qt.QVTKRWIBase = "QGLWidget"
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
为了使用 QGLWidget,我必须安装以下包:
sudo apt-get install python3-pyqt5.qtopengl
新版vtk解决方案:
# this should be done before importing vtk
import vtkmodules.qt
vtkmodules.qt.QVTKRWIBase = 'QGLWidget'
import vtk