Advice on grid formats

Hi all.

For the last couple of years I have been using the vtkUnstructuredGrid file format as an output format for my solver infrastructure–-basically it’s storing N-dimensional [point]→(f0,f1,...) scalar data corresponding to a custom compressed solution (via grid->GetPointData()->AddArray() calls).

I now have a need to output the underlying uncompressed grid, which is a standard uniform grid. From what I can tell it directly matches the regular topology and geometry provided by an N-dimensional vtkImageData grid (or possibly vtkStructuredPoints, details are a little hard to come by for this subclass).

Is either vtkImageData or vtkStructuredPoints an appropriate choice for a [point]→(f0,f1,...) type of dense dataset, such that it will basically fit into an existing Paraview analysis methodology based around vtkUnstructuredGrid? I don’t see any corresponding XMLWriter functionality so I suspect it’s not.

I don’t mind continuing to use unstructured grids as an output format but skipping the explicit point and coordinate data output for the regular case would save me a bunch of memory.

Any advice is appreciated.

Thanks,
Luke

Oh, I just ran into vtkXMLImageDataWriter… don’t know how I missed that earlier. Maybe this vtkImageData is exactly what I want even though I’m not dealing with image data specifically.

It sounds like it’s a fit based on what I understand. If you have a workflow around vtkUnstructuredGrids, if you change dataset type to vtkImageData then you may have to find equivalent filters, or perform data conversion, to process the data. One thing good about vtkImageData is that many specialized algorithms and rendering techniques exist which are often much faster than the vtkUnstructuredGrid equivalents.

vtkStructuredPoints and vtkImageData are pretty much the same thing except the way the origin and extent are handled. Typically vtkImageData is used.

The classes vtkXMLImageDataWriter / vtkXMLImageDataReader are available for writing / reading data.

Okay, I’ll give that a shot and see if the poor souls (i.e., grad students) that actually have to analyze results have any problem synthesizing the physical or logical coordinate data.

Thank you,
Luke

Is the image origin a logical thing or a physical thing? If I have an (e.g.,) 1D physical domain that’s (-1, 1), should I be setting Origin for that? Or is that information unavailable in the vtkImageData model (or something I get via inheritance, that I just don’t see right now)?

Look at the documentation in vtkImageData.h. It can be tricky - I have to remind myself often of the concepts. What follows is off the cuff so there may be some bad advice here but hopefully it will get you going :slight_smile:

SetOrigin() specifies the position of the logical index (i=0,j=0,k=0). Since the actual image extents do not need to contain index (0,0,0), the physical origin position can be outside of the actual volume.

Typically beginners find that using extents starting at (0,0,0) with the origin specified in 3D space using SetOrigin() (as well as specifying voxel spacing with SetSpacing()) is less confusing. Since there is a relationship with the dimensions of the 3D image with the extent, an image can be specified with: SetDimensions(iDim,jDim,kDim); SetOrigin(xO,yO,zO); SetSpacing(vx,vy,vz). Then use AllocateScalars() to allocate memory for the data values associated with the image.

Finally, the concept of image or volume dimensions can be very confusing. This follows since VTK has the notion of both point data and cell data, and that cells are interpolation fields across regions of space. For example, in VTK a 3D image consisting of a single voxel is of dimensions (2x2x2) since eight points define a voxel. Of course, if your perspective is one of “cells” then a single voxel volume is of dimensions (1x1x1). Many people are more comfortable describing an image/volume in terms of “number of pixels” or “number of voxels” so it’s important to be careful of terminology. (And a related issue is the physical origin and “size” of a volume specified using cell dimensions - there is 1/2 voxel shifting required etc.) All these are simple concepts but can drive you crazy if not thought through carefully.

Thanks Will.

I was just trying to understand the call to SetOrigin, as its argument is named ijk which we would normally use for discrete logical indexing, rather than x or xyz which would be a floating-point physical index.

It sounds like I’m using it correctly though, in that SetOrigin(-M_PI,-M_PI,0) should imply that logical index 0,0,0 would correspond with the physical location -M_PI,-M_PI,0.