Read a VTK from a file content

Hi everyone,
I’m using Python,
I have a tar file that contains some VTK files,
I don’t want to extract the files to the hard disk and then read the file with a reader-
Instead, I assign the VTK file content in run time to a local variable, and I’m looking for a way to read it.

This is the method I’m using for reading directly from a VTK file and it works:

def load_vtk_to_array(path: str):
    reader = vtkStructuredPointsReader()
    reader.SetFileName(path)
    reader.Update()
    data = reader.GetOutput()
    shape = data.GetDimensions()[::-1]
    array = numpy_support.vtk_to_numpy(data.GetPointData().GetArray(0)).reshape(shape)
    return array

But I want to use something like this method:


def load_vtk_to_array(file_content: bytes):
    reader = vtkStructuredPointsReader()
    reader.SetBinaryInputString(file_content)
    reader.Update()
    data = reader.GetOutput() 
    shape = data.GetDimensions()[::-1]  ## we get (0,0,0)
    array = numpy_support.vtk_to_numpy(data.GetPointData().GetArray(0)).reshape(shape)  
    return array

But this is not work here, the data does not contain GetPointData() method so it raise an exception and the Dimensions we get is (0,0,0):frowning:

the file headers:


# vtk DataFile Version 3.0
vtk output
BINARY
DATASET STRUCTURED_POINTS
DIMENSIONS tel:272 102 288
SPACING 1.62 1.62 2.14
ORIGIN 0 0 0
CELL_DATA tel:7855477
POINT_DATA tel:7990272
SCALARS scalars unsigned_short
LOOKUP_TABLE default

Thanks in advance

Not many readers support this mode of operation. Even if they did, there’d need to be some way to hand over a Python object as a stream to the filter via the wrappers (@dgobbi). I made one years ago with boost::iostreams, but I’d have to dig it up again (we’d also not want a Boost dependency there anyways).

1 Like

Are you sure about this? Even if the reader fails, a vtkStructuredPoints data set always has a GetPointData() method.

>>> reader = vtkStructuredPointsReader()
>>> data = reader.GetOutput()
>>> type(data)
<class 'vtkmodules.vtkCommonDataModel.vtkStructuredPoints'>
>>> pd = data.GetPointData()
>>> type(pd)
<class 'vtkmodules.vtkCommonDataModel.vtkPointData'>

It’s possible that SetBinaryInputString()/Update() fails because the Python wrappers encode the binary char* as a utf-8 encoded string instead of as binary data.

Have you tried using an ASCII data file with the SetInputString() method to see if that works? If an ASCII data file works but a binary data file does not work, then we will know that the SetBinaryInputString() method is the problem.

1 Like

This doesn’t look right

void vtkDataReader::SetBinaryInputString(const char* in, int len)
{
  this->SetInputString(in, len);
}

Since the file header provides information about whether the data is stored in text or in binary, it’s not inconceivable that SetInputString(in,len) and SetBinaryInputString(in,len) would share the same implementation.

Shouldn’t this be const unsigned char* so that the wrapper code doesn’t convert to utf-8?