Search code examples
c++fortranvtk

How to read a binary structured_points data file generated in Fortran by C++ and VTK?


I am new to VTK, and I am trying to read a binary structured_points (image data) file in vtk but getting the "Error reading binary data" error with a blank window. I am using a simple fortran program to create the data file (gaussian field data) as follows,

 program gaussian

            implicit none
            integer i, j, k
            character(1) c

    open(unit=100, file='energyDensity.vtk',
 1        form="unformatted",access="stream")
    write(100) '# vtk DataFile Version 3.0', new_line(c)
    write(100) 'First time trying vtk import \n', new_line(c)
    write(100) 'BINARY', new_line(c)
    write(100) 'DATASET STRUCTURED_POINTS', new_line(c)
    write(100) 'DIMENSIONS 101 101 101', new_line(c)
    write(100) 'ORIGIN 0 0 0', new_line(c)
    write(100) 'SPACING 1 1 1', new_line(c)
    write(100) 'POINT_DATA 1030301', new_line(c)
    write(100) 'SCALARS volume_scalars double 1', new_line(c)
    write(100) 'LOOKUP_TABLE default', new_line(c)


            do k = -50,50
            do j = -50,50
            do i = -50,50

            write(100) 50.*exp(float((-(i*i+j*j+k*k))/25)) 

            enddo
            enddo
            enddo
    close(100)

endprogram

VTK reads and plots the data nicely if the data is in ASCII format (see the picture below)

enter image description here

I am using the following code C++ in VTK to read the data (without any setting for endian),

vtkNew<vtkStructuredPointsReader> reader;
  reader->SetFileName (argv[1]);
  reader->Update();

I have tried searching a lot on internet but couldn't find the correct way of reading structured_points data in binary. It seems there is no way of setting the endian thing for structured points reader as well. I am not sure what do here. Any help would be really appreciated.


Solution

  • Following Vladimir's suggestions about legacy formats only accepting big_endian, a few simple changes to my fortran code above did the trick for me. Setting the "convert" parameter in the "open" file statement to "big_endian" solved the biggest problem. Also, float should be changed to "real(real64)" to be consistent with double data type in the vtk data file.

        program gaussian
    
        use iso_fortran_env
    
                implicit none
                integer i, j, k
                character(1) c
                real(real64) x
    
        open(unit=100, file='energyDensity.vtk',
     1        form="unformatted",access="stream",convert="big_endian")
        write(100) '# vtk DataFile Version 3.0', new_line(c)
        write(100) 'First time trying vtk import \n', new_line(c)
        write(100) 'BINARY', new_line(c)
        write(100) 'DATASET STRUCTURED_POINTS', new_line(c)
        write(100) 'DIMENSIONS 101 101 101', new_line(c)
        write(100) 'ORIGIN 0 0 0', new_line(c)
        write(100) 'SPACING 1 1 1', new_line(c)
        write(100) 'POINT_DATA 1030301', new_line(c)
        write(100) 'SCALARS volume_scalars double 1', new_line(c)
        write(100) 'LOOKUP_TABLE default', new_line(c)
    
    
                do k = -50,50
                do j = -50,50
                do i = -50,50
    
                x=50.*exp(real((-(i*i+j*j+k*k))/25,real64))
    
                write(100) x
    
                enddo
                enddo
                enddo
        close(100)
    
        endprogram