[英]Python VTK polydata not updating
我正在尝试使用VTK绘制点,然后以给定的点位置集交互地更新其位置。
我可以交互地使用polydata对象来绘制点,但是当我调用self.polydata.Update()
时,它们不会更新。 当我调用self.polydata.GetCellData().SetScalars(someCharArray)
时,这些点将更新
这是VTK中的错误,还是我没有正确更新点坐标?
我提供了一个示例脚本。 如果在self.polydata.GetCellData().SetScalars(someCharArray)
注释了self.polydata.GetCellData().SetScalars(someCharArray)
,则在使用滑块时,绘图将不会更新该点的坐标。 但是,如果您保留该行,它们将更新。
谢谢!
import numpy as np
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt4 import QtGui
import sys
class ViewerWithScrollBar(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ViewerWithScrollBar, self).__init__(parent)
# Define the renderer and Qt window ------------------------
self.frame = QtGui.QFrame()
self.hl = QtGui.QHBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.hl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
self.ren.ResetCamera()
self.frame.setLayout(self.hl)
self.setCentralWidget(self.frame)
# Point coordinate data ---------------------------------
self.coordData = {}
self.coordData[0] = np.array([[0,0,0], [1,0,0], [1,1,0]])
self.coordData[1] = self.coordData[0] + np.array([[0.2, 0.1, -0.05], [0,0,0], [0,0,0]])
self.coordData[2] = self.coordData[1] + np.array([[0.2, 0.1, -0.05], [0,0,0], [0,0,0]])
# Define the slider bar and add it to the window ---------------
slider = QtGui.QSlider()
slider.setAccessibleName('Time index')
slider.setRange(0, len(self.coordData)-1)
slider.valueChanged.connect(self.sliderCallback)
self.hl.addWidget(slider)
# Create the polydata object -----------------------------
points = vtk.vtkPoints()
points.SetNumberOfPoints(len(self.coordData[0]))
self.polydata = vtk.vtkPolyData()
for i in range(len(self.coordData[0])):
points.SetPoint(i, self.coordData[0][i])
self.polydata.SetPoints(points)
ptsFilter = vtk.vtkVertexGlyphFilter()
ptsFilter.SetInputConnection(self.polydata.GetProducerPort())
ptsMapper = vtk.vtkPolyDataMapper()
ptsMapper.SetInputConnection(ptsFilter.GetOutputPort())
ptsActor = vtk.vtkActor()
ptsActor.SetMapper(ptsMapper)
ptsActor.GetProperty().SetPointSize(10)
self.ren.AddActor(ptsActor)
self.show()
self.iren.Initialize()
def sliderCallback(self):
index = self.sender().value() # The index that the slider bar is currently on
someCharArray = vtk.vtkUnsignedCharArray()
points = self.polydata.GetPoints()
for i in range(len(self.coordData[index])):
points.SetPoint(i, self.coordData[index][i])
self.polydata.GetCellData().SetScalars(someCharArray) # For some reason the polydata won't update unless this is called.
# self.polydata.Update()
self.iren.Render()
return
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = ViewerWithScrollBar()
sys.exit(app.exec_())
在lib的建议下,我修改了代码。 在sliderCallback方法中调用self.polydata.Modified()解决了该问题
import numpy as np
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt4 import QtGui
import sys
class ViewerWithScrollBar(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ViewerWithScrollBar, self).__init__(parent)
# Define the renderer and Qt window ------------------------
self.frame = QtGui.QFrame()
self.hl = QtGui.QHBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.hl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
self.ren.ResetCamera()
self.frame.setLayout(self.hl)
self.setCentralWidget(self.frame)
# Point coordinate data ---------------------------------
self.coordData = {}
self.coordData[0] = np.array([[0,0,0], [1,0,0], [1,1,0]])
self.coordData[1] = self.coordData[0] + np.array([[0.2, 0.1, -0.05], [0,0,0], [0,0,0]])
self.coordData[2] = self.coordData[1] + np.array([[0.2, 0.1, -0.05], [0,0,0], [0,0,0]])
# Define the slider bar and add it to the window ---------------
slider = QtGui.QSlider()
slider.setAccessibleName('Time index')
slider.setRange(0, len(self.coordData)-1)
slider.valueChanged.connect(self.sliderCallback)
self.hl.addWidget(slider)
# Create the polydata object -----------------------------
points = vtk.vtkPoints()
points.SetNumberOfPoints(len(self.coordData[0]))
self.polydata = vtk.vtkPolyData()
for i in range(len(self.coordData[0])):
points.SetPoint(i, self.coordData[0][i])
self.polydata.SetPoints(points)
ptsFilter = vtk.vtkVertexGlyphFilter()
ptsFilter.SetInputData(self.polydata)
ptsMapper = vtk.vtkPolyDataMapper()
ptsMapper.SetInputConnection(ptsFilter.GetOutputPort())
ptsActor = vtk.vtkActor()
ptsActor.SetMapper(ptsMapper)
ptsActor.GetProperty().SetPointSize(10)
self.ren.AddActor(ptsActor)
self.show()
self.iren.Initialize()
def sliderCallback(self):
index = self.sender().value() # The index that the slider bar is currently on
points = self.polydata.GetPoints()
for i in range(len(self.coordData[index])):
points.SetPoint(i, self.coordData[index][i])
self.polydata.Modified()
self.iren.Render()
return
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = ViewerWithScrollBar()
sys.exit(app.exec_())
我将其修订为PyQt5版本,并在Windows 10 PyCharm 2018.1(社区版)下使用最新的vtk 8.1.0和PyQt5 5.10.1运行并测试了以上代码。 看起来需要修改“点”而不是“ self.polydata”。 否则,将不会显示更新的点。
import numpy as np
import vtk
from vtk.qt.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor
from PyQt5 import Qt
import sys
class ViewerWithScrollBar(Qt.QMainWindow):
def __init__(self, parent=None):
super(ViewerWithScrollBar, self).__init__(parent)
# Define the renderer and Qt window ------------------------
self.frame = Qt.QFrame()
self.hl = Qt.QHBoxLayout()
self.vtkWidget = QVTKRenderWindowInteractor(self.frame)
self.hl.addWidget(self.vtkWidget)
self.ren = vtk.vtkRenderer()
self.vtkWidget.GetRenderWindow().AddRenderer(self.ren)
self.iren = self.vtkWidget.GetRenderWindow().GetInteractor()
self.iren.SetInteractorStyle(vtk.vtkInteractorStyleTrackballCamera())
self.ren.ResetCamera()
self.frame.setLayout(self.hl)
self.setCentralWidget(self.frame)
# Point coordinate data ---------------------------------
self.coordData = {}
self.coordData[0] = np.array([[0,0,0], [1,0,0], [1,1,0]])
self.coordData[1] = self.coordData[0] + np.array([[0.2, 0.0, -0.05], [0,2,0], [0,0,3.5]])
self.coordData[2] = self.coordData[1] + np.array([[0.2, 10.0, -0.05], [0,5.0,0], [0,0,0]])
# Define the slider bar and add it to the window ---------------
slider = Qt.QSlider()
slider.setAccessibleName('Time index')
slider.setRange(0, len(self.coordData)-1)
slider.valueChanged.connect(self.sliderCallback)
self.hl.addWidget(slider)
# Create the polydata object -----------------------------
points = vtk.vtkPoints()
points.SetNumberOfPoints(len(self.coordData[0]))
self.polydata = vtk.vtkPolyData()
for i in range(len(self.coordData[0])):
points.SetPoint(i, self.coordData[0][i])
self.polydata.SetPoints(points)
self.ptsFilter = vtk.vtkVertexGlyphFilter()
self.ptsFilter.SetInputData(self.polydata)
ptsMapper = vtk.vtkPolyDataMapper()
ptsMapper.SetInputConnection(self.ptsFilter.GetOutputPort())
self.ptsActor = vtk.vtkActor()
self.ptsActor.SetMapper(ptsMapper)
self.ptsActor.GetProperty().SetPointSize(10)
self.ren.AddActor(self.ptsActor)
self.show()
self.iren.Initialize()
self.iren.Start()
def sliderCallback(self):
index = self.sender().value() # The index that the slider bar is currently on
points = self.polydata.GetPoints()
for i in range(len(self.coordData[index])):
points.SetPoint(i, self.coordData[index][i])
points.Modified() # Here you need to call Modified for points
self.show()
self.iren.Render()
return
if __name__ == "__main__":
app = Qt.QApplication(sys.argv)
window = ViewerWithScrollBar()
sys.exit(app.exec_())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.