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