更新 vtk 中的实时点云数据 python

update live pointcloud data in vtk python

我有一个基本问题,因为我是 VTK 的新手。我必须在 VTK 中绘制实时点云数据。我修改了How to display point cloud in vtk in different colors?中给出的代码。

点云应该更新迭代中给定的次数(这里是 30)。我已经使用 Initialize() 来避免某些解决方案中提到的阻塞控制流,在每次迭代中更新点云,并调用 render() 以便它可以用新数据更新 window。

我不明白为什么这会阻塞控制流,并且数据没有更新。只有在迭代结束后,调用 renderWindowInteractor.Start() 后,才会启用交互。

import vtk
from numpy import random

class VtkPointCloud:

    def __init__(self, zMin=-10.0, zMax=10.0, maxNumPoints=1e6):
        self.maxNumPoints = maxNumPoints
        self.vtkPolyData = vtk.vtkPolyData()
        self.clearPoints()
        mapper = vtk.vtkPolyDataMapper()
        mapper.SetInputData(self.vtkPolyData)
        mapper.SetColorModeToDefault()
        mapper.SetScalarRange(zMin, zMax)
        mapper.SetScalarVisibility(1)
        self.vtkActor = vtk.vtkActor()
        self.vtkActor.SetMapper(mapper)

    def addPoint(self, point):
        if self.vtkPoints.GetNumberOfPoints() < self.maxNumPoints:
            pointId = self.vtkPoints.InsertNextPoint(point[:])
            self.vtkDepth.InsertNextValue(point[2])
            self.vtkCells.InsertNextCell(1)
            self.vtkCells.InsertCellPoint(pointId)
        else:
            r = random.randint(0, self.maxNumPoints)
            self.vtkPoints.SetPoint(r, point[:])
        self.vtkCells.Modified()
        self.vtkPoints.Modified()
        self.vtkDepth.Modified()

    def clearPoints(self):
        self.vtkPoints = vtk.vtkPoints()
        self.vtkCells = vtk.vtkCellArray()
        self.vtkDepth = vtk.vtkDoubleArray()
        self.vtkDepth.SetName('DepthArray')
        self.vtkPolyData.SetPoints(self.vtkPoints)
        self.vtkPolyData.SetVerts(self.vtkCells)
        self.vtkPolyData.GetPointData().SetScalars(self.vtkDepth)
        self.vtkPolyData.GetPointData().SetActiveScalars('DepthArray')

def func(pointCloud):
    # Renderer
    renderer = vtk.vtkRenderer()
    renderer.AddActor(pointCloud.vtkActor)
    renderer.SetBackground(.2, .3, .4)
    renderer.ResetCamera()

    # Render Window
    renderWindow = vtk.vtkRenderWindow()

    renderWindow.AddRenderer(renderer)

    # Interactor
    renderWindowInteractor = vtk.vtkRenderWindowInteractor()
    renderWindowInteractor.SetRenderWindow(renderWindow)

    # Begin Interaction
    renderWindow.Render()
    renderWindowInteractor.Initialize()
    return renderWindow,renderWindowInteractor

def main(iter):
    while iter > 0:
        pointCloud = VtkPointCloud()
        for k in xrange(10000):
            point = 20*(random.rand(3)-0.5)
            pointCloud.addPoint(point)
        pointCloud.addPoint([0,0,0])
        pointCloud.addPoint([0,0,0])
        pointCloud.addPoint([0,0,0])
        pointCloud.addPoint([0,0,0])
        if iter == 30:
            renderWindow,renderWindowInteractor = func(pointCloud)
        else:
            #pointCloud.vtkPolyData.Modified()
            renderWindow.Render()
        iter -= 1
    renderWindowInteractor.Start()

main(30)

所以你想做一个动画。 更好的做法是遵循 this sample 说明如何使用 TimerEvent。

这是您的代码的样子:

</p> <pre><code>import vtk from numpy import random class VtkPointCloud: def __init__(self, zMin=-10.0, zMax=10.0, maxNumPoints=1e6): self.maxNumPoints = maxNumPoints self.vtkPolyData = vtk.vtkPolyData() self.clearPoints() mapper = vtk.vtkPolyDataMapper() mapper.SetInputData(self.vtkPolyData) mapper.SetColorModeToDefault() mapper.SetScalarRange(zMin, zMax) mapper.SetScalarVisibility(1) self.vtkActor = vtk.vtkActor() self.vtkActor.SetMapper(mapper) def addPoint(self, point): if self.vtkPoints.GetNumberOfPoints() < self.maxNumPoints: pointId = self.vtkPoints.InsertNextPoint(point[:]) self.vtkDepth.InsertNextValue(point[2]) self.vtkCells.InsertNextCell(1) self.vtkCells.InsertCellPoint(pointId) else: r = random.randint(0, self.maxNumPoints) self.vtkPoints.SetPoint(r, point[:]) self.vtkCells.Modified() self.vtkPoints.Modified() self.vtkDepth.Modified() def clearPoints(self): self.vtkPoints = vtk.vtkPoints() self.vtkCells = vtk.vtkCellArray() self.vtkDepth = vtk.vtkDoubleArray() self.vtkDepth.SetName('DepthArray') self.vtkPolyData.SetPoints(self.vtkPoints) self.vtkPolyData.SetVerts(self.vtkCells) self.vtkPolyData.GetPointData().SetScalars(self.vtkDepth) self.vtkPolyData.GetPointData().SetActiveScalars('DepthArray') class AddPointCloudTimerCallback(): def __init__(self, renderer, iterations): self.iterations = iterations self.renderer = renderer def execute(self, iren, event): if self.iterations == 0: iren.DestroyTimer(self.timerId) pointCloud = VtkPointCloud() self.renderer.AddActor(pointCloud.vtkActor) pointCloud.clearPoints() for k in xrange(10000): point = 20*(random.rand(3)-0.5) pointCloud.addPoint(point) pointCloud.addPoint([0,0,0]) pointCloud.addPoint([0,0,0]) pointCloud.addPoint([0,0,0]) pointCloud.addPoint([0,0,0]) iren.GetRenderWindow().Render() if self.iterations == 30: self.renderer.ResetCamera() self.iterations -= 1 if __name__ == "__main__": # Renderer renderer = vtk.vtkRenderer() renderer.SetBackground(.2, .3, .4) renderer.ResetCamera() # Render Window renderWindow = vtk.vtkRenderWindow() renderWindow.AddRenderer(renderer) # Interactor renderWindowInteractor = vtk.vtkRenderWindowInteractor() renderWindowInteractor.SetRenderWindow(renderWindow) renderWindowInteractor.Initialize() # Initialize a timer for the animation addPointCloudTimerCallback = AddPointCloudTimerCallback(renderer, 30) renderWindowInteractor.AddObserver('TimerEvent', addPointCloudTimerCallback.execute) timerId = renderWindowInteractor.CreateRepeatingTimer(10) addPointCloudTimerCallback.timerId = timerId # Begin Interaction renderWindow.Render() renderWindowInteractor.Start()

请注意,我将 iter 重命名为迭代,因为 iter 是 Python 中的保留名称。