代码之家  ›  专栏  ›  技术社区  ›  wzaylor

Python VTK polydata未更新

  •  0
  • wzaylor  · 技术社区  · 10 年前

    我正在尝试使用VTK绘制点,然后用一组给定的点位置以交互方式更新它们的位置。

    我可以交互式地使用多数据对象来绘制点,但是当我调用时它们不会更新 self.polydata.Update() 。我打电话时积分会更新 self.polydata.GetCellData().SetScalars(someCharArray)

    这是VTK中的错误,还是我没有正确更新点坐标?

    我包括了一个示例脚本。如果你发表评论 self.polydata.GetCellData().SetScalar(someCharArray) 在sliderCallback中,使用滑块时,绘图不会更新点的坐标。但是,如果您保留该行,它们将更新。

    谢谢

    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_())
    
    2 回复  |  直到 10 年前
        1
  •  2
  •   wzaylor    10 年前

    在lib的建议下,我修改了代码。调用self.polydata。sliderCallback方法中的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_())
    
        2
  •  1
  •   tonychang    8 年前

    我将其修改为PyQt5版本,并在Windows 10、PyCharm 2018.1(社区版)下使用最新的vtk 8.1.0和PyQt 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_())