# Visualize complex-valued 3D volume

**URL:** https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982
**Category:** Support
**Created:** [October 27, 2021, 8:05am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982 "2021-10-27T08:05:50Z")
**Posts on this page:** 6
**Page:** 1

<div class="post-metadata">

### Author: ![brnk](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/ecd19e/32.png) [@brnk](https://discourse.vtk.org/u/brnk)
#### Post date: [October 27, 2021, 8:05am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/1 "2021-10-27T08:05:50Z")

</div>

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:

```auto
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](https://kitware.github.io/vtk-examples/site/Cxx/Math/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`:

```auto
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

```

---

<div class="post-metadata">

### Author: ![nicolas.vuaille](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nicolas.vuaille/32/5363_2.png) [@nicolas.vuaille](https://discourse.vtk.org/u/nicolas.vuaille)
#### Post date: [October 27, 2021, 8:12am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/2 "2021-10-27T08:12:06Z")

</div>

As discussed [here](https://stackoverflow.com/questions/69723512/c-vtk-initialize-volume-using-pointer), 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

---

<div class="post-metadata">

### Author: ![huaweiping](https://discourse.vtk.org/user_avatar/discourse.vtk.org/huaweiping/32/8231_2.png) [@huaweiping](https://discourse.vtk.org/u/huaweiping)
#### Post date: [October 27, 2021, 11:34am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/3 "2021-10-27T11:34:52Z")

</div>

@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.

---

<div class="post-metadata">

### Author: ![nicolas.vuaille](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nicolas.vuaille/32/5363_2.png) [@nicolas.vuaille](https://discourse.vtk.org/u/nicolas.vuaille)
#### Post date: [October 27, 2021, 1:21pm UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/4 "2021-10-27T13:21:15Z")

</div>

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

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

```

(and think to use `SetName` on your array)

---

<div class="post-metadata">

### Author: ![brnk](https://discourse.vtk.org/letter_avatar_proxy/v4/letter/b/ecd19e/32.png) [@brnk](https://discourse.vtk.org/u/brnk)
#### Post date: [October 28, 2021, 6:15am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/5 "2021-10-28T06:15:54Z")

</div>

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?

---

<div class="post-metadata">

### Author: ![nicolas.vuaille](https://discourse.vtk.org/user_avatar/discourse.vtk.org/nicolas.vuaille/32/5363_2.png) [@nicolas.vuaille](https://discourse.vtk.org/u/nicolas.vuaille)
#### Post date: [October 28, 2021, 11:13am UTC](https://discourse.vtk.org/t/visualize-complex-valued-3d-volume/6982/6 "2021-10-28T11:13:03Z")

</div>

@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`](https://vtk.org/doc/nightly/html/classvtkDataSet.html)

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.
