OpenVDB 11.0.0

Loading...
Searching...
No Matches
LevelSetMeasure.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3//
4/// @author Ken Museth
5///
6/// @file LevelSetMeasure.h
7
8#ifndef OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
9#define OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
10
11#include <openvdb/Types.h>
12#include <openvdb/Grid.h>
13#include <openvdb/tree/LeafManager.h>
14#include <openvdb/tree/ValueAccessor.h>
15#include <openvdb/math/Math.h>
16#include <openvdb/math/FiniteDifference.h>
17#include <openvdb/math/Operators.h>
18#include <openvdb/math/Stencils.h>
19#include <openvdb/util/NullInterrupter.h>
20#include <openvdb/thread/Threading.h>
21#include <openvdb/openvdb.h>
22
23#include <tbb/parallel_for.h>
24#include <tbb/parallel_sort.h>
25#include <tbb/parallel_invoke.h>
26
27#include <type_traits>
28
29 namespace openvdb {
30 OPENVDB_USE_VERSION_NAMESPACE
31 namespace OPENVDB_VERSION_NAME {
32 namespace tools {
33
34/// @brief Return the surface area of a narrow-band level set.
35///
36/// @param grid a scalar, floating-point grid with one or more disjoint,
37/// closed level set surfaces
38/// @param useWorldSpace if true the area is computed in
39/// world space units, else in voxel units.
40///
41/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
42 template<class GridType>
43 Real
44 levelSetArea(const GridType& grid, bool useWorldSpace = true);
45
46/// @brief Return the volume of a narrow-band level set surface.
47///
48/// @param grid a scalar, floating-point grid with one or more disjoint,
49/// closed level set surfaces
50/// @param useWorldSpace if true the volume is computed in
51/// world space units, else in voxel units.
52///
53/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
54 template<class GridType>
55 Real
56 levelSetVolume(const GridType& grid, bool useWorldSpace = true);
57
58/// @brief Return the Euler Characteristics of a narrow-band level set surface (possibly disconnected).
59///
60/// @param grid a scalar, floating-point grid with one or more disjoint,
61/// closed level set surfaces
62///
63/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
64 template<class GridType>
65 int
66 levelSetEulerCharacteristic(const GridType& grid);
67
68/// @brief Return the genus of a narrow-band level set surface.
69///
70/// @param grid a scalar, floating-point grid with one or more disjoint,
71/// closed level set surfaces
72/// @warning The genus is only well defined for a single connected surface
73///
74/// @throw TypeError if @a grid is not scalar or not floating-point or not a level set or empty.
75 template<class GridType>
76 int
77 levelSetGenus(const GridType& grid);
78
79////////////////////////////////////////////////////////////////////////////////////////
80
81/// @brief Smeared-out and continuous Dirac Delta function.
82 template<typename RealT>
83 class DiracDelta
84{
85 public:
86 // eps is the half-width of the dirac delta function in units of phi
87 DiracDelta(RealT eps) : mC(0.5/eps), mD(2*math::pi<RealT>()*mC), mE(eps) {}
88 // values of the dirac delta function are in units of one over the units of phi
89 inline RealT operator()(RealT phi) const { return math::Abs(phi) > mE ? 0 : mC*(1+cos(mD*phi)); }
90 private:
91 const RealT mC, mD, mE;
92};// DiracDelta functor
93
94
95/// @brief Multi-threaded computation of surface area, volume and
96/// average mean-curvature for narrow band level sets.
97///
98/// @details To reduce the risk of round-off errors (primarily due to
99/// catastrophic cancellation) and guarantee determinism during
100/// multi-threading this class is implemented using parallel_for, and
101/// delayed reduction of a sorted list.
102 template<typename GridT, typename InterruptT = util::NullInterrupter>
103 class LevelSetMeasure
104{
105 public:
106 using GridType = GridT;
107 using TreeType = typename GridType::TreeType;
108 using ValueType = typename TreeType::ValueType;
109 using ManagerType = typename tree::LeafManager<const TreeType>;
110
111 static_assert(std::is_floating_point<ValueType>::value,
112 "level set measure is supported only for scalar, floating-point grids");
113
114 /// @brief Main constructor from a grid
115 /// @param grid The level set to be measured.
116 /// @param interrupt Optional interrupter.
117 /// @throw RuntimeError if the grid is not a level set or if it's empty.
118 LevelSetMeasure(const GridType& grid, InterruptT* interrupt = nullptr);
119
120 /// @brief Re-initialize using the specified grid.
121 /// @param grid The level set to be measured.
122 /// @throw RuntimeError if the grid is not a level set or if it's empty.
123 void init(const GridType& grid);
124
125 /// @brief Destructor
126 virtual ~LevelSetMeasure() {}
127
128 /// @return the grain-size used for multi-threading
129 int getGrainSize() const { return mGrainSize; }
130
131 /// @brief Set the grain-size used for multi-threading.
132 /// @note A grain size of 0 or less disables multi-threading!
133 void setGrainSize(int grainsize) { mGrainSize = grainsize; }
134
135 /// @brief Compute the surface area of the level set.
136 /// @param useWorldUnits Specifies if the result is in world or voxel units.
137 /// @note Performs internal caching so only the initial call incurs actual computation.
138 Real area(bool useWorldUnits = true);
139
140 /// @brief Compute the volume of the level set surface.
141 /// @param useWorldUnits Specifies if the result is in world or voxel units.
142 /// @note Performs internal caching so only the initial call incurs actual computation.
143 Real volume(bool useWorldUnits = true);
144
145 /// @brief Compute the total mean curvature of the level set surface.
146 /// @param useWorldUnits Specifies if the result is in world or voxel units.
147 /// @note Performs internal caching so only the initial call incurs actual computation.
148 Real totMeanCurvature(bool useWorldUnits = true);
149
150 /// @brief Compute the total gaussian curvature of the level set surface.
151 /// @param useWorldUnits Specifies if the result is in world or voxel units.
152 /// @note Performs internal caching so only the initial call incurs actual computation.
153 Real totGaussianCurvature(bool useWorldUnits = true);
154
155 /// @brief Compute the average mean curvature of the level set surface.
156 /// @param useWorldUnits Specifies if the result is in world or voxel units.
157 /// @note Performs internal caching so only the initial call incurs actual computation.
158 Real avgMeanCurvature(bool useWorldUnits = true) {return this->totMeanCurvature(useWorldUnits) / this->area(useWorldUnits);}
159
160 /// @brief Compute the average gaussian curvature of the level set surface.
161 /// @param useWorldUnits Specifies if the result is in world or voxel units.
162 /// @note Performs internal caching so only the initial call incurs actual computation.
163 Real avgGaussianCurvature(bool useWorldUnits = true) {return this->totGaussianCurvature(useWorldUnits) / this->area(useWorldUnits); }
164
165 /// @brief Compute the Euler characteristic of the level set surface.
166 /// @note Performs internal caching so only the initial call incurs actual computation.
167 int eulerCharacteristic();
168
169 /// @brief Compute the genus of the level set surface.
170 /// @warning The genus is only well defined for a single connected surface.
171 /// @note Performs internal caching so only the initial call incurs actual computation.
172 int genus() { return 1 - this->eulerCharacteristic()/2;}
173
174 private:
175
176 using LeafT = typename TreeType::LeafNodeType;
177 using VoxelCIterT = typename LeafT::ValueOnCIter;
178 using LeafRange = typename ManagerType::LeafRange;
179 using LeafIterT = typename LeafRange::Iterator;
180 using ManagerPtr = std::unique_ptr<ManagerType>;
181 using BufferPtr = std::unique_ptr<double[]>;
182
183 // disallow copy construction and copy by assignment!
184 LevelSetMeasure(const LevelSetMeasure&);// not implemented
185 LevelSetMeasure& operator=(const LevelSetMeasure&);// not implemented
186
187 const GridType *mGrid;
188 ManagerPtr mLeafs;
189 BufferPtr mBuffer;
190 InterruptT *mInterrupter;
191 double mDx, mArea, mVolume, mTotMeanCurvature, mTotGausCurvature;
192 int mGrainSize;
193 bool mUpdateArea, mUpdateCurvature;
194
195 // @brief Return false if the process was interrupted
196 bool checkInterrupter();
197
198 struct MeasureArea
199 {
200 MeasureArea(LevelSetMeasure* parent) : mParent(parent), mStencil(*mParent->mGrid)
201 {
202 if (parent->mInterrupter) parent->mInterrupter->start("Measuring area and volume of level set");
203 if (parent->mGrainSize>0) {
204 tbb::parallel_for(parent->mLeafs->leafRange(parent->mGrainSize), *this);
205 } else {
206 (*this)(parent->mLeafs->leafRange());
207 }
208 tbb::parallel_invoke([&](){parent->mArea = parent->reduce(0);},
209 [&](){parent->mVolume = parent->reduce(1)/3.0;});
210 parent->mUpdateArea = false;
211 if (parent->mInterrupter) parent->mInterrupter->end();
212 }
213 MeasureArea(const MeasureArea& other) : mParent(other.mParent), mStencil(*mParent->mGrid) {}
214 void operator()(const LeafRange& range) const;
215 LevelSetMeasure* mParent;
216 mutable math::GradStencil<GridT, false> mStencil;
217 };// MeasureArea
218
219 struct MeasureCurvatures
220 {
221 MeasureCurvatures(LevelSetMeasure* parent) : mParent(parent), mStencil(*mParent->mGrid)
222 {
223 if (parent->mInterrupter) parent->mInterrupter->start("Measuring curvatures of level set");
224 if (parent->mGrainSize>0) {
225 tbb::parallel_for(parent->mLeafs->leafRange(parent->mGrainSize), *this);
226 } else {
227 (*this)(parent->mLeafs->leafRange());
228 }
229 tbb::parallel_invoke([&](){parent->mTotMeanCurvature = parent->reduce(0);},
230 [&](){parent->mTotGausCurvature = parent->reduce(1);});
231 parent->mUpdateCurvature = false;
232 if (parent->mInterrupter) parent->mInterrupter->end();
233 }
234 MeasureCurvatures(const MeasureCurvatures& other) : mParent(other.mParent), mStencil(*mParent->mGrid) {}
235 void operator()(const LeafRange& range) const;
236 LevelSetMeasure* mParent;
237 mutable math::CurvatureStencil<GridT, false> mStencil;
238 };// MeasureCurvatures
239
240 double reduce(int offset)
241 {
242 double *first = mBuffer.get() + offset*mLeafs->leafCount(), *last = first + mLeafs->leafCount();
243 tbb::parallel_sort(first, last);// mitigates catastrophic cancellation
244 Real sum = 0.0;
245 while(first != last) sum += *first++;
246 return sum;
247 }
248
249}; // end of LevelSetMeasure class
250
251
252 template<typename GridT, typename InterruptT>
253 inline
254 LevelSetMeasure<GridT, InterruptT>::LevelSetMeasure(const GridType& grid, InterruptT* interrupt)
255 : mInterrupter(interrupt)
256 , mGrainSize(1)
257{
258 this->init(grid);
259}
260
261 template<typename GridT, typename InterruptT>
262 inline void
263 LevelSetMeasure<GridT, InterruptT>::init(const GridType& grid)
264{
265 if (!grid.hasUniformVoxels()) {
266 OPENVDB_THROW(RuntimeError,
267 "The transform must have uniform scale for the LevelSetMeasure to function");
268 }
269 if (grid.getGridClass() != GRID_LEVEL_SET) {
270 OPENVDB_THROW(RuntimeError,
271 "LevelSetMeasure only supports level sets;"
272 " try setting the grid class to \"level set\"");
273 }
274 if (grid.empty()) {
275 OPENVDB_THROW(RuntimeError,
276 "LevelSetMeasure does not support empty grids;");
277 }
278 mGrid = &grid;
279 mDx = grid.voxelSize()[0];
280 mLeafs = std::make_unique<ManagerType>(mGrid->tree());
281 mBuffer = std::make_unique<double[]>(2*mLeafs->leafCount());
282 mUpdateArea = mUpdateCurvature = true;
283}
284
285 template<typename GridT, typename InterruptT>
286 inline Real
287 LevelSetMeasure<GridT, InterruptT>::area(bool useWorldUnits)
288{
289 if (mUpdateArea) {MeasureArea m(this);};
290 double area = mArea;
291 if (useWorldUnits) area *= math::Pow2(mDx);
292 return area;
293}
294
295 template<typename GridT, typename InterruptT>
296 inline Real
297 LevelSetMeasure<GridT, InterruptT>::volume(bool useWorldUnits)
298{
299 if (mUpdateArea) {MeasureArea m(this);};
300 double volume = mVolume;
301 if (useWorldUnits) volume *= math::Pow3(mDx) ;
302 return volume;
303}
304
305 template<typename GridT, typename InterruptT>
306 inline Real
307 LevelSetMeasure<GridT, InterruptT>::totMeanCurvature(bool useWorldUnits)
308{
309 if (mUpdateCurvature) {MeasureCurvatures m(this);};
310 return mTotMeanCurvature * (useWorldUnits ? mDx : 1);
311}
312
313 template<typename GridT, typename InterruptT>
314 inline Real
315 LevelSetMeasure<GridT, InterruptT>::totGaussianCurvature(bool)
316{
317 if (mUpdateCurvature) {MeasureCurvatures m(this);};
318 return mTotGausCurvature;
319}
320
321 template<typename GridT, typename InterruptT>
322 inline int
323 LevelSetMeasure<GridT, InterruptT>::eulerCharacteristic()
324{
325 const Real x = this->totGaussianCurvature(true) / (2.0*math::pi<Real>());
326 return int(math::Round( x ));
327}
328
329///////////////////////// PRIVATE METHODS //////////////////////
330
331 template<typename GridT, typename InterruptT>
332 inline bool
333 LevelSetMeasure<GridT, InterruptT>::checkInterrupter()
334{
335 if (util::wasInterrupted(mInterrupter)) {
336 thread::cancelGroupExecution();
337 return false;
338 }
339 return true;
340}
341
342 template<typename GridT, typename InterruptT>
343 inline void
344LevelSetMeasure<GridT, InterruptT>::
345MeasureArea::operator()(const LeafRange& range) const
346{
347 using Vec3T = math::Vec3<ValueType>;
348 // computations are performed in index space where dV = 1
349 mParent->checkInterrupter();
350 const Real invDx = 1.0/mParent->mDx;
351 const DiracDelta<Real> DD(1.5);// dirac delta function is 3 voxel units wide
352 const size_t leafCount = mParent->mLeafs->leafCount();
353 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
354 Real sumA = 0, sumV = 0;//reduce risk of catastrophic cancellation
355 for (VoxelCIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
356 const Real dd = DD(invDx * (*voxelIter));
357 if (dd > 0.0) {
358 mStencil.moveTo(voxelIter);
359 const Coord& p = mStencil.getCenterCoord();// in voxel units
360 const Vec3T g = mStencil.gradient();// in world units
361 sumA += dd*g.length();// \delta(\phi)*|\nabla\phi|
362 sumV += dd*(g[0]*Real(p[0]) + g[1]*Real(p[1]) + g[2]*Real(p[2]));// \delta(\phi)\vec{x}\cdot\nabla\phi
363 }
364 }
365 double* ptr = mParent->mBuffer.get() + leafIter.pos();
366 *ptr = sumA;
367 ptr += leafCount;
368 *ptr = sumV;
369 }
370}
371
372 template<typename GridT, typename InterruptT>
373 inline void
374LevelSetMeasure<GridT, InterruptT>::
375MeasureCurvatures::operator()(const LeafRange& range) const
376{
377 using Vec3T = math::Vec3<ValueType>;
378 // computations are performed in index space where dV = 1
379 mParent->checkInterrupter();
380 const Real dx = mParent->mDx, dx2=dx*dx, invDx = 1.0/dx;
381 const DiracDelta<Real> DD(1.5);// dirac delta function is 3 voxel units wide
382 ValueType mean, gauss;
383 const size_t leafCount = mParent->mLeafs->leafCount();
384 for (LeafIterT leafIter=range.begin(); leafIter; ++leafIter) {
385 Real sumM = 0, sumG = 0;//reduce risk of catastrophic cancellation
386 for (VoxelCIterT voxelIter = leafIter->cbeginValueOn(); voxelIter; ++voxelIter) {
387 const Real dd = DD(invDx * (*voxelIter));
388 if (dd > 0.0) {
389 mStencil.moveTo(voxelIter);
390 const Vec3T g = mStencil.gradient();
391 const Real dA = dd*g.length();// \delta(\phi)*\delta(\phi)
392 mStencil.curvatures(mean, gauss);
393 sumM += dA*mean*dx;// \delta(\phi)*\delta(\phi)*MeanCurvature
394 sumG += dA*gauss*dx2;// \delta(\phi)*\delta(\phi)*GaussCurvature
395 }
396 }
397 double* ptr = mParent->mBuffer.get() + leafIter.pos();
398 *ptr = sumM;
399 ptr += leafCount;
400 *ptr = sumG;
401 }
402}
403
404////////////////////////////////////////
405
406//{
407/// @cond OPENVDB_DOCS_INTERNAL
408
409 template<class GridT>
410 inline
411 typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, Real>::type
412doLevelSetArea(const GridT& grid, bool useWorldUnits)
413{
414 LevelSetMeasure<GridT> m(grid);
415 return m.area(useWorldUnits);
416}
417
418 template<class GridT>
419 inline
420 typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, Real>::type
421doLevelSetArea(const GridT&, bool)
422{
423 OPENVDB_THROW(TypeError,
424 "level set area is supported only for scalar, floating-point grids");
425}
426
427/// @endcond
428//}
429
430 template<class GridT>
431 Real
432 levelSetArea(const GridT& grid, bool useWorldUnits)
433{
434 return doLevelSetArea<GridT>(grid, useWorldUnits);
435}
436
437////////////////////////////////////////
438
439//{
440/// @cond OPENVDB_DOCS_INTERNAL
441
442 template<class GridT>
443 inline
444 typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, Real>::type
445doLevelSetVolume(const GridT& grid, bool useWorldUnits)
446{
447 LevelSetMeasure<GridT> m(grid);
448 return m.volume(useWorldUnits);
449}
450
451 template<class GridT>
452 inline
453 typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, Real>::type
454doLevelSetVolume(const GridT&, bool)
455{
456 OPENVDB_THROW(TypeError,
457 "level set volume is supported only for scalar, floating-point grids");
458}
459
460/// @endcond
461//}
462
463 template<class GridT>
464 Real
465 levelSetVolume(const GridT& grid, bool useWorldUnits)
466{
467 return doLevelSetVolume<GridT>(grid, useWorldUnits);
468}
469
470////////////////////////////////////////
471
472//{
473/// @cond OPENVDB_DOCS_INTERNAL
474
475 template<class GridT>
476 inline
477 typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
478doLevelSetEulerCharacteristic(const GridT& grid)
479{
480 LevelSetMeasure<GridT> m(grid);
481 return m.eulerCharacteristic();
482}
483
484 template<class GridT>
485 inline
486 typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, int>::type
487doLevelSetEulerCharacteristic(const GridT&)
488{
489 OPENVDB_THROW(TypeError,
490 "level set euler characteristic is supported only for scalar, floating-point grids");
491}
492
493/// @endcond
494//}
495
496
497 template<class GridT>
498 int
499 levelSetEulerCharacteristic(const GridT& grid)
500{
501 return doLevelSetEulerCharacteristic(grid);
502}
503
504////////////////////////////////////////
505
506//{
507/// @cond OPENVDB_DOCS_INTERNAL
508
509 template<class GridT>
510 inline
511 typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
512doLevelSetEuler(const GridT& grid)
513{
514 LevelSetMeasure<GridT> m(grid);
515 return m.eulerCharacteristics();
516
517}
518
519 template<class GridT>
520 inline
521 typename std::enable_if<std::is_floating_point<typename GridT::ValueType>::value, int>::type
522doLevelSetGenus(const GridT& grid)
523{
524 LevelSetMeasure<GridT> m(grid);
525 return m.genus();
526}
527
528 template<class GridT>
529 inline
530 typename std::enable_if<!std::is_floating_point<typename GridT::ValueType>::value, int>::type
531doLevelSetGenus(const GridT&)
532{
533 OPENVDB_THROW(TypeError,
534 "level set genus is supported only for scalar, floating-point grids");
535}
536
537/// @endcond
538//}
539
540 template<class GridT>
541 int
542 levelSetGenus(const GridT& grid)
543{
544 return doLevelSetGenus(grid);
545}
546
547
548////////////////////////////////////////
549
550
551// Explicit Template Instantiation
552
553#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
554
555#ifdef OPENVDB_INSTANTIATE_LEVELSETMEASURE
556#include <openvdb/util/ExplicitInstantiation.h>
557#endif
558
559#define _FUNCTION(TreeT) \
560 Real levelSetArea(const Grid<TreeT>&, bool)
561 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
562#undef _FUNCTION
563
564#define _FUNCTION(TreeT) \
565 Real levelSetVolume(const Grid<TreeT>&, bool)
566 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
567#undef _FUNCTION
568
569#define _FUNCTION(TreeT) \
570 int levelSetEulerCharacteristic(const Grid<TreeT>&)
571 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
572#undef _FUNCTION
573
574#define _FUNCTION(TreeT) \
575 int levelSetGenus(const Grid<TreeT>&)
576 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
577#undef _FUNCTION
578
579 OPENVDB_INSTANTIATE_CLASS LevelSetMeasure<FloatGrid, util::NullInterrupter>;
580 OPENVDB_INSTANTIATE_CLASS LevelSetMeasure<DoubleGrid, util::NullInterrupter>;
581
582#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
583
584
585} // namespace tools
586} // namespace OPENVDB_VERSION_NAME
587} // namespace openvdb
588
589#endif // OPENVDB_TOOLS_LEVELSETMEASURE_HAS_BEEN_INCLUDED
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
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
Types.h
ValueAccessor.h
ValueAccessors are designed to help accelerate accesses into the OpenVDB Tree structures by storing c...
openvdb::v11_0::RuntimeError
Definition Exceptions.h:63
openvdb::v11_0::TypeError
Definition Exceptions.h:64
openvdb::v11_0::math::Coord
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:25
openvdb::v11_0::math::Vec3
Definition Vec3.h:24
openvdb::v11_0::tools::DiracDelta
Smeared-out and continuous Dirac Delta function.
Definition LevelSetMeasure.h:84
openvdb::v11_0::tools::DiracDelta::DiracDelta
DiracDelta(RealT eps)
Definition LevelSetMeasure.h:87
openvdb::v11_0::tools::DiracDelta::operator()
RealT operator()(RealT phi) const
Definition LevelSetMeasure.h:89
openvdb::v11_0::tools::LevelSetMeasure
Multi-threaded computation of surface area, volume and average mean-curvature for narrow band level s...
Definition LevelSetMeasure.h:104
openvdb::v11_0::tools::LevelSetMeasure::genus
int genus()
Compute the genus of the level set surface.
Definition LevelSetMeasure.h:172
openvdb::v11_0::tools::LevelSetMeasure::avgGaussianCurvature
Real avgGaussianCurvature(bool useWorldUnits=true)
Compute the average gaussian curvature of the level set surface.
Definition LevelSetMeasure.h:163
openvdb::v11_0::tools::LevelSetMeasure::eulerCharacteristic
int eulerCharacteristic()
Compute the Euler characteristic of the level set surface.
Definition LevelSetMeasure.h:323
openvdb::v11_0::tools::LevelSetMeasure::~LevelSetMeasure
virtual ~LevelSetMeasure()
Destructor.
Definition LevelSetMeasure.h:126
openvdb::v11_0::tools::LevelSetMeasure::init
void init(const GridType &grid)
Re-initialize using the specified grid.
Definition LevelSetMeasure.h:263
openvdb::v11_0::tools::LevelSetMeasure::ValueType
typename TreeType::ValueType ValueType
Definition LevelSetMeasure.h:108
openvdb::v11_0::tools::LevelSetMeasure::ManagerType
typename tree::LeafManager< const TreeType > ManagerType
Definition LevelSetMeasure.h:109
openvdb::v11_0::tools::LevelSetMeasure::totGaussianCurvature
Real totGaussianCurvature(bool useWorldUnits=true)
Compute the total gaussian curvature of the level set surface.
Definition LevelSetMeasure.h:315
openvdb::v11_0::tools::LevelSetMeasure::setGrainSize
void setGrainSize(int grainsize)
Set the grain-size used for multi-threading.
Definition LevelSetMeasure.h:133
openvdb::v11_0::tools::LevelSetMeasure::getGrainSize
int getGrainSize() const
Definition LevelSetMeasure.h:129
openvdb::v11_0::tools::LevelSetMeasure::TreeType
typename GridType::TreeType TreeType
Definition LevelSetMeasure.h:107
openvdb::v11_0::tools::LevelSetMeasure::area
Real area(bool useWorldUnits=true)
Compute the surface area of the level set.
Definition LevelSetMeasure.h:287
openvdb::v11_0::tools::LevelSetMeasure::volume
Real volume(bool useWorldUnits=true)
Compute the volume of the level set surface.
Definition LevelSetMeasure.h:297
openvdb::v11_0::tools::LevelSetMeasure::avgMeanCurvature
Real avgMeanCurvature(bool useWorldUnits=true)
Compute the average mean curvature of the level set surface.
Definition LevelSetMeasure.h:158
openvdb::v11_0::tools::LevelSetMeasure::totMeanCurvature
Real totMeanCurvature(bool useWorldUnits=true)
Compute the total mean curvature of the level set surface.
Definition LevelSetMeasure.h:307
openvdb::v11_0::tools::LevelSetMeasure::GridType
GridT GridType
Definition LevelSetMeasure.h:106
openvdb::v11_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::v11_0::math::Round
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
openvdb::v11_0::math::Pow3
Type Pow3(Type x)
Return x3.
Definition Math.h:552
openvdb::v11_0::math::Pow2
Type Pow2(Type x)
Return x2.
Definition Math.h:548
openvdb::v11_0::tools::levelSetArea
Real levelSetArea(const GridType &grid, bool useWorldSpace=true)
Return the surface area of a narrow-band level set.
openvdb::v11_0::tools::levelSetGenus
int levelSetGenus(const GridType &grid)
Return the genus of a narrow-band level set surface.
openvdb::v11_0::tools::levelSetEulerCharacteristic
int levelSetEulerCharacteristic(const GridType &grid)
Return the Euler Characteristics of a narrow-band level set surface (possibly disconnected).
openvdb::v11_0::tools::levelSetVolume
Real levelSetVolume(const GridType &grid, bool useWorldSpace=true)
Return the volume of a narrow-band level set surface.
openvdb::v11_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
openvdb::v11_0::Real
double Real
Definition Types.h:60
openvdb::v11_0::GRID_LEVEL_SET
@ GRID_LEVEL_SET
Definition Types.h:455
openvdb
Definition Exceptions.h:13
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