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

David Gobbi david.gobbi at gmail.com
Wed May 19 07:49:02 EDT 2010


Hi Anton,

The PipelineMTime is computed only from the algorithms in the
pipeline, never from the data, so the only Modified call that does
anything is this one:

mapper->Modified();

PolyData (or any data except ImageData) should always be initialized
and rebuilt whenever you want it to update, because the internal Cell
and Link lists that it maintains will not be updated otherwise.

polyData->Initialize()
polyData->SetPoint(points);
polyData->SetLines(cells);

Note that the points & cells don't have to be rebuilt, you can just
keep reusing them over and over again.  The important thing here is
calling Initialize() on the data object. That should be everything
that you need for getting the updates to occur (at least I hope so,
I've been burned by update issues on several occasions myself).


As a side issue, I recommend that you don't actually create a
vtkPolyLine object: its IdList will just get copied element-by-element
to the CellArray anyway (the CellArray has no knowledge of what cell
types it contains).  It is better to build the CellArray directly
using these APIs:

InsertNextCell(vtkIdType npts, const vtkIdType* pts);

or

InsertNextCell(vtkIdType npts), InsertCellPoint(vtkIdType id)

or you can use cells->GetData() to get a data array and then do the
same memory-sharing trick that you did with the points. If you use
this trick, the only thing you need to do to keep things consistent is
to call cells->SetNumberOfCells() afterwards to indicate how many
cells the array contains.

   David


On Tue, May 18, 2010 at 9: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
>
> ---
> Anton Deguet, Research Engineer, ERC-CISST/LCSR, Johns Hopkins University
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>



More information about the vtkusers mailing list