openvdb icon indicating copy to clipboard operation
openvdb copied to clipboard

[BUG] NanoVDB NanoGrid returns incorrect voxel size when initialized from VDB with transform

Open w0utert opened this issue 1 year ago • 5 comments

Environment

Operating System: Linux Ubuntu 22.04 Version / Commit SHA: OpenVDB 11.0.1 Other: gcc-10.5.0

Describe the bug

When loading a level set from a .vdb that has a transform that is not a simple linear scale, then creating a NanoGrid from it, it appears the voxel size for the resulting NanoGrid is not set correctly.

In my case I'm loading a VDB that contains a unit box with voxel size 0.1 and a Transform that rotates 45 degrees around the z-axis. I created this VDB using vdb_tool:

vdb_tool -platonic faces=6 scale=1 voxel=0.1 -transform rotate='(0,0,0.78539816339744830961566084581988)' vdb=0 -write box.rotated.vdb

The x, y, x components of the voxel size returned by NanoGrid<T>::voxelSize() appear to be initialized not from the length of the transform axes, but by just taking their corresponding component from the rotated basis vectors (or something along those lines).

To Reproduce

The following small program reproduces this behavior:

#include <openvdb/openvdb.h>
#include <openvdb/io/Stream.h>
#include <nanovdb/tools/CreateNanoGrid.h>

int main(int argc, char **argv)
{
  openvdb::initialize();

  std::ifstream in("box.rotated.vdb");

  openvdb::io::Stream stream(in);

  openvdb::FloatGrid::Ptr grid = openvdb::DynamicPtrCast<openvdb::FloatGrid>(stream.getGrids()->front());

  auto handle = nanovdb::tools::createNanoGrid<openvdb::FloatGrid, float, GpuBufferT>(*grid);

  nanovdb::NanoGrid<float> *nano_grid = handle.grid<float>();

  const auto vdb_voxel_size = grid->voxelSize();
  const auto nano_voxel_size = nano_grid->voxelSize();

  std::cerr << "OpenVDB voxel size: " << vdb_voxel_size << std::endl;
  std::cerr << "NanoVDB voxel size: " << nano_voxel_size[0] << ", " << nano_voxel_size[1] << ", " << nano_voxel_size[2] << std::endl;
}

When I build & run this program on the attached vdb file it prints:

OpenVDB voxel_size: [0.1, 0.1, 0.1]
NanoVDB voxel_size: 1.38778e-17, 0.141421, 0.1

Expected behavior

I would expect NanoGrid<T>::voxelSize() to return the same vector as FloatGrid::voxelSize() for a NanoVDB grid created from an OpenVDB grid.

w0utert avatar Jun 06 '24 15:06 w0utert

Has there been any update on this bug? @w0utert

anja-sheppard avatar Nov 04 '24 16:11 anja-sheppard

@anja-sheppard no update unfortunately, my NanoVDB prototyping work has been blocked by #1846 so I shelved it, I'm just now considering to have a second look at it but it does not seem like there have been any fixes to NanoVDB for either this problem or #1846 (neither did I get any feedback there is not actually a bug but I'm using it wrong)

w0utert avatar Mar 12 '25 14:03 w0utert

sorry about the delay - I'll have a look at this shortly

kmuseth avatar Mar 12 '25 23:03 kmuseth

the code above doesn't build (anymore), but when I run "vdb_print -l box,rotated.vdb" I get:

Transform: voxel size: 0.1 index to world: [0.0707, 0.0707, 0, 0] [-0.0707, 0.0707, 0, 0] [0, 0, 0.1, 0] [0, 0, 0, 1]

which seems correct to me. However, this obviously doesn't prove that there isn't a problem when it's converted to nanovdb. I'll test this next ...

kmuseth avatar Mar 20 '25 04:03 kmuseth

@kmuseth thanks! The result when strictly using OpenVDB is indeed as expected, it’s only when using NanoVDB with the same grid that some components of the voxel size vector are different (and, I think, incorrect)

w0utert avatar Mar 20 '25 14:03 w0utert