8 #ifndef OPENVDB_TOOLS_VOLUME_TO_SPHERES_HAS_BEEN_INCLUDED 9 #define OPENVDB_TOOLS_VOLUME_TO_SPHERES_HAS_BEEN_INCLUDED 19 #include <boost/mpl/at.hpp> 20 #include <boost/mpl/int.hpp> 21 #include <tbb/blocked_range.h> 22 #include <tbb/parallel_for.h> 23 #include <tbb/parallel_reduce.h> 61 template<
typename Gr
idT,
typename InterrupterT = util::NullInterrupter>
65 std::vector<openvdb::Vec4s>& spheres,
67 bool overlapping =
false,
68 float minRadius = 1.0,
71 int instanceCount = 10000,
72 InterrupterT* interrupter =
nullptr);
76 template<
typename Gr
idT,
typename InterrupterT = util::NullInterrupter>
81 std::vector<openvdb::Vec4s>& spheres,
83 bool overlapping =
false,
84 float minRadius = 1.0,
87 int instanceCount = 10000,
88 InterrupterT* interrupter =
nullptr);
97 template<
typename Gr
idT>
101 using Ptr = std::unique_ptr<ClosestSurfacePoint>;
102 using TreeT =
typename GridT::TreeType;
103 using BoolTreeT =
typename TreeT::template ValueConverter<bool>::Type;
104 using Index32TreeT =
typename TreeT::template ValueConverter<Index32>::Type;
105 using Int16TreeT =
typename TreeT::template ValueConverter<Int16>::Type;
118 template<
typename InterrupterT = util::NullInterrupter>
119 static inline Ptr create(
const GridT& grid,
float isovalue = 0.0,
120 InterrupterT* interrupter =
nullptr);
125 inline bool search(
const std::vector<Vec3R>& points, std::vector<float>& distances);
130 inline bool searchAndReplace(std::vector<Vec3R>& points, std::vector<float>& distances);
138 using Index32LeafT =
typename Index32TreeT::LeafNodeType;
139 using IndexRange = std::pair<size_t, size_t>;
141 std::vector<Vec4R> mLeafBoundingSpheres, mNodeBoundingSpheres;
142 std::vector<IndexRange> mLeafRanges;
143 std::vector<const Index32LeafT*> mLeafNodes;
145 size_t mPointListSize = 0, mMaxNodeLeafs = 0;
146 typename Index32TreeT::Ptr mIdxTreePt;
147 typename Int16TreeT::Ptr mSignTreePt;
150 template<
typename InterrupterT = util::NullInterrupter>
151 inline bool initialize(
const GridT&,
float isovalue, InterrupterT*);
152 inline bool search(std::vector<Vec3R>&, std::vector<float>&,
bool transformPoints);
161 namespace v2s_internal {
172 mPoints.push_back(pos);
175 std::vector<Vec3R>& mPoints;
179 template<
typename Index32LeafT>
184 LeafOp(std::vector<Vec4R>& leafBoundingSpheres,
185 const std::vector<const Index32LeafT*>& leafNodes,
189 void run(
bool threaded =
true);
192 void operator()(
const tbb::blocked_range<size_t>&)
const;
195 std::vector<Vec4R>& mLeafBoundingSpheres;
196 const std::vector<const Index32LeafT*>& mLeafNodes;
201 template<
typename Index32LeafT>
203 std::vector<Vec4R>& leafBoundingSpheres,
204 const std::vector<const Index32LeafT*>& leafNodes,
207 : mLeafBoundingSpheres(leafBoundingSpheres)
208 , mLeafNodes(leafNodes)
209 , mTransform(transform)
210 , mSurfacePointList(surfacePointList)
214 template<
typename Index32LeafT>
219 tbb::parallel_for(tbb::blocked_range<size_t>(0, mLeafNodes.size()), *
this);
221 (*this)(tbb::blocked_range<size_t>(0, mLeafNodes.size()));
225 template<
typename Index32LeafT>
229 typename Index32LeafT::ValueOnCIter iter;
232 for (
size_t n = range.begin(); n != range.end(); ++n) {
238 for (iter = mLeafNodes[n]->cbeginValueOn(); iter; ++iter) {
239 avg += mSurfacePointList[iter.getValue()];
242 if (count > 1) avg *= float(1.0 /
double(count));
245 for (iter = mLeafNodes[n]->cbeginValueOn(); iter; ++iter) {
246 float tmpDist = (mSurfacePointList[iter.getValue()] - avg).lengthSqr();
247 if (tmpDist > maxDist) maxDist = tmpDist;
250 Vec4R& sphere = mLeafBoundingSpheres[n];
254 sphere[3] = maxDist * 2.0;
264 NodeOp(std::vector<Vec4R>& nodeBoundingSpheres,
265 const std::vector<IndexRange>& leafRanges,
266 const std::vector<Vec4R>& leafBoundingSpheres);
268 inline void run(
bool threaded =
true);
270 inline void operator()(
const tbb::blocked_range<size_t>&)
const;
273 std::vector<Vec4R>& mNodeBoundingSpheres;
274 const std::vector<IndexRange>& mLeafRanges;
275 const std::vector<Vec4R>& mLeafBoundingSpheres;
280 const std::vector<IndexRange>& leafRanges,
281 const std::vector<Vec4R>& leafBoundingSpheres)
282 : mNodeBoundingSpheres(nodeBoundingSpheres)
283 , mLeafRanges(leafRanges)
284 , mLeafBoundingSpheres(leafBoundingSpheres)
292 tbb::parallel_for(tbb::blocked_range<size_t>(0, mLeafRanges.size()), *
this);
294 (*this)(tbb::blocked_range<size_t>(0, mLeafRanges.size()));
303 for (
size_t n = range.begin(); n != range.end(); ++n) {
309 int count = int(mLeafRanges[n].second) - int(mLeafRanges[n].first);
311 for (
size_t i = mLeafRanges[n].first; i < mLeafRanges[n].second; ++i) {
312 avg[0] += mLeafBoundingSpheres[i][0];
313 avg[1] += mLeafBoundingSpheres[i][1];
314 avg[2] += mLeafBoundingSpheres[i][2];
317 if (count > 1) avg *= float(1.0 /
double(count));
320 double maxDist = 0.0;
322 for (
size_t i = mLeafRanges[n].first; i < mLeafRanges[n].second; ++i) {
323 pos[0] = mLeafBoundingSpheres[i][0];
324 pos[1] = mLeafBoundingSpheres[i][1];
325 pos[2] = mLeafBoundingSpheres[i][2];
326 const auto radiusSqr = mLeafBoundingSpheres[i][3];
328 double tmpDist = (pos - avg).lengthSqr() + radiusSqr;
329 if (tmpDist > maxDist) maxDist = tmpDist;
332 Vec4R& sphere = mNodeBoundingSpheres[n];
337 sphere[3] = maxDist * 2.0;
345 template<
typename Index32LeafT>
352 std::vector<Vec3R>& instancePoints,
353 std::vector<float>& instanceDistances,
355 const std::vector<const Index32LeafT*>& leafNodes,
356 const std::vector<IndexRange>& leafRanges,
357 const std::vector<Vec4R>& leafBoundingSpheres,
358 const std::vector<Vec4R>& nodeBoundingSpheres,
360 bool transformPoints =
false);
363 void run(
bool threaded =
true);
366 void operator()(
const tbb::blocked_range<size_t>&)
const;
370 void evalLeaf(
size_t index,
const Index32LeafT& leaf)
const;
371 void evalNode(
size_t pointIndex,
size_t nodeIndex)
const;
374 std::vector<Vec3R>& mInstancePoints;
375 std::vector<float>& mInstanceDistances;
379 const std::vector<const Index32LeafT*>& mLeafNodes;
380 const std::vector<IndexRange>& mLeafRanges;
381 const std::vector<Vec4R>& mLeafBoundingSpheres;
382 const std::vector<Vec4R>& mNodeBoundingSpheres;
384 std::vector<float> mLeafDistances, mNodeDistances;
386 const bool mTransformPoints;
387 size_t mClosestPointIndex;
391 template<
typename Index32LeafT>
393 std::vector<Vec3R>& instancePoints,
394 std::vector<float>& instanceDistances,
396 const std::vector<const Index32LeafT*>& leafNodes,
397 const std::vector<IndexRange>& leafRanges,
398 const std::vector<Vec4R>& leafBoundingSpheres,
399 const std::vector<Vec4R>& nodeBoundingSpheres,
401 bool transformPoints)
402 : mInstancePoints(instancePoints)
403 , mInstanceDistances(instanceDistances)
404 , mSurfacePointList(surfacePointList)
405 , mLeafNodes(leafNodes)
406 , mLeafRanges(leafRanges)
407 , mLeafBoundingSpheres(leafBoundingSpheres)
408 , mNodeBoundingSpheres(nodeBoundingSpheres)
409 , mLeafDistances(maxNodeLeafs, 0.0)
410 , mNodeDistances(leafRanges.size(), 0.0)
411 , mTransformPoints(transformPoints)
412 , mClosestPointIndex(0)
417 template<
typename Index32LeafT>
422 tbb::parallel_for(tbb::blocked_range<size_t>(0, mInstancePoints.size()), *
this);
424 (*this)(tbb::blocked_range<size_t>(0, mInstancePoints.size()));
428 template<
typename Index32LeafT>
432 typename Index32LeafT::ValueOnCIter iter;
433 const Vec3s center = mInstancePoints[index];
434 size_t& closestPointIndex = const_cast<size_t&>(mClosestPointIndex);
436 for (iter = leaf.cbeginValueOn(); iter; ++iter) {
438 const Vec3s& point = mSurfacePointList[iter.getValue()];
439 float tmpDist = (point - center).lengthSqr();
441 if (tmpDist < mInstanceDistances[index]) {
442 mInstanceDistances[index] = tmpDist;
443 closestPointIndex = iter.getValue();
449 template<
typename Index32LeafT>
451 ClosestPointDist<Index32LeafT>::evalNode(
size_t pointIndex,
size_t nodeIndex)
const 453 if (nodeIndex >= mLeafRanges.size())
return;
455 const Vec3R& pos = mInstancePoints[pointIndex];
456 float minDist = mInstanceDistances[pointIndex];
457 size_t minDistIdx = 0;
459 bool updatedDist =
false;
461 for (
size_t i = mLeafRanges[nodeIndex].first, n = 0;
462 i < mLeafRanges[nodeIndex].second; ++i, ++n)
464 float& distToLeaf = const_cast<float&>(mLeafDistances[n]);
466 center[0] = mLeafBoundingSpheres[i][0];
467 center[1] = mLeafBoundingSpheres[i][1];
468 center[2] = mLeafBoundingSpheres[i][2];
469 const auto radiusSqr = mLeafBoundingSpheres[i][3];
471 distToLeaf = float(
std::max(0.0, (pos - center).lengthSqr() - radiusSqr));
473 if (distToLeaf < minDist) {
474 minDist = distToLeaf;
480 if (!updatedDist)
return;
482 evalLeaf(pointIndex, *mLeafNodes[minDistIdx]);
484 for (
size_t i = mLeafRanges[nodeIndex].first, n = 0;
485 i < mLeafRanges[nodeIndex].second; ++i, ++n)
487 if (mLeafDistances[n] < mInstanceDistances[pointIndex] && i != minDistIdx) {
488 evalLeaf(pointIndex, *mLeafNodes[i]);
494 template<
typename Index32LeafT>
499 for (
size_t n = range.begin(); n != range.end(); ++n) {
501 const Vec3R& pos = mInstancePoints[n];
502 float minDist = mInstanceDistances[n];
503 size_t minDistIdx = 0;
505 for (
size_t i = 0, I = mNodeDistances.size(); i < I; ++i) {
506 float& distToNode = const_cast<float&>(mNodeDistances[i]);
508 center[0] = mNodeBoundingSpheres[i][0];
509 center[1] = mNodeBoundingSpheres[i][1];
510 center[2] = mNodeBoundingSpheres[i][2];
511 const auto radiusSqr = mNodeBoundingSpheres[i][3];
513 distToNode = float(
std::max(0.0, (pos - center).lengthSqr() - radiusSqr));
515 if (distToNode < minDist) {
516 minDist = distToNode;
521 evalNode(n, minDistIdx);
523 for (
size_t i = 0, I = mNodeDistances.size(); i < I; ++i) {
524 if (mNodeDistances[i] < mInstanceDistances[n] && i != minDistIdx) {
529 mInstanceDistances[n] = std::sqrt(mInstanceDistances[n]);
531 if (mTransformPoints) mInstancePoints[n] = mSurfacePointList[mClosestPointIndex];
541 const std::vector<Vec3R>& points,
542 std::vector<float>& distances,
543 std::vector<unsigned char>& mask,
547 int index()
const {
return mIndex; }
549 inline void run(
bool threaded =
true);
553 inline void operator()(
const tbb::blocked_range<size_t>& range);
556 if (rhs.mRadius > mRadius) {
557 mRadius = rhs.mRadius;
563 const Vec4s& mSphere;
564 const std::vector<Vec3R>& mPoints;
565 std::vector<float>& mDistances;
566 std::vector<unsigned char>& mMask;
575 const std::vector<Vec3R>& points,
576 std::vector<float>& distances,
577 std::vector<unsigned char>& mask,
581 , mDistances(distances)
583 , mOverlapping(overlapping)
591 : mSphere(rhs.mSphere)
592 , mPoints(rhs.mPoints)
593 , mDistances(rhs.mDistances)
595 , mOverlapping(rhs.mOverlapping)
596 , mRadius(rhs.mRadius)
605 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, mPoints.size()), *
this);
607 (*this)(tbb::blocked_range<size_t>(0, mPoints.size()));
615 for (
size_t n = range.begin(); n != range.end(); ++n) {
616 if (mMask[n])
continue;
618 pos.
x() = float(mPoints[n].x()) - mSphere[0];
619 pos.y() = float(mPoints[n].y()) - mSphere[1];
620 pos.z() = float(mPoints[n].z()) - mSphere[2];
622 float dist = pos.length();
624 if (dist < mSphere[3]) {
630 mDistances[n] =
std::min(mDistances[n], (dist - mSphere[3]));
633 if (mDistances[n] > mRadius) {
634 mRadius = mDistances[n];
647 template<
typename Gr
idT,
typename InterrupterT>
651 std::vector<openvdb::Vec4s>& spheres,
658 InterrupterT* interrupter)
661 minRadius, maxRadius, isovalue, instanceCount, interrupter);
665 template<
typename Gr
idT,
typename InterrupterT>
669 std::vector<openvdb::Vec4s>& spheres,
670 const Vec2i& sphereCount,
676 InterrupterT* interrupter)
680 if (grid.empty())
return;
683 minSphereCount = sphereCount[0],
684 maxSphereCount = sphereCount[1];
685 if ((minSphereCount > maxSphereCount) || (maxSphereCount < 1)) {
687 << minSphereCount <<
") exceeds maximum count (" << maxSphereCount <<
")");
690 spheres.reserve(maxSphereCount);
692 auto gridPtr = grid.copy();
711 auto numVoxels = gridPtr->activeVoxelCount();
712 if (numVoxels < 10000) {
713 const auto scale = 1.0 /
math::Cbrt(2.0 * 10000.0 /
double(numVoxels));
714 auto scaledXform = gridPtr->transform().copy();
715 scaledXform->preScale(
scale);
720 const auto newNumVoxels = newGridPtr->activeVoxelCount();
721 if (newNumVoxels > numVoxels) {
723 << numVoxels <<
" voxel" << (numVoxels == 1 ?
"" :
"s")
724 <<
" to " << newNumVoxels <<
" voxel" << (newNumVoxels == 1 ?
"" :
"s"));
725 gridPtr = newGridPtr;
726 numVoxels = newNumVoxels;
730 const bool addNarrowBandPoints = (numVoxels < 10000);
731 int instances =
std::max(instanceCount, maxSphereCount);
733 using TreeT =
typename GridT::TreeType;
734 using BoolTreeT =
typename TreeT::template ValueConverter<bool>::Type;
735 using Int16TreeT =
typename TreeT::template ValueConverter<Int16>::Type;
737 using RandGen = std::mersenne_twister_engine<uint32_t, 32, 351, 175, 19,
738 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 1812433253>;
741 const TreeT& tree = gridPtr->tree();
744 std::vector<Vec3R> instancePoints;
754 interiorMaskPtr->
tree().topologyUnion(tree);
757 if (interrupter && interrupter->wasInterrupted())
return;
762 if (!addNarrowBandPoints || (minSphereCount <= 0)) {
765 auto& maskTree = interiorMaskPtr->
tree();
766 auto copyOfTree = StaticPtrCast<BoolTreeT>(maskTree.copy());
768 if (maskTree.empty()) { interiorMaskPtr->
setTree(copyOfTree); }
772 instancePoints.reserve(instances);
775 const auto scatterCount =
Index64(addNarrowBandPoints ? (instances / 2) : instances);
778 ptnAcc, scatterCount, mtRand, 1.0, interrupter);
779 scatter(*interiorMaskPtr);
782 if (interrupter && interrupter->wasInterrupted())
return;
788 if (instancePoints.size() < size_t(instances)) {
789 const Int16TreeT& signTree = csp->signTree();
790 for (
auto leafIt = signTree.cbeginLeaf(); leafIt; ++leafIt) {
791 for (
auto it = leafIt->cbeginValueOn(); it; ++it) {
792 const int flags = int(it.getValue());
796 instancePoints.push_back(transform.
indexToWorld(it.getCoord()));
798 if (instancePoints.size() == size_t(instances))
break;
800 if (instancePoints.size() == size_t(instances))
break;
804 if (interrupter && interrupter->wasInterrupted())
return;
808 std::vector<float> instanceRadius;
809 if (!csp->search(instancePoints, instanceRadius))
return;
811 float largestRadius = 0.0;
812 int largestRadiusIdx = 0;
813 for (
size_t n = 0, N = instancePoints.size(); n < N; ++n) {
814 if (instanceRadius[n] > largestRadius) {
815 largestRadius = instanceRadius[n];
816 largestRadiusIdx = int(n);
820 std::vector<unsigned char> instanceMask(instancePoints.size(), 0);
822 minRadius = float(minRadius * transform.
voxelSize()[0]);
823 maxRadius = float(maxRadius * transform.
voxelSize()[0]);
825 for (
size_t s = 0, S =
std::min(
size_t(maxSphereCount), instancePoints.size()); s < S; ++s) {
827 if (interrupter && interrupter->wasInterrupted())
return;
829 largestRadius =
std::min(maxRadius, largestRadius);
831 if ((
int(s) >= minSphereCount) && (largestRadius < minRadius))
break;
834 float(instancePoints[largestRadiusIdx].x()),
835 float(instancePoints[largestRadiusIdx].y()),
836 float(instancePoints[largestRadiusIdx].z()),
839 spheres.push_back(sphere);
840 instanceMask[largestRadiusIdx] = 1;
843 sphere, instancePoints, instanceRadius, instanceMask, overlapping);
846 largestRadius = op.
radius();
847 largestRadiusIdx = op.
index();
855 template<
typename Gr
idT>
856 template<
typename InterrupterT>
861 if (!csp->initialize(grid, isovalue, interrupter)) csp.reset();
866 template<
typename Gr
idT>
867 template<
typename InterrupterT>
870 const GridT& grid,
float isovalue, InterrupterT* interrupter)
873 using ValueT =
typename GridT::ValueType;
875 const TreeT& tree = grid.
tree();
880 BoolTreeT mask(
false);
883 mSignTreePt.reset(
new Int16TreeT(0));
888 *mSignTreePt, *mIdxTreePt, mask, tree, ValueT(isovalue));
890 if (interrupter && interrupter->wasInterrupted())
return false;
894 using Int16LeafNodeType =
typename Int16TreeT::LeafNodeType;
895 using Index32LeafNodeType =
typename Index32TreeT::LeafNodeType;
897 std::vector<Int16LeafNodeType*> signFlagsLeafNodes;
898 mSignTreePt->getNodes(signFlagsLeafNodes);
900 const tbb::blocked_range<size_t> auxiliaryLeafNodeRange(0, signFlagsLeafNodes.size());
902 std::unique_ptr<Index32[]> leafNodeOffsets(
new Index32[signFlagsLeafNodes.size()]);
904 tbb::parallel_for(auxiliaryLeafNodeRange,
906 (signFlagsLeafNodes, leafNodeOffsets));
910 for (
size_t n = 0, N = signFlagsLeafNodes.size(); n < N; ++n) {
911 const Index32 tmp = leafNodeOffsets[n];
917 mSurfacePointList.reset(
new Vec3s[mPointListSize]);
921 std::vector<Index32LeafNodeType*> pointIndexLeafNodes;
922 mIdxTreePt->getNodes(pointIndexLeafNodes);
924 tbb::parallel_for(auxiliaryLeafNodeRange, volume_to_mesh_internal::ComputePoints<TreeT>(
925 mSurfacePointList.get(), tree, pointIndexLeafNodes,
926 signFlagsLeafNodes, leafNodeOffsets, transform, ValueT(isovalue)));
929 if (interrupter && interrupter->wasInterrupted())
return false;
931 Index32LeafManagerT idxLeafs(*mIdxTreePt);
933 using Index32RootNodeT =
typename Index32TreeT::RootNodeType;
934 using Index32NodeChainT =
typename Index32RootNodeT::NodeChainType;
935 static_assert(boost::mpl::size<Index32NodeChainT>::value > 1,
936 "expected tree depth greater than one");
937 using Index32InternalNodeT =
938 typename boost::mpl::at<Index32NodeChainT, boost::mpl::int_<1> >::type;
940 typename Index32TreeT::NodeCIter nIt = mIdxTreePt->cbeginNode();
941 nIt.setMinDepth(Index32TreeT::NodeCIter::LEAF_DEPTH - 1);
942 nIt.setMaxDepth(Index32TreeT::NodeCIter::LEAF_DEPTH - 1);
944 std::vector<const Index32InternalNodeT*> internalNodes;
946 const Index32InternalNodeT* node =
nullptr;
949 if (node) internalNodes.push_back(node);
952 std::vector<IndexRange>().swap(mLeafRanges);
953 mLeafRanges.resize(internalNodes.size());
955 std::vector<const Index32LeafT*>().swap(mLeafNodes);
956 mLeafNodes.reserve(idxLeafs.leafCount());
958 typename Index32InternalNodeT::ChildOnCIter leafIt;
960 for (
size_t n = 0, N = internalNodes.size(); n < N; ++n) {
962 mLeafRanges[n].first = mLeafNodes.size();
964 size_t leafCount = 0;
965 for (leafIt = internalNodes[n]->cbeginChildOn(); leafIt; ++leafIt) {
966 mLeafNodes.push_back(&(*leafIt));
970 mMaxNodeLeafs =
std::max(leafCount, mMaxNodeLeafs);
972 mLeafRanges[n].second = mLeafNodes.size();
975 std::vector<Vec4R>().swap(mLeafBoundingSpheres);
976 mLeafBoundingSpheres.resize(mLeafNodes.size());
978 v2s_internal::LeafOp<Index32LeafT> leafBS(
979 mLeafBoundingSpheres, mLeafNodes, transform, mSurfacePointList);
983 std::vector<Vec4R>().swap(mNodeBoundingSpheres);
984 mNodeBoundingSpheres.resize(internalNodes.size());
986 v2s_internal::NodeOp nodeBS(mNodeBoundingSpheres, mLeafRanges, mLeafBoundingSpheres);
992 template<
typename Gr
idT>
995 std::vector<float>& distances,
bool transformPoints)
998 distances.resize(points.size(), std::numeric_limits<float>::infinity());
1000 v2s_internal::ClosestPointDist<Index32LeafT> cpd(points, distances, mSurfacePointList,
1001 mLeafNodes, mLeafRanges, mLeafBoundingSpheres, mNodeBoundingSpheres,
1002 mMaxNodeLeafs, transformPoints);
1010 template<
typename Gr
idT>
1014 return search(
const_cast<std::vector<Vec3R>&
>(points), distances,
false);
1018 template<
typename Gr
idT>
1021 std::vector<float>& distances)
1023 return search(points, distances,
true);
1030 #endif // OPENVDB_TOOLS_VOLUME_TO_MESH_HAS_BEEN_INCLUDED
OPENVDB_IMPORT void initialize()
Global registration of basic types.
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:460
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Vec3< double > Vec3d
Definition: Vec3.h:662
SharedPtr< Grid > Ptr
Definition: Grid.h:574
#define OPENVDB_LOG_DEBUG_RUNTIME(message)
Log a debugging message in both debug and optimized builds.
Definition: logging.h:267
uint32_t Index32
Definition: Types.h:29
Index64 pointCount(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Count the total number of points in a PointDataTree.
Definition: PointCount.h:88
static T value()
Definition: Math.h:90
const TreeType & tree() const
Return a const reference to tree associated with this manager.
Definition: LeafManager.h:315
Extract polygonal surfaces from scalar volumes.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:253
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:905
void setTree(TreeBase::Ptr) override
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1460
Vec2< int32_t > Vec2i
Definition: Vec2.h:529
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:13
Vec4< float > Vec4s
Definition: Vec4.h:559
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:82
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:83
float Cbrt(float x)
Return the cube root of a floating-point value.
Definition: Math.h:716
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:203
Tolerance for floating-point comparison.
Definition: Math.h:90
Vec3< float > Vec3s
Definition: Vec3.h:661
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
uint64_t Index64
Definition: Types.h:30
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:620
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform.
Definition: Grid.h:1242