Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ vtk xml writer (vtkImageData) - multiple variables in the same vti file

Tags:

c++

xml

vtk

I am trying to write data from a uniform grid to a vtk XML file, so that I can render it using Paraview. I would like my output file to contain two variables: one 3-component vector and one scalar value at every point. I have managed to write a .vti file, containing the vectors only, like so:

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataWriter.h>
#include <vtkImageData.h>    

int main()
{
    int nx = 10, ny = 10, nz = 10;

    vtkSmartPointer<vtkImageData> imageData =
        vtkSmartPointer<vtkImageData>::New();
    imageData->SetDimensions(nx, ny, nz);

#if VTK_MAJOR_VERSION <= 5
    imageData->SetNumberOfScalarComponents(3);
    imageData->SetScalarTypeToDouble();
#else
    imageData->AllocateScalars(VTK_DOUBLE, 3);
#endif

    for (int k = 0; k < nz; ++k) {
        for (int j = 0; j < ny; ++j) {
            for (int i = 0; i < nx; ++i) {
                double * voxel = static_cast<double*>(imageData->GetScalarPointer(i,j,k));
                int coord = i + j * nx + k * nx * ny;
                double t = 0.0;
                double p = 1.0;
                voxel[0] = sin(t) * cos(p);
                voxel[1] = sin(t) * sin(p);
                voxel[2] = cos(t);
            }
        }
    }

    vtkSmartPointer<vtkXMLImageDataWriter> writer = 
        vtkSmartPointer<vtkXMLImageDataWriter>::New();

    writer->SetFileName("test.vti");
#if VTK_MAJOR_VERSION <= 5
    writer->SetInputConnection(imageData->GetProducerPort());
#else
    writer->SetInputData(imageData);
#endif
    writer->Write();

    return EXIT_SUCCESS;
}

How can I add an additional scalar value to every point on the grid?

like image 348
Tom Fenech Avatar asked Feb 19 '13 18:02

Tom Fenech


People also ask

What is the difference between XML and VTK?

The XML formats support random access, parallel I/O, and portable data compression and are preferred to the serial VTK file formats whenever possible. The legacy VTK file formats consist of five basic parts. The first part is the file version and identifier. This part contains the single line: vtk DataFile Version x.x.

What kind of data can VTK file format handle?

As you should already be aware if you have read the VTK file formats documentation, VTK can handle several kinds of datasets, for points data and cells data. The primary are: PolyData. StructuredPoints is the "simplest" format: you only have to set the mesh dimensions (nx, ny, nz), mesh origin (x0, y0, z0) and cell dimensions (dx, dy, dz).

How do I write a VTK file in Python?

Using python, you can write "legacy" VTK files with your own methods or use pyvtk for VTK version 2.0 format. The new XML format is somewhat more complex, but ultimately more flexible. Different types of data have different file extensions.

Why does the Visualization Toolkit have its own file formats?

The Visualization Toolkit also provides some of its own file formats. The main reason for creating yet another data file format is to offer a consistent data representation scheme for a variety of dataset types, and to provide a simple method to communicate data between software.


1 Answers

I worked out how to do this myself, based on the python code in this answer:

https://stackoverflow.com/a/7667417/2088135

In case anyone is interested in how to do the same thing, here's the "translated" code.

#include <vtkVersion.h>
#include <vtkSmartPointer.h>
#include <vtkXMLImageDataWriter.h>
#include <vtkImageData.h>
#include <vtkPointData.h>
#include <vtkDoubleArray.h>

int main()
{
    int nx = 10, ny = 10, nz = 10;

    vtkSmartPointer<vtkImageData> imageData =
            vtkSmartPointer<vtkImageData>::New();

    imageData->SetDimensions(nx, ny, nz);

    vtkSmartPointer<vtkDoubleArray> director =
            vtkSmartPointer<vtkDoubleArray>::New();

    director->SetNumberOfComponents(3);
    director->SetNumberOfTuples(nx * ny * nz);

    vtkSmartPointer<vtkDoubleArray> energy =
            vtkSmartPointer<vtkDoubleArray>::New();

    energy->SetNumberOfComponents(1);
    energy->SetNumberOfTuples(nx * ny * nz);

    for (int i = 0; i < director->GetNumberOfTuples(); ++i) {
        double t = 1.0;
        double p = 0.0;
        double e = 5.0;
        double x = sin(t) * cos(p),
                y = sin(t) * sin(p),
                z = cos(t);

        director->SetTuple3(i, x, y, z);
        energy->SetValue(i, e);
    }

    imageData->GetPointData()->AddArray(director);
    director->SetName("Director");

    imageData->GetPointData()->AddArray(energy);
    energy->SetName("Energy");

    vtkSmartPointer<vtkXMLImageDataWriter> writer =
            vtkSmartPointer<vtkXMLImageDataWriter>::New();

    writer->SetFileName("test.vti");
#if VTK_MAJOR_VERSION <= 5
    writer->SetInputConnection(imageData->GetProducerPort());
#else
    writer->SetInputData(imageData);
#endif
    writer->Write();

    return EXIT_SUCCESS;
}
like image 88
Tom Fenech Avatar answered Oct 10 '22 20:10

Tom Fenech