read data array with integral types from file?

I’m trying to write a simple file reader to load the int32 and int64 data fields from a polydata file, with name ‘gid’. The VTK document (https://vtk.org/Wiki/VTK/Tutorials/DataArrays#vtkDataArray) says the old API converts data to double and may lose accuracy for large integers:

vtkSmartPointer gidData = polydata1->GetCellData()->GetArray(“gid”);

I’m trying something like this, using vtkArrayDownCast and vtkDataArrayAccessor:

vtkTypeInt64Array *gidData = vtkArrayDownCast<vtkTypeInt64Array>(
            polydata->GetCellData()->GetAbstractArray("gid"));
vtkDataArrayAccessor<vtkTypeInt64Array> gidAccessor(gidData);
for(int i=0;i<10;i++)
    long gid = gidAccessor.Get(i, 0);

This piece of code compiles, but I’m not sure if my implementation is correct. Can I get some advice here? I have little experience writing code using vtk.

The code should work as written for the case when gid is always an array of int64_t and long is 64-bit (this is not true on all platforms). You may want to replace the long gid = ... bit with std::int64_t or vtkTypeInt64 to make sure that you don’t have portability issues later.

There’s a newer range-based API that replaces the accessors: https://blog.kitware.com/working-with-vtkdataarrays-2019-edition/. It can be a bit more familiar if you’re used to working with pointer/iterator APIs.

From your description, it sounds like you’ll also need to handle the case where the gid array holds 32-bit ints. You may be interested in using the vtkArrayDispatch utility to handle both the 32-bit and 64-bit case with a single algorithm implementation. There’s more information on this in the post I linked above.

Thank you very much for your reply. I will learn the range-based new api.
Could you please also comment the conventional ‘GetTypedComponent()’ API? If my data is always int64, can I simply use the following code?

vtkTypeInt64Array *gidData = vtkArrayDownCast<vtkTypeInt64Array>(polydata->GetCellData()->GetAbstractArray("gid"));
for(int i=0;i<10;i++)
    int64_t gid = gidData->GetTypedComponent(i,0);

If your data is always int64, that will absolutely work and is a much simpler approach. The GetTypedComponent method should not truncate 64-bit ints.

The ranges and dispatchers are most useful when working with unknown array valuetypes – if you know the exact type of the array, what you have here is preferable :slight_smile:

1 Like

Thank you again. This is very helpful.