11#ifndef OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED 
   12#define OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED 
   20#include <openvdb/thread/Threading.h> 
   23#include <tbb/blocked_range.h> 
   24#include <tbb/parallel_reduce.h> 
   65template<
class Gr
idType>
 
   89template<
class Gr
idType>
 
  101template<
class Gr
idType>
 
  104    std::vector<typename GridType::ValueType>& values, 
size_t numValues);
 
  110template<
typename Gr
idT, 
typename TreeIterT = 
typename Gr
idT::ValueOnCIter>
 
  116        typename TreeIterT::NodeT, 
typename TreeIterT::ValueIterT>::template
 
  117            NodeConverter<typename GridT::TreeType::LeafNodeType>::Type;
 
  127    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  130        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  135    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  141    std::string 
str()
 const { 
return "NaN"; }
 
 
  148template <
typename GridT,
 
  149          typename TreeIterT = 
typename GridT::ValueOnCIter>
 
  155        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  156            typename GridT::TreeType::LeafNodeType>
::Type;
 
  166    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  169        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  174    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  180    std::string 
str()
 const { 
return "infinite"; }
 
 
  186template <
typename GridT,
 
  187          typename TreeIterT = 
typename GridT::ValueOnCIter>
 
  193        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  194            typename GridT::TreeType::LeafNodeType>
::Type;
 
  204    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  206        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  211    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  217    std::string 
str()
 const { 
return "not finite"; }
 
 
  224template <
typename GridT,
 
  225          typename TreeIterT = 
typename GridT::ValueOffCIter>
 
  231        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  232            typename GridT::TreeType::LeafNodeType>
::Type;
 
  250    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  253        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  258    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  266        std::ostringstream ss;
 
  267        ss << 
"not equal to +/-"<<
absVal<<
" with a tolerance of "<<
tolVal;
 
 
 
  277template <
typename GridT,
 
  278          bool MinInclusive = 
true,
 
  279          bool MaxInclusive = 
true,
 
  280          typename TreeIterT = 
typename GridT::ValueOnCIter>
 
  286        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  287            typename GridT::TreeType::LeafNodeType>
::Type;
 
  306    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  308        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  313    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  321        std::ostringstream ss;
 
  322        ss << 
"outside the value range " << (MinInclusive ? 
"[" : 
"]")
 
  323           << 
minVal << 
"," << 
maxVal    << (MaxInclusive ? 
"]" : 
"[");
 
 
 
  333template <
typename GridT,
 
  334          typename TreeIterT = 
typename GridT::ValueOnCIter>
 
  340        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  341            typename GridT::TreeType::LeafNodeType>
::Type;
 
  351    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  353        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  358    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  366        std::ostringstream ss;
 
  367        ss << 
"smaller than "<<
minVal;
 
 
 
  377template <
typename GridT,
 
  378          typename TreeIterT = 
typename GridT::ValueOnCIter>
 
  384        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  385            typename GridT::TreeType::LeafNodeType>
::Type;
 
  395    inline typename std::enable_if<VecTraits<T>::IsVec, 
bool>::type
 
  397        for (
int i=0; i<VecTraits<T>::Size; ++i) 
if ((*
this)(v[i])) 
return true;
 
 
  402    bool operator()(
const TreeIterT  &iter)
 const { 
return (*
this)(*iter); }
 
  410        std::ostringstream ss;
 
  411        ss << 
"larger than "<<
maxVal;
 
 
 
  425template<
typename GridT,
 
  426         typename TreeIterT = 
typename GridT::ValueOnCIter,
 
  431    static_assert(std::is_floating_point<ValueType>::value,
 
  432        "openvdb::tools::CheckNormGrad requires a scalar, floating-point grid");
 
  435        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  436            typename GridT::TreeType::LeafNodeType>
::Type;
 
  437    using AccT = 
typename GridT::ConstAccessor;
 
  441        : 
acc(grid.getConstAccessor())
 
  446        if ( !grid.hasUniformVoxels() ) {
 
  447            OPENVDB_THROW(ValueError, 
"CheckNormGrad: The transform must have uniform scale");
 
 
  473        const Coord ijk = iter.getCoord();
 
 
  480        std::ostringstream ss;
 
 
 
  495template<
typename GridT,
 
  496         typename TreeIterT = 
typename GridT::ValueOnCIter,
 
  501    static_assert(std::is_floating_point<ValueType>::value,
 
  502        "openvdb::tools::CheckEikonal requires a scalar, floating-point grid");
 
  505        typename TreeIterT::ValueIterT> ::template NodeConverter<
 
  506            typename GridT::TreeType::LeafNodeType>
::Type;
 
  512        if ( !grid.hasUniformVoxels() ) {
 
  513            OPENVDB_THROW(ValueError, 
"CheckEikonal: The transform must have uniform scale");
 
 
  537        if (!
stencil.zeroCrossing()) 
return false;
 
  538        return (*
this)(
stencil.normSqGrad());
 
 
  544        std::ostringstream ss;
 
  545        ss << 
"outside the range of NormGrad ["<<
minVal<<
","<<
maxVal<<
"]";
 
 
 
  556template<
typename GridT,
 
  557         typename TreeIterT = 
typename GridT::ValueOnCIter,
 
  563    static_assert(std::is_floating_point<ElementType>::value,
 
  564        "openvdb::tools::CheckDivergence requires a floating-point vector grid");
 
  567        typename TreeIterT::ValueIterT>::template NodeConverter<
 
  568            typename GridT::TreeType::LeafNodeType>
::Type;
 
  569    using AccT = 
typename GridT::ConstAccessor;
 
  575        : 
acc(grid.getConstAccessor())
 
  580        if ( !grid.hasUniformVoxels() ) {
 
  581            OPENVDB_THROW(ValueError, 
"CheckDivergence: The transform must have uniform scale");
 
 
  598        const Coord ijk = iter.getCoord();
 
 
  605        std::ostringstream ss;
 
  606        ss << 
"outside the range of divergence ["<<
minVal<<
","<<
maxVal<<
"]";
 
 
 
  618template <
typename Gr
idT>
 
  622    using MaskType = 
typename GridT::template ValueConverter<bool>::Type;
 
  626        mMask->setTransform(
grid.transformPtr()->copy());
 
 
  629    template <
typename CheckT>
 
  631                      bool updateMask = 
false,
 
  632                      bool checkVoxels = 
true,
 
  633                      bool checkTiles = 
true,
 
  634                      bool checkBackground = 
true)
 
  636        typename MaskType::TreeType* 
mask = updateMask ? &(mMask->tree()) : 
nullptr;
 
  637        CheckValues<CheckT> cc(
mask, mGrid, 
check);
 
  638        std::ostringstream ss;
 
  639        if (checkBackground) ss << cc.checkBackground();
 
  640        if (checkTiles)      ss << cc.checkTiles();
 
  641        if (checkVoxels)     ss << cc.checkVoxels();
 
 
  650    typename MaskType::ConstPtr 
mask()
 const { 
return mMask; }
 
  651    typename MaskType::Ptr 
mask() { 
return mMask; }
 
  664    const GridT& 
grid()
 const { 
return *mGrid; }
 
  675    typename MaskType::Ptr mMask;
 
  679    template <
typename CheckT>
 
  682        using MaskT = 
typename MaskType::TreeType;
 
  683        using LeafT = 
typename GridT::TreeType::LeafNodeType;
 
  685        const bool      mOwnsMask;
 
  691        CheckValues(MaskT* mask, 
const GridT* grid, 
const CheckT& check)
 
  699        CheckValues(CheckValues& other, tbb::split)
 
  701            , mMask(other.mMask ? new MaskT() : nullptr)
 
  703            , mCheck(other.mCheck)
 
  707        ~CheckValues() { 
if (mOwnsMask) 
delete mMask; }
 
  709        std::string checkBackground()
 
  711            std::ostringstream ss;
 
  712            if (mCheck(mGrid->background())) {
 
  714                ss << 
"Background is " + mCheck.str() << std::endl;
 
  719        std::string checkTiles()
 
  721            std::ostringstream ss;
 
  723            typename CheckT::TileIterT i(mGrid->tree());
 
  724            for (i.setMaxDepth(GridT::TreeType::RootNodeType::LEVEL - 1); i; ++i) {
 
  727                    if (mMask) mMask->fill(i.getBoundingBox(), 
true, 
true);
 
  730            if (
const Index64 m = mCount - n) {
 
  731                ss << m << 
" tile" << (m==1 ? 
" is " : 
"s are ") + mCheck.str() << std::endl;
 
  736        std::string checkVoxels()
 
  738            std::ostringstream ss;
 
  739            LeafManagerT leafs(mGrid->tree());
 
  741            tbb::parallel_reduce(leafs.leafRange(), *
this);
 
  742            if (
const Index64 m = mCount - n) {
 
  743                ss << m << 
" voxel" << (m==1 ? 
" is " : 
"s are ") + mCheck.str() << std::endl;
 
  748        void operator()(
const typename LeafManagerT::LeafRange& r)
 
  750            using VoxelIterT = 
typename CheckT::VoxelIterT;
 
  752                for (
typename LeafManagerT::LeafRange::Iterator i=r.begin(); i; ++i) {
 
  753                    typename MaskT::LeafNodeType* maskLeaf = 
nullptr;
 
  754                    for (VoxelIterT j = tree::IterTraits<LeafT, VoxelIterT>::begin(*i); j; ++j) {
 
  757                            if (maskLeaf == 
nullptr) maskLeaf = mMask->touchLeaf(j.getCoord());
 
  758                            maskLeaf->setValueOn(j.pos(), 
true);
 
  763                for (
typename LeafManagerT::LeafRange::Iterator i=r.begin(); i; ++i) {
 
  764                    for (VoxelIterT j = tree::IterTraits<LeafT, VoxelIterT>::begin(*i); j; ++j) {
 
  765                        if (mCheck(j)) ++mCount;
 
  770        void join(
const CheckValues& other)
 
  773            mCount += other.mCount;
 
 
  785template<
class Gr
idType>
 
  790    using MaskType = 
typename GridType::template ValueConverter<bool>::Type;
 
  798    typename MaskType::ConstPtr 
mask()
 const { 
return mDiagnose.mask(); }
 
  799    typename MaskType::Ptr 
mask() { 
return mDiagnose.mask(); }
 
  812    const GridType& 
grid()
 const { 
return mDiagnose.grid(); }
 
  822        static const bool test = std::is_floating_point<ValueType>::value;
 
  823        return test ? 
"" : 
"Value type is not floating point\n";
 
 
  831        const bool test = mDiagnose.grid().getGridClass() == 
GRID_LEVEL_SET;
 
  832        return test ? 
"" : 
"Class type is not \"GRID_LEVEL_SET\"\n";
 
 
  840        return mDiagnose.grid().hasUniformVoxels() ? 
"" : 
"Does not have uniform voxels\n";
 
 
  849        const Real w = mDiagnose.grid().background() / mDiagnose.grid().voxelSize()[0];
 
  851            std::ostringstream ss;
 
  852            ss << 
"The background value ("<< mDiagnose.grid().background()<<
") is less than " 
  853               << halfWidth << 
" voxel units\n";
 
 
  864        const bool test = mDiagnose.grid().tree().hasActiveTiles();
 
  865        return test ? 
"Has active tile values\n" : 
"";
 
 
  874        return mDiagnose.check(c, updateMask, 
true, 
true, 
true);
 
 
  882        const ValueType& background = mDiagnose.grid().background();
 
  884        return mDiagnose.check(c, updateMask, 
true, 
false, 
false);
 
 
  893        const ValueType& background = mDiagnose.grid().background();
 
  895        return mDiagnose.check(c, updateMask, 
true, 
true, 
false);
 
 
  905        return mDiagnose.check(c, updateMask, 
true, 
false, 
false);
 
 
  925    std::string 
check(
size_t n=9, 
bool updateMask = 
false)
 
  931        if (str.empty() && n>4) str = this->
checkTiles();
 
  932        if (str.empty() && n>5) str = this->
checkFinite(updateMask);
 
  933        if (str.empty() && n>6) str = this->
checkRange(updateMask);
 
  935        if (str.empty() && n>8) str = this->
checkEikonal(updateMask);
 
 
 
  948template<
class Gr
idType>
 
  953    return c.
check(n, 
false);
 
 
  961template<
class Gr
idType>
 
  966    using MaskType = 
typename GridType::template ValueConverter<bool>::Type;
 
  974    typename MaskType::ConstPtr 
mask()
 const { 
return mDiagnose.mask(); }
 
  975    typename MaskType::Ptr 
mask() { 
return mDiagnose.mask(); }
 
  988    const GridType& 
grid()
 const { 
return mDiagnose.grid(); }
 
  998        static const bool test = std::is_floating_point<ValueType>::value;
 
  999        return test ? 
"" : 
"Value type is not floating point";
 
 
 1008        return test ? 
"" : 
"Class type is not \"GRID_LEVEL_SET\"";
 
 
 1017            std::ostringstream ss;
 
 1018            ss << 
"The background value ("<< mDiagnose.grid().background()<<
") is not zero";
 
 
 1030        return mDiagnose.check(c, updateMask, 
true, 
true, 
true);
 
 
 1039        return mDiagnose.check(c, updateMask, 
true, 
true, 
true);
 
 
 1049        return mDiagnose.check(c, updateMask, 
true, 
true, 
false);
 
 
 1064    std::string 
check(
size_t n=6, 
bool updateMask = 
false)
 
 1069        if (str.empty() && n>3) str = this->
checkFinite(updateMask);
 
 1071        if (str.empty() && n>5) str = this->
checkRange(updateMask);
 
 
 
 1084template<
class Gr
idType>
 
 1089    return c.
check(n, 
false);
 
 
 1099namespace diagnostics_internal {
 
 1102template<
typename TreeType>
 
 1103class InactiveVoxelValues
 
 1107    using ValueType = 
typename TreeType::ValueType;
 
 1108    using SetType = std::set<ValueType>;
 
 1110    InactiveVoxelValues(LeafArray&, 
size_t numValues);
 
 1115    void getInactiveValues(SetType&) 
const;
 
 1117    inline InactiveVoxelValues(
const InactiveVoxelValues<TreeType>&, tbb::split);
 
 1118    inline void operator()(
const tbb::blocked_range<size_t>&);
 
 1119    inline void join(
const InactiveVoxelValues<TreeType>&);
 
 1122    LeafArray& mLeafArray;
 
 1123    SetType mInactiveValues;
 
 1127template<
typename TreeType>
 
 1128InactiveVoxelValues<TreeType>::InactiveVoxelValues(LeafArray& leafs, 
size_t numValues)
 
 1131    , mNumValues(numValues)
 
 1135template <
typename TreeType>
 
 1137InactiveVoxelValues<TreeType>::InactiveVoxelValues(
 
 1138    const InactiveVoxelValues<TreeType>& rhs, tbb::split)
 
 1139    : mLeafArray(rhs.mLeafArray)
 
 1141    , mNumValues(rhs.mNumValues)
 
 1145template<
typename TreeType>
 
 1147InactiveVoxelValues<TreeType>::runParallel()
 
 1149    tbb::parallel_reduce(mLeafArray.getRange(), *
this);
 
 1153template<
typename TreeType>
 
 1155InactiveVoxelValues<TreeType>::runSerial()
 
 1157    (*this)(mLeafArray.getRange());
 
 1161template<
typename TreeType>
 
 1163InactiveVoxelValues<TreeType>::operator()(
const tbb::blocked_range<size_t>& range)
 
 1165    typename TreeType::LeafNodeType::ValueOffCIter iter;
 
 1167    for (
size_t n = range.begin(); n < range.end() && !thread::isGroupExecutionCancelled(); ++n) {
 
 1168        for (iter = mLeafArray.leaf(n).cbeginValueOff(); iter; ++iter) {
 
 1169            mInactiveValues.insert(iter.getValue());
 
 1172        if (mInactiveValues.size() > mNumValues) {
 
 1173            thread::cancelGroupExecution();
 
 1178template<
typename TreeType>
 
 1180InactiveVoxelValues<TreeType>::join(
const InactiveVoxelValues<TreeType>& rhs)
 
 1182    mInactiveValues.insert(rhs.mInactiveValues.begin(), rhs.mInactiveValues.end());
 
 1185template<
typename TreeType>
 
 1187InactiveVoxelValues<TreeType>::getInactiveValues(SetType& values)
 const 
 1189    values.insert(mInactiveValues.begin(), mInactiveValues.end());
 
 1196template<
typename TreeType>
 
 1197class InactiveTileValues
 
 1200    using IterRange = tree::IteratorRange<typename TreeType::ValueOffCIter>;
 
 1201    using ValueType = 
typename TreeType::ValueType;
 
 1202    using SetType = std::set<ValueType>;
 
 1204    InactiveTileValues(
size_t numValues);
 
 1206    void runParallel(IterRange&);
 
 1207    void runSerial(IterRange&);
 
 1209    void getInactiveValues(SetType&) 
const;
 
 1211    inline InactiveTileValues(
const InactiveTileValues<TreeType>&, tbb::split);
 
 1212    inline void operator()(
const IterRange&);
 
 1213    inline void join(
const InactiveTileValues<TreeType>&);
 
 1216    SetType mInactiveValues;
 
 1221template<
typename TreeType>
 
 1222InactiveTileValues<TreeType>::InactiveTileValues(
size_t numValues)
 
 1224    , mNumValues(numValues)
 
 1228template <
typename TreeType>
 
 1230InactiveTileValues<TreeType>::InactiveTileValues(
 
 1231    const InactiveTileValues<TreeType>& rhs, tbb::split)
 
 1233    , mNumValues(rhs.mNumValues)
 
 1237template<
typename TreeType>
 
 1239InactiveTileValues<TreeType>::runParallel(IterRange& range)
 
 1241    tbb::parallel_reduce(range, *
this);
 
 1245template<
typename TreeType>
 
 1247InactiveTileValues<TreeType>::runSerial(IterRange& range)
 
 1253template<
typename TreeType>
 
 1255InactiveTileValues<TreeType>::operator()(
const IterRange& range)
 
 1257    for (IterRange it(range); it.test() && !thread::isGroupExecutionCancelled(); ++it) {
 
 1258        typename TreeType::ValueOffCIter iter = it.iterator();
 
 1259        for (; iter; ++iter) {
 
 1260            mInactiveValues.insert(iter.getValue());
 
 1263        if (mInactiveValues.size() > mNumValues) {
 
 1264            thread::cancelGroupExecution();
 
 1269template<
typename TreeType>
 
 1271InactiveTileValues<TreeType>::join(
const InactiveTileValues<TreeType>& rhs)
 
 1273    mInactiveValues.insert(rhs.mInactiveValues.begin(), rhs.mInactiveValues.end());
 
 1276template<
typename TreeType>
 
 1278InactiveTileValues<TreeType>::getInactiveValues(SetType& values)
 const 
 1280    values.insert(mInactiveValues.begin(), mInactiveValues.end());
 
 1290template<
class Gr
idType>
 
 1293    std::vector<typename GridType::ValueType>& values, 
size_t numValues)
 
 1295    using TreeType = 
typename GridType::TreeType;
 
 1296    using ValueType = 
typename GridType::ValueType;
 
 1297    using SetType = std::set<ValueType>;
 
 1299    SetType uniqueValues;
 
 1302        TreeType& 
tree = 
const_cast<TreeType&
>(grid.tree());
 
 1304        diagnostics_internal::InactiveVoxelValues<TreeType> voxelOp(leafs, numValues);
 
 1305        voxelOp.runParallel();
 
 1306        voxelOp.getInactiveValues(uniqueValues);
 
 1310    if (uniqueValues.size() <= numValues) {
 
 1311        typename TreeType::ValueOffCIter iter(grid.tree());
 
 1312        iter.setMaxDepth(TreeType::ValueAllIter::LEAF_DEPTH - 1);
 
 1313        diagnostics_internal::InactiveTileValues<TreeType> tileOp(numValues);
 
 1316        tileOp.runParallel(range);
 
 1318        tileOp.getInactiveValues(uniqueValues);
 
 1322    values.reserve(uniqueValues.size());
 
 1324    typename SetType::iterator it = uniqueValues.begin();
 
 1325    for ( ; it != uniqueValues.end(); ++it) {
 
 1326        values.push_back(*it);
 
 1329    return values.size() <= numValues;
 
 
 1338#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION 
 1340#ifdef OPENVDB_INSTANTIATE_DIAGNOSTICS 
 1344#define _FUNCTION(TreeT) \ 
 1345    std::string checkLevelSet(const Grid<TreeT>&, size_t) 
 1349#define _FUNCTION(TreeT) \ 
 1350    std::string checkFogVolume(const Grid<TreeT>&, size_t) 
 1354#define _FUNCTION(TreeT) \ 
 1355    bool uniqueInactiveValues(const Grid<TreeT>&, std::vector<TreeT::ValueType>&, size_t) 
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Definition Exceptions.h:65
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
This is a special 19-point stencil that supports optimal fifth-order WENO upwinding,...
Definition Stencils.h:1366
Definition TreeIterator.h:1304
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition LeafManager.h:86
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance.
Definition Math.h:349
DScheme
Different discrete schemes used in the first derivatives.
Definition FiniteDifference.h:31
@ CD_2ND
Definition FiniteDifference.h:34
float Sqrt(float x)
Return the square root of a floating-point value.
Definition Math.h:761
BiasedGradientScheme
Biased Gradients are limited to non-centered differences.
Definition FiniteDifference.h:164
@ FIRST_BIAS
Definition FiniteDifference.h:166
Coord Abs(const Coord &xyz)
Definition Coord.h:518
Definition PointDataGrid.h:170
static const Real LEVEL_SET_HALF_WIDTH
Definition Types.h:461
double Real
Definition Types.h:60
@ GRID_FOG_VOLUME
Definition Types.h:456
@ GRID_LEVEL_SET
Definition Types.h:455
uint64_t Index64
Definition Types.h:53
@ MERGE_ACTIVE_STATES_AND_NODES
Definition Types.h:509
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
typename T::ValueType ElementType
Definition Types.h:247
static Accessor::ValueType::value_type result(const Accessor &grid, const Coord &ijk)
Definition Operators.h:476
static Accessor::ValueType result(const Accessor &grid, const Coord &ijk)
Definition Operators.h:239
static T value()
Definition Math.h:148
Definition TreeIterator.h:61
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition version.h.in:162
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition version.h.in:165