Issue with Empty vtkImageData and Rendering Updates

Hi everyone,

I’m encountering an issue that:
a vtkVolume still will not being displayed after modifying the data of corresponding vtkImageData when it was initially empty (all values set to 0).
However, if I create a new vtkImageData and DeepCopy the data, it works as expected.

Here’s a detailed description:

Case 1:

  1. create a vtkImageData object and initialized with all values set to 0.
  2. create a vtkVolume and add it to a rendering window. (The volume is empty as expected.)
  3. Modify a to contain non-zero values (e.g., {0, 1}), call Modified() on a, and call Update() on the associated vtkVolume.
    The volume still does not display anything, which is unexpected.

Case 2:

  1. Create a new vtkImageData object b and use DeepCopy to copy the modified data from a to b.
  2. Rendering the volume_b works, and the content displays correctly.

Case 3:
If the initial vtkImageData is not entirely zero (e.g., contains at least one non-zero pixel), then everything works as expected.

Pseudo Code Example

a = {0}
volume_a = make_volume(a);
display(volume_a); // Displays nothing, as expected

// Modify a to have non-zero values
a = {0, 1}
a->Modified();
volume_a->Update();
display(volume_a); // Still displays nothing (unexpected)

// Copy data to a new vtkImageData object
b = vtkImageData::New();
b->DeepCopy(a);
display(make_volume(b)); // Displays content as expected

Context
VTK Version: 9.1
Language: C++

Thank you!
Best regards.

I think you must call Modified() on the point scalars rather than the vtkImageData itself for the modifications to be taken into account. This is also true for polydata scalars.

a->GetPointData()->GetScalars()->Modified()

It works, thank you!

But I still have two questions:

  1. When imageData “a” is initialized by {0, 1}, it works on my original code. (with only img->Modified()). Why does the different initialization matter?

  2. I used the vtkImageReslice->ColorMap->ImageActor channel to display the CT slice, and it seems that it does not need PointData()->GetScalars()->Modified(), only img->Modified() is needed.

Thank you again.

The answer to your first question is that the new ‘OpenGL2’ rendering backend changed the way timestamps are used to figure out when GPU data needs to be refreshed. For the new backend, the basic rule is that a vtkDataArray is only reloaded onto the GPU if its timestamp is changed.

For the second question, the answer is that the VTK data pipeline still works the same way as before. The data pipeline wasn’t changed when the rendering changed.

Got it, thanks a lot