GetBounds() fails with NaN points in VTK9

Did vtkWarpScalar change in the 9.x release of VTK?

Take this example dataset: surface.vtp (3.8 MB)

import vtk

reader = vtk.vtkXMLPolyDataReader()
reader.SetFileName("surface.vtp")
reader.Update()
surface = reader.GetOutputDataObject(0)

alg = vtk.vtkWarpScalar()
alg.SetInputDataObject(surface)
# args: (idx, port, connection, field, name)
alg.SetInputArrayToProcess(0, 0, 0, 0, "my data")
alg.SetScaleFactor(1.0)
alg.Update()
output = alg.GetOutputDataObject(0)

print(output.GetBounds())

Output:

VTK 8.x VTK 9.x
(639926.0, 728426.0, 5669105.0, 5818551.0, 218.24110412597656, 1170.1644287109375) (nan, nan, nan, nan, nan, nan)

Basically, the problem arises when the scalar array contains NaN values.

Perhaps this is red herring and the real issue lives in theGetBounds()/points implementation? In VTK 8 and 9, the vtkWarpScalar outputs NaN points in this case, but the bounds are not correctly computed in VTK 9

To add to the oddness, (in VTK9) GetBounds() on the vtkPolyData object returns Nan while GetBounds() on the vtkPoints returns the correct bounds

>>> output.GetBounds()
(nan, nan, nan, nan, nan, nan)
>>> output.GetPoints().GetBounds()
(639926.0, 728426.0, 5669105.0, 5818551.0, 218.24110412597656, 1170.1644287109375)

Also, I just downloaded the latest nightly ParaView (which presumably has VTK9?) and I loaded this surface, applied the “Warp by Scalar” filter, and the result is not able to be displayed

(previous versions of ParaView with VTK8 can show the output)

This problem was fixed in June 2015 in this commit. Since VTK-8.2 was released, the file was modified twice: [1], [2]. You could confirm that one of these commits caused the regression by reverting them and rebuilding VTK and testing bounds computation again.

TestExodusWithNaN.py is supposed to test range computation with presence of NaN, so you may have a look at this test, too.

I had a look at the code and the same mistake that was fixed in June 2015 (using a variable that may contain NaN as first argument in comparison, ternary, or min/max operations) was introduced in new code in vtkBoundingBox class.

I’ve fixed the issue - see necessary changes here: https://github.com/lassoan/VTK/commit/92b1ee09385c271a88dc4d38d8ce4e4dc5940d9f

I don’t have more time to work on this, so you or other VTK developers would need to cherry-pick the fix, add a test, run dashboard tests, get it reviewed, and merged.

On a general note: I would stay away from using NaNs. It could be a convenience for users to assign some meaning to NaN (e.g., it could mean missing data), but if you allow such values then they may show up in completely unexpected places (basically anywhere). To properly handle NaN values, VTK developers would need to add more checks and special case detections everywhere, which could impact performance and would be enormous development and maintenance effort and would require special developer skills.

A potential solution, which would not require a huge effort, could be to describe in VTK documentation that NaN values are only supported in those classes that explicitly state this in their documentation (and add notes to classes that are tested to work well with NaNs).

For the record, this was posted to GitLab: https://gitlab.kitware.com/vtk/vtk/-/issues/18019

Thanks for your insight and patch, @lassoan!

1 Like