AcademySoftwareFoundation / openvdb

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

Dense allocation for VDB that contains only one voxel point #1329

Open YoshuaNava opened 2 years ago

YoshuaNava commented 2 years ago

Environment

Operating System: Ubuntu 20.04 Version / Commit SHA: I installed the library from an Ubuntu PPA (Debian v6.2.1-8ubuntu1.1 500) Other: gcc with C++14

Describe the bug

I have implemented a program that creates an OpenVDB (regular node configuration <5,4,3>) with a custom Voxel type, and resolution 7.5cm. Additionally, I implemented visualization primitives to render voxel/node centroids as points. This visualization covers:

  1. Internal octree nodes (accessed through Grid::Tree::NodeCIter iterator) a. Root (Color: Red) b. Internal nodes level 1 (Color: Green) c. Internal nodes level 2 (Color: Blue) d. Lead nodes level 2 (Color: White)
  2. Voxel-carrying nodes (accessed through Grid::ValueAllCIter iterator) a. Active voxels (Color: Yellow) a. Inactive voxels (Color: Pink-ish)

During a test, I add one point manually, at (x=1, y=1, z=1).

When I rendered the corresponding centroids, I noticed that while the internal nodes of VDB are quite sparse (literally only one active):

image

The inactive voxel-carrying nodes (internal nodes level 2 and leaf nodes) close to the leafs seem to be plenty:

image

Upon zooming out and increasing the visualization marker size, I could see the same pattern on internal nodes level 1 and 2:

image

Furthermore, I collected some metrics:

image

As you can see, the bounding box is minimal, only containing the point I added to the tree, and the voxel count is 1. Nonetheless, 1.6MB of memory for such a sparse tree (only one element) seems like quite a bit.

To Reproduce

Steps to reproduce the behavior:

  1. Build the following snippet:

    
    // Type aliases.
    using Coord = openvdb::math::Coord;
    
    using Vec3f = openvdb::Vec3s;
    using Vec4i = openvdb::Vec4i;
    
    using DataTree = openvdb::tree::Tree4<DataContainer, 5, 4, 3>::Type;
    using DataGrid = openvdb::Grid<DataTree>;

// Custom voxel struct. struct DataContainer { using Vec3f = openvdb::Vec3s; using Vec4i = openvdb::Vec4i;

Vec3f position{0, 0, 0}; Vec3f normals{0, 0, 0}; Vec4i color_{0, 0, 0, 0};

... };

const float resolution{0.075};

// Init VDB. openvdb::initialize(); if (!DataGrid::isRegistered()) { DataGrid::registerGrid(); } DataContainer defaultValues; DataGrid::Ptr map = DataGrid::create(defaultValues); map->setGridClass(openvdb::GRID_LEVEL_SET); map->setTransform(openvdb::math::Transform::createLinearTransform(m_resolution));

// Add data to map. auto acc = map->getUnsafeAccessor(); const Coord ptIndexCoordinates{1, 1, 1}; DataContainer data{{1, 1, 1}, {0, 0, 0}, {0, 0, 0,0}}; acc.setValue(ptIndexCoordinates, data); acc.setActiveState(ptIndexCoordinates, true);


2. Run it.
3. Visualize inactive voxels and tree nodes.

### Expected behavior
VDB seems to be allocating a whole sub-branch where we would store the voxel of interest. Although these nodes don't have 'data' per se, the **tree topology** is still present in memory, and has a noticeable footprint for a 1-point dataset.

I would expect that upon adding a point to VDB, only a subset of tree voxels are instantiated. This would keep the memory footprint of the structure minimal.

### Questions
1. Am I doing something wrong?
1. Is there any way to configure VDB so that it allocates tree nodes more sparsely? I can see the current allocation strategies becoming a bottleneck for my application of interest.

### Additional context
I am evaluating OpenVDB for 3D mapping applications. After an evaluation of multiple representations for volumetric data, I think that VDB combines the characteristics of the S.O.T.A. in this field: [sparse voxel octrees](https://www.doc.ic.ac.uk/~sleutene/publications/Vespa_3DV19.pdf) and [voxel hashing](https://niessnerlab.org/papers/2013/4hashing/niessner2013hashing.pdf).
yinloonga commented 2 years ago

hi, can you provide more detail about the test code, I run the code you snippet, but I got some error messages. thank you!

yinloonga commented 2 years ago

If you don't mind, you can send a copy to my mail:yinlonga@gmail.com. Thank you!