在vtk python中更新实时pointcloud数据

时间:2017-05-25 19:52:07

标签: python vtk point-clouds

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

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

我无法弄清楚为什么这会阻止控制流,并且数据不会更新。只有在迭代结束后,在调用 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)

1 个答案:

答案 0 :(得分:2)

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

以下是您的代码的样子:

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

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重命名为迭代,因为它是Python中的保留名称。