2017-05-25 14 views
1

私はVTKを初めて使っているので基本的な質問があります。 VTKにライブポイントクラウドデータを描画する必要があります。私はHow to display point cloud in vtk in different colors?で与えられたコードを修正しました。vtk pythonでライブポイントクラウドデータを更新

反復回数(ここでは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) 

答えて

0

アニメーションを行います。 より良い方法は、TimerEventの使用方法を説明するthis sampleに従うことです。ここで

は、それはあなたのコードでどのように見えるかです:ITERはPythonの予約名ですので、私は、反復にITERと改名

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

注意。

+1

ありがとう、これは私が欲しかったものです。タイマーを作成する前に、小さな修正を行うだけで、renderWindowInteractorを初期化する必要があります。 –

+0

ようこそ。私はあなたが言及したエラーは表示されません。また、私はここではかなり新しいですが、私は、 "解決"の目的のために "解決された"という質問をするためのボタンがあると思います。 –

+0

ありがとう、素晴らしい提案。私はちょうど最初に "初期化された"あなたが "オブジェクトの作成"を意味していた(すでにそうだった)と思ったが、実際にはあなたは "Initialize()"メソッドを呼び出すことを意味した。 –