HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Diagnostics.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 ///
4 /// @file Diagnostics.h
5 ///
6 /// @author Ken Museth
7 ///
8 /// @brief Various diagnostic tools to identify potential issues with
9 /// for example narrow-band level sets or fog volumes
10 ///
11 #ifndef OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED
12 #define OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED
13 
14 #include "openvdb/Grid.h"
15 #include "openvdb/math/Math.h"
16 #include "openvdb/math/Vec3.h"
17 #include "openvdb/math/Stencils.h"
18 #include "openvdb/math/Operators.h"
21 
22 #include <tbb/blocked_range.h>
23 #include <tbb/parallel_reduce.h>
24 
25 #include <cmath> // for std::isnan(), std::isfinite()
26 #include <set>
27 #include <sstream>
28 #include <string>
29 #include <type_traits>
30 #include <vector>
31 
32 namespace openvdb {
34 namespace OPENVDB_VERSION_NAME {
35 namespace tools {
36 
37 ////////////////////////////////////////////////////////////////////////////////
38 
39 /// @brief Perform checks on a grid to see if it is a valid symmetric,
40 /// narrow-band level set.
41 ///
42 /// @param grid Grid to be checked
43 /// @param number Number of the checks to be performed (see below)
44 /// @return string with a message indicating the nature of the
45 /// issue. If no issue is detected the return string is empty.
46 ///
47 /// @details @a number refers to the following ordered list of
48 /// checks - always starting from the top.
49 /// Fast checks
50 /// 1: value type is floating point
51 /// 2: has level set class type
52 /// 3: has uniform scale
53 /// 4: background value is positive and n*dx
54 ///
55 /// Slower checks
56 /// 5: no active tiles
57 /// 6: all the values are finite, i.e not NaN or infinite
58 /// 7: active values in range between +-background
59 /// 8: abs of inactive values = background, i.e. assuming a symmetric
60 /// narrow band!
61 ///
62 /// Relatively slow check (however multithreaded)
63 /// 9: norm gradient is close to one, i.e. satisfied the Eikonal equation.
64 template<class GridType>
66 checkLevelSet(const GridType& grid, size_t number=9);
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 
70 /// @brief Perform checks on a grid to see if it is a valid fog volume.
71 ///
72 /// @param grid Grid to be checked
73 /// @param number Number of the checks to be performed (see below)
74 /// @return string with a message indicating the nature of the
75 /// issue. If no issue is detected the return string is empty.
76 ///
77 /// @details @a number refers to the following ordered list of
78 /// checks - always starting from the top.
79 /// Fast checks
80 /// 1: value type is floating point
81 /// 2: has FOG volume class type
82 /// 3: background value is zero
83 ///
84 /// Slower checks
85 /// 4: all the values are finite, i.e not NaN or infinite
86 /// 5: inactive values are zero
87 /// 6: active values are in the range [0,1]
88 template<class GridType>
90 checkFogVolume(const GridType& grid, size_t number=6);
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 
94 /// @brief Threaded method to find unique inactive values.
95 ///
96 /// @param grid A VDB volume.
97 /// @param values List of unique inactive values, returned by this method.
98 /// @param numValues Number of values to look for.
99 /// @return @c false if the @a grid has more than @a numValues inactive values.
100 template<class GridType>
101 bool
102 uniqueInactiveValues(const GridType& grid,
103  std::vector<typename GridType::ValueType>& values, size_t numValues);
104 
105 
106 ////////////////////////////////////////////////////////////////////////////////
107 
108 /// @brief Checks NaN values
109 template<typename GridT, typename TreeIterT = typename GridT::ValueOnCIter>
110 struct CheckNan
111 {
113  using TileIterT = TreeIterT;
114  using VoxelIterT = typename tree::IterTraits<
115  typename TreeIterT::NodeT, typename TreeIterT::ValueIterT>::template
117 
118  /// @brief Default constructor
119  CheckNan() {}
120 
121  /// Return true if the scalar value is NaN
122  inline bool operator()(const ElementType& v) const { return std::isnan(v); }
123 
124  /// @brief This allows for vector values to be checked component-wise
125  template<typename T>
126  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
127  operator()(const T& v) const
128  {
129  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;//should unroll
130  return false;
131  }
132 
133  /// @brief Return true if the tile at the iterator location is NaN
134  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
135 
136  /// @brief Return true if the voxel at the iterator location is NaN
137  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
138 
139  /// @brief Return a string describing a failed check.
140  std::string str() const { return "NaN"; }
141 
142 };// CheckNan
143 
144 ////////////////////////////////////////////////////////////////////////////////
145 
146 /// @brief Checks for infinite values, e.g. 1/0 or -1/0
147 template <typename GridT,
148  typename TreeIterT = typename GridT::ValueOnCIter>
149 struct CheckInf
150 {
152  using TileIterT = TreeIterT;
153  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
154  typename TreeIterT::ValueIterT> ::template NodeConverter<
155  typename GridT::TreeType::LeafNodeType>::Type;
156 
157  /// @brief Default constructor
158  CheckInf() {}
159 
160  /// Return true if the value is infinite
161  inline bool operator()(const ElementType& v) const { return std::isinf(v); }
162 
163  /// Return true if any of the vector components are infinite.
164  template<typename T>
165  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
166  operator()(const T& v) const
167  {
168  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
169  return false;
170  }
171 
172  /// @brief Return true if the tile at the iterator location is infinite
173  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
174 
175  /// @brief Return true if the tile at the iterator location is infinite
176  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
177 
178  /// @brief Return a string describing a failed check.
179  std::string str() const { return "infinite"; }
180 };// CheckInf
181 
182 ////////////////////////////////////////////////////////////////////////////////
183 
184 /// @brief Checks for both NaN and inf values, i.e. any value that is not finite.
185 template <typename GridT,
186  typename TreeIterT = typename GridT::ValueOnCIter>
188 {
190  using TileIterT = TreeIterT;
191  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
192  typename TreeIterT::ValueIterT> ::template NodeConverter<
193  typename GridT::TreeType::LeafNodeType>::Type;
194 
195  /// @brief Default constructor
197 
198  /// Return true if the value is NOT finite, i.e. it's NaN or infinite
199  inline bool operator()(const ElementType& v) const { return !std::isfinite(v); }
200 
201  /// Return true if any of the vector components are NaN or infinite.
202  template<typename T>
203  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
204  operator()(const T& v) const {
205  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
206  return false;
207  }
208 
209  /// @brief Return true if the tile at the iterator location is NaN or infinite.
210  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
211 
212  /// @brief Return true if the tile at the iterator location is NaN or infinite.
213  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
214 
215  /// @brief Return a string describing a failed check.
216  std::string str() const { return "not finite"; }
217 };// CheckFinite
218 
219 ////////////////////////////////////////////////////////////////////////////////
220 
221 /// @brief Check that the magnitude of a value, a, is close to a fixed
222 /// magnitude, b, given a fixed tolerance c. That is | |a| - |b| | <= c
223 template <typename GridT,
224  typename TreeIterT = typename GridT::ValueOffCIter>
226 {
228  using TileIterT = TreeIterT;
229  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
230  typename TreeIterT::ValueIterT> ::template NodeConverter<
231  typename GridT::TreeType::LeafNodeType>::Type;
232 
233  /// @brief Default constructor
236  : absVal(math::Abs(a)), tolVal(math::Abs(t))
237  {
238  }
239 
240  /// Return true if the magnitude of the value is not approximately
241  /// equal to totVal.
242  inline bool operator()(const ElementType& v) const
243  {
244  return math::Abs(math::Abs(v) - absVal) > tolVal;
245  }
246 
247  /// Return true if any of the vector components are infinite.
248  template<typename T>
249  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
250  operator()(const T& v) const
251  {
252  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
253  return false;
254  }
255 
256  /// @brief Return true if the tile at the iterator location is infinite
257  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
258 
259  /// @brief Return true if the tile at the iterator location is infinite
260  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
261 
262  /// @brief Return a string describing a failed check.
263  std::string str() const
264  {
265  std::ostringstream ss;
266  ss << "not equal to +/-"<<absVal<<" with a tolerance of "<<tolVal;
267  return ss.str();
268  }
269 
271 };// CheckMagnitude
272 
273 ////////////////////////////////////////////////////////////////////////////////
274 
275 /// @brief Checks a value against a range
276 template <typename GridT,
277  bool MinInclusive = true,//is min part of the range?
278  bool MaxInclusive = true,//is max part of the range?
279  typename TreeIterT = typename GridT::ValueOnCIter>
281 {
283  using TileIterT = TreeIterT;
284  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
285  typename TreeIterT::ValueIterT> ::template NodeConverter<
286  typename GridT::TreeType::LeafNodeType>::Type;
287 
288  // @brief Constructor taking a range to be tested against.
289  CheckRange(const ElementType& _min, const ElementType& _max) : minVal(_min), maxVal(_max)
290  {
291  if (minVal > maxVal) {
292  OPENVDB_THROW(ValueError, "CheckRange: Invalid range (min > max)");
293  }
294  }
295 
296  /// Return true if the value is smaller than min or larger than max.
297  inline bool operator()(const ElementType& v) const
298  {
299  return (MinInclusive ? v<minVal : v<=minVal) ||
300  (MaxInclusive ? v>maxVal : v>=maxVal);
301  }
302 
303  /// Return true if any of the vector components are out of range.
304  template<typename T>
305  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
306  operator()(const T& v) const {
307  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
308  return false;
309  }
310 
311  /// @brief Return true if the voxel at the iterator location is out of range.
312  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
313 
314  /// @brief Return true if the tile at the iterator location is out of range.
315  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
316 
317  /// @brief Return a string describing a failed check.
318  std::string str() const
319  {
320  std::ostringstream ss;
321  ss << "outside the value range " << (MinInclusive ? "[" : "]")
322  << minVal << "," << maxVal << (MaxInclusive ? "]" : "[");
323  return ss.str();
324  }
325 
327 };// CheckRange
328 
329 ////////////////////////////////////////////////////////////////////////////////
330 
331 /// @brief Checks a value against a minimum
332 template <typename GridT,
333  typename TreeIterT = typename GridT::ValueOnCIter>
334 struct CheckMin
335 {
337  using TileIterT = TreeIterT;
338  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
339  typename TreeIterT::ValueIterT> ::template NodeConverter<
340  typename GridT::TreeType::LeafNodeType>::Type;
341 
342  // @brief Constructor taking a minimum to be tested against.
343  CheckMin(const ElementType& _min) : minVal(_min) {}
344 
345  /// Return true if the value is smaller than min.
346  inline bool operator()(const ElementType& v) const { return v<minVal; }
347 
348  /// Return true if any of the vector components are smaller than min.
349  template<typename T>
350  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
351  operator()(const T& v) const {
352  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
353  return false;
354  }
355 
356  /// @brief Return true if the voxel at the iterator location is smaller than min.
357  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
358 
359  /// @brief Return true if the tile at the iterator location is smaller than min.
360  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
361 
362  /// @brief Return a string describing a failed check.
363  std::string str() const
364  {
365  std::ostringstream ss;
366  ss << "smaller than "<<minVal;
367  return ss.str();
368  }
369 
371 };// CheckMin
372 
373 ////////////////////////////////////////////////////////////////////////////////
374 
375 /// @brief Checks a value against a maximum
376 template <typename GridT,
377  typename TreeIterT = typename GridT::ValueOnCIter>
378 struct CheckMax
379 {
381  using TileIterT = TreeIterT;
382  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
383  typename TreeIterT::ValueIterT> ::template NodeConverter<
384  typename GridT::TreeType::LeafNodeType>::Type;
385 
386  /// @brief Constructor taking a maximum to be tested against.
387  CheckMax(const ElementType& _max) : maxVal(_max) {}
388 
389  /// Return true if the value is larger than max.
390  inline bool operator()(const ElementType& v) const { return v>maxVal; }
391 
392  /// Return true if any of the vector components are larger than max.
393  template<typename T>
394  inline typename std::enable_if<VecTraits<T>::IsVec, bool>::type
395  operator()(const T& v) const {
396  for (int i=0; i<VecTraits<T>::Size; ++i) if ((*this)(v[i])) return true;
397  return false;
398  }
399 
400  /// @brief Return true if the tile at the iterator location is larger than max.
401  bool operator()(const TreeIterT &iter) const { return (*this)(*iter); }
402 
403  /// @brief Return true if the voxel at the iterator location is larger than max.
404  bool operator()(const VoxelIterT &iter) const { return (*this)(*iter); }
405 
406  /// @brief Return a string describing a failed check.
407  std::string str() const
408  {
409  std::ostringstream ss;
410  ss << "larger than "<<maxVal;
411  return ss.str();
412  }
413 
415 };// CheckMax
416 
417 ////////////////////////////////////////////////////////////////////////////////
418 
419 /// @brief Checks the norm of the gradient against a range, i.e.,
420 /// |&nabla;&Phi;| &isin; [min, max]
421 ///
422 /// @note Internally the test is performed as
423 /// |&nabla;&Phi;|&sup2; &isin; [min&sup2;, max&sup2;] for optimization reasons.
424 template<typename GridT,
425  typename TreeIterT = typename GridT::ValueOnCIter,
426  math::BiasedGradientScheme GradScheme = math::FIRST_BIAS>//math::WENO5_BIAS>
428 {
429  using ValueType = typename GridT::ValueType;
431  "openvdb::tools::CheckNormGrad requires a scalar, floating-point grid");
432  using TileIterT = TreeIterT;
433  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
434  typename TreeIterT::ValueIterT> ::template NodeConverter<
435  typename GridT::TreeType::LeafNodeType>::Type;
436  using AccT = typename GridT::ConstAccessor;
437 
438  /// @brief Constructor taking a grid and a range to be tested against.
439  CheckNormGrad(const GridT& grid, const ValueType& _min, const ValueType& _max)
440  : acc(grid.getConstAccessor())
441  , invdx2(ValueType(1.0/math::Pow2(grid.voxelSize()[0])))
442  , minVal2(_min*_min)
443  , maxVal2(_max*_max)
444  {
445  if ( !grid.hasUniformVoxels() ) {
446  OPENVDB_THROW(ValueError, "CheckNormGrad: The transform must have uniform scale");
447  }
448  if (_min > _max) {
449  OPENVDB_THROW(ValueError, "CheckNormGrad: Invalid range (min > max)");
450  }
451  }
452 
454  : acc(other.acc.tree())
455  , invdx2(other.invdx2)
456  , minVal2(other.minVal2)
457  , maxVal2(other.maxVal2)
458  {
459  }
460 
461  /// Return true if the value is smaller than min or larger than max.
462  inline bool operator()(const ValueType& v) const { return v<minVal2 || v>maxVal2; }
463 
464  /// @brief Return true if zero is outside the range.
465  /// @note We assume that the norm of the gradient of a tile is always zero.
466  inline bool operator()(const TreeIterT&) const { return (*this)(ValueType(0)); }
467 
468  /// @brief Return true if the norm of the gradient at a voxel
469  /// location of the iterator is out of range.
470  inline bool operator()(const VoxelIterT &iter) const
471  {
472  const Coord ijk = iter.getCoord();
474  }
475 
476  /// @brief Return a string describing a failed check.
477  std::string str() const
478  {
479  std::ostringstream ss;
480  ss << "outside the range of NormGrad ["<<math::Sqrt(minVal2)<<","<<math::Sqrt(maxVal2)<<"]";
481  return ss.str();
482  }
483 
486 };// CheckNormGrad
487 
488 ////////////////////////////////////////////////////////////////////////////////
489 
490 /// @brief Checks the norm of the gradient at zero-crossing voxels against a range
491 /// @details CheckEikonal differs from CheckNormGrad in that it only
492 /// checks the norm of the gradient at voxel locations where the
493 /// FD-stencil crosses the zero isosurface!
494 template<typename GridT,
495  typename TreeIterT = typename GridT::ValueOnCIter,
496  typename StencilT = math::WenoStencil<GridT> >//math::GradStencil<GridT>
498 {
499  using ValueType = typename GridT::ValueType;
501  "openvdb::tools::CheckEikonal requires a scalar, floating-point grid");
502  using TileIterT = TreeIterT;
503  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
504  typename TreeIterT::ValueIterT> ::template NodeConverter<
505  typename GridT::TreeType::LeafNodeType>::Type;
506 
507  /// @brief Constructor taking a grid and a range to be tested against.
508  CheckEikonal(const GridT& grid, const ValueType& _min, const ValueType& _max)
509  : stencil(grid), minVal(_min), maxVal(_max)
510  {
511  if ( !grid.hasUniformVoxels() ) {
512  OPENVDB_THROW(ValueError, "CheckEikonal: The transform must have uniform scale");
513  }
514  if (minVal > maxVal) {
515  OPENVDB_THROW(ValueError, "CheckEikonal: Invalid range (min > max)");
516  }
517  }
518 
520  : stencil(other.stencil.grid()), minVal(other.minVal), maxVal(other.maxVal)
521  {
522  }
523 
524  /// Return true if the value is smaller than min or larger than max.
525  inline bool operator()(const ValueType& v) const { return v<minVal || v>maxVal; }
526 
527  /// @brief Return true if zero is outside the range.
528  /// @note We assume that the norm of the gradient of a tile is always zero.
529  inline bool operator()(const TreeIterT&) const { return (*this)(ValueType(0)); }
530 
531  /// @brief Return true if the norm of the gradient at a
532  /// zero-crossing voxel location of the iterator is out of range.
533  inline bool operator()(const VoxelIterT &iter) const
534  {
535  stencil.moveTo(iter);
536  if (!stencil.zeroCrossing()) return false;
537  return (*this)(stencil.normSqGrad());
538  }
539 
540  /// @brief Return a string describing a failed check.
541  std::string str() const
542  {
543  std::ostringstream ss;
544  ss << "outside the range of NormGrad ["<<minVal<<","<<maxVal<<"]";
545  return ss.str();
546  }
547 
548  mutable StencilT stencil;
550 };// CheckEikonal
551 
552 ////////////////////////////////////////////////////////////////////////////////
553 
554 /// @brief Checks the divergence against a range
555 template<typename GridT,
556  typename TreeIterT = typename GridT::ValueOnCIter,
557  math::DScheme DiffScheme = math::CD_2ND>
559 {
560  using ValueType = typename GridT::ValueType;
563  "openvdb::tools::CheckDivergence requires a floating-point vector grid");
564  using TileIterT = TreeIterT;
565  using VoxelIterT = typename tree::IterTraits<typename TreeIterT::NodeT,
566  typename TreeIterT::ValueIterT>::template NodeConverter<
567  typename GridT::TreeType::LeafNodeType>::Type;
568  using AccT = typename GridT::ConstAccessor;
569 
570  /// @brief Constructor taking a grid and a range to be tested against.
571  CheckDivergence(const GridT& grid,
572  const ValueType& _min,
573  const ValueType& _max)
574  : acc(grid.getConstAccessor())
575  , invdx(ValueType(1.0/grid.voxelSize()[0]))
576  , minVal(_min)
577  , maxVal(_max)
578  {
579  if ( !grid.hasUniformVoxels() ) {
580  OPENVDB_THROW(ValueError, "CheckDivergence: The transform must have uniform scale");
581  }
582  if (minVal > maxVal) {
583  OPENVDB_THROW(ValueError, "CheckDivergence: Invalid range (min > max)");
584  }
585  }
586  /// Return true if the value is smaller than min or larger than max.
587  inline bool operator()(const ElementType& v) const { return v<minVal || v>maxVal; }
588 
589  /// @brief Return true if zero is outside the range.
590  /// @note We assume that the divergence of a tile is always zero.
591  inline bool operator()(const TreeIterT&) const { return (*this)(ElementType(0)); }
592 
593  /// @brief Return true if the divergence at a voxel location of
594  /// the iterator is out of range.
595  inline bool operator()(const VoxelIterT &iter) const
596  {
597  const Coord ijk = iter.getCoord();
598  return (*this)(invdx * math::ISDivergence<DiffScheme>::result(acc, ijk));
599  }
600 
601  /// @brief Return a string describing a failed check.
602  std::string str() const
603  {
604  std::ostringstream ss;
605  ss << "outside the range of divergence ["<<minVal<<","<<maxVal<<"]";
606  return ss.str();
607  }
608 
611 };// CheckDivergence
612 
613 ////////////////////////////////////////////////////////////////////////////////
614 
615 /// @brief Performs multithreaded diagnostics of a grid
616 /// @note More documentation will be added soon!
617 template <typename GridT>
618 class Diagnose
619 {
620 public:
621  using MaskType = typename GridT::template ValueConverter<bool>::Type;
622 
623  Diagnose(const GridT& grid) : mGrid(&grid), mMask(new MaskType()), mCount(0)
624  {
625  mMask->setTransform(grid.transformPtr()->copy());
626  }
627 
628  template <typename CheckT>
629  std::string check(const CheckT& check,
630  bool updateMask = false,
631  bool checkVoxels = true,
632  bool checkTiles = true,
633  bool checkBackground = true)
634  {
635  typename MaskType::TreeType* mask = updateMask ? &(mMask->tree()) : nullptr;
636  CheckValues<CheckT> cc(mask, mGrid, check);
637  std::ostringstream ss;
638  if (checkBackground) ss << cc.checkBackground();
639  if (checkTiles) ss << cc.checkTiles();
640  if (checkVoxels) ss << cc.checkVoxels();
641  mCount += cc.mCount;
642  return ss.str();
643  }
644 
645  //@{
646  /// @brief Return a boolean mask of all the values
647  /// (i.e. tiles and/or voxels) that have failed one or
648  /// more checks.
649  typename MaskType::ConstPtr mask() const { return mMask; }
650  typename MaskType::Ptr mask() { return mMask; }
651  //@}
652 
653  /// @brief Return the number of values (i.e. background, tiles or
654  /// voxels) that have failed one or more checks.
655  Index64 valueCount() const { return mMask->activeVoxelCount(); }
656 
657  /// @brief Return total number of failed checks
658  /// @note If only one check was performed and the mask was updated
659  /// failureCount equals valueCount.
660  Index64 failureCount() const { return mCount; }
661 
662  /// @brief Return a const reference to the grid
663  const GridT& grid() const { return *mGrid; }
664 
665  /// @brief Clear the mask and error counter
666  void clear() { mMask = new MaskType(); mCount = 0; }
667 
668 private:
669  // disallow copy construction and copy by assignment!
670  Diagnose(const Diagnose&);// not implemented
671  Diagnose& operator=(const Diagnose&);// not implemented
672 
673  const GridT* mGrid;
674  typename MaskType::Ptr mMask;
675  Index64 mCount;
676 
677  /// @brief Private class that performs the multithreaded checks
678  template <typename CheckT>
679  struct CheckValues
680  {
681  using MaskT = typename MaskType::TreeType;
682  using LeafT = typename GridT::TreeType::LeafNodeType;
683  using LeafManagerT = typename tree::LeafManager<const typename GridT::TreeType>;
684  const bool mOwnsMask;
685  MaskT* mMask;
686  const GridT* mGrid;
687  const CheckT mCheck;
688  Index64 mCount;
689 
690  CheckValues(MaskT* mask, const GridT* grid, const CheckT& check)
691  : mOwnsMask(false)
692  , mMask(mask)
693  , mGrid(grid)
694  , mCheck(check)
695  , mCount(0)
696  {
697  }
698  CheckValues(CheckValues& other, tbb::split)
699  : mOwnsMask(true)
700  , mMask(other.mMask ? new MaskT() : nullptr)
701  , mGrid(other.mGrid)
702  , mCheck(other.mCheck)
703  , mCount(0)
704  {
705  }
706  ~CheckValues() { if (mOwnsMask) delete mMask; }
707 
708  std::string checkBackground()
709  {
710  std::ostringstream ss;
711  if (mCheck(mGrid->background())) {
712  ++mCount;
713  ss << "Background is " + mCheck.str() << std::endl;
714  }
715  return ss.str();
716  }
717 
718  std::string checkTiles()
719  {
720  std::ostringstream ss;
721  const Index64 n = mCount;
722  typename CheckT::TileIterT i(mGrid->tree());
723  for (i.setMaxDepth(GridT::TreeType::RootNodeType::LEVEL - 1); i; ++i) {
724  if (mCheck(i)) {
725  ++mCount;
726  if (mMask) mMask->fill(i.getBoundingBox(), true, true);
727  }
728  }
729  if (const Index64 m = mCount - n) {
730  ss << m << " tile" << (m==1 ? " is " : "s are ") + mCheck.str() << std::endl;
731  }
732  return ss.str();
733  }
734 
735  std::string checkVoxels()
736  {
737  std::ostringstream ss;
738  LeafManagerT leafs(mGrid->tree());
739  const Index64 n = mCount;
740  tbb::parallel_reduce(leafs.leafRange(), *this);
741  if (const Index64 m = mCount - n) {
742  ss << m << " voxel" << (m==1 ? " is " : "s are ") + mCheck.str() << std::endl;
743  }
744  return ss.str();
745  }
746 
747  void operator()(const typename LeafManagerT::LeafRange& r)
748  {
749  using VoxelIterT = typename CheckT::VoxelIterT;
750  if (mMask) {
751  for (typename LeafManagerT::LeafRange::Iterator i=r.begin(); i; ++i) {
752  typename MaskT::LeafNodeType* maskLeaf = nullptr;
753  for (VoxelIterT j = tree::IterTraits<LeafT, VoxelIterT>::begin(*i); j; ++j) {
754  if (mCheck(j)) {
755  ++mCount;
756  if (maskLeaf == nullptr) maskLeaf = mMask->touchLeaf(j.getCoord());
757  maskLeaf->setValueOn(j.pos(), true);
758  }
759  }
760  }
761  } else {
762  for (typename LeafManagerT::LeafRange::Iterator i=r.begin(); i; ++i) {
763  for (VoxelIterT j = tree::IterTraits<LeafT, VoxelIterT>::begin(*i); j; ++j) {
764  if (mCheck(j)) ++mCount;
765  }
766  }
767  }
768  }
769  void join(const CheckValues& other)
770  {
771  if (mMask) mMask->merge(*(other.mMask), openvdb::MERGE_ACTIVE_STATES_AND_NODES);
772  mCount += other.mCount;
773  }
774  };//End of private class CheckValues
775 
776 };// End of public class Diagnose
777 
778 
779 ////////////////////////////////////////////////////////////////////////////////
780 
781 /// @brief Class that performs various types of checks on narrow-band level sets.
782 ///
783 /// @note The most common usage is to simply call CheckLevelSet::check()
784 template<class GridType>
786 {
787 public:
788  using ValueType = typename GridType::ValueType;
789  using MaskType = typename GridType::template ValueConverter<bool>::Type;
790 
791  CheckLevelSet(const GridType& grid) : mDiagnose(grid) {}
792 
793  //@{
794  /// @brief Return a boolean mask of all the values
795  /// (i.e. tiles and/or voxels) that have failed one or
796  /// more checks.
797  typename MaskType::ConstPtr mask() const { return mDiagnose.mask(); }
798  typename MaskType::Ptr mask() { return mDiagnose.mask(); }
799  //@}
800 
801  /// @brief Return the number of values (i.e. background, tiles or
802  /// voxels) that have failed one or more checks.
803  Index64 valueCount() const { return mDiagnose.valueCount(); }
804 
805  /// @brief Return total number of failed checks
806  /// @note If only one check was performed and the mask was updated
807  /// failureCount equals valueCount.
808  Index64 failureCount() const { return mDiagnose.failureCount(); }
809 
810  /// @brief Return a const reference to the grid
811  const GridType& grid() const { return mDiagnose.grid(); }
812 
813  /// @brief Clear the mask and error counter
814  void clear() { mDiagnose.clear(); }
815 
816  /// @brief Return a nonempty message if the grid's value type is a floating point.
817  ///
818  /// @note No run-time overhead
820  {
822  return test ? "" : "Value type is not floating point\n";
823  }
824 
825  /// @brief Return message if the grid's class is a level set.
826  ///
827  /// @note Small run-time overhead
829  {
830  const bool test = mDiagnose.grid().getGridClass() == GRID_LEVEL_SET;
831  return test ? "" : "Class type is not \"GRID_LEVEL_SET\"\n";
832  }
833 
834  /// @brief Return a nonempty message if the grid's transform does not have uniform scaling.
835  ///
836  /// @note Small run-time overhead
838  {
839  return mDiagnose.grid().hasUniformVoxels() ? "" : "Does not have uniform voxels\n";
840  }
841 
842  /// @brief Return a nonempty message if the background value is larger than or
843  /// equal to the halfWidth*voxelSize.
844  ///
845  /// @note Small run-time overhead
846  std::string checkBackground(Real halfWidth = LEVEL_SET_HALF_WIDTH) const
847  {
848  const Real w = mDiagnose.grid().background() / mDiagnose.grid().voxelSize()[0];
849  if (w < halfWidth) {
850  std::ostringstream ss;
851  ss << "The background value ("<< mDiagnose.grid().background()<<") is less than "
852  << halfWidth << " voxel units\n";
853  return ss.str();
854  }
855  return "";
856  }
857 
858  /// @brief Return a nonempty message if the grid has no active tile values.
859  ///
860  /// @note Medium run-time overhead
862  {
863  const bool test = mDiagnose.grid().tree().hasActiveTiles();
864  return test ? "Has active tile values\n" : "";
865  }
866 
867  /// @brief Return a nonempty message if any of the values are not finite. i.e. NaN or inf.
868  ///
869  /// @note Medium run-time overhead
870  std::string checkFinite(bool updateMask = false)
871  {
873  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/true, /*background*/true);
874  }
875 
876  /// @brief Return a nonempty message if the active voxel values are out-of-range.
877  ///
878  /// @note Medium run-time overhead
879  std::string checkRange(bool updateMask = false)
880  {
881  const ValueType& background = mDiagnose.grid().background();
882  CheckRange<GridType> c(-background, background);
883  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/false, /*background*/false);
884  }
885 
886  /// @brief Return a nonempty message if the the inactive values do not have a
887  /// magnitude equal to the background value.
888  ///
889  /// @note Medium run-time overhead
890  std::string checkInactiveValues(bool updateMask = false)
891  {
892  const ValueType& background = mDiagnose.grid().background();
894  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/true, /*background*/false);
895  }
896 
897  /// @brief Return a nonempty message if the norm of the gradient of the
898  /// active voxels is out of the range minV to maxV.
899  ///
900  /// @note Significant run-time overhead
901  std::string checkEikonal(bool updateMask = false, ValueType minV = 0.5, ValueType maxV = 1.5)
902  {
903  CheckEikonal<GridType> c(mDiagnose.grid(), minV, maxV);
904  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/false, /*background*/false);
905  }
906 
907  /// @brief Return a nonempty message if an error or issue is detected. Only
908  /// runs tests with a number lower than or equal to n, where:
909  ///
910  /// Fast checks
911  /// 1: value type is floating point
912  /// 2: has level set class type
913  /// 3: has uniform scale
914  /// 4: background value is positive and n*dx
915  ///
916  /// Slower checks
917  /// 5: no active tiles
918  /// 6: all the values are finite, i.e not NaN or infinite
919  /// 7: active values in range between +-background
920  /// 8: abs of inactive values = background, i.e. assuming a symmetric narrow band!
921  ///
922  /// Relatively slow check (however multi-threaded)
923  /// 9: norm of gradient at zero-crossings is one, i.e. satisfied the Eikonal equation.
924  std::string check(size_t n=9, bool updateMask = false)
925  {
926  std::string str = this->checkValueType();
927  if (str.empty() && n>1) str = this->checkClassType();
928  if (str.empty() && n>2) str = this->checkTransform();
929  if (str.empty() && n>3) str = this->checkBackground();
930  if (str.empty() && n>4) str = this->checkTiles();
931  if (str.empty() && n>5) str = this->checkFinite(updateMask);
932  if (str.empty() && n>6) str = this->checkRange(updateMask);
933  if (str.empty() && n>7) str = this->checkInactiveValues(updateMask);
934  if (str.empty() && n>8) str = this->checkEikonal(updateMask);
935  return str;
936  }
937 
938 private:
939  // disallow copy construction and copy by assignment!
940  CheckLevelSet(const CheckLevelSet&);// not implemented
941  CheckLevelSet& operator=(const CheckLevelSet&);// not implemented
942 
943  // Member data
944  Diagnose<GridType> mDiagnose;
945 };// CheckLevelSet
946 
947 template<class GridType>
949 checkLevelSet(const GridType& grid, size_t n)
950 {
952  return c.check(n, false);
953 }
954 
955 ////////////////////////////////////////////////////////////////////////////////
956 
957 /// @brief Class that performs various types of checks on fog volumes.
958 ///
959 /// @note The most common usage is to simply call CheckFogVolume::check()
960 template<class GridType>
962 {
963 public:
964  using ValueType = typename GridType::ValueType;
965  using MaskType = typename GridType::template ValueConverter<bool>::Type;
966 
967  CheckFogVolume(const GridType& grid) : mDiagnose(grid) {}
968 
969  //@{
970  /// @brief Return a boolean mask of all the values
971  /// (i.e. tiles and/or voxels) that have failed one or
972  /// more checks.
973  typename MaskType::ConstPtr mask() const { return mDiagnose.mask(); }
974  typename MaskType::Ptr mask() { return mDiagnose.mask(); }
975  //@}
976 
977  /// @brief Return the number of values (i.e. background, tiles or
978  /// voxels) that have failed one or more checks.
979  Index64 valueCount() const { return mDiagnose.valueCount(); }
980 
981  /// @brief Return total number of failed checks
982  /// @note If only one check was performed and the mask was updated
983  /// failureCount equals valueCount.
984  Index64 failureCount() const { return mDiagnose.failureCount(); }
985 
986  /// @brief Return a const reference to the grid
987  const GridType& grid() const { return mDiagnose.grid(); }
988 
989  /// @brief Clear the mask and error counter
990  void clear() { mDiagnose.clear(); }
991 
992  /// @brief Return a nonempty message if the grid's value type is a floating point.
993  ///
994  /// @note No run-time overhead
996  {
998  return test ? "" : "Value type is not floating point";
999  }
1000 
1001  /// @brief Return a nonempty message if the grid's class is a level set.
1002  ///
1003  /// @note Small run-time overhead
1005  {
1006  const bool test = mDiagnose.grid().getGridClass() == GRID_FOG_VOLUME;
1007  return test ? "" : "Class type is not \"GRID_LEVEL_SET\"";
1008  }
1009 
1010  /// @brief Return a nonempty message if the background value is not zero.
1011  ///
1012  /// @note Small run-time overhead
1014  {
1015  if (!math::isApproxZero(mDiagnose.grid().background())) {
1016  std::ostringstream ss;
1017  ss << "The background value ("<< mDiagnose.grid().background()<<") is not zero";
1018  return ss.str();
1019  }
1020  return "";
1021  }
1022 
1023  /// @brief Return a nonempty message if any of the values are not finite. i.e. NaN or inf.
1024  ///
1025  /// @note Medium run-time overhead
1026  std::string checkFinite(bool updateMask = false)
1027  {
1029  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/true, /*background*/true);
1030  }
1031 
1032  /// @brief Return a nonempty message if any of the inactive values are not zero.
1033  ///
1034  /// @note Medium run-time overhead
1035  std::string checkInactiveValues(bool updateMask = false)
1036  {
1038  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/true, /*background*/true);
1039  }
1040 
1041  /// @brief Return a nonempty message if the active voxel values
1042  /// are out-of-range, i.e. not in the range [0,1].
1043  ///
1044  /// @note Medium run-time overhead
1045  std::string checkRange(bool updateMask = false)
1046  {
1047  CheckRange<GridType> c(0, 1);
1048  return mDiagnose.check(c, updateMask, /*voxel*/true, /*tiles*/true, /*background*/false);
1049  }
1050 
1051  /// @brief Return a nonempty message if an error or issue is detected. Only
1052  /// runs tests with a number lower than or equal to n, where:
1053  ///
1054  /// Fast checks
1055  /// 1: value type is floating point
1056  /// 2: has FOG volume class type
1057  /// 3: background value is zero
1058  ///
1059  /// Slower checks
1060  /// 4: all the values are finite, i.e not NaN or infinite
1061  /// 5: inactive values are zero
1062  /// 6: active values are in the range [0,1]
1063  std::string check(size_t n=6, bool updateMask = false)
1064  {
1065  std::string str = this->checkValueType();
1066  if (str.empty() && n>1) str = this->checkClassType();
1067  if (str.empty() && n>2) str = this->checkBackground();
1068  if (str.empty() && n>3) str = this->checkFinite(updateMask);
1069  if (str.empty() && n>4) str = this->checkInactiveValues(updateMask);
1070  if (str.empty() && n>5) str = this->checkRange(updateMask);
1071  return str;
1072  }
1073 
1074 private:
1075  // disallow copy construction and copy by assignment!
1076  CheckFogVolume(const CheckFogVolume&);// not implemented
1077  CheckFogVolume& operator=(const CheckFogVolume&);// not implemented
1078 
1079  // Member data
1080  Diagnose<GridType> mDiagnose;
1081 };// CheckFogVolume
1082 
1083 template<class GridType>
1085 checkFogVolume(const GridType& grid, size_t n)
1086 {
1088  return c.check(n, false);
1089 }
1090 
1091 
1092 ////////////////////////////////////////////////////////////////////////////////
1093 
1094 // Internal utility objects and implementation details
1095 
1096 /// @cond OPENVDB_DOCS_INTERNAL
1097 
1098 namespace diagnostics_internal {
1099 
1100 
1101 template<typename TreeType>
1102 class InactiveVoxelValues
1103 {
1104 public:
1105  using LeafArray = tree::LeafManager<TreeType>;
1106  using ValueType = typename TreeType::ValueType;
1107  using SetType = std::set<ValueType>;
1108 
1109  InactiveVoxelValues(LeafArray&, size_t numValues);
1110 
1111  void runParallel();
1112  void runSerial();
1113 
1114  void getInactiveValues(SetType&) const;
1115 
1116  inline InactiveVoxelValues(const InactiveVoxelValues<TreeType>&, tbb::split);
1117  inline void operator()(const tbb::blocked_range<size_t>&);
1118  inline void join(const InactiveVoxelValues<TreeType>&);
1119 
1120 private:
1121  LeafArray& mLeafArray;
1122  SetType mInactiveValues;
1123  size_t mNumValues;
1124 };// InactiveVoxelValues
1125 
1126 template<typename TreeType>
1127 InactiveVoxelValues<TreeType>::InactiveVoxelValues(LeafArray& leafs, size_t numValues)
1128  : mLeafArray(leafs)
1129  , mInactiveValues()
1130  , mNumValues(numValues)
1131 {
1132 }
1133 
1134 template <typename TreeType>
1135 inline
1136 InactiveVoxelValues<TreeType>::InactiveVoxelValues(
1137  const InactiveVoxelValues<TreeType>& rhs, tbb::split)
1138  : mLeafArray(rhs.mLeafArray)
1139  , mInactiveValues()
1140  , mNumValues(rhs.mNumValues)
1141 {
1142 }
1143 
1144 template<typename TreeType>
1145 void
1146 InactiveVoxelValues<TreeType>::runParallel()
1147 {
1148  tbb::parallel_reduce(mLeafArray.getRange(), *this);
1149 }
1150 
1151 
1152 template<typename TreeType>
1153 void
1154 InactiveVoxelValues<TreeType>::runSerial()
1155 {
1156  (*this)(mLeafArray.getRange());
1157 }
1158 
1159 
1160 template<typename TreeType>
1161 inline void
1162 InactiveVoxelValues<TreeType>::operator()(const tbb::blocked_range<size_t>& range)
1163 {
1164  typename TreeType::LeafNodeType::ValueOffCIter iter;
1165 
1166  for (size_t n = range.begin(); n < range.end() && !thread::isGroupExecutionCancelled(); ++n) {
1167  for (iter = mLeafArray.leaf(n).cbeginValueOff(); iter; ++iter) {
1168  mInactiveValues.insert(iter.getValue());
1169  }
1170 
1171  if (mInactiveValues.size() > mNumValues) {
1173  }
1174  }
1175 }
1176 
1177 template<typename TreeType>
1178 inline void
1179 InactiveVoxelValues<TreeType>::join(const InactiveVoxelValues<TreeType>& rhs)
1180 {
1181  mInactiveValues.insert(rhs.mInactiveValues.begin(), rhs.mInactiveValues.end());
1182 }
1183 
1184 template<typename TreeType>
1185 inline void
1186 InactiveVoxelValues<TreeType>::getInactiveValues(SetType& values) const
1187 {
1188  values.insert(mInactiveValues.begin(), mInactiveValues.end());
1189 }
1190 
1191 
1192 ////////////////////////////////////////
1193 
1194 
1195 template<typename TreeType>
1196 class InactiveTileValues
1197 {
1198 public:
1199  using IterRange = tree::IteratorRange<typename TreeType::ValueOffCIter>;
1200  using ValueType = typename TreeType::ValueType;
1201  using SetType = std::set<ValueType>;
1202 
1203  InactiveTileValues(size_t numValues);
1204 
1205  void runParallel(IterRange&);
1206  void runSerial(IterRange&);
1207 
1208  void getInactiveValues(SetType&) const;
1209 
1210  inline InactiveTileValues(const InactiveTileValues<TreeType>&, tbb::split);
1211  inline void operator()(IterRange&);
1212  inline void join(const InactiveTileValues<TreeType>&);
1213 
1214 private:
1215  SetType mInactiveValues;
1216  size_t mNumValues;
1217 };
1218 
1219 
1220 template<typename TreeType>
1221 InactiveTileValues<TreeType>::InactiveTileValues(size_t numValues)
1222  : mInactiveValues()
1223  , mNumValues(numValues)
1224 {
1225 }
1226 
1227 template <typename TreeType>
1228 inline
1229 InactiveTileValues<TreeType>::InactiveTileValues(
1230  const InactiveTileValues<TreeType>& rhs, tbb::split)
1231  : mInactiveValues()
1232  , mNumValues(rhs.mNumValues)
1233 {
1234 }
1235 
1236 template<typename TreeType>
1237 void
1238 InactiveTileValues<TreeType>::runParallel(IterRange& range)
1239 {
1240  tbb::parallel_reduce(range, *this);
1241 }
1242 
1243 
1244 template<typename TreeType>
1245 void
1246 InactiveTileValues<TreeType>::runSerial(IterRange& range)
1247 {
1248  (*this)(range);
1249 }
1250 
1251 
1252 template<typename TreeType>
1253 inline void
1254 InactiveTileValues<TreeType>::operator()(IterRange& range)
1255 {
1256  for (; range && !thread::isGroupExecutionCancelled(); ++range) {
1257  typename TreeType::ValueOffCIter iter = range.iterator();
1258  for (; iter; ++iter) {
1259  mInactiveValues.insert(iter.getValue());
1260  }
1261 
1262  if (mInactiveValues.size() > mNumValues) {
1264  }
1265  }
1266 }
1267 
1268 template<typename TreeType>
1269 inline void
1270 InactiveTileValues<TreeType>::join(const InactiveTileValues<TreeType>& rhs)
1271 {
1272  mInactiveValues.insert(rhs.mInactiveValues.begin(), rhs.mInactiveValues.end());
1273 }
1274 
1275 template<typename TreeType>
1276 inline void
1277 InactiveTileValues<TreeType>::getInactiveValues(SetType& values) const
1278 {
1279  values.insert(mInactiveValues.begin(), mInactiveValues.end());
1280 }
1281 
1282 } // namespace diagnostics_internal
1283 
1284 /// @endcond
1285 
1286 ////////////////////////////////////////
1287 
1288 
1289 template<class GridType>
1290 bool
1291 uniqueInactiveValues(const GridType& grid,
1292  std::vector<typename GridType::ValueType>& values, size_t numValues)
1293 {
1294  using TreeType = typename GridType::TreeType;
1295  using ValueType = typename GridType::ValueType;
1296  using SetType = std::set<ValueType>;
1297 
1298  SetType uniqueValues;
1299 
1300  { // Check inactive voxels
1301  TreeType& tree = const_cast<TreeType&>(grid.tree());
1302  tree::LeafManager<TreeType> leafs(tree);
1303  diagnostics_internal::InactiveVoxelValues<TreeType> voxelOp(leafs, numValues);
1304  voxelOp.runParallel();
1305  voxelOp.getInactiveValues(uniqueValues);
1306  }
1307 
1308  // Check inactive tiles
1309  if (uniqueValues.size() <= numValues) {
1310  typename TreeType::ValueOffCIter iter(grid.tree());
1311  iter.setMaxDepth(TreeType::ValueAllIter::LEAF_DEPTH - 1);
1312  diagnostics_internal::InactiveTileValues<TreeType> tileOp(numValues);
1313 
1315  tileOp.runParallel(range);
1316 
1317  tileOp.getInactiveValues(uniqueValues);
1318  }
1319 
1320  values.clear();
1321  values.reserve(uniqueValues.size());
1322 
1323  typename SetType::iterator it = uniqueValues.begin();
1324  for ( ; it != uniqueValues.end(); ++it) {
1325  values.push_back(*it);
1326  }
1327 
1328  return values.size() <= numValues;
1329 }
1330 
1331 } // namespace tools
1332 } // namespace OPENVDB_VERSION_NAME
1333 } // namespace openvdb
1334 
1335 #endif // OPENVDB_TOOLS_DIAGNOSTICS_HAS_BEEN_INCLUDED
bool operator()(const VoxelIterT &iter) const
Return true if the tile at the iterator location is NaN or infinite.
Definition: Diagnostics.h:213
std::string checkRange(bool updateMask=false)
Return a nonempty message if the active voxel values are out-of-range, i.e. not in the range [0...
Definition: Diagnostics.h:1045
std::string checkInactiveValues(bool updateMask=false)
Return a nonempty message if any of the inactive values are not zero.
Definition: Diagnostics.h:1035
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:116
cvex test(vector P=0;int unbound=3;export float s=0;export vector Cf=0;)
Definition: test.vfl:11
MeshToVoxelEdgeData::EdgeData Abs(const MeshToVoxelEdgeData::EdgeData &x)
bool operator()(const VoxelIterT &iter) const
Return true if the voxel at the iterator location is larger than max.
Definition: Diagnostics.h:404
bool operator()(const ElementType &v) const
Return true if the value is NOT finite, i.e. it's NaN or infinite.
Definition: Diagnostics.h:199
MaskType::Ptr mask()
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:974
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:193
bool operator()(const VoxelIterT &iter) const
Return true if the voxel at the iterator location is NaN.
Definition: Diagnostics.h:137
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:477
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:282
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:384
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:380
bool operator()(const VoxelIterT &iter) const
Return true if the divergence at a voxel location of the iterator is out of range.
Definition: Diagnostics.h:595
MaskType::ConstPtr mask() const
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:649
Type Pow2(Type x)
Return x2.
Definition: Math.h:551
typename GridType::template ValueConverter< bool >::Type MaskType
Definition: Diagnostics.h:789
Checks for both NaN and inf values, i.e. any value that is not finite.
Definition: Diagnostics.h:187
typename T::ValueType ElementType
Definition: Types.h:204
std::string checkBackground() const
Return a nonempty message if the background value is not zero.
Definition: Diagnostics.h:1013
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:189
MaskType::Ptr mask()
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:798
static Accessor::ValueType result(const Accessor &grid, const Coord &ijk)
Definition: Operators.h:239
const GLfloat * c
Definition: glew.h:16631
bool operator()(const ValueType &v) const
Return true if the value is smaller than min or larger than max.
Definition: Diagnostics.h:462
Index64 valueCount() const
Return the number of values (i.e. background, tiles or voxels) that have failed one or more checks...
Definition: Diagnostics.h:803
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:541
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:407
bool operator()(const ElementType &v) const
Return true if the value is larger than max.
Definition: Diagnostics.h:390
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:140
bool operator()(const TreeIterT &) const
Return true if zero is outside the range.
Definition: Diagnostics.h:529
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:178
CheckRange(const ElementType &_min, const ElementType &_max)
Definition: Diagnostics.h:289
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:336
bool operator()(const TreeIterT &iter) const
Return true if the tile at the iterator location is NaN.
Definition: Diagnostics.h:134
bool operator()(const TreeIterT &iter) const
Return true if the tile at the iterator location is NaN or infinite.
Definition: Diagnostics.h:210
bool operator()(const TreeIterT &iter) const
Return true if the tile at the iterator location is infinite.
Definition: Diagnostics.h:173
std::string checkFinite(bool updateMask=false)
Return a nonempty message if any of the values are not finite. i.e. NaN or inf.
Definition: Diagnostics.h:870
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are infinite.
Definition: Diagnostics.h:250
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:263
CheckEikonal(const GridT &grid, const ValueType &_min, const ValueType &_max)
Constructor taking a grid and a range to be tested against.
Definition: Diagnostics.h:508
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:112
GLdouble GLdouble t
Definition: glew.h:1403
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are smaller than min.
Definition: Diagnostics.h:351
Tolerance for floating-point comparison.
Definition: Math.h:147
Performs multithreaded diagnostics of a grid.
Definition: Diagnostics.h:618
BiasedGradientScheme
Biased Gradients are limited to non-centered differences.
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are larger than max.
Definition: Diagnostics.h:395
GLenum GLsizei GLsizei GLint * values
Definition: glcorearb.h:1601
Index64 valueCount() const
Return the number of values (i.e. background, tiles or voxels) that have failed one or more checks...
Definition: Diagnostics.h:655
DScheme
Different discrete schemes used in the first derivatives.
bool operator()(const TreeIterT &iter) const
Return true if the tile at the iterator location is infinite.
Definition: Diagnostics.h:257
typename GridType::template ValueConverter< bool >::Type MaskType
Definition: Diagnostics.h:621
GLubyte GLubyte GLubyte GLubyte w
Definition: glcorearb.h:856
std::string checkTransform() const
Return a nonempty message if the grid's transform does not have uniform scaling.
Definition: Diagnostics.h:837
std::string checkFinite(bool updateMask=false)
Return a nonempty message if any of the values are not finite. i.e. NaN or inf.
Definition: Diagnostics.h:1026
CheckDivergence(const GridT &grid, const ValueType &_min, const ValueType &_max)
Constructor taking a grid and a range to be tested against.
Definition: Diagnostics.h:571
static std::string checkValueType()
Return a nonempty message if the grid's value type is a floating point.
Definition: Diagnostics.h:995
void OIIO_API split(string_view str, std::vector< string_view > &result, string_view sep=string_view(), int maxsplit=-1)
GLint GLint GLsizei GLint GLenum GLenum type
Definition: glcorearb.h:107
bool operator()(const VoxelIterT &iter) const
Return true if the tile at the iterator location is out of range.
Definition: Diagnostics.h:315
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:179
Coord Abs(const Coord &xyz)
Definition: Coord.h:514
std::string check(const CheckT &check, bool updateMask=false, bool checkVoxels=true, bool checkTiles=true, bool checkBackground=true)
Definition: Diagnostics.h:629
bool operator()(const ElementType &v) const
Return true if the scalar value is NaN.
Definition: Diagnostics.h:122
GLint GLuint mask
Definition: glcorearb.h:123
bool operator()(const ElementType &v) const
Return true if the value is smaller than min.
Definition: Diagnostics.h:346
CheckMax(const ElementType &_max)
Constructor taking a maximum to be tested against.
Definition: Diagnostics.h:387
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:151
Checks a value against a maximum.
Definition: Diagnostics.h:378
std::string check(size_t n=9, bool updateMask=false)
Return a nonempty message if an error or issue is detected. Only runs tests with a number lower than ...
Definition: Diagnostics.h:924
const GLdouble * v
Definition: glcorearb.h:836
std::string checkClassType() const
Return message if the grid's class is a level set.
Definition: Diagnostics.h:828
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1221
Index64 failureCount() const
Return total number of failed checks.
Definition: Diagnostics.h:984
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:363
GLsizei const GLchar *const * string
Definition: glcorearb.h:813
Index64 failureCount() const
Return total number of failed checks.
Definition: Diagnostics.h:808
std::string checkBackground(Real halfWidth=LEVEL_SET_HALF_WIDTH) const
Return a nonempty message if the background value is larger than or equal to the halfWidth*voxelSize...
Definition: Diagnostics.h:846
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:764
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:216
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:84
const GridType & grid() const
Return a const reference to the grid.
Definition: Diagnostics.h:987
MaskType::ConstPtr mask() const
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:973
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:505
std::string checkFogVolume(const GridType &grid, size_t number=6)
Perform checks on a grid to see if it is a valid fog volume.
Definition: Diagnostics.h:1085
MaskType::Ptr mask()
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:650
static std::string checkValueType()
Return a nonempty message if the grid's value type is a floating point.
Definition: Diagnostics.h:819
bool operator()(const ElementType &v) const
Return true if the value is infinite.
Definition: Diagnostics.h:161
void clear()
Clear the mask and error counter.
Definition: Diagnostics.h:666
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:435
Checks the norm of the gradient at zero-crossing voxels against a range.
Definition: Diagnostics.h:497
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:350
bool operator()(const VoxelIterT &iter) const
Return true if the tile at the iterator location is infinite.
Definition: Diagnostics.h:260
bool operator()(const TreeIterT &iter) const
Return true if the voxel at the iterator location is smaller than min.
Definition: Diagnostics.h:357
std::string checkInactiveValues(bool updateMask=false)
Return a nonempty message if the the inactive values do not have a magnitude equal to the background ...
Definition: Diagnostics.h:890
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
This allows for vector values to be checked component-wise.
Definition: Diagnostics.h:127
Checks the divergence against a range.
Definition: Diagnostics.h:558
static Accessor::ValueType::value_type result(const Accessor &grid, const Coord &ijk)
Definition: Operators.h:476
GLdouble n
Definition: glcorearb.h:2007
bool operator()(const VoxelIterT &iter) const
Return true if the tile at the iterator location is smaller than min.
Definition: Diagnostics.h:360
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are NaN or infinite.
Definition: Diagnostics.h:204
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are infinite.
Definition: Diagnostics.h:166
MaskType::ConstPtr mask() const
Return a boolean mask of all the values (i.e. tiles and/or voxels) that have failed one or more check...
Definition: Diagnostics.h:797
Checks the norm of the gradient against a range, i.e., |∇Φ| ∈ [min, max].
Definition: Diagnostics.h:427
Checks a value against a range.
Definition: Diagnostics.h:280
bool operator()(const ValueType &v) const
Return true if the value is smaller than min or larger than max.
Definition: Diagnostics.h:525
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:602
std::string check(size_t n=6, bool updateMask=false)
Return a nonempty message if an error or issue is detected. Only runs tests with a number lower than ...
Definition: Diagnostics.h:1063
std::string checkClassType() const
Return a nonempty message if the grid's class is a level set.
Definition: Diagnostics.h:1004
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:155
bool operator()(const ElementType &v) const
Definition: Diagnostics.h:242
bool operator()(const VoxelIterT &iter) const
Return true if the tile at the iterator location is infinite.
Definition: Diagnostics.h:176
std::string checkLevelSet(const GridType &grid, size_t number=9)
Perform checks on a grid to see if it is a valid symmetric, narrow-band level set.
Definition: Diagnostics.h:949
Index64 valueCount() const
Return the number of values (i.e. background, tiles or voxels) that have failed one or more checks...
Definition: Diagnostics.h:979
bool operator()(const TreeIterT &iter) const
Return true if the voxel at the iterator location is out of range.
Definition: Diagnostics.h:312
std::string str() const
Return a string describing a failed check.
Definition: Diagnostics.h:318
Class that performs various types of checks on fog volumes.
Definition: Diagnostics.h:961
typename VecTraits< ValueType >::ElementType ElementType
Definition: Diagnostics.h:561
std::enable_if< VecTraits< T >::IsVec, bool >::type operator()(const T &v) const
Return true if any of the vector components are out of range.
Definition: Diagnostics.h:306
bool operator()(const ElementType &v) const
Return true if the value is smaller than min or larger than max.
Definition: Diagnostics.h:297
const GLdouble * m
Definition: glew.h:9166
GLsizei const GLfloat * value
Definition: glcorearb.h:823
const GridT & grid() const
Return a const reference to the grid.
Definition: Diagnostics.h:663
Defines various finite difference stencils by means of the "curiously recurring template pattern" on ...
This is a special 19-point stencil that supports optimal fifth-order WENO upwinding, second-order central differencing, Laplacian, and zero-crossing test.
Definition: Stencils.h:1365
bool operator()(const TreeIterT &) const
Return true if zero is outside the range.
Definition: Diagnostics.h:591
GLenum GLint * range
Definition: glcorearb.h:1924
CheckMagnitude(const ElementType &a, const ElementType &t=math::Tolerance< ElementType >::value())
Default constructor.
Definition: Diagnostics.h:234
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:567
std::string checkRange(bool updateMask=false)
Return a nonempty message if the active voxel values are out-of-range.
Definition: Diagnostics.h:879
bool operator()(const TreeIterT &iter) const
Return true if the tile at the iterator location is larger than max.
Definition: Diagnostics.h:401
A LeafManager manages a linear array of pointers to a given tree's leaf nodes, as well as optional au...
Index64 failureCount() const
Return total number of failed checks.
Definition: Diagnostics.h:660
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:231
GLint GLfloat GLint stencil
Definition: glcorearb.h:1277
bool uniqueInactiveValues(const GridType &grid, std::vector< typename GridType::ValueType > &values, size_t numValues)
Threaded method to find unique inactive values.
Definition: Diagnostics.h:1291
std::string checkEikonal(bool updateMask=false, ValueType minV=0.5, ValueType maxV=1.5)
Return a nonempty message if the norm of the gradient of the active voxels is out of the range minV t...
Definition: Diagnostics.h:901
GLboolean r
Definition: glcorearb.h:1221
bool operator()(const VoxelIterT &iter) const
Return true if the norm of the gradient at a voxel location of the iterator is out of range...
Definition: Diagnostics.h:470
Class that performs various types of checks on narrow-band level sets.
Definition: Diagnostics.h:785
typename VecTraits< typename GridT::ValueType >::ElementType ElementType
Definition: Diagnostics.h:227
const GridType & grid() const
Return a const reference to the grid.
Definition: Diagnostics.h:811
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:340
Checks for infinite values, e.g. 1/0 or -1/0.
Definition: Diagnostics.h:149
std::string checkTiles() const
Return a nonempty message if the grid has no active tile values.
Definition: Diagnostics.h:861
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:114
typename tree::IterTraits< typename TreeIterT::NodeT, typename TreeIterT::ValueIterT >::template NodeConverter< typename GridT::TreeType::LeafNodeType >::Type VoxelIterT
Definition: Diagnostics.h:286
arg_join< It, Sentinel, char > join(It begin, Sentinel end, string_view sep)
Definition: format.h:3681
bool operator()(const VoxelIterT &iter) const
Return true if the norm of the gradient at a zero-crossing voxel location of the iterator is out of r...
Definition: Diagnostics.h:533
void clear()
Clear the mask and error counter.
Definition: Diagnostics.h:990
bool operator()(const ElementType &v) const
Return true if the value is smaller than min or larger than max.
Definition: Diagnostics.h:587
CheckNormGrad(const GridT &grid, const ValueType &_min, const ValueType &_max)
Constructor taking a grid and a range to be tested against.
Definition: Diagnostics.h:439
Checks a value against a minimum.
Definition: Diagnostics.h:334
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
void clear()
Clear the mask and error counter.
Definition: Diagnostics.h:814
typename GridType::template ValueConverter< bool >::Type MaskType
Definition: Diagnostics.h:965
bool operator()(const TreeIterT &) const
Return true if zero is outside the range.
Definition: Diagnostics.h:466
Check that the magnitude of a value, a, is close to a fixed magnitude, b, given a fixed tolerance c...
Definition: Diagnostics.h:225