-
Notifications
You must be signed in to change notification settings - Fork 765
Expand file tree
/
Copy pathcoarsen_nanovdb_cpu.cpp
More file actions
138 lines (124 loc) · 6.94 KB
/
Copy pathcoarsen_nanovdb_cpu.cpp
File metadata and controls
138 lines (124 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: Apache-2.0
// the following files are from OpenVDB
#include <openvdb/tree/LeafManager.h>
#include <openvdb/util/CpuTimer.h>
// the following files are from NanoVDB
#include <nanovdb/NanoVDB.h>
#include <nanovdb/tools/CreateNanoGrid.h>
template<class CoordT>
inline CoordT
coarsenCoord(const CoordT& coord)
{
auto coarsenComponent = [](const typename CoordT::ValueType n) {return (n>=0) ? (n>>1) : -((-n+1)>>1);};
CoordT result;
result[0] = coarsenComponent(coord[0]);
result[1] = coarsenComponent(coord[1]);
result[2] = coarsenComponent(coord[2]);
return result;
}
template<typename BuildT>
void mainCoarsenGrid(
nanovdb::NanoGrid<BuildT> *srcGrid, // original (un-coarsened) grid
nanovdb::NanoGrid<BuildT> *indexGridCoarsened,
uint32_t benchmark_iters
);
/// @brief This example depends on OpenVDB, NanoVDB, and CUDA
int main(int argc, char *argv[])
{
using GridT = openvdb::FloatGrid;
using BuildT = nanovdb::ValueOnIndex;
openvdb::util::CpuTimer cpuTimer;
const bool printGridDiagnostics = true;
try {
if (argc<2) OPENVDB_THROW(openvdb::ValueError, "usage: "+std::string(argv[0])+" input.vdb [<iterations>]\n");
int benchmark_iters = 10;
if (argc > 2) sscanf(argv[2], "%d", &benchmark_iters);
// Read the initial level set from file
cpuTimer.start("Read input VDB file");
openvdb::initialize();
openvdb::io::File inFile(argv[1]);
inFile.open(false); // disable delayed loading
auto baseGrids = inFile.getGrids();
inFile.close();
auto grid = openvdb::gridPtrCast<GridT>(baseGrids->at(0));
if (!grid) OPENVDB_THROW(openvdb::ValueError, "First grid is not a FloatGrid\n");
cpuTimer.stop();
// Convert to indexGrid (original, un-coarsened)
cpuTimer.start("Converting openVDB input to indexGrid (original version)");
auto handleOriginal = nanovdb::tools::openToIndexVDB<BuildT, nanovdb::HostBuffer>(
grid,
0u, // Don't copy data channel
false, // No stats
false, // No tiles
1 // Verbose mode
);
auto *indexGridOriginal = handleOriginal.grid<BuildT>();
cpuTimer.stop();
if (printGridDiagnostics) {
std::cout << "============ Original Grid ===========" << std::endl;
std::cout << "Allocated values [valueCount()] : " << indexGridOriginal->valueCount() << std::endl;
std::cout << "Active voxels [activeVoxelCount()] : " << indexGridOriginal->activeVoxelCount() << std::endl;
auto minCorner = indexGridOriginal->indexBBox().min(), maxCorner = indexGridOriginal->indexBBox().max();
std::cout << "Index-space bounding box : [" << minCorner.x() << "," << minCorner.y() << "," << minCorner.z()
<< "] -> [" << maxCorner.x() << "," << maxCorner.y() << "," << maxCorner.z() << "]" << std::endl;
std::cout << "Leaf nodes : " << indexGridOriginal->tree().nodeCount(0) << std::endl;
std::cout << "Lower internal nodes : " << indexGridOriginal->tree().nodeCount(1) << std::endl;
std::cout << "Upper internal nodes : " << indexGridOriginal->tree().nodeCount(2) << std::endl;
std::cout << "Leaf-level occupancy : "
<< 100.f * (float)(indexGridOriginal->activeVoxelCount())/(float)(indexGridOriginal->tree().nodeCount(0) * 512)
<< "%" << std::endl;
std::cout << "Memory usage : " << indexGridOriginal->gridSize() << " bytes" << std::endl;
}
// Coarsening (CPU/OpenVDB version), used as the correctness reference
cpuTimer.start("Coarsening OpenVDB (on CPU)");
using TreeT = GridT::TreeType;
using LeafManagerT = openvdb::tree::LeafManager<const TreeT>;
LeafManagerT leafMgr(grid->tree());
auto coarsenedGrid = openvdb::FloatGrid::create(grid->background());
coarsenedGrid->setTransform(grid->transform().copy());
coarsenedGrid->setName(grid->getName());
auto dstAcc = coarsenedGrid->getAccessor();
for (std::size_t leafID = 0; leafID < leafMgr.leafCount(); ++leafID) {
const auto& srcLeaf = leafMgr.leaf(leafID);
for (auto iter = srcLeaf.cbeginValueOn(); iter; ++iter) {
const auto dstCoord = coarsenCoord(iter.getCoord());
if (!dstAcc.isValueOn(dstCoord))
dstAcc.setValue(dstCoord, iter.getValue());
}
}
cpuTimer.stop();
// Convert to indexGrid (coarsened reference)
cpuTimer.start("Converting openVDB input to indexGrid (coarsened version)");
auto handleCoarsened = nanovdb::tools::openToIndexVDB<BuildT, nanovdb::HostBuffer>(
coarsenedGrid,
0u, // Don't copy data channel
false, // No stats
false, // No tiles
1 // Verbose mode
);
auto *indexGridCoarsened = handleCoarsened.grid<BuildT>();
cpuTimer.stop();
if (printGridDiagnostics) {
std::cout << "=========== Coarsened Grid ===========" << std::endl;
std::cout << "Allocated values [valueCount()] : " << indexGridCoarsened->valueCount() << std::endl;
std::cout << "Active voxels [activeVoxelCount()] : " << indexGridCoarsened->activeVoxelCount() << std::endl;
auto minCorner = indexGridCoarsened->indexBBox().min(), maxCorner = indexGridCoarsened->indexBBox().max();
std::cout << "Index-space bounding box : [" << minCorner.x() << "," << minCorner.y() << "," << minCorner.z()
<< "] -> [" << maxCorner.x() << "," << maxCorner.y() << "," << maxCorner.z() << "]" << std::endl;
std::cout << "Leaf nodes : " << indexGridCoarsened->tree().nodeCount(0) << std::endl;
std::cout << "Lower internal nodes : " << indexGridCoarsened->tree().nodeCount(1) << std::endl;
std::cout << "Upper internal nodes : " << indexGridCoarsened->tree().nodeCount(2) << std::endl;
std::cout << "Leaf-level occupancy : "
<< 100.f * (float)(indexGridCoarsened->activeVoxelCount())/(float)(indexGridCoarsened->tree().nodeCount(0) * 512)
<< "%" << std::endl;
std::cout << "Memory usage : " << indexGridCoarsened->gridSize() << " bytes" << std::endl;
}
// All grids are host-resident (HostBuffer); the operators read them directly.
mainCoarsenGrid( indexGridOriginal, indexGridCoarsened, benchmark_iters );
}
catch (const std::exception& e) {
std::cerr << "An exception occurred: \"" << e.what() << "\"" << std::endl;
}
return 0;
}