36 #ifndef OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED 37 #define OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED 45 #include <boost/scoped_array.hpp> 46 #include <tbb/parallel_for.h> 59 template<
typename DenseT,
typename Gr
idOrTreeT>
62 const GridOrTreeT& sparse,
73 template<
typename DenseT,
typename Gr
idOrTreeT>
78 const typename GridOrTreeT::ValueType& tolerance,
97 template<
typename ValueT, MemoryLayout Layout>
class DenseBase;
102 template<
typename ValueT>
112 inline size_t coordToOffset(
size_t i,
size_t j,
size_t k)
const {
return i*mX + j*mY + k; }
120 const size_t x = n / mX;
122 const size_t y = n / mY;
149 template<
typename ValueT>
159 inline size_t coordToOffset(
size_t i,
size_t j,
size_t k)
const {
return i + j*mY + k*mZ; }
167 const size_t z = n / mZ;
169 const size_t y = n / mY;
205 template<
typename ValueT, MemoryLayout Layout = LayoutZYX>
244 if (BaseT::mBBox.empty()) {
267 inline ValueT*
data() {
return mData; }
271 inline const ValueT*
data()
const {
return mData; }
284 inline void setValue(
size_t offset,
const ValueT& value) { mData[offset] = value; }
287 const ValueT&
getValue(
size_t offset)
const {
return mData[offset]; }
290 ValueT&
getValue(
size_t offset) {
return mData[offset]; }
294 inline void setValue(
size_t i,
size_t j,
size_t k,
const ValueT& value)
296 mData[BaseT::coordToOffset(i,j,k)] = value;
302 inline const ValueT&
getValue(
size_t i,
size_t j,
size_t k)
const 304 return mData[BaseT::coordToOffset(i,j,k)];
312 return mData[BaseT::coordToOffset(i,j,k)];
319 mData[this->coordToOffset(xyz)] = value;
326 return mData[this->coordToOffset(xyz)];
334 return mData[this->coordToOffset(xyz)];
338 inline void fill(
const ValueT& value)
340 size_t size = this->valueCount();
342 while(size--) *a++ = value;
353 assert(BaseT::mBBox.isInside(xyz));
354 return BaseT::coordToOffset(
size_t(xyz[0]-BaseT::mBBox.
min()[0]),
355 size_t(xyz[1]-BaseT::mBBox.
min()[1]),
356 size_t(xyz[2]-BaseT::mBBox.
min()[2]));
362 return this->offsetToLocalCoord(n) + BaseT::mBBox.
min();
368 return sizeof(*this) + BaseT::mBBox.volume() *
sizeof(
ValueType);
373 void print(
const std::string& name =
"", std::ostream& os = std::cout)
const 375 const Coord dim = BaseT::mBBox.dim();
377 if (!name.empty()) os <<
" \"" << name <<
"\"";
379 os <<
" Dimensions of grid : " << dim[0] <<
" x " << dim[1] <<
" x " << dim[2] <<
"\n";
381 os <<
" Bounding box of voxels: " << BaseT::mBBox <<
"\n";
382 os <<
" Memory layout: " << (Layout == LayoutZYX ?
"ZYX (" :
"XYZ (dis")
383 <<
"similar to VDB)\n";
390 if (BaseT::mBBox.empty()) {
393 mArray.reset(
new ValueT[BaseT::mBBox.volume()]);
394 mData = mArray.get();
397 boost::scoped_array<ValueT> mArray;
410 template<
typename _TreeT,
typename _DenseT = Dense<
typename _TreeT::ValueType> >
416 using ValueT =
typename TreeT::ValueType;
419 : mRoot(&(tree.root())), mDense(&dense) {}
421 void copy(
bool serial =
false)
const 424 mRoot->copyToDense(mDense->bbox(), *mDense);
426 tbb::parallel_for(mDense->bbox(), *
this);
433 mRoot->copyToDense(bbox, *mDense);
437 const typename TreeT::RootNodeType* mRoot;
443 template<
typename DenseT,
typename Gr
idOrTreeT>
445 copyToDense(
const GridOrTreeT& sparse, DenseT& dense,
bool serial)
448 using TreeT =
typename Adapter::TreeType;
467 template<
typename _TreeT,
typename _DenseT = Dense<
typename _TreeT::ValueType> >
473 using ValueT =
typename TreeT::ValueType;
474 using LeafT =
typename TreeT::LeafNodeType;
481 mTolerance(tolerance),
482 mAccessor(tree.empty() ? nullptr : new
AccessorT(tree))
486 : mDense(other.mDense),
488 mBlocks(other.mBlocks),
489 mTolerance(other.mTolerance),
490 mAccessor(other.mAccessor.get() == nullptr ? nullptr : new
AccessorT(*mTree))
497 mBlocks =
new std::vector<Block>();
501 for (sub.min()[1] = bbox.min()[1]; sub.min()[1] <= bbox.max()[1];
502 sub.min()[1] = sub.max()[1] + 1)
504 for (sub.min()[2] = bbox.min()[2]; sub.min()[2] <= bbox.max()[2];
505 sub.min()[2] = sub.max()[2] + 1)
508 (sub.min()&(~(LeafT::DIM-1u))).offsetBy(LeafT::DIM-1u));
509 mBlocks->push_back(Block(sub));
516 (*this)(tbb::blocked_range<size_t>(0, mBlocks->size()));
518 tbb::parallel_for(tbb::blocked_range<size_t>(0, mBlocks->size()), *
this);
523 for (
size_t m=0,
size = mBlocks->size(); m<
size; ++m) {
524 Block& block = (*mBlocks)[m];
527 }
else if (block.tile.second) {
528 acc.
addTile(1, block.bbox.min(), block.tile.first,
true);
544 for (
size_t m=r.begin(), n=0, end = r.end(); m != end; ++m, ++n) {
546 Block& block = (*mBlocks)[m];
549 if (mAccessor.get() ==
nullptr) {
550 leaf->fill(mTree->background(),
false);
552 if (
const LeafT* target = mAccessor->probeConstLeaf(bbox.
min())) {
555 ValueT value = zeroVal<ValueT>();
556 bool state = mAccessor->probeValue(bbox.
min(), value);
557 leaf->fill(value, state);
561 leaf->copyFromDense(bbox, *mDense, mTree->background(), mTolerance);
563 if (!leaf->isConstant(block.tile.first, block.tile.second, mTolerance)) {
564 leaf->setOrigin(bbox.
min() & (~(LeafT::DIM - 1)));
577 std::pair<ValueT, bool> tile;
578 Block(
const CoordBBox& b) : bbox(b), leaf(
nullptr) {}
583 std::vector<Block>* mBlocks;
585 std::unique_ptr<AccessorT> mAccessor;
590 template<
typename DenseT,
typename Gr
idOrTreeT>
593 const typename GridOrTreeT::ValueType& tolerance,
bool serial)
596 using TreeT =
typename Adapter::TreeType;
606 #endif // OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED
std::shared_ptr< T > SharedPtr
Definition: Types.h:130
FormattedInt< IntT > formattedInt(IntT n)
Definition: Formats.h:130
static Coord min()
Return the smallest possible coordinate.
Definition: Coord.h:67
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:101
tbb::atomic< Index32 > i
Definition: LeafBuffer.h:71
void addTile(Index level, const Coord &xyz, const ValueType &value, bool state)
Add a tile at the specified tree level that contains voxel (x, y, z), possibly deleting existing node...
Definition: ValueAccessor.h:382
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:261
T * data
Definition: LeafBuffer.h:71
void addLeaf(LeafNodeT *leaf)
Add the specified leaf to this tree, possibly creating a child branch in the process. If the leaf node already exists, replace it.
Definition: ValueAccessor.h:374
Defined various multi-threaded utility functions for trees.
uint64_t Index64
Definition: Types.h:56
#define OPENVDB_VERSION_NAME
Definition: version.h:43
static Coord max()
Return the largest possible coordinate.
Definition: Coord.h:70
Definition: Exceptions.h:39
void minComponent(const Coord &other)
Perform a component-wise minimum with the other Coord.
Definition: Coord.h:199
const Coord & max() const
Definition: Coord.h:335
OPENVDB_API int printBytes(std::ostream &os, uint64_t bytes, const std::string &head="", const std::string &tail="\, bool exact=false, int width=8, int precision=3)
Definition: Exceptions.h:92
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:48
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Int32 ValueType
Definition: Coord.h:56
const Coord & min() const
Definition: Coord.h:334
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:943
static constexpr size_t size
The size of a LeafBuffer when LeafBuffer::mOutOfCore is atomic.
Definition: LeafBuffer.h:85