10 #ifndef NANOVDB_DENSEGRID_H_HAS_BEEN_INCLUDED 11 #define NANOVDB_DENSEGRID_H_HAS_BEEN_INCLUDED 23 #define LOG2_TILE_SIZE 2 28 template<
typename BufferT = HostBuffer>
31 #define DENSE_MAGIC_NUMBER 0x42445665736e6544UL // "DenseVDB" in hex - little endian (uint64_t) 48 template<
typename Vec3T>
50 template<
typename Vec3T>
52 template<
typename Vec3T>
54 template<
typename Vec3T>
56 template<
typename Vec3T>
59 template<
typename Vec3T>
61 template<
typename Vec3T>
63 template<
typename Vec3T>
65 template<
typename Vec3T>
67 template<
typename Vec3T>
73 template<
typename ValueT>
76 #if LOG2_TILE_SIZE > 0 77 static constexpr uint32_t TileLog2 =
LOG2_TILE_SIZE, TileMask = (1 << TileLog2) - 1, TileDim = 1 << (3*TileLog2);
79 using DenseData = DenseData;
84 template<
typename BufferT = HostBuffer>
90 const BufferT& allocator = BufferT());
112 template<
typename Vec3T>
116 template<
typename Vec3T>
121 template<
typename Vec3T>
126 template<
typename Vec3T>
131 template<
typename Vec3T>
135 template<
typename Vec3T>
139 template<
typename Vec3T>
144 template<
typename Vec3T>
149 template<
typename Vec3T>
154 template<
typename Vec3T>
173 __hostdev__ const DenseData*
data()
const {
return reinterpret_cast<const DenseData*
>(
this); }
182 template<
typename ValueT>
183 template<
typename BufferT>
190 const BufferT& allocator)
193 throw std::runtime_error(
"GridBuilder: voxel size is zero or negative");
197 #if LOG2_TILE_SIZE > 0 198 const uint64_t
dim[3] = {(uint64_t(max[0] - min[0]) + TileMask) >> TileLog2,
199 (uint64_t(max[1] - min[1]) + TileMask) >> TileLog2,
200 (uint64_t(max[2] - min[2]) + TileMask) >> TileLog2};
201 const uint64_t size =
sizeof(
DenseGrid) +
sizeof(ValueT)*TileDim*dim[0]*dim[1]*dim[2];
203 const uint64_t dim[3] = {uint64_t(max[0] - min[0]),
204 uint64_t(max[1] - min[1]),
205 uint64_t(max[2] - min[2])};
206 const uint64_t size =
sizeof(
DenseGrid) +
sizeof(ValueT)*dim[0]*dim[1]*dim[2];
212 const double Tx = p0[0], Ty = p0[1], Tz = p0[2];
213 const double mat[4][4] = {
219 const double invMat[4][4] = {
220 {1 / dx, 0.0, 0.0, 0.0},
221 {0.0, 1 / dx, 0.0, 0.0},
222 {0.0, 0.0, 1 / dx, 0.0},
223 {-Tx, -Ty, -Tz, 1.0},
226 grid->mMap.set(mat, invMat, 1.0);
227 for (
int i=0; i<3; ++i) {
228 grid->mIndexBBox[0][i] = min[i];
229 grid->mIndexBBox[1][i] = max[i] - 1;
231 grid->mWorldBBox[0] = grid->mWorldBBox[1] = grid->mMap.applyMap(
Vec3d(min[0], min[1], min[2]));
232 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(min[0], min[1], max[2])));
233 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(min[0], max[1], min[2])));
234 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(max[0], min[1], min[2])));
235 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(max[0], max[1], min[2])));
236 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(max[0], min[1], max[2])));
237 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(min[0], max[1], max[2])));
238 grid->mWorldBBox.expand(grid->mMap.applyMap(
Vec3d(max[0], max[1], max[2])));
239 grid->mVoxelSize = grid->mMap.applyMap(
Vec3d(1)) - grid->mMap.applyMap(
Vec3d(0));
241 throw std::runtime_error(
"Level sets are expected to be floating point types");
243 throw std::runtime_error(
"Fog volumes are expected to be floating point types");
244 grid->mGridClass = gridClass;
245 grid->mGridType = mapToGridType<ValueT>();
247 grid->mX = dim[2] * dim[1];
251 template<
typename ValueT>
259 template<
typename ValueT>
262 assert(this->test(ijk));
263 #if LOG2_TILE_SIZE > 0 265 const uint32_t y = ijk[1] - mIndexBBox[0][1];
266 const uint32_t z = ijk[2] - mIndexBBox[0][2];
267 return ((
mX*(x>>TileLog2) +
mY*(y>>TileLog2) + (z>>TileLog2))<<(3*TileLog2)) +
268 ((x&TileMask)<<(2*TileLog2)) + ((y&TileMask)<<TileLog2) + (z&TileMask);
270 return uint64_t(ijk[0]-mIndexBBox[0][0])*
mX +
271 uint64_t(ijk[1]-mIndexBBox[0][1])*
mY +
272 uint64_t(ijk[2]-mIndexBBox[0][2]);
276 template<
typename ValueT>
279 return this->values()[this->coordToOffset(ijk)];
282 template<
typename ValueT>
285 this->values()[this->coordToOffset(ijk)] =
value;
288 template<
typename ValueT>
298 template<
typename ValueT>
301 std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
303 throw std::runtime_error(
"Unable to open file for output");
306 os.write(reinterpret_cast<const char*>(tmp), 2*
sizeof(uint64_t));
307 os.write(reinterpret_cast<const char*>(&grid), tmp[1]);
310 template<
typename BufferT>
313 std::ofstream os(fileName, std::ios::out | std::ios::binary | std::ios::trunc);
315 throw std::runtime_error(
"Unable to open file for output");
318 os.write(reinterpret_cast<const char*>(tmp), 2*
sizeof(uint64_t));
319 os.write(reinterpret_cast<const char*>(handle.
data()), tmp[1]);
322 template<
typename BufferT = HostBuffer>
324 readDense(
const char* fileName,
const BufferT& allocator = BufferT())
326 std::ifstream is(fileName, std::ios::in | std::ios::binary);
328 throw std::runtime_error(
"Unable to open file for input");
331 is.read(reinterpret_cast<char*>(tmp), 2*
sizeof(uint64_t));
333 throw std::runtime_error(
"This is not a dense NanoVDB file!");
336 is.read(reinterpret_cast<char*>(handle.data()), tmp[1]);
343 template<
typename Gr
idT,
typename BufferT = HostBuffer>
346 using ValueT =
typename GridT::ValueType;
348 const Coord min = grid.indexBBox().
min(), max = grid.indexBBox().
max() +
Coord(1,1,1);
349 #if LOG2_TILE_SIZE > 0 350 static constexpr uint32_t TileLog2 =
LOG2_TILE_SIZE, TileMask = (1 << TileLog2) - 1, TileDim = 1 << (3*TileLog2);
351 const uint64_t
dim[3] = {(uint64_t(max[0] - min[0]) + TileMask) >> TileLog2,
352 (uint64_t(max[1] - min[1]) + TileMask) >> TileLog2,
353 (uint64_t(max[2] - min[2]) + TileMask) >> TileLog2};
354 const uint64_t size =
sizeof(DenseT) +
sizeof(ValueT)*TileDim*dim[0]*dim[1]*dim[2];
356 const uint64_t dim[3] = {uint64_t(max[0] - min[0]),
357 uint64_t(max[1] - min[1]),
358 uint64_t(max[2] - min[2])};
359 const uint64_t size =
sizeof(DenseT) +
sizeof(ValueT)*dim[0]*dim[1]*dim[2];
363 auto *dense =
reinterpret_cast<DenseT*
>(handle.data());
364 auto *data = dense->
data();
367 data->mMap = grid.map();
368 data->mIndexBBox = grid.indexBBox();
369 data->mWorldBBox = grid.worldBBox();
370 data->mVoxelSize = grid.voxelSize();
371 data->mGridClass = grid.gridClass();
372 data->mGridType = grid.gridType();
374 data->mX = dim[2] * dim[1];
379 auto acc = grid.getAccessor();
381 for (ijk[0] = r.begin(); ijk[0] < r.end(); ++ijk[0]) {
382 for (ijk[1] = min[1]; ijk[1] < max[1]; ++ijk[1]) {
383 for (ijk[2] = min[2]; ijk[2] < max[2]; ++ijk[2]) {
384 dense->setValue(ijk, acc.getValue(ijk));
400 template<
typename BufferT>
416 mBuffer = std::move(other.mBuffer);
427 const BufferT&
buffer()
const {
return mBuffer; }
432 uint8_t*
data() {
return mBuffer.data();}
437 const uint8_t*
data()
const {
return mBuffer.data();}
440 uint64_t
size()
const {
return mBuffer.size();}
446 template<
typename ValueT>
450 GridT* grid =
reinterpret_cast<GridT*
>(mBuffer.data());
451 return (grid && grid->isValidType()) ? grid :
nullptr;
454 template<
typename ValueT>
458 GridT* grid =
reinterpret_cast<GridT*
>(mBuffer.data());
459 return (grid && grid->isValidType()) ? grid :
nullptr;
462 template<
typename ValueT,
typename U = BufferT>
463 typename std::enable_if<BufferTraits<U>::hasDeviceDual,
const DenseGrid<ValueT>*>::type
467 bool isValidType =
reinterpret_cast<GridT*
>(mBuffer.data())->isValidType();
468 GridT* grid =
reinterpret_cast<GridT*
>(mBuffer.deviceData());
469 return (grid && isValidType) ? grid :
nullptr;
472 template<
typename U = BufferT>
473 typename std::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
475 mBuffer.deviceUpload(stream, sync);
478 template<
typename U = BufferT>
479 typename std::enable_if<BufferTraits<U>::hasDeviceDual,
void>::type
481 mBuffer.deviceDownload(stream, sync);
487 #endif // NANOVDB_DENSEGRID_HAS_BEEN_INCLUDED void reset()
Definition: DenseGrid.h:424
BufferT & buffer()
Definition: DenseGrid.h:426
__hostdev__ Coord dim() const
Definition: DenseGrid.h:45
GridType mGridType
Definition: DenseGrid.h:41
__hostdev__ const Vec3R & voxelSize() const
Definition: DenseGrid.h:109
DenseGridHandle(DenseGridHandle &&other) noexcept
Move copy-constructor.
Definition: DenseGrid.h:420
Vec3R mVoxelSize
Definition: DenseGrid.h:39
DenseGridHandle< BufferT > convertToDense(const GridT &grid, const BufferT &allocator=BufferT())
Converts a NanoVDB grid to a DenseGrid.
Definition: DenseGrid.h:344
uint64_t mX
Definition: DenseGrid.h:42
Definition: DenseGrid.h:29
__hostdev__ void setValue(const Coord &ijk, const ValueT &v)
Definition: DenseGrid.h:283
GridClass
Classes (defined in OpenVDB) that are currently supported by NanoVDB.
Definition: NanoVDB.h:253
A unified wrapper for tbb::parallel_for and a naive std::thread fallback.
HostBuffer - a buffer that contains a shared or private bump pool to either externally or internally ...
Definition: DenseGrid.h:34
#define LOG2_TILE_SIZE
Definition: DenseGrid.h:23
__hostdev__ Vec3T worldToIndexDirF(const Vec3T &dir) const
transformation from world space direction to index space direction
Definition: DenseGrid.h:150
GridClass mGridClass
Definition: DenseGrid.h:40
__hostdev__ bool isFogVolume() const
Definition: DenseGrid.h:161
const DenseGrid< ValueT > * grid() const
Returns a const pointer to the NanoVDB grid encoded in the DenseGridHandle.
Definition: DenseGrid.h:447
__hostdev__ Vec3T indexToWorldGrad(const Vec3T &grad) const
transform the gradient from index space to world space.
Definition: DenseGrid.h:132
Vec3T applyIJTF(const Vec3T &xyz) const
Definition: NanoVDB.h:2041
__hostdev__ bool test(const Coord &ijk) const
Definition: DenseGrid.h:252
__hostdev__ const Coord & max() const
Definition: DenseGrid.h:102
const BufferT & buffer() const
Definition: DenseGrid.h:427
__hostdev__ bool isLevelSet() const
Definition: DenseGrid.h:160
Vec3T applyMapF(const Vec3T &xyz) const
Definition: NanoVDB.h:2015
__hostdev__ const GridType & gridType() const
Definition: DenseGrid.h:169
__hostdev__ Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition: DenseGrid.h:62
__hostdev__ const ValueT & getValue(const Coord &ijk) const
Definition: DenseGrid.h:277
void forEach(RangeT range, const FuncT &func)
simple wrapper for tbb::parallel_for with a naive std fallback
Definition: ForEach.h:40
BBox< Vec3R > mWorldBBox
Definition: DenseGrid.h:38
__hostdev__ Vec3T worldToIndex(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:113
Simple dense grid class.
Definition: DenseGrid.h:74
__hostdev__ Vec3T applyIJTF(const Vec3T &xyz) const
Definition: DenseGrid.h:68
Implements a light-weight self-contained VDB data-structure in a single file! In other words...
__hostdev__ uint64_t size() const
Definition: DenseGrid.h:96
uint64_t mY
Definition: DenseGrid.h:42
Definition: NanoVDB.h:184
~DenseGridHandle()
Default destructor.
Definition: DenseGrid.h:422
__hostdev__ Vec3T applyMapF(const Vec3T &xyz) const
Definition: DenseGrid.h:60
__hostdev__ const DenseData * data() const
Definition: DenseGrid.h:173
__hostdev__ const BBox< Vec3R > & worldBBox() const
Computes a AABB of active values in world space.
Definition: DenseGrid.h:158
__hostdev__ Vec3T applyInverseMap(const Vec3T &xyz) const
Definition: DenseGrid.h:51
Map mMap
Definition: DenseGrid.h:36
Vec3T applyJacobian(const Vec3T &xyz) const
Definition: NanoVDB.h:2018
__hostdev__ Vec3T applyJacobian(const Vec3T &xyz) const
Definition: DenseGrid.h:53
std::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceUpload(void *stream=nullptr, bool sync=true)
Definition: DenseGrid.h:474
Vec3T applyInverseMap(const Vec3T &xyz) const
Definition: NanoVDB.h:2023
ValueT ValueType
Definition: DenseGrid.h:82
__hostdev__ bool isValidType() const
Definition: DenseGrid.h:289
uint8_t * data()
Returns a non-const pointer to the data.
Definition: DenseGrid.h:432
Vec3T applyIJT(const Vec3T &xyz) const
Definition: NanoVDB.h:2039
std::enable_if< BufferTraits< U >::hasDeviceDual, const DenseGrid< ValueT > * >::type deviceGrid() const
Definition: DenseGrid.h:464
__hostdev__ Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition: DenseGrid.h:55
__hostdev__ uint64_t gridSize() const
Definition: DenseGrid.h:100
__hostdev__ Vec3T applyMap(const Vec3T &xyz) const
Definition: DenseGrid.h:49
__hostdev__ Vec3T indexToWorldDir(const Vec3T &dir) const
transformation from index space direction to world space direction
Definition: DenseGrid.h:122
__hostdev__ uint64_t coordToOffset(const Coord &ijk) const
Definition: DenseGrid.h:260
__hostdev__ const Map & map() const
Return a const reference to the Map for this grid.
Definition: DenseGrid.h:106
__hostdev__ const Coord & min() const
Definition: DenseGrid.h:101
__hostdev__ Vec3T indexToWorldGradF(const Vec3T &grad) const
Transforms the gradient from index space to world space.
Definition: DenseGrid.h:155
ValueT value
Definition: GridBuilder.h:1287
std::enable_if< BufferTraits< U >::hasDeviceDual, void >::type deviceDownload(void *stream=nullptr, bool sync=true)
Definition: DenseGrid.h:480
__hostdev__ uint64_t memUsage() const
Definition: DenseGrid.h:99
__hostdev__ DenseData * data()
Definition: DenseGrid.h:172
void writeDense(const DenseGridHandle< BufferT > &handle, const char *fileName)
Definition: DenseGrid.h:311
__hostdev__ Vec3T worldToIndexF(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:136
__hostdev__ const GridClass & gridClass() const
Definition: DenseGrid.h:170
uint64_t size() const
Returns the size in bytes of the raw memory buffer managed by this DenseGridHandle's allocator...
Definition: DenseGrid.h:440
__hostdev__ Vec3T indexToWorld(const Vec3T &xyz) const
world to index space transformation
Definition: DenseGrid.h:117
Defines an affine transform and its inverse represented as a 3x3 matrix and a vec3 translation...
Definition: NanoVDB.h:1997
GridType
List of types that are currently supported by NanoVDB.
Definition: NanoVDB.h:216
#define DENSE_MAGIC_NUMBER
Definition: DenseGrid.h:31
DenseGridHandle(BufferT &&resources)
Definition: DenseGrid.h:406
static DenseGridHandle< BufferT > create(Coord min, Coord max, double dx=1.0, const Vec3d &p0=Vec3d(0.0), GridClass gridClass=GridClass::Unknown, const BufferT &allocator=BufferT())
Definition: DenseGrid.h:185
Vec3T applyInverseMapF(const Vec3T &xyz) const
Definition: NanoVDB.h:2028
__hostdev__ Vec3T indexToWorldDirF(const Vec3T &dir) const
transformation from index space direction to world space direction
Definition: DenseGrid.h:145
static Coord max()
Definition: NanoVDB.h:897
__hostdev__ ValueT * values()
Definition: DenseGrid.h:175
__hostdev__ Vec3T applyIJT(const Vec3T &xyz) const
Definition: DenseGrid.h:57
__hostdev__ Vec3T indexToWorldF(const Vec3T &xyz) const
index to world space transformation
Definition: DenseGrid.h:140
__hostdev__ Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition: DenseGrid.h:66
DenseGridHandle< BufferT > readDense(const char *fileName, const BufferT &allocator=BufferT())
Definition: DenseGrid.h:324
__hostdev__ const CoordBBox & indexBBox() const
Computes a AABB of active values in index space.
Definition: DenseGrid.h:167
static Coord min()
Definition: NanoVDB.h:899
uint64_t mSize
Definition: DenseGrid.h:43
__hostdev__ Vec3T applyJacobianF(const Vec3T &xyz) const
Definition: DenseGrid.h:64
__hostdev__ Vec3T worldToIndexDir(const Vec3T &dir) const
transformation from world space direction to index space direction
Definition: DenseGrid.h:127
DenseGrid< ValueT > * grid()
Definition: DenseGrid.h:455
#define __hostdev__
Definition: NanoVDB.h:168
Vec3T applyInverseJacobianF(const Vec3T &xyz) const
Definition: NanoVDB.h:2036
const uint8_t * data() const
Returns a const pointer to the data.
Definition: DenseGrid.h:437
DenseGridHandle & operator=(DenseGridHandle &&other) noexcept
Move copy assignment operation.
Definition: DenseGrid.h:414
Signed (i, j, k) 32-bit integer coordinate class, similar to openvdb::math::Coord.
Definition: NanoVDB.h:859
C++11 implementation of std::is_floating_point.
Definition: NanoVDB.h:355
Vec3T applyJacobianF(const Vec3T &xyz) const
Definition: NanoVDB.h:2020
Vec3T applyInverseJacobian(const Vec3T &xyz) const
Definition: NanoVDB.h:2034
CoordBBox mIndexBBox
Definition: DenseGrid.h:37
Vec3T applyMap(const Vec3T &xyz) const
Definition: NanoVDB.h:2013
__hostdev__ const ValueT * values() const
Definition: DenseGrid.h:176