Skip to content

Commit

Permalink
Extend RootNode unit test to support map and delete test cases
Browse files Browse the repository at this point in the history
Signed-off-by: Dan Bailey <[email protected]>
  • Loading branch information
danrbailey committed Oct 26, 2024
1 parent a984443 commit 0cda152
Showing 1 changed file with 353 additions and 0 deletions.
353 changes: 353 additions & 0 deletions openvdb/openvdb/unittest/TestRootNode.cc
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,356 @@ TEST_F(TestRoot, test)
EXPECT_EQ(Index32(5), rootNode3.transientData());
}
}

TEST_F(TestRoot, testMap)
{
using RootNode = FloatTree::RootNodeType;

{ // empty root node
RootNode root(1.0f);

// background checks

EXPECT_EQ(root.background(), 1.0f);
root.setBackground(2.0f, false);
EXPECT_EQ(root.background(), 2.0f);
EXPECT_EQ(root.numBackgroundTiles(), 0);

// count checks

EXPECT_TRUE(root.empty());
EXPECT_FALSE(root.hasActiveTiles());
EXPECT_EQ(root.getTableSize(), 0);
EXPECT_EQ(root.leafCount(), 0);
EXPECT_EQ(root.nonLeafCount(), 1); // root counts as a node
EXPECT_EQ(root.childCount(), 0);
EXPECT_EQ(root.tileCount(), 0);
EXPECT_EQ(root.activeTileCount(), 0);
EXPECT_EQ(root.inactiveTileCount(), 0);

EXPECT_EQ(root.onVoxelCount(), 0);
EXPECT_EQ(root.offVoxelCount(), 0);
EXPECT_EQ(root.onLeafVoxelCount(), 0);
EXPECT_EQ(root.offLeafVoxelCount(), 0);
EXPECT_EQ(root.onTileCount(), 0);

// bounding box checks

EXPECT_EQ(root.getMinIndex(), Coord());
EXPECT_EQ(root.getMaxIndex(), Coord());
EXPECT_EQ(root.getWidth(), 0);
EXPECT_EQ(root.getHeight(), 0);
EXPECT_EQ(root.getDepth(), 0);
EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite

CoordBBox bbox;
root.evalActiveBoundingBox(bbox);
EXPECT_EQ(bbox, CoordBBox()); // empty bbox

root.getIndexRange(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(0))); // zero bbox

// origin checks

root.setOrigin(Coord(0, 0, 0));
EXPECT_THROW(root.setOrigin(Coord(1, 2, 3)), ValueError); // non-zero origins not supported

// key checks

EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), -1);

EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096));

EXPECT_FALSE(root.hasKey(Coord(0, 0, 0)));
}

{ // one active, non-background root node tile
RootNode root(1.0f);
root.addTile(Coord(1, 2, 3), 2.0f, true);

// background checks

EXPECT_EQ(root.background(), 1.0f);
EXPECT_EQ(root.numBackgroundTiles(), 0);

// count checks

EXPECT_FALSE(root.empty());
EXPECT_TRUE(root.hasActiveTiles());
EXPECT_EQ(root.getTableSize(), 1);
EXPECT_EQ(root.leafCount(), 0);
EXPECT_EQ(root.nonLeafCount(), 1);
EXPECT_EQ(root.childCount(), 0);
EXPECT_EQ(root.tileCount(), 1);
EXPECT_EQ(root.activeTileCount(), 1);
EXPECT_EQ(root.inactiveTileCount(), 0);

Index64 voxels = Index64(4096) * 4096 * 4096;
EXPECT_EQ(root.onVoxelCount(), voxels);
EXPECT_EQ(root.offVoxelCount(), 0);
EXPECT_EQ(root.onLeafVoxelCount(), 0);
EXPECT_EQ(root.offLeafVoxelCount(), 0);
EXPECT_EQ(root.onTileCount(), 1);

// bounding box checks

EXPECT_EQ(root.getMinIndex(), Coord(0));
EXPECT_EQ(root.getMaxIndex(), Coord(4095));
EXPECT_EQ(root.getWidth(), 4095);
EXPECT_EQ(root.getHeight(), 4095);
EXPECT_EQ(root.getDepth(), 4095);
EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite

CoordBBox bbox;
root.evalActiveBoundingBox(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

root.getIndexRange(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

// key checks

EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0);

EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096));

EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(1, 2, 3)));

// erase background tiles

root.eraseBackgroundTiles();
EXPECT_EQ(root.getTableSize(), 1);
EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));

// clear root

root.clear();
EXPECT_EQ(root.getTableSize(), 0);
EXPECT_FALSE(root.hasKey(Coord(0, 0, 0)));
}

{ // one inactive, background root node tile
RootNode root(1.0f);
root.addTile(Coord(1, 2, 3), 1.0f, false);

// background checks

EXPECT_EQ(root.background(), 1.0f);
EXPECT_EQ(root.numBackgroundTiles(), 1);

// count checks

EXPECT_TRUE(root.empty()); // root is empty if it only has inactive background tiles
EXPECT_FALSE(root.hasActiveTiles());
EXPECT_EQ(root.getTableSize(), 1);
EXPECT_EQ(root.leafCount(), 0);
EXPECT_EQ(root.nonLeafCount(), 1);
EXPECT_EQ(root.childCount(), 0);
EXPECT_EQ(root.tileCount(), 1);
EXPECT_EQ(root.activeTileCount(), 0);
EXPECT_EQ(root.inactiveTileCount(), 1);

EXPECT_EQ(root.onVoxelCount(), 0);
EXPECT_EQ(root.offVoxelCount(), 0);
EXPECT_EQ(root.onLeafVoxelCount(), 0);
EXPECT_EQ(root.offLeafVoxelCount(), 0);
EXPECT_EQ(root.onTileCount(), 0);

// bounding box checks

EXPECT_EQ(root.getMinIndex(), Coord(0));
EXPECT_EQ(root.getMaxIndex(), Coord(4095));
EXPECT_EQ(root.getWidth(), 4095);
EXPECT_EQ(root.getHeight(), 4095);
EXPECT_EQ(root.getDepth(), 4095);
EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite

CoordBBox bbox;
root.evalActiveBoundingBox(bbox);
EXPECT_EQ(bbox, CoordBBox()); // empty bbox

root.getIndexRange(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

// key checks

EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0);

EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096));

EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(1, 2, 3)));

// erase background tiles

root.eraseBackgroundTiles();
EXPECT_EQ(root.getTableSize(), 0);
EXPECT_FALSE(root.hasKey(Coord(0, 0, 0)));
}

{ // one active, background root node tile
RootNode root(1.0f);
root.addTile(Coord(1, 2, 3), 1.0f, true);

// background checks

EXPECT_EQ(root.background(), 1.0f);
EXPECT_EQ(root.numBackgroundTiles(), 0);

// count checks

EXPECT_FALSE(root.empty());
EXPECT_TRUE(root.hasActiveTiles());
EXPECT_EQ(root.getTableSize(), 1);
EXPECT_EQ(root.leafCount(), 0);
EXPECT_EQ(root.nonLeafCount(), 1);
EXPECT_EQ(root.childCount(), 0);
EXPECT_EQ(root.tileCount(), 1);
EXPECT_EQ(root.activeTileCount(), 1);
EXPECT_EQ(root.inactiveTileCount(), 0);

Index64 voxels = Index64(4096) * 4096 * 4096;
EXPECT_EQ(root.onVoxelCount(), voxels);
EXPECT_EQ(root.offVoxelCount(), 0);
EXPECT_EQ(root.onLeafVoxelCount(), 0);
EXPECT_EQ(root.offLeafVoxelCount(), 0);
EXPECT_EQ(root.onTileCount(), 1);

// bounding box checks

EXPECT_EQ(root.getMinIndex(), Coord(0));
EXPECT_EQ(root.getMaxIndex(), Coord(4095));
EXPECT_EQ(root.getWidth(), 4095);
EXPECT_EQ(root.getHeight(), 4095);
EXPECT_EQ(root.getDepth(), 4095);
EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite

CoordBBox bbox;
root.evalActiveBoundingBox(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

root.getIndexRange(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

// key checks

EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 0);

EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096));

EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(1, 2, 3)));
}

{ // one internal node tile (which implicitly adds a root node child)
RootNode root(1.0f);
root.addTile(2, Coord(1, 2, 3), 2.0f, true);

// count checks

EXPECT_FALSE(root.empty());
EXPECT_TRUE(root.hasActiveTiles()); // this method recurses down the tree
EXPECT_EQ(root.getTableSize(), 1);
EXPECT_EQ(root.leafCount(), 0);
EXPECT_EQ(root.nonLeafCount(), 2);
EXPECT_EQ(root.childCount(), 1);
EXPECT_EQ(root.tileCount(), 0);
EXPECT_EQ(root.activeTileCount(), 0);
EXPECT_EQ(root.inactiveTileCount(), 0);

Index64 totalVoxels = Index64(4096) * 4096 * 4096;
Index64 onVoxels = Index64(128) * 128 * 128;
EXPECT_EQ(root.onVoxelCount(), onVoxels);
EXPECT_EQ(root.offVoxelCount(), totalVoxels - onVoxels);
EXPECT_EQ(root.onLeafVoxelCount(), 0);
EXPECT_EQ(root.offLeafVoxelCount(), 0);
EXPECT_EQ(root.onTileCount(), 1);

// bounding box checks

EXPECT_EQ(root.getMinIndex(), Coord(0));
EXPECT_EQ(root.getMaxIndex(), Coord(4095));
EXPECT_EQ(root.getWidth(), 4095);
EXPECT_EQ(root.getHeight(), 4095);
EXPECT_EQ(root.getDepth(), 4095);
EXPECT_EQ(root.getNodeBoundingBox(), CoordBBox::inf()); // always infinite

CoordBBox bbox;
root.evalActiveBoundingBox(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(127)));

root.getIndexRange(bbox);
EXPECT_EQ(bbox, CoordBBox(Coord(0), Coord(4095)));

// key checks

EXPECT_EQ(root.getValueDepth(Coord(0, 0, 0)), 1); // InternalNode 1

EXPECT_EQ(root.coordToKey(Coord(0, 0, 0)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(1, 2, 3)), Coord(0, 0, 0));
EXPECT_EQ(root.coordToKey(Coord(5000, 6000, 7000)), Coord(4096, 4096, 4096));

EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(1, 2, 3)));
}
}

TEST_F(TestRoot, testDelete)
{
using RootNode = FloatTree::RootNodeType;

RootNode root(1.0f);

root.addTile(Coord(1, 2, 3), 2.0f, true);
root.addTile(Coord(4096, 2, 3), 3.0f, true);

auto* child = new RootNode::ChildNodeType(Coord(0, 0, 4096), 5.0f, true);
EXPECT_TRUE(root.addChild(child)); // always returns true

EXPECT_EQ(root.getTableSize(), 3);
EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_TRUE(root.hasKey(Coord(4096, 0, 0)));
EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096)));
EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0)));

EXPECT_FALSE(root.deleteChildOrTile(Coord(4096, 4096, 0)));

EXPECT_EQ(root.getTableSize(), 3);
EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_TRUE(root.hasKey(Coord(4096, 0, 0)));
EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096)));
EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0)));

EXPECT_TRUE(root.deleteChildOrTile(Coord(4096, 5, 6)));

EXPECT_EQ(root.getTableSize(), 2);
EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0)));
EXPECT_TRUE(root.hasKey(Coord(0, 0, 4096)));
EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0)));

EXPECT_TRUE(root.deleteChildOrTile(Coord(1, 5, 4097)));

EXPECT_EQ(root.getTableSize(), 1);
EXPECT_TRUE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(0, 0, 4096)));
EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0)));

EXPECT_TRUE(root.deleteChildOrTile(Coord(1, 5, 7)));

EXPECT_EQ(root.getTableSize(), 0);
EXPECT_FALSE(root.hasKey(Coord(0, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(4096, 0, 0)));
EXPECT_FALSE(root.hasKey(Coord(0, 0, 4096)));
EXPECT_FALSE(root.hasKey(Coord(4096, 4096, 0)));
}

0 comments on commit 0cda152

Please sign in to comment.