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

So how to represent missing z-values in a VtkPoints collection, if not with NaN? E.g. I have a sparse topographic dataset with many missing data values. I just insert each point, which may have NaN for z:

for (row = 0; row < nRows; row++) {
  for (col = 0; col < nCols; col++) {
    # Get x, y, and z. Note that missing z-value is represented as NaN
    getMyData(row, col, &x, &y, &z);
    # Insert point
    vtkIdType id = myPoints->InsertNextPoint(x, y, z);
  }
}

The resulting vtkPoints display as expected with visible ā€˜gapsā€™ where z-data is missing, but vtkPicker->GetPointId() always returns -1 no matter where I click, even where there is z data. So how to properly depict missing data in this case? Thanks!

According to VTK core developers NaN point coordinates do not make sense and the advice is to not add them to the point cloud.

1 Like

Thanks @lassoan - what is the proper way to depict a set of points with missing z-data?

If the coordinates are not known then you cannot display the point. If you donā€™t know the distance value then you can remove the point from the data set and display all the other points; or you can replace unknown z positions by some distant value.

1 Like