2016-02-05 52 views
0

我正在嘗試使用VTK繪製點,然後使用給定的一組點位置交互更新它們的位置。Python VTK polydata沒有更新

我可以交互式地使用polydata對象繪製點,但是當我呼叫self.polydata.Update()時,它們不會更新。我會致電self.polydata.GetCellData().SetScalars(someCharArray)

這是VTK中的錯誤,還是我沒有正確更新點座標?

我已經包含了一個示例腳本。如果您在sliderCallback中註釋掉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_()) 
+0

您是否嘗試過更新前的polydata.GetPoints()。Modified()?可能setscalars設置修改標誌polydata – lib

+0

這工作!調用self.polydata.Modified()修復了這個問題。 – shoe02

回答

2

在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_())