35 #ifndef OPENVDB_TOOLS_VOLUME_TO_SPHERES_HAS_BEEN_INCLUDED 36 #define OPENVDB_TOOLS_VOLUME_TO_SPHERES_HAS_BEEN_INCLUDED 46 #include <boost/mpl/at.hpp> 47 #include <boost/mpl/int.hpp> 48 #include <boost/scoped_array.hpp> 49 #include <tbb/blocked_range.h> 50 #include <tbb/parallel_for.h> 51 #include <tbb/parallel_reduce.h> 89 template<
typename Gr
idT,
typename InterrupterT = util::NullInterrupter>
93 std::vector<openvdb::Vec4s>& spheres,
95 bool overlapping =
false,
96 float minRadius = 1.0,
99 int instanceCount = 10000,
100 InterrupterT* interrupter =
nullptr);
104 template<
typename Gr
idT,
typename InterrupterT = util::NullInterrupter>
109 std::vector<openvdb::Vec4s>& spheres,
111 bool overlapping =
false,
112 float minRadius = 1.0,
114 float isovalue = 0.0,
115 int instanceCount = 10000,
116 InterrupterT* interrupter =
nullptr);
125 template<
typename Gr
idT>
129 using Ptr = std::unique_ptr<ClosestSurfacePoint>;
130 using TreeT =
typename GridT::TreeType;
131 using BoolTreeT =
typename TreeT::template ValueConverter<bool>::Type;
132 using Index32TreeT =
typename TreeT::template ValueConverter<Index32>::Type;
133 using Int16TreeT =
typename TreeT::template ValueConverter<Int16>::Type;
146 template<
typename InterrupterT = util::NullInterrupter>
147 static inline Ptr create(
const GridT& grid,
float isovalue = 0.0,
148 InterrupterT* interrupter =
nullptr);
153 inline bool search(
const std::vector<Vec3R>& points, std::vector<float>& distances);
158 inline bool searchAndReplace(std::vector<Vec3R>& points, std::vector<float>& distances);
166 using Index32LeafT =
typename Index32TreeT::LeafNodeType;
167 using IndexRange = std::pair<size_t, size_t>;
169 std::vector<Vec4R> mLeafBoundingSpheres, mNodeBoundingSpheres;
170 std::vector<IndexRange> mLeafRanges;
171 std::vector<const Index32LeafT*> mLeafNodes;
173 size_t mPointListSize = 0, mMaxNodeLeafs = 0;
174 typename Index32TreeT::Ptr mIdxTreePt;
175 typename Int16TreeT::Ptr mSignTreePt;
178 template<
typename InterrupterT = util::NullInterrupter>
179 inline bool initialize(
const GridT&,
float isovalue, InterrupterT*);
180 inline bool search(std::vector<Vec3R>&, std::vector<float>&,
bool transformPoints);
189 namespace v2s_internal {
200 mPoints.push_back(pos);
203 std::vector<Vec3R>& mPoints;
207 template<
typename Index32LeafT>
212 LeafOp(std::vector<Vec4R>& leafBoundingSpheres,
213 const std::vector<const Index32LeafT*>& leafNodes,
217 void run(
bool threaded =
true);
220 void operator()(
const tbb::blocked_range<size_t>&)
const;
223 std::vector<Vec4R>& mLeafBoundingSpheres;
224 const std::vector<const Index32LeafT*>& mLeafNodes;
229 template<
typename Index32LeafT>
231 std::vector<Vec4R>& leafBoundingSpheres,
232 const std::vector<const Index32LeafT*>& leafNodes,
235 : mLeafBoundingSpheres(leafBoundingSpheres)
236 , mLeafNodes(leafNodes)
237 , mTransform(transform)
238 , mSurfacePointList(surfacePointList)
242 template<
typename Index32LeafT>
247 tbb::parallel_for(tbb::blocked_range<size_t>(0, mLeafNodes.size()), *
this);
249 (*this)(tbb::blocked_range<size_t>(0, mLeafNodes.size()));
253 template<
typename Index32LeafT>
257 typename Index32LeafT::ValueOnCIter iter;
260 for (
size_t n = range.begin(); n != range.end(); ++n) {
266 for (iter = mLeafNodes[n]->cbeginValueOn(); iter; ++iter) {
267 avg += mSurfacePointList[iter.getValue()];
270 if (count > 1) avg *= float(1.0 /
double(count));
273 for (iter = mLeafNodes[n]->cbeginValueOn(); iter; ++iter) {
274 float tmpDist = (mSurfacePointList[iter.getValue()] - avg).lengthSqr();
275 if (tmpDist > maxDist) maxDist = tmpDist;
278 Vec4R& sphere = mLeafBoundingSpheres[n];
282 sphere[3] = maxDist * 2.0;
292 NodeOp(std::vector<Vec4R>& nodeBoundingSpheres,
293 const std::vector<IndexRange>& leafRanges,
294 const std::vector<Vec4R>& leafBoundingSpheres);
296 inline void run(
bool threaded =
true);
298 inline void operator()(
const tbb::blocked_range<size_t>&)
const;
301 std::vector<Vec4R>& mNodeBoundingSpheres;
302 const std::vector<IndexRange>& mLeafRanges;
303 const std::vector<Vec4R>& mLeafBoundingSpheres;
308 const std::vector<IndexRange>& leafRanges,
309 const std::vector<Vec4R>& leafBoundingSpheres)
310 : mNodeBoundingSpheres(nodeBoundingSpheres)
311 , mLeafRanges(leafRanges)
312 , mLeafBoundingSpheres(leafBoundingSpheres)
320 tbb::parallel_for(tbb::blocked_range<size_t>(0, mLeafRanges.size()), *
this);
322 (*this)(tbb::blocked_range<size_t>(0, mLeafRanges.size()));
331 for (
size_t n = range.begin(); n != range.end(); ++n) {
337 int count = int(mLeafRanges[n].second) - int(mLeafRanges[n].first);
339 for (
size_t i = mLeafRanges[n].first; i < mLeafRanges[n].second; ++i) {
340 avg[0] += mLeafBoundingSpheres[i][0];
341 avg[1] += mLeafBoundingSpheres[i][1];
342 avg[2] += mLeafBoundingSpheres[i][2];
345 if (count > 1) avg *= float(1.0 /
double(count));
348 double maxDist = 0.0;
350 for (
size_t i = mLeafRanges[n].first; i < mLeafRanges[n].second; ++i) {
351 pos[0] = mLeafBoundingSpheres[i][0];
352 pos[1] = mLeafBoundingSpheres[i][1];
353 pos[2] = mLeafBoundingSpheres[i][2];
354 const auto radiusSqr = mLeafBoundingSpheres[i][3];
356 double tmpDist = (pos - avg).lengthSqr() + radiusSqr;
357 if (tmpDist > maxDist) maxDist = tmpDist;
360 Vec4R& sphere = mNodeBoundingSpheres[n];
365 sphere[3] = maxDist * 2.0;
373 template<
typename Index32LeafT>
380 std::vector<Vec3R>& instancePoints,
381 std::vector<float>& instanceDistances,
383 const std::vector<const Index32LeafT*>& leafNodes,
384 const std::vector<IndexRange>& leafRanges,
385 const std::vector<Vec4R>& leafBoundingSpheres,
386 const std::vector<Vec4R>& nodeBoundingSpheres,
388 bool transformPoints =
false);
391 void run(
bool threaded =
true);
394 void operator()(
const tbb::blocked_range<size_t>&)
const;
398 void evalLeaf(
size_t index,
const Index32LeafT& leaf)
const;
399 void evalNode(
size_t pointIndex,
size_t nodeIndex)
const;
402 std::vector<Vec3R>& mInstancePoints;
403 std::vector<float>& mInstanceDistances;
407 const std::vector<const Index32LeafT*>& mLeafNodes;
408 const std::vector<IndexRange>& mLeafRanges;
409 const std::vector<Vec4R>& mLeafBoundingSpheres;
410 const std::vector<Vec4R>& mNodeBoundingSpheres;
412 std::vector<float> mLeafDistances, mNodeDistances;
414 const bool mTransformPoints;
415 size_t mClosestPointIndex;
419 template<
typename Index32LeafT>
421 std::vector<Vec3R>& instancePoints,
422 std::vector<float>& instanceDistances,
424 const std::vector<const Index32LeafT*>& leafNodes,
425 const std::vector<IndexRange>& leafRanges,
426 const std::vector<Vec4R>& leafBoundingSpheres,
427 const std::vector<Vec4R>& nodeBoundingSpheres,
429 bool transformPoints)
430 : mInstancePoints(instancePoints)
431 , mInstanceDistances(instanceDistances)
432 , mSurfacePointList(surfacePointList)
433 , mLeafNodes(leafNodes)
434 , mLeafRanges(leafRanges)
435 , mLeafBoundingSpheres(leafBoundingSpheres)
436 , mNodeBoundingSpheres(nodeBoundingSpheres)
437 , mLeafDistances(maxNodeLeafs, 0.0)
438 , mNodeDistances(leafRanges.size(), 0.0)
439 , mTransformPoints(transformPoints)
440 , mClosestPointIndex(0)
445 template<
typename Index32LeafT>
450 tbb::parallel_for(tbb::blocked_range<size_t>(0, mInstancePoints.size()), *
this);
452 (*this)(tbb::blocked_range<size_t>(0, mInstancePoints.size()));
456 template<
typename Index32LeafT>
460 typename Index32LeafT::ValueOnCIter iter;
461 const Vec3s center = mInstancePoints[index];
462 size_t& closestPointIndex =
const_cast<size_t&
>(mClosestPointIndex);
464 for (iter = leaf.cbeginValueOn(); iter; ++iter) {
466 const Vec3s& point = mSurfacePointList[iter.getValue()];
467 float tmpDist = (point - center).lengthSqr();
469 if (tmpDist < mInstanceDistances[index]) {
470 mInstanceDistances[index] = tmpDist;
471 closestPointIndex = iter.getValue();
477 template<
typename Index32LeafT>
481 if (nodeIndex >= mLeafRanges.size())
return;
483 const Vec3R& pos = mInstancePoints[pointIndex];
484 float minDist = mInstanceDistances[pointIndex];
485 size_t minDistIdx = 0;
487 bool updatedDist =
false;
489 for (
size_t i = mLeafRanges[nodeIndex].first, n = 0;
490 i < mLeafRanges[nodeIndex].second; ++i, ++n)
492 float& distToLeaf =
const_cast<float&
>(mLeafDistances[n]);
494 center[0] = mLeafBoundingSpheres[i][0];
495 center[1] = mLeafBoundingSpheres[i][1];
496 center[2] = mLeafBoundingSpheres[i][2];
497 const auto radiusSqr = mLeafBoundingSpheres[i][3];
499 distToLeaf = float(
std::max(0.0, (pos - center).lengthSqr() - radiusSqr));
501 if (distToLeaf < minDist) {
502 minDist = distToLeaf;
508 if (!updatedDist)
return;
510 evalLeaf(pointIndex, *mLeafNodes[minDistIdx]);
512 for (
size_t i = mLeafRanges[nodeIndex].first, n = 0;
513 i < mLeafRanges[nodeIndex].second; ++i, ++n)
515 if (mLeafDistances[n] < mInstanceDistances[pointIndex] && i != minDistIdx) {
516 evalLeaf(pointIndex, *mLeafNodes[i]);
522 template<
typename Index32LeafT>
527 for (
size_t n = range.begin(); n != range.end(); ++n) {
529 const Vec3R& pos = mInstancePoints[n];
530 float minDist = mInstanceDistances[n];
531 size_t minDistIdx = 0;
533 for (
size_t i = 0, I = mNodeDistances.size(); i < I; ++i) {
534 float& distToNode =
const_cast<float&
>(mNodeDistances[i]);
536 center[0] = mNodeBoundingSpheres[i][0];
537 center[1] = mNodeBoundingSpheres[i][1];
538 center[2] = mNodeBoundingSpheres[i][2];
539 const auto radiusSqr = mNodeBoundingSpheres[i][3];
541 distToNode = float(
std::max(0.0, (pos - center).lengthSqr() - radiusSqr));
543 if (distToNode < minDist) {
544 minDist = distToNode;
549 evalNode(n, minDistIdx);
551 for (
size_t i = 0, I = mNodeDistances.size(); i < I; ++i) {
552 if (mNodeDistances[i] < mInstanceDistances[n] && i != minDistIdx) {
557 mInstanceDistances[n] = std::sqrt(mInstanceDistances[n]);
559 if (mTransformPoints) mInstancePoints[n] = mSurfacePointList[mClosestPointIndex];
569 const std::vector<Vec3R>& points,
570 std::vector<float>& distances,
571 std::vector<unsigned char>& mask,
575 int index()
const {
return mIndex; }
577 inline void run(
bool threaded =
true);
581 inline void operator()(
const tbb::blocked_range<size_t>& range);
584 if (rhs.mRadius > mRadius) {
585 mRadius = rhs.mRadius;
591 const Vec4s& mSphere;
592 const std::vector<Vec3R>& mPoints;
593 std::vector<float>& mDistances;
594 std::vector<unsigned char>& mMask;
603 const std::vector<Vec3R>& points,
604 std::vector<float>& distances,
605 std::vector<unsigned char>& mask,
609 , mDistances(distances)
611 , mOverlapping(overlapping)
619 : mSphere(rhs.mSphere)
620 , mPoints(rhs.mPoints)
621 , mDistances(rhs.mDistances)
623 , mOverlapping(rhs.mOverlapping)
624 , mRadius(rhs.mRadius)
633 tbb::parallel_reduce(tbb::blocked_range<size_t>(0, mPoints.size()), *
this);
635 (*this)(tbb::blocked_range<size_t>(0, mPoints.size()));
643 for (
size_t n = range.begin(); n != range.end(); ++n) {
644 if (mMask[n])
continue;
646 pos.x() = float(mPoints[n].x()) - mSphere[0];
647 pos.y() = float(mPoints[n].y()) - mSphere[1];
648 pos.z() = float(mPoints[n].z()) - mSphere[2];
650 float dist = pos.length();
652 if (dist < mSphere[3]) {
658 mDistances[n] =
std::min(mDistances[n], (dist - mSphere[3]));
661 if (mDistances[n] > mRadius) {
662 mRadius = mDistances[n];
675 template<
typename Gr
idT,
typename InterrupterT>
679 std::vector<openvdb::Vec4s>& spheres,
686 InterrupterT* interrupter)
689 minRadius, maxRadius, isovalue, instanceCount, interrupter);
693 template<
typename Gr
idT,
typename InterrupterT>
697 std::vector<openvdb::Vec4s>& spheres,
698 const Vec2i& sphereCount,
704 InterrupterT* interrupter)
708 if (grid.empty())
return;
711 minSphereCount = sphereCount[0],
712 maxSphereCount = sphereCount[1];
713 if ((minSphereCount > maxSphereCount) || (maxSphereCount < 1)) {
715 << minSphereCount <<
") exceeds maximum count (" << maxSphereCount <<
")");
718 spheres.reserve(maxSphereCount);
720 auto gridPtr = grid.copy();
739 auto numVoxels = gridPtr->activeVoxelCount();
740 if (numVoxels < 10000) {
741 const auto scale = 1.0 /
math::Cbrt(2.0 * 10000.0 /
double(numVoxels));
742 auto scaledXform = gridPtr->transform().copy();
743 scaledXform->preScale(
scale);
748 const auto newNumVoxels = newGridPtr->activeVoxelCount();
749 if (newNumVoxels > numVoxels) {
751 << numVoxels <<
" voxel" << (numVoxels == 1 ?
"" :
"s")
752 <<
" to " << newNumVoxels <<
" voxel" << (newNumVoxels == 1 ?
"" :
"s"));
753 gridPtr = newGridPtr;
754 numVoxels = newNumVoxels;
758 const bool addNarrowBandPoints = (numVoxels < 10000);
759 int instances =
std::max(instanceCount, maxSphereCount);
761 using TreeT =
typename GridT::TreeType;
762 using BoolTreeT =
typename TreeT::template ValueConverter<bool>::Type;
763 using Int16TreeT =
typename TreeT::template ValueConverter<Int16>::Type;
765 using RandGen = std::mersenne_twister_engine<uint32_t, 32, 351, 175, 19,
766 0xccab8ee7, 11, 0xffffffff, 7, 0x31b6ab00, 15, 0xffe50000, 17, 1812433253>;
769 const TreeT& tree = gridPtr->tree();
772 std::vector<Vec3R> instancePoints;
782 interiorMaskPtr->
tree().topologyUnion(tree);
785 if (interrupter && interrupter->wasInterrupted())
return;
790 if (!addNarrowBandPoints || (minSphereCount <= 0)) {
793 auto& maskTree = interiorMaskPtr->
tree();
794 auto copyOfTree = StaticPtrCast<BoolTreeT>(maskTree.copy());
796 if (maskTree.empty()) { interiorMaskPtr->
setTree(copyOfTree); }
800 instancePoints.reserve(instances);
803 const auto scatterCount =
Index64(addNarrowBandPoints ? (instances / 2) : instances);
806 ptnAcc, scatterCount, mtRand, 1.0, interrupter);
807 scatter(*interiorMaskPtr);
810 if (interrupter && interrupter->wasInterrupted())
return;
816 if (instancePoints.size() < size_t(instances)) {
817 const Int16TreeT& signTree = csp->signTree();
818 for (
auto leafIt = signTree.cbeginLeaf(); leafIt; ++leafIt) {
819 for (
auto it = leafIt->cbeginValueOn(); it; ++it) {
820 const int flags = int(it.getValue());
824 instancePoints.push_back(transform.
indexToWorld(it.getCoord()));
826 if (instancePoints.size() == size_t(instances))
break;
828 if (instancePoints.size() == size_t(instances))
break;
832 if (interrupter && interrupter->wasInterrupted())
return;
836 std::vector<float> instanceRadius;
837 if (!csp->search(instancePoints, instanceRadius))
return;
839 float largestRadius = 0.0;
840 int largestRadiusIdx = 0;
841 for (
size_t n = 0, N = instancePoints.size(); n < N; ++n) {
842 if (instanceRadius[n] > largestRadius) {
843 largestRadius = instanceRadius[n];
844 largestRadiusIdx = int(n);
848 std::vector<unsigned char> instanceMask(instancePoints.size(), 0);
850 minRadius = float(minRadius * transform.
voxelSize()[0]);
851 maxRadius = float(maxRadius * transform.
voxelSize()[0]);
853 for (
size_t s = 0, S =
std::min(
size_t(maxSphereCount), instancePoints.size()); s < S; ++s) {
855 if (interrupter && interrupter->wasInterrupted())
return;
857 largestRadius =
std::min(maxRadius, largestRadius);
859 if ((
int(s) >= minSphereCount) && (largestRadius < minRadius))
break;
862 float(instancePoints[largestRadiusIdx].x()),
863 float(instancePoints[largestRadiusIdx].y()),
864 float(instancePoints[largestRadiusIdx].z()),
867 spheres.push_back(sphere);
868 instanceMask[largestRadiusIdx] = 1;
871 sphere, instancePoints, instanceRadius, instanceMask, overlapping);
874 largestRadius = op.
radius();
875 largestRadiusIdx = op.
index();
883 template<
typename Gr
idT>
884 template<
typename InterrupterT>
889 if (!csp->initialize(grid, isovalue, interrupter)) csp.reset();
894 template<
typename Gr
idT>
895 template<
typename InterrupterT>
898 const GridT& grid,
float isovalue, InterrupterT* interrupter)
901 using ValueT =
typename GridT::ValueType;
916 *mSignTreePt, *mIdxTreePt, mask, tree, ValueT(isovalue));
918 if (interrupter && interrupter->wasInterrupted())
return false;
922 using Int16LeafNodeType =
typename Int16TreeT::LeafNodeType;
923 using Index32LeafNodeType =
typename Index32TreeT::LeafNodeType;
925 std::vector<Int16LeafNodeType*> signFlagsLeafNodes;
926 mSignTreePt->getNodes(signFlagsLeafNodes);
928 const tbb::blocked_range<size_t> auxiliaryLeafNodeRange(0, signFlagsLeafNodes.size());
930 boost::scoped_array<Index32> leafNodeOffsets(
new Index32[signFlagsLeafNodes.size()]);
932 tbb::parallel_for(auxiliaryLeafNodeRange,
934 (signFlagsLeafNodes, leafNodeOffsets));
938 for (
size_t n = 0, N = signFlagsLeafNodes.size(); n < N; ++n) {
939 const Index32 tmp = leafNodeOffsets[n];
944 mPointListSize = size_t(pointCount);
945 mSurfacePointList.reset(
new Vec3s[mPointListSize]);
949 std::vector<Index32LeafNodeType*> pointIndexLeafNodes;
950 mIdxTreePt->getNodes(pointIndexLeafNodes);
953 mSurfacePointList.get(), tree, pointIndexLeafNodes,
954 signFlagsLeafNodes, leafNodeOffsets, transform, ValueT(isovalue)));
957 if (interrupter && interrupter->wasInterrupted())
return false;
959 Index32LeafManagerT idxLeafs(*mIdxTreePt);
961 using Index32RootNodeT =
typename Index32TreeT::RootNodeType;
962 using Index32NodeChainT =
typename Index32RootNodeT::NodeChainType;
963 static_assert(boost::mpl::size<Index32NodeChainT>::value > 1,
964 "expected tree depth greater than one");
965 using Index32InternalNodeT =
966 typename boost::mpl::at<Index32NodeChainT, boost::mpl::int_<1> >::type;
968 typename Index32TreeT::NodeCIter nIt = mIdxTreePt->cbeginNode();
969 nIt.setMinDepth(Index32TreeT::NodeCIter::LEAF_DEPTH - 1);
970 nIt.setMaxDepth(Index32TreeT::NodeCIter::LEAF_DEPTH - 1);
972 std::vector<const Index32InternalNodeT*> internalNodes;
974 const Index32InternalNodeT* node =
nullptr;
977 if (node) internalNodes.push_back(node);
980 std::vector<IndexRange>().swap(mLeafRanges);
981 mLeafRanges.resize(internalNodes.size());
983 std::vector<const Index32LeafT*>().swap(mLeafNodes);
984 mLeafNodes.reserve(idxLeafs.leafCount());
986 typename Index32InternalNodeT::ChildOnCIter leafIt;
988 for (
size_t n = 0, N = internalNodes.size(); n < N; ++n) {
990 mLeafRanges[n].first = mLeafNodes.size();
992 size_t leafCount = 0;
993 for (leafIt = internalNodes[n]->cbeginChildOn(); leafIt; ++leafIt) {
994 mLeafNodes.push_back(&(*leafIt));
998 mMaxNodeLeafs =
std::max(leafCount, mMaxNodeLeafs);
1000 mLeafRanges[n].second = mLeafNodes.size();
1003 std::vector<Vec4R>().swap(mLeafBoundingSpheres);
1004 mLeafBoundingSpheres.resize(mLeafNodes.size());
1007 mLeafBoundingSpheres, mLeafNodes, transform, mSurfacePointList);
1011 std::vector<Vec4R>().swap(mNodeBoundingSpheres);
1012 mNodeBoundingSpheres.resize(internalNodes.size());
1020 template<
typename Gr
idT>
1023 std::vector<float>& distances,
bool transformPoints)
1026 distances.resize(points.size(), std::numeric_limits<float>::infinity());
1029 mLeafNodes, mLeafRanges, mLeafBoundingSpheres, mNodeBoundingSpheres,
1030 mMaxNodeLeafs, transformPoints);
1038 template<
typename Gr
idT>
1042 return search(
const_cast<std::vector<Vec3R>&
>(points), distances,
false);
1046 template<
typename Gr
idT>
1049 std::vector<float>& distances)
1051 return search(points, distances,
true);
1058 #endif // OPENVDB_TOOLS_VOLUME_TO_MESH_HAS_BEEN_INCLUDED
float Cbrt(float x)
Return the cube root of a floating-point value.
Definition: Math.h:743
TreeType & tree()
Return a reference to this grid's tree, which might be shared with other grids.
Definition: Grid.h:919
void setTree(TreeBase::Ptr) override
Associate the given tree with this grid, in place of its existing tree.
Definition: Grid.h:1442
static T value()
Definition: Math.h:117
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
#define OPENVDB_LOG_DEBUG_RUNTIME(message)
Log a debugging message in both debug and optimized builds.
Definition: logging.h:294
Vec4< float > Vec4s
Definition: Vec4.h:586
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:230
static const Real LEVEL_SET_HALF_WIDTH
Definition: Types.h:510
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:55
Vec3< double > Vec3d
Definition: Vec3.h:689
OPENVDB_IMPORT void initialize()
Global registration of basic types.
Extract polygonal surfaces from scalar volumes.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
#define OPENVDB_LOG_WARN(message)
Log a warning message of the form 'someVar << "some text" << ...'.
Definition: logging.h:280
Implementation of morphological dilation and erosion.
Definition: Exceptions.h:40
Vec2< int32_t > Vec2i
Definition: Vec2.h:556
Tolerance for floating-point comparison.
Definition: Math.h:117
Vec3< float > Vec3s
Definition: Vec3.h:688
uint64_t Index64
Definition: Types.h:60
SharedPtr< Grid > Ptr
Definition: Grid.h:596
const TreeType & tree() const
Return a const reference to tree associated with this manager.
Definition: LeafManager.h:342
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:115
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:109
void setTransform(math::Transform::Ptr)
Associate the given transform with this grid, in place of its existing transform. ...
Definition: Grid.h:1245
Miscellaneous utility methods that operate primarily or exclusively on level set grids.
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
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:647
uint32_t Index32
Definition: Types.h:59