[vtkusers] Displaying a poly line using an existing array of doubles

David Doria daviddoria+vtk at gmail.com
Wed May 19 07:48:03 EDT 2010


On Tue, May 18, 2010 at 11:27 PM, Anton Deguet <anton.deguet at jhu.edu> wrote:
> Hello,
>
> I have been able to display a polyline using an existing array of doubles along with a set of point IDs.   I am now trying to do the following:
> - change the data (direct access to the array of doubles)
> - refresh the point IDs (the array is a circular buffer)
> At that point, I can't seem to get VTK to refresh the poly line.
>
> My test code looks like this for setup:
>
>        // use vctDynamicVector of 3D points (vct3)
>        actualData.SetSize(10);
>        actualData[0] = vct3(1.0, 0.0, 0.0);
>        actualData[1] = vct3(1.0, 2.0, 0.0);
>        actualData[2] = vct3(4.0, 1.0, 0.0);
>        actualData[3] = vct3(1.0, 0.0, 2.0);
>        actualData[4] = vct3(3.0, 1.0, 2.0);
>        actualData[5] = vct3(0.0, 0.0, 0.0);
>        actualData[6] = vct3(1.0, 0.0, 0.0);
>        actualData[7] = vct3(0.0, 1.0, 0.0);
>        actualData[8] = vct3(0.0, 1.0, 2.0);
>        actualData[9] = vct3(1.0, 2.0, 3.0);
>
>        // create a VTK array that points to the cisst vector data
>        dataArray = vtkDoubleArray::New();
>        dataArray->SetNumberOfComponents(vct3::SIZE); // we set the number of components
>        dataArray->SetArray(actualData[0].Pointer(), actualData.size(), 1); // number of points, last parameter tells VTK to not free the memory
>
>        // points use this data
>        points = vtkPoints::New();
>        points->SetData(dataArray);
>
>        // polyline is mostly a list of indices
>        polyLine = vtkPolyLine::New();
>        polyLine->GetPointIds()->SetNumberOfIds(5);
>        for (unsigned int i = 0; i < 5; i++) {
>                polyLine->GetPointIds()->SetId(i, 5 + i);
>        }
>
>        // Create a cell array to store the lines in and add the lines to it
>        cells = vtkCellArray::New();
>        cells->InsertNextCell(polyLine);
>
>        // Create a polydata to store everything in
>        polyData = vtkPolyData::New();
>        polyData->SetPoints(points);
>        polyData->SetLines(cells);
>
>        // setup actor and mapper
>        mapper = vtkPolyDataMapper::New();
>        mapper->SetInput(polyData);
>
>        actor = vtkActor::New();
>        actor->SetMapper(mapper);
>
> The initial render works fine.   Then in refresh (in a loop), I tried:
>
>        // refresh which points to use
>        Counter++;
>        if (Counter > 5) {
>                Counter = 0;
>        }
>        for (unsigned int i = 0; i < 5; i++) {
>                polyLine->GetPointIds()->SetId(i, Counter + i);
>        }
>
>        // all following are attempts to tell VTK to refresh
>        dataArray->SetArray(actualData[0].Pointer(), actualData.size(), 1);
>        points->Modified();
>        dataArray->Modified();
>        polyData->Modified();
>        polyLine->Modified();
>        cells->Modified();
>        mapper->Modified();
>
> FYI, Initially my refresh happened in a different thread but it now happens in the same thread that creates all the VTK objects.   What is the obvious thing I am missing?
>
> Anton
>

I don't know what the problem is, but here is a compilable piece of
code that I think is trying to do what you want that folks can play
with to try to help you:

#include <vtkSmartPointer.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkPolyLine.h>
#include <vtkCellArray.h>
#include <vtkPoints.h>
#include <vtkDoubleArray.h>
#include <vtkPolyData.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>

int main(int, char *[])
{
  vtkSmartPointer<vtkDoubleArray> dataArray =
      vtkSmartPointer<vtkDoubleArray>::New();
  dataArray->SetNumberOfComponents(3);
  dataArray->InsertNextTuple3(1.0, 0.0, 0.0);
  dataArray->InsertNextTuple3(1.0, 2.0, 0.0);
  dataArray->InsertNextTuple3(4.0, 1.0, 0.0);
  dataArray->InsertNextTuple3(1.0, 0.0, 2.0);
  dataArray->InsertNextTuple3(3.0, 1.0, 2.0);
  dataArray->InsertNextTuple3(0.0, 0.0, 0.0);
  dataArray->InsertNextTuple3(1.0, 0.0, 0.0);
  dataArray->InsertNextTuple3(0.0, 1.0, 0.0);
  dataArray->InsertNextTuple3(0.0, 1.0, 2.0);
  dataArray->InsertNextTuple3(1.0, 2.0, 3.0);

  // points use this data
  vtkSmartPointer<vtkPoints> points =
      vtkSmartPointer<vtkPoints>::New();
  points->SetData(dataArray);

  // polyline is mostly a list of indices
  vtkSmartPointer<vtkPolyLine> polyLine =
      vtkSmartPointer<vtkPolyLine>::New();
  polyLine->GetPointIds()->SetNumberOfIds(5);
  for (unsigned int i = 0; i < 5; i++)
    {
    polyLine->GetPointIds()->SetId(i, i);
    }

  // Create a cell array to store the lines in and add the lines to it
  vtkSmartPointer<vtkCellArray> cells =
      vtkSmartPointer<vtkCellArray>::New();
  cells->InsertNextCell(polyLine);

  // Create a polydata to store everything in
  vtkSmartPointer<vtkPolyData> polyData =
      vtkSmartPointer<vtkPolyData>::New();
  polyData->SetPoints(points);
  polyData->SetLines(cells);

  // setup actor and mapper
  vtkSmartPointer<vtkPolyDataMapper> mapper =
      vtkSmartPointer<vtkPolyDataMapper>::New();
  mapper->SetInput(polyData);

  vtkSmartPointer<vtkActor> actor =
      vtkSmartPointer<vtkActor>::New();
  actor->SetMapper(mapper);

    //Create a renderer, render window, and interactor
  vtkSmartPointer<vtkRenderer> renderer =
      vtkSmartPointer<vtkRenderer>::New();
  vtkSmartPointer<vtkRenderWindow> renderWindow =
      vtkSmartPointer<vtkRenderWindow>::New();
  renderWindow->AddRenderer(renderer);
  vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
      vtkSmartPointer<vtkRenderWindowInteractor>::New();
  renderWindowInteractor->SetRenderWindow(renderWindow);

  //Add the actor to the scene
  renderer->AddActor(actor);
  renderer->SetBackground(.3, .6, .3); // Background color green

  //Render and interact
  renderWindow->Render();
  renderWindowInteractor->Start();

  //change the data and refresh
  int offset = 5;
  for (unsigned int i = 0; i < 5; i++)
    {
    polyLine->GetPointIds()->SetId(i, offset + i);
    }

  points->Modified();
  dataArray->Modified();
  polyData->Modified();
  polyLine->Modified();
  cells->Modified();
  mapper->Modified();
  std::cout << "Modified." << std::endl;

  renderWindow->Render();
  renderer->Render();
  renderWindowInteractor->Start();

  return EXIT_SUCCESS;
}


Thanks,

David



More information about the vtkusers mailing list