36 #ifndef OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED
37 #define OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED
39 #include <openvdb/Types.h>
40 #include <openvdb/Grid.h>
41 #include <openvdb/tree/ValueAccessor.h>
42 #include <openvdb/Exceptions.h>
43 #include <tbb/parallel_for.h>
44 #include <boost/scoped_array.hpp>
45 #include <boost/scoped_ptr.hpp>
58 template<
typename DenseT,
typename Gr
idOrTreeT>
61 const GridOrTreeT& sparse,
72 template<
typename DenseT,
typename Gr
idOrTreeT>
77 const typename GridOrTreeT::ValueType& tolerance,
96 template<
typename ValueT, MemoryLayout Layout>
class DenseBase;
101 template<
typename ValueT>
111 inline size_t coordToOffset(
size_t i,
size_t j,
size_t k)
const {
return i*mX + j*mY + k; }
119 const size_t x = n / mX;
121 const size_t y = n / mY;
122 return Coord(Coord::ValueType(x), Coord::ValueType(y), Coord::ValueType(n - mY*y));
139 DenseBase(
const CoordBBox& bbox) : mBBox(bbox), mY(bbox.dim()[2]), mX(mY*bbox.dim()[1]) {}
148 template<
typename ValueT>
158 inline size_t coordToOffset(
size_t i,
size_t j,
size_t k)
const {
return i + j*mY + k*mZ; }
166 const size_t z = n / mZ;
168 const size_t y = n / mY;
169 return Coord(Coord::ValueType(n - mY*y), Coord::ValueType(y), Coord::ValueType(z));
186 DenseBase(
const CoordBBox& bbox) : mBBox(bbox), mY(bbox.dim()[0]), mZ(mY*bbox.dim()[1]) {}
204 template<
typename ValueT, MemoryLayout Layout = LayoutZYX>
216 Dense(
const CoordBBox& bbox) : BaseT(bbox) { this->init(); }
224 Dense(
const CoordBBox& bbox,
const ValueT& value) : BaseT(bbox)
239 Dense(
const CoordBBox& bbox, ValueT* data) : BaseT(bbox), mData(data)
241 if (BaseT::mBBox.empty()) {
253 Dense(
const Coord& dim,
const Coord&
min = Coord(0))
254 : BaseT(CoordBBox(
min,
min+dim.offsetBy(-1)))
264 inline ValueT*
data() {
return mData; }
268 inline const ValueT*
data()
const {
return mData; }
272 inline const CoordBBox&
bbox()
const {
return BaseT::mBBox; }
275 inline const Coord&
origin()
const {
return BaseT::mBBox.min(); }
281 inline void setValue(
size_t offset,
const ValueT& value) { mData[offset] = value; }
284 const ValueT&
getValue(
size_t offset)
const {
return mData[offset]; }
288 inline void setValue(
size_t i,
size_t j,
size_t k,
const ValueT& value)
290 mData[BaseT::coordToOffset(i,j,k)] = value;
295 inline const ValueT&
getValue(
size_t i,
size_t j,
size_t k)
const
297 return mData[BaseT::coordToOffset(i,j,k)];
302 inline void setValue(
const Coord& xyz,
const ValueT& value)
304 mData[this->coordToOffset(xyz)] = value;
309 inline const ValueT&
getValue(
const Coord& xyz)
const
311 return mData[this->coordToOffset(xyz)];
315 inline void fill(
const ValueT& value)
317 size_t size = this->valueCount();
319 while(size--) *a++ = value;
330 assert(BaseT::mBBox.isInside(xyz));
331 return BaseT::coordToOffset(
size_t(xyz[0]-BaseT::mBBox.
min()[0]),
332 size_t(xyz[1]-BaseT::mBBox.
min()[1]),
333 size_t(xyz[2]-BaseT::mBBox.
min()[2]));
339 return this->offsetToLocalCoord(n) + BaseT::mBBox.min();
345 return sizeof(*this) + BaseT::mBBox.volume() *
sizeof(ValueType);
353 if (BaseT::mBBox.empty()) {
356 mArray.reset(
new ValueT[BaseT::mBBox.volume()]);
357 mData = mArray.get();
360 boost::scoped_array<ValueT> mArray;
373 template<
typename _TreeT,
typename _DenseT = Dense<
typename _TreeT::ValueType> >
379 typedef typename TreeT::ValueType
ValueT;
382 : mRoot(&(tree.root())), mDense(&dense) {}
384 void copy(
bool serial =
false)
const
387 mRoot->copyToDense(mDense->bbox(), *mDense);
389 tbb::parallel_for(mDense->bbox(), *
this);
396 mRoot->copyToDense(bbox, *mDense);
400 const typename TreeT::RootNodeType* mRoot;
406 template<
typename DenseT,
typename Gr
idOrTreeT>
408 copyToDense(
const GridOrTreeT& sparse, DenseT& dense,
bool serial)
411 typedef typename Adapter::TreeType TreeT;
430 template<
typename _TreeT,
typename _DenseT = Dense<
typename _TreeT::ValueType> >
436 typedef typename TreeT::ValueType
ValueT;
437 typedef typename TreeT::LeafNodeType
LeafT;
444 mTolerance(tolerance),
445 mAccessor(tree.empty() ? NULL : new AccessorT(tree))
449 : mDense(other.mDense),
451 mBlocks(other.mBlocks),
452 mTolerance(other.mTolerance),
453 mAccessor(other.mAccessor.get() == NULL ? NULL : new AccessorT(*mTree))
460 mBlocks =
new std::vector<Block>();
461 const CoordBBox& bbox = mDense->bbox();
463 for (CoordBBox sub=bbox; sub.min()[0] <= bbox.max()[0]; sub.min()[0] = sub.max()[0] + 1) {
464 for (sub.min()[1] = bbox.min()[1]; sub.min()[1] <= bbox.max()[1];
465 sub.min()[1] = sub.max()[1] + 1)
467 for (sub.min()[2] = bbox.min()[2]; sub.min()[2] <= bbox.max()[2];
468 sub.min()[2] = sub.max()[2] + 1)
471 (sub.min()&(~(LeafT::DIM-1u))).offsetBy(LeafT::DIM-1u));
472 mBlocks->push_back(Block(sub));
479 (*this)(tbb::blocked_range<size_t>(0, mBlocks->size()));
481 tbb::parallel_for(tbb::blocked_range<size_t>(0, mBlocks->size()), *
this);
486 for (
size_t m=0, size = mBlocks->size(); m<size; ++m) {
487 Block& block = (*mBlocks)[m];
490 }
else if (block.tile.second) {
491 acc.
addTile(1, block.bbox.min(), block.tile.first,
true);
505 LeafT* leaf =
new LeafT();
507 for (
size_t m=r.begin(), n=0, end = r.end(); m != end; ++m, ++n) {
509 Block& block = (*mBlocks)[m];
510 const CoordBBox &bbox = block.bbox;
512 if (mAccessor.get() == NULL) {
513 leaf->fill(mTree->background(),
false);
515 if (
const LeafT* target = mAccessor->probeConstLeaf(bbox.min())) {
518 ValueT value = zeroVal<ValueT>();
519 bool state = mAccessor->probeValue(bbox.min(), value);
520 leaf->fill(value, state);
524 leaf->copyFromDense(bbox, *mDense, mTree->background(), mTolerance);
526 if (!leaf->isConstant(block.tile.first, block.tile.second, mTolerance)) {
527 leaf->setOrigin(bbox.min() & (~(LeafT::DIM - 1)));
540 std::pair<ValueT, bool> tile;
541 Block(
const CoordBBox& b) : bbox(b), leaf(NULL) {}
544 const DenseT* mDense;
546 std::vector<Block>* mBlocks;
548 boost::scoped_ptr<AccessorT> mAccessor;
553 template<
typename DenseT,
typename Gr
idOrTreeT>
556 const typename GridOrTreeT::ValueType& tolerance,
bool serial)
559 typedef typename Adapter::TreeType TreeT;
569 #endif // OPENVDB_TOOLS_DENSE_HAS_BEEN_INCLUDED
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
Definition: Exceptions.h:88
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:97
Defined various multi-threaded utility functions for trees.
Vec2< T > minComponent(const Vec2< T > &v1, const Vec2< T > &v2)
Return component-wise minimum of the two vectors.
Definition: Vec2.h:511
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Definition: Exceptions.h:39
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
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:880
uint64_t Index64
Definition: Types.h:57
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71