Visualize complex-valued 3D volume

I have a three-dimensional complex-valued matrix of size NX x NY x NZ whose values are stored as a flat vector of size NX * NY * NZ * 2 (factor 2 for real and imaginary parts).

Each element in the matrix corresponds to a known three-dimensional coordinate.

I want to visualize that matrix as a volume but I’m facing two problems:

  1. How do I initialize the volume using a pointer without performing a deep copy?
    My current approach is the following:
int nx = 100, ny = 100, nz = 100;
int dataSize = nx * ny * nz;
float *volPtr = (float *)malloc(sizeof(float) * dataSize * 2); // factor 2 for real and imaginary parts
vtkNew<vtkFloatArray> volArr;
volArr->SetNumberOfComponents(2); // real and imaginary
volArr->SetNumberOfTuples(dataSize);  // number of complex-valued elements in the volume
volArr->SetArray(volPtr, dataSize * 2, 1);  // Set values using pointer vol_ptr
  1. How do I compute the magnitude which should be used for the color and the opacity? The VectorNorm example throws a warning that the number of components is wrong if I use an array with just two components in setVectors().
    This is my approach to convert the array to a vtkStructuredGrid:
vtkNew<vtkPoints> points;
auto x = 0.0;
auto y = 0.0;
auto z = 0.0;
for (unsigned int k = 0; k < nz; k++)
{
	z += 1.0;
	for (unsigned int j = 0; j < ny; j++)
	{
		y += 1.0;
		for (unsigned int i = 0; i < nx; i++)
		{
			x += 1.0;
			points->InsertNextPoint(x, y, z);
		}
	}
}
vtkNew<vtkStructuredGrid> sgrid;
sgrid->SetDimensions(nx, ny, nz);
sgrid->SetPoints(points);
sgrid->GetPointData()->SetScalars(volArr); // here, I want to use the magnitude. SetVectors(volArr) is not working as volArr only has two components

As discussed here, your approach for float array is correct but you should better use a vtkImageData, as points are implicits, and add your array as CellData, as it concerns voxels and not points

@nicolas.vuaille Could you explain why using vtkImageData? I thought it would be vtkStructureGrid.

@brnk You only have two components in you dataset but you could create a 3D matrix with zero on the third component and use SetVectors. There are three choices in the VTK: Scalar, vector or Tensor. You have to use one of them rather than a 2 component data.

With a vtkImageData, points coordinates are implicit, no need to create the vtkPoints structure: saying that the grid is Nx My Nz is enough to compute each point position on the fly when needed. It saves memory and is more efficient.

Wheras we have the concept of Scalars, vector and tensor to facilitate some use cases, using arbitrary number of components for data array is OK in VTK. You should then use

sgrid->GetPointData()->AddArray(volArr);

(and think to use SetName on your array)

Using vtkImageData is only preferable if the coordinates describe a uniform rectangular three-dimensional grid as in my example, isn’t it? If I would change the coordinates in the vtkPoints structure, e.g., to spherical coordinates, would an vtkImageData structure be still preferable?

Also, why is it important to set a name for the array?

@brnk : Using vtkImageData is only possible if the coordinates describe a uniform rectangular three-dimensional grid.
You have a lot of data structure available, each one optimized for one use case. You can have a look on all classes inheriting from vtkDataSet

Setting a name on the array is useful to refer to it later, for instance to choose coloration in the rendering part, or to apply a filter on it. If you have only one array, it is not so important.