Description
Environment
Operating System: Ubuntu 22.04
Version / Commit SHA: v9.1.0
Other: Using the Python bindings
Describe the bug
When setting the background value of a (Float) grid, if the previous background value was NaN, the values of all inactive voxels get changed to the new value.
To Reproduce
Example script:
import pyopenvdb as vdb
import math
import itertools
grid = vdb.FloatGrid()
grid.background = 0.0
accessor = grid.getAccessor()
# create a few blocks of active voxels
on_list = [(5,5,5), (-5,-5,-5)]
for coords in on_list:
accessor.setValueOn(coords, 1.0)
# set a few off voxels
off_list = [(-2,-2,-2),(2,2,2)]
for coords in off_list:
accessor.setValueOff(coords, 5.0)
# check values
unchanged = [(0,0,0)]
print("** initial values **")
for coords in itertools.chain(on_list, off_list, unchanged):
print(f"Voxel {coords} is {accessor.probeValue(coords)}")
# change background
grid.background = -1.0
print("** after background change to -1.0 **") # here, our custom inactive voxels are still at 5.0
# check values
for coords in itertools.chain(on_list, off_list, unchanged):
print(f"Voxel {coords} is {accessor.probeValue(coords)}")
# change background again
grid.background = math.nan
print("** after background change to nan **") # still at 5.0
# check values
for coords in itertools.chain(on_list, off_list, unchanged):
print(f"Voxel {coords} is {accessor.probeValue(coords)}")
# change background again
grid.background = -12.0
print("** after background change to -12 **") # changed from 5.0 to -12
# check values
for coords in itertools.chain(on_list, off_list, unchanged):
print(f"Voxel {coords} is {accessor.probeValue(coords)}")
Output:
** initial values **
Voxel (5, 5, 5) is (1.0, True)
Voxel (-5, -5, -5) is (1.0, True)
Voxel (-2, -2, -2) is (5.0, False)
Voxel (2, 2, 2) is (5.0, False)
Voxel (0, 0, 0) is (0.0, False)
** after background change to -1.0 **
Voxel (5, 5, 5) is (1.0, True)
Voxel (-5, -5, -5) is (1.0, True)
Voxel (-2, -2, -2) is (5.0, False)
Voxel (2, 2, 2) is (5.0, False)
Voxel (0, 0, 0) is (-1.0, False)
** after background change to nan **
Voxel (5, 5, 5) is (1.0, True)
Voxel (-5, -5, -5) is (1.0, True)
Voxel (-2, -2, -2) is (5.0, False)
Voxel (2, 2, 2) is (5.0, False)
Voxel (0, 0, 0) is (nan, False)
** after background change to -12 **
Voxel (5, 5, 5) is (1.0, True)
Voxel (-5, -5, -5) is (1.0, True)
Voxel (-2, -2, -2) is (-12.0, False)
Voxel (2, 2, 2) is (-12.0, False)
Voxel (0, 0, 0) is (-12.0, False)
Expected behavior
Inactive voxels with a value different from the previous background value should not be changed when the background value is changed. This is specified in the documentation of tools::changeBackground
which gets called when setting grid.background
through the Python API
Additional context
As a side note, it is unclear from the python API that setting grid.background
will change the values (by calling tools::changeBackground
) instead of setting a reference value. Understanding this behaviour required digging through the pyopenvdb source code.
openvdb/openvdb/openvdb/python/pyGrid.h
Line 1476 in de7a496
openvdb/openvdb/openvdb/python/pyGrid.h
Line 119 in de7a496