How to get the data out of a .vtu file?

I have some data from a 3D-Lidar scan in a.vtu file (a snapshot of a single frame) and I’d like to be able to access them in a programming environment (This is why I am using VTK). I am talking PRIMITIVE access (e.g. a std::array< vector3d > that ONLY contains the points (no intensity or anything like that) or something like that.)

I found this example: https://kitware.github.io/vtk-examples/site/Cxx/IO/ReadUnstructuredGrid/ that reads a .vtu file and renders the scene and that works without a problem. However, a class called “vtkXMLUnstructuredGridReader” just reads the data for itself and this data is passed to the renderer under the hood without me being able to access this data. I tried to get to the data by calling “getOutput” on the reader, but that leaves me with a vtkUnstructuredGrid object which I don’t know how to handle. I looked at the documentation (https://vtk.org/doc/nightly/html/classvtkUnstructuredGrid.html) and I am not entirely sure how to get to the 3D points.

You could have something that looks like below. I’m showcasing what you can do with arrays in VTK, and how to have a handle on that from the reader…

#include <vtkDataArray.h>
#include <vtkDataArrayRange.h>
#include <vtkNew.h>
#include <vtkPoints.h>
#include <vtkUnstructuredGrid.h>
#include <vtkXMLUnstructuredGridReader.h>

#include <algorithm>
#include <vector>

int main()
{
  vtkNew<vtkXMLUnstructuredGridReader> reader;
  const char* fileName = "a.vtu";
  reader->SetFileName(fileName);
  reader->Update();

  vtkUnstructuredGrid* ug = vtkUnstructuredGrid::SafeDownCast(reader->GetOutputDataObject(0));
  vtkPoints* points = ug->GetPoints();
  if (points)
  {
    // Here are my points
    for (vtkIdType pointId = 0; pointId < points->GetNumberOfPoints(); ++pointId)
    {
      double p[3];
      points->GetPoint(pointId, p);
      // Do something
    }
    // Here's a handle to a vtkDataArray holding the points.
    vtkDataArray* pointsArray = points->GetData();
    if (pointsArray)
    {
      // Interfacing the point array with ranges on which you can call STL algorithms
      auto pointsRange = vtk::DataArrayTupleRange<3>(pointsArray);
      using ConstTupleRef = typename decltype(pointsRange)::ConstTupleReferenceType;
      using ConstCompRef = typename decltype(pointsRange)::ConstComponentReferenceType;
      for (ConstTuplesRef point : pointsRange)
      {
        for (ConstCompRef comp : point)
        {
           // Here I have access to the coordinates.
        }
      }

      // Copying into a std::vector
      // Look at vtkArrayDispatch to have a type dependent access.
      std::vector<double> dest(points->GetNumberOfPoints() * 3);
      std::copy(pointsRange.begin(), pointsRange.end(), dest.begin());
    }
  }
  return EXIT_SUCCESS;
}

Edit: I didn’t try to compile this code, but it’s compile-ready near enough.

1 Like

Thanks, this was very helpful