vtkImageData: SetScalarComponentFromDouble do not change GetScalarRange

For a vtkImageData, I want to modify the scalar using SetScalarComponentFromDouble. But, I find the GetScalarRange do not return the correct result after SetScalarComponentFromDouble.

My test code is:

import vtkmodules.all as vtk

img = vtk.vtkImageData()
img.SetDimensions(100, 100, 1)
img.AllocateScalars(vtk.VTK_DOUBLE, 1)

for i in range(100):
    for j in range(100):
        img.SetScalarComponentFromDouble(i, j, 0, 0, i+j)

range1 = img.GetScalarRange()
print('range1: ', range1)

img.SetScalarComponentFromDouble(0, 0, 0, 0, 1000)
img.Modified()
range2 = img.GetScalarRange()
print('range2: ', range2)

The range2 is the same with range1 (0~198) even img.SetScalarComponentFromDouble(0, 0, 0, 0, 1000).

After look at the c++ code, I find that the range do not computer after SetScalarComponentFromDouble. For vtkDataArray, the GetRange explain that:

The range is computed and then cached, and will not be re-computed on subsequent calls to GetRange().

How can I force it to re-compute range?

The explanation of vtkDataArray::ComputeRange said: “Call ClearRange to force a recomputation if it is needed.”

  1. I can not find ClearRange method in vtk.
  2. How to call ClearRange in vtkImageData?

The ClearRange() method doesn’t exist in VTK anymore (I’m not sure when it was removed).

But to answer your original question, instead of img.Modified(), call the following:

img.GetPointData().GetScalars().Modified()

To see why, consider how SetScalarComponentFromDouble() is implemented in vtkImageData.cxx:

vtkIdType index = this->GetScalarIndex(x, y, z);
vtkDataArray* scalars = this->GetPointData()->GetScalars();
scalars->SetComponent(index, comp);

The Set method is being called on the vtkDataArray object.

2 Likes