Loading...
Searching...
No Matches
LevelSetMeasure.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
//
/// @author Ken Museth
///
/// @file LevelSetMeasure.h
#ifndef OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
#define OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
#include <openvdb/Types.h>
#include <openvdb/Grid.h>
#include <openvdb/tree/LeafManager.h>
#include <openvdb/tree/ValueAccessor.h>
#include <openvdb/math/Math.h>
#include <openvdb/math/FiniteDifference.h>
#include <openvdb/math/Operators.h>
#include <openvdb/math/Stencils.h>
#include <openvdb/util/NullInterrupter.h>
#include <openvdb/thread/Threading.h>
#include <openvdb/openvdb.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_sort.h>
#include <tbb/parallel_invoke.h>
#include <type_traits>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace tools {
/// @brief Return the surface area of a narrow-band level set.
///
/// @param grid a scalar, floating-point grid with one or more disjoint,
/// closed level set surfaces
/// @param useWorldSpace if true the area is computed in
/// world space units, else in voxel units.
///
/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
template<class GridType>
Real
levelSetArea(const GridType& grid, bool useWorldSpace = true);
/// @brief Return the volume of a narrow-band level set surface.
///
/// @param grid a scalar, floating-point grid with one or more disjoint,
/// closed level set surfaces
/// @param useWorldSpace if true the volume is computed in
/// world space units, else in voxel units.
///
/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
template<class GridType>
Real
levelSetVolume(const GridType& grid, bool useWorldSpace = true);
/// @brief Return the Euler Characteristics of a narrow-band level set surface (possibly disconnected).
///
/// @param grid a scalar, floating-point grid with one or more disjoint,
/// closed level set surfaces
///
/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
template<class GridType>
int
levelSetEulerCharacteristic(const GridType& grid);
/// @brief Return the genus of a narrow-band level set surface.
///
/// @param grid a scalar, floating-point grid with one or more disjoint,
/// closed level set surfaces
/// @warning The genus is only well defined for a single connected surface
///
/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
template<class GridType>
int
levelSetGenus(const GridType& grid);
////////////////////////////////////////////////////////////////////////////////////////
/// @brief Smeared-out and continuous Dirac Delta function.
template<typename RealT>
class DiracDelta
{
public:
// eps is the half-width of the dirac delta function in units of phi
DiracDelta(RealT eps) : mC(0.5/eps), mD(2*math::pi<RealT>()*mC), mE(eps) {}
// values of the dirac delta function are in units of one over the units of phi
inline RealT operator()(RealT phi) const { return math::Abs(phi) > mE ? 0 : mC*(1+cos(mD*phi)); }
private:
const RealT mC, mD, mE;
};// DiracDelta functor
/// @brief Multi-threaded computation of surface area, volume and
/// average mean-curvature for narrow band level sets.
///
/// @details To reduce the risk of round-off errors (primarily due to
/// catastrophic cancellation) and guarantee determinism during
/// multi-threading this class is implemented using parallel_for, and
/// delayed reduction of a sorted list.
template<typename GridT, typename InterruptT = util::NullInterrupter>
class LevelSetMeasure
{
public:
using GridType = GridT;
using TreeType = typename GridType::TreeType;
using ValueType = typename TreeType::ValueType;
using ManagerType = typename tree::LeafManager<const TreeType>;
static_assert(std::is_floating_point<ValueType>::value,
"level set measure is supported only for scalar, floating-point grids");
/// @brief Main constructor from a grid
/// @param grid The level set to be measured.
/// @param interrupt Optional interrupter.
/// @throw RuntimeError if the grid is not a level set or if it's empty.
LevelSetMeasure(const GridType& grid, InterruptT* interrupt = nullptr);
/// @brief Re-initialize using the specified grid.
/// @param grid The level set to be measured.
/// @throw RuntimeError if the grid is not a level set or if it's empty.
void init(const GridType& grid);
/// @brief Destructor
virtual ~LevelSetMeasure() {}
/// @return the grain-size used for multi-threading
int getGrainSize() const { return mGrainSize; }
/// @brief Set the grain-size used for multi-threading.
/// @note A grain size of 0 or less disables multi-threading!
void setGrainSize(int grainsize) { mGrainSize = grainsize; }
/// @brief Compute the surface area of the level set.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real area(bool useWorldUnits = true);
/// @brief Compute the volume of the level set surface.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real volume(bool useWorldUnits = true);
/// @brief Compute the total mean curvature of the level set surface.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real totMeanCurvature(bool useWorldUnits = true);
/// @brief Compute the total gaussian curvature of the level set surface.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real totGaussianCurvature(bool useWorldUnits = true);
/// @brief Compute the average mean curvature of the level set surface.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real avgMeanCurvature(bool useWorldUnits = true) {return this->totMeanCurvature(useWorldUnits) / this->area(useWorldUnits);}
/// @brief Compute the average gaussian curvature of the level set surface.
/// @param useWorldUnits Specifies if the result is in world or voxel units.
/// @note Performs internal caching so only the initial call incurs actual computation.
Real avgGaussianCurvature(bool useWorldUnits = true) {return this->totGaussianCurvature(useWorldUnits) / this->area(useWorldUnits); }
/// @brief Compute the Euler characteristic of the level set surface.
/// @note Performs internal caching so only the initial call incurs actual computation.
int eulerCharacteristic();
/// @brief Compute the genus of the level set surface.
/// @warning The genus is only well defined for a single connected surface.
/// @note Performs internal caching so only the initial call incurs actual computation.
int genus() { return 1 - this->eulerCharacteristic()/2;}
private:
using LeafT = typename TreeType::LeafNodeType;
using VoxelCIterT = typename LeafT::ValueOnCIter;
using LeafRange = typename ManagerType::LeafRange;
using LeafIterT = typename LeafRange::Iterator;
using ManagerPtr = std::unique_ptr<ManagerType>;
using BufferPtr = std::unique_ptr<double[]>;
// disallow copy construction and copy by assignment!
LevelSetMeasure(const LevelSetMeasure&);// not implemented
LevelSetMeasure& operator=(const LevelSetMeasure&);// not implemented
const GridType *mGrid;
ManagerPtr mLeafs;
BufferPtr mBuffer;
InterruptT *mInterrupter;
double mDx, mArea, mVolume, mTotMeanCurvature, mTotGausCurvature;
int mGrainSize;
bool mUpdateArea, mUpdateCurvature;
// @brief Return false if the process was interrupted
bool checkInterrupter();
struct MeasureArea
{
MeasureArea(LevelSetMeasure* parent) : mParent(parent), mStencil(*mParent->mGrid)
{
if (parent->mInterrupter) parent->mInterrupter->start("Measuring area and volume of level set");
if (parent->mGrainSize>0) {
tbb::parallel_for(parent->mLeafs->leafRange(parent->mGrainSize), *this);
} else {
(*this)(parent->mLeafs->leafRange());
}
tbb::parallel_invoke([&](){parent->mArea = parent->reduce(0);},
[&](){parent->mVolume = parent->reduce(1)/3.0;});
parent->mUpdateArea = false;
if (parent->mInterrupter) parent->mInterrupter->end();
}
MeasureArea(const MeasureArea& other) : mParent(other.mParent), mStencil(*mParent->mGrid) {}
void operator()(const LeafRange& range) const;
LevelSetMeasure* mParent;
mutable math::GradStencil<GridT, false> mStencil;
};// MeasureArea
struct MeasureCurvatures
{
MeasureCurvatures(LevelSetMeasure* parent) : mParent(parent), mStencil(*mParent->mGrid)
{
if (parent->mInterrupter) parent->mInterrupter->start("Measuring curvatures of level set");
if (parent->mGrainSize>0) {
tbb::parallel_for(parent->mLeafs->leafRange(parent->mGrainSize), *this);
} else {
(*this)(parent->mLeafs->leafRange());
}
tbb::parallel_invoke([&](){parent->mTotMeanCurvature = parent->reduce(0);},
[&](){parent->mTotGausCurvature = parent->reduce(1);});
parent->mUpdateCurvature = false;
if (parent->mInterrupter) parent->mInterrupter->end();
}
MeasureCurvatures(const MeasureCurvatures& other) : mParent(other.mParent), mStencil(*mParent->mGrid) {}
void operator()(const LeafRange& range) const;
LevelSetMeasure* mParent;
mutable math::CurvatureStencil<GridT, false> mStencil;
};// MeasureCurvatures
double reduce(int offset)
{
double *first = mBuffer.get() + offset*mLeafs->leafCount(), *last = first + mLeafs->leafCount();
tbb::parallel_sort(first, last);// mitigates catastrophic cancellation
Real sum = 0.0;
while(first != last) sum += *first++;
return sum;
}
}; // end of LevelSetMeasure class
template<typename GridT, typename InterruptT>
inline
LevelSetMeasure<GridT, InterruptT>::LevelSetMeasure(const GridType& grid, InterruptT* interrupt)
: mInterrupter(interrupt)
, mGrainSize(1)
{
this->init(grid);
}
template<typename GridT, typename InterruptT>
inline void
LevelSetMeasure<GridT, InterruptT>::init(const GridType& grid)
{
if (!grid.hasUniformVoxels()) {
OPENVDB_THROW(RuntimeError,
"The transform must have uniform scale for the LevelSetMeasure to function");
}
if (grid.getGridClass() != GRID_LEVEL_SET) {
OPENVDB_THROW(RuntimeError,
"LevelSetMeasure only supports level sets;"
" try setting the grid class to \"level set\"");
}
if (grid.empty()) {
OPENVDB_THROW(RuntimeError,
"LevelSetMeasure does not support empty grids;");
}
mGrid = &grid;
mDx = grid.voxelSize()[0];
mLeafs = std::make_unique<ManagerType>(mGrid->tree());
mBuffer = std::make_unique<double[]>(2*mLeafs->leafCount());
mUpdateArea = mUpdateCurvature = true;
}
template<typename GridT, typename InterruptT>
inline Real
LevelSetMeasure<GridT, InterruptT>::area(bool useWorldUnits)
{
if (mUpdateArea) {MeasureArea m(this);};
double area = mArea;
if (useWorldUnits) area *= math::Pow2(mDx);
return area;
}
template<typename GridT, typename InterruptT>
inline Real
LevelSetMeasure<GridT, InterruptT>::volume(bool useWorldUnits)
{
if (mUpdateArea) {MeasureArea m(this);};
double volume = mVolume;
if (useWorldUnits) volume *= math::Pow3(mDx) ;
return volume;
}
template<typename GridT, typename InterruptT>
inline Real
LevelSetMeasure<GridT, InterruptT>::totMeanCurvature(bool useWorldUnits)
{
if (mUpdateCurvature) {MeasureCurvatures m(this);};
return mTotMeanCurvature * (useWorldUnits ? mDx : 1);
}
template<typename GridT, typename InterruptT>
inline Real
LevelSetMeasure<GridT, InterruptT>::totGaussianCurvature(bool)
{
if (mUpdateCurvature) {MeasureCurvatures m(this);};
return mTotGausCurvature;
}
template<typename GridT, typename InterruptT>
inline int
LevelSetMeasure<GridT, InterruptT>::eulerCharacteristic()
{
const Real x = this->totGaussianCurvature(true) / (2.0*math::pi<Real>());
return int(math::Round( x ));
}
///////////////////////// PRIVATE METHODS //////////////////////
template<typename GridT, typename InterruptT>
inline bool
LevelSetMeasure<GridT, InterruptT>::checkInterrupter()
{
if (util::wasInterrupted(mInterrupter)) {
thread::cancelGroupExecution();
return false;
}
return true;
}
template<typename GridT, typename InterruptT>
inline void
LevelSetMeasure<GridT, InterruptT>::
MeasureArea::operator()(const LeafRange& range) const
{
using Vec3T = math::Vec3<ValueType>;
// computations are performed in index space where dV = 1
mParent->checkInterrupter();
const Real invDx = 1.0/mParent->mDx;
const DiracDelta<Real> DD(1.5);// dirac delta function is 3 voxel units wide
const size_t leafCount = mParent->mLeafs->leafCount();
for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
Real sumA = 0, sumV = 0;//reduce risk of catastrophic cancellation
for (VoxelCIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
const Real dd = DD(invDx * (*voxelIter));
if (dd > 0.0) {
mStencil.moveTo(voxelIter);
const Coord& p = mStencil.getCenterCoord();// in voxel units
const Vec3T g = mStencil.gradient();// in world units
sumA += dd*g.length();// \delta(\phi)*|\nabla\phi|
sumV += dd*(g[0]*Real(p[0]) + g[1]*Real(p[1]) + g[2]*Real(p[2]));// \delta(\phi)\vec{x}\cdot\nabla\phi
}
}
double* ptr = mParent->mBuffer.get() + leafIter.pos();
*ptr = sumA;
ptr += leafCount;
*ptr = sumV;
}
}
template<typename GridT, typename InterruptT>
inline void
LevelSetMeasure<GridT, InterruptT>::
MeasureCurvatures::operator()(const LeafRange& range) const
{
using Vec3T = math::Vec3<ValueType>;
// computations are performed in index space where dV = 1
mParent->checkInterrupter();
const Real dx = mParent->mDx, dx2=dx*dx, invDx = 1.0/dx;
const DiracDelta<Real> DD(1.5);// dirac delta function is 3 voxel units wide
ValueType mean, gauss;
const size_t leafCount = mParent->mLeafs->leafCount();
for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
Real sumM = 0, sumG = 0;//reduce risk of catastrophic cancellation
for (VoxelCIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
const Real dd = DD(invDx * (*voxelIter));
if (dd > 0.0) {
mStencil.moveTo(voxelIter);
const Vec3T g = mStencil.gradient();
const Real dA = dd*g.length();// \delta(\phi)*\delta(\phi)
mStencil.curvatures(mean, gauss);
sumM += dA*mean*dx;// \delta(\phi)*\delta(\phi)*MeanCurvature
sumG += dA*gauss*dx2;// \delta(\phi)*\delta(\phi)*GaussCurvature
}
}
double* ptr = mParent->mBuffer.get() + leafIter.pos();
*ptr = sumM;
ptr += leafCount;
*ptr = sumG;
}
}
////////////////////////////////////////
//{
/// @cond OPENVDB_DOCS_INTERNAL
template<class GridT>
inline
typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, Real>::type
doLevelSetArea(const GridT& grid, bool useWorldUnits)
{
LevelSetMeasure<GridT> m(grid);
return m.area(useWorldUnits);
}
template<class GridT>
inline
typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, Real>::type
doLevelSetArea(const GridT&, bool)
{
OPENVDB_THROW(TypeError,
"level set area is supported only for scalar, floating-point grids");
}
/// @endcond
//}
template<class GridT>
Real
levelSetArea(const GridT& grid, bool useWorldUnits)
{
return doLevelSetArea<GridT>(grid, useWorldUnits);
}
////////////////////////////////////////
//{
/// @cond OPENVDB_DOCS_INTERNAL
template<class GridT>
inline
typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, Real>::type
doLevelSetVolume(const GridT& grid, bool useWorldUnits)
{
LevelSetMeasure<GridT> m(grid);
return m.volume(useWorldUnits);
}
template<class GridT>
inline
typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, Real>::type
doLevelSetVolume(const GridT&, bool)
{
OPENVDB_THROW(TypeError,
"level set volume is supported only for scalar, floating-point grids");
}
/// @endcond
//}
template<class GridT>
Real
levelSetVolume(const GridT& grid, bool useWorldUnits)
{
return doLevelSetVolume<GridT>(grid, useWorldUnits);
}
////////////////////////////////////////
//{
/// @cond OPENVDB_DOCS_INTERNAL
template<class GridT>
inline
typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
doLevelSetEulerCharacteristic(const GridT& grid)
{
LevelSetMeasure<GridT> m(grid);
return m.eulerCharacteristic();
}
template<class GridT>
inline
typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, int>::type
doLevelSetEulerCharacteristic(const GridT&)
{
OPENVDB_THROW(TypeError,
"level set euler characteristic is supported only for scalar, floating-point grids");
}
/// @endcond
//}
template<class GridT>
int
levelSetEulerCharacteristic(const GridT& grid)
{
return doLevelSetEulerCharacteristic(grid);
}
////////////////////////////////////////
//{
/// @cond OPENVDB_DOCS_INTERNAL
template<class GridT>
inline
typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
doLevelSetEuler(const GridT& grid)
{
LevelSetMeasure<GridT> m(grid);
return m.eulerCharacteristics();
}
template<class GridT>
inline
typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
doLevelSetGenus(const GridT& grid)
{
LevelSetMeasure<GridT> m(grid);
return m.genus();
}
template<class GridT>
inline
typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, int>::type
doLevelSetGenus(const GridT&)
{
OPENVDB_THROW(TypeError,
"level set genus is supported only for scalar, floating-point grids");
}
/// @endcond
//}
template<class GridT>
int
levelSetGenus(const GridT& grid)
{
return doLevelSetGenus(grid);
}
////////////////////////////////////////
// Explicit Template Instantiation
#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
#ifdef OPENVDB_INSTANTIATE_LEVELSETMEASURE
#include <openvdb/util/ExplicitInstantiation.h>
#endif
#define _FUNCTION(TreeT) \
Real levelSetArea(const Grid<TreeT>&, bool)
OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
#undef _FUNCTION
#define _FUNCTION(TreeT) \
Real levelSetVolume(const Grid<TreeT>&, bool)
OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
#undef _FUNCTION
#define _FUNCTION(TreeT) \
int levelSetEulerCharacteristic(const Grid<TreeT>&)
OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
#undef _FUNCTION
#define _FUNCTION(TreeT) \
int levelSetGenus(const Grid<TreeT>&)
OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
#undef _FUNCTION
OPENVDB_INSTANTIATE_CLASS LevelSetMeasure<FloatGrid, util::NullInterrupter>;
OPENVDB_INSTANTIATE_CLASS LevelSetMeasure<DoubleGrid, util::NullInterrupter>;
#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
} // namespace tools
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
ExplicitInstantiation.h
FiniteDifference.h
Grid.h
LeafManager.h
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
NullInterrupter.h
Operators.h
ValueAccessor.h
openvdb::v10_0::RuntimeError
Definition Exceptions.h:63
openvdb::v10_0::TypeError
Definition Exceptions.h:64
openvdb::v10_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
openvdb::v10_0::math::GradStencil
Definition Stencils.h:1233
openvdb::v10_0::math::Vec3
Definition Vec3.h:24
openvdb::v10_0::tools::DiracDelta
Smeared-out and continuous Dirac Delta function.
Definition LevelSetMeasure.h:84
openvdb::v10_0::tools::DiracDelta::DiracDelta
DiracDelta(RealT eps)
Definition LevelSetMeasure.h:87
openvdb::v10_0::tools::DiracDelta::operator()
RealT operator()(RealT phi) const
Definition LevelSetMeasure.h:89
openvdb::v10_0::tools::LevelSetMeasure
Multi-threaded computation of surface area, volume and average mean-curvature for narrow band level s...
Definition LevelSetMeasure.h:104
openvdb::v10_0::tools::LevelSetMeasure::genus
int genus()
Compute the genus of the level set surface.
Definition LevelSetMeasure.h:172
openvdb::v10_0::tools::LevelSetMeasure::avgGaussianCurvature
Real avgGaussianCurvature(bool useWorldUnits=true)
Compute the average gaussian curvature of the level set surface.
Definition LevelSetMeasure.h:163
openvdb::v10_0::tools::LevelSetMeasure::eulerCharacteristic
int eulerCharacteristic()
Compute the Euler characteristic of the level set surface.
Definition LevelSetMeasure.h:323
openvdb::v10_0::tools::LevelSetMeasure::~LevelSetMeasure
virtual ~LevelSetMeasure()
Destructor.
Definition LevelSetMeasure.h:126
openvdb::v10_0::tools::LevelSetMeasure::init
void init(const GridType &grid)
Re-initialize using the specified grid.
Definition LevelSetMeasure.h:263
openvdb::v10_0::tools::LevelSetMeasure::ValueType
typename TreeType::ValueType ValueType
Definition LevelSetMeasure.h:108
openvdb::v10_0::tools::LevelSetMeasure::LevelSetMeasure
LevelSetMeasure(const GridType &grid, InterruptT *interrupt=nullptr)
Main constructor from a grid.
Definition LevelSetMeasure.h:254
openvdb::v10_0::tools::LevelSetMeasure::ManagerType
typename tree::LeafManager< const TreeType > ManagerType
Definition LevelSetMeasure.h:109
openvdb::v10_0::tools::LevelSetMeasure::totGaussianCurvature
Real totGaussianCurvature(bool useWorldUnits=true)
Compute the total gaussian curvature of the level set surface.
Definition LevelSetMeasure.h:315
openvdb::v10_0::tools::LevelSetMeasure::setGrainSize
void setGrainSize(int grainsize)
Set the grain-size used for multi-threading.
Definition LevelSetMeasure.h:133
openvdb::v10_0::tools::LevelSetMeasure::getGrainSize
int getGrainSize() const
Definition LevelSetMeasure.h:129
openvdb::v10_0::tools::LevelSetMeasure::TreeType
typename GridType::TreeType TreeType
Definition LevelSetMeasure.h:107
openvdb::v10_0::tools::LevelSetMeasure::area
Real area(bool useWorldUnits=true)
Compute the surface area of the level set.
Definition LevelSetMeasure.h:287
openvdb::v10_0::tools::LevelSetMeasure::volume
Real volume(bool useWorldUnits=true)
Compute the volume of the level set surface.
Definition LevelSetMeasure.h:297
openvdb::v10_0::tools::LevelSetMeasure::avgMeanCurvature
Real avgMeanCurvature(bool useWorldUnits=true)
Compute the average mean curvature of the level set surface.
Definition LevelSetMeasure.h:158
openvdb::v10_0::tools::LevelSetMeasure::totMeanCurvature
Real totMeanCurvature(bool useWorldUnits=true)
Compute the total mean curvature of the level set surface.
Definition LevelSetMeasure.h:307
openvdb::v10_0::tools::LevelSetMeasure::GridType
GridT GridType
Definition LevelSetMeasure.h:106
openvdb::v10_0::tree::LeafManager
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:85
nanovdb::reduce
T reduce(RangeT range, const T &identity, const FuncT &func, const JoinT &join)
Definition Reduce.h:42
openvdb::v10_0::math
Definition Types.h:28
openvdb::v10_0::math::pi
constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition Math.h:119
openvdb::v10_0::math::Abs
Coord Abs(const Coord &xyz)
Definition Coord.h:515
openvdb::v10_0::math::Round
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
openvdb::v10_0::math::Pow3
Type Pow3(Type x)
Return x3.
Definition Math.h:552
openvdb::v10_0::math::Pow2
Type Pow2(Type x)
Return x2.
Definition Math.h:548
openvdb::v10_0::tools::levelSetArea
Real levelSetArea(const GridType &grid, bool useWorldSpace=true)
Return the surface area of a narrow-band level set.
openvdb::v10_0::tools::levelSetGenus
int levelSetGenus(const GridType &grid)
Return the genus of a narrow-band level set surface.
openvdb::v10_0::tools::levelSetEulerCharacteristic
int levelSetEulerCharacteristic(const GridType &grid)
Return the Euler Characteristics of a narrow-band level set surface (possibly disconnected).
openvdb::v10_0::tools::levelSetVolume
Real levelSetVolume(const GridType &grid, bool useWorldSpace=true)
Return the volume of a narrow-band level set surface.
openvdb::v10_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
openvdb::v10_0::Real
double Real
Definition Types.h:60
openvdb::v10_0::GRID_LEVEL_SET
@ GRID_LEVEL_SET
Definition Types.h:416
openvdb
Definition Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Types.h
Stencils.h
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
openvdb.h
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212
OPENVDB_INSTANTIATE_CLASS
#define OPENVDB_INSTANTIATE_CLASS
Definition version.h.in:153
OPENVDB_REAL_TREE_INSTANTIATE
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition version.h.in:157