AcademySoftwareFoundation / openvdb

OpenVDB - Sparse volume data structure and tools
http://www.openvdb.org/
Apache License 2.0
2.71k stars 660 forks source link

[BUG] VDB Analysis Closest Point doesnt seem to move outer boundary points accurately #1647

Open orionflame opened 1 year ago

orionflame commented 1 year ago

Environment

Operating System: (e.g. Windows 11) Version / Commit SHA: (e.g Latest VDB that comes with Houdini 19.5) Other: (e.g compiler, C++ standard etc.)

Describe the bug

VDB Analysis Closest Point doesnt seem to move outer boundary points accurately.

To Reproduce

Steps to reproduce the behavior: I submitted this to SideFX and got this answer where he commented on your source code:

"I stashed the original positions and then lerped between original & computed positions. This let me see it is the points in the outer boundary that aren't moving all the way in.

I then looked at the VDB code, https://github.com/AcademySoftwareFoundation/openvdb/blob/master/openvdb/openvdb/tools/GridOperators.h is where Cpt() is created, this then runs CPT() on all the voxels, the latter is in https://github.com/AcademySoftwareFoundation/openvdb/blob/master/openvdb/openvdb/math/Operators.h

Therein you'll see code like this: // compute gradient in physical space where it is a unit normal // since the grid holds a distance level set. Vec3d vectorFromSurface(d*Gradient<MapType,DiffScheme>::result(map, grid, ijk)); if (is_linear::value) { Vec3d result = ijk.asVec3d() - map.applyInverseMap(vectorFromSurface);
return Vec3Type(result); } else { Vec3d location = map.applyMap(ijk.asVec3d()); Vec3d result = map.applyInverseMap(location - vectorFromSurface); return Vec3Type(result); }

Noticeably absent from this code is an normalization of the gradient. This means that at the outer ring of active voxels where the sdf clamps to the border value; the gradient will drop from what it is in the bandwidth. This means the voxel values at the boundary have less than unit gradients, so undershoot the surface. "

Expected behavior

The question of whether CPT should normalize the gradient to get a better answer for the outermost row of voxels.

Additional context

(Add any other context about the problem here.)