简体   繁体   English

在vtk python中更新实时pointcloud数据

[英]update live pointcloud data in vtk python

I have a basic question as i am new to VTK. 我有一个基本的问题,因为我是VTK的新手。 I have to draw live point cloud data in VTK. 我必须在VTK中绘制实时点云数据。 I have modified the code given in How to display point cloud in vtk in different colors? 我修改了如何在不同颜色的vtk中显示点云中给出的代码 .

The pointcloud should update for number of times given in iterations(here 30). pointcloud应该更新迭代中给出的次数(这里是30)。 I have used Initialize() to avoid blocking control flow as mentioned in some solutions, in every iteration the point cloud is updated, and render() is called so that it can update the window with new data. 我已经使用Initialize()来避免阻塞控制流,如某些解决方案中所述,在每次迭代中更新点云,并调用render()以便它可以使用新数据更新窗口。

I cannot figure out why this is blocking the control flow, and the data is not updated. 我无法弄清楚为什么这会阻止控制流,并且数据不会更新。 Only once the iterations are over, after renderWindowInteractor.Start() is called, the interaction is enabled. 只有在迭代结束后,在调用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)

So you want to do an animation. 所以你想做一个动画。 A better practice is to follow this sample explaining how to do use a TimerEvent. 更好的做法是按照此示例说明如何使用TimerEvent。

Here is what it would look like with your 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() 

Note that I renamed iter to iterations because iter is a reserved name in Python. 请注意,我将iter重命名为迭代,因为iter是Python中的保留名称。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM