HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ChangeBackground.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 ChangeBackground.h
5 ///
6 /// @brief Efficient multi-threaded replacement of the background
7 /// values in tree.
8 ///
9 /// @author Ken Museth
10 
11 #ifndef OPENVDB_TOOLS_ChangeBACKGROUND_HAS_BEEN_INCLUDED
12 #define OPENVDB_TOOLS_ChangeBACKGROUND_HAS_BEEN_INCLUDED
13 
14 #include <openvdb/math/Math.h> // for isNegative and negative
15 #include <openvdb/Types.h> // for Index typedef
17 
18 
19 namespace openvdb {
21 namespace OPENVDB_VERSION_NAME {
22 namespace tools {
23 
24 /// @brief Replace the background value in all the nodes of a tree.
25 /// @details The sign of the background value is preserved, and only
26 /// inactive values equal to the old background value are replaced.
27 ///
28 /// @note If a LeafManager is used the cached leaf nodes are reused,
29 /// resulting in slightly better overall performance.
30 ///
31 /// @param tree Tree (or LeafManager) that will have its background value changed
32 /// @param background the new background value
33 /// @param threaded enable or disable threading (threading is enabled by default)
34 /// @param grainSize used to control the threading granularity (default is 32)
35 template<typename TreeOrLeafManagerT>
36 inline void
38  TreeOrLeafManagerT& tree,
39  const typename TreeOrLeafManagerT::ValueType& background,
40  bool threaded = true,
41  size_t grainSize = 32);
42 
43 
44 /// @brief Replace the background value in all the nodes of a floating-point tree
45 /// containing a symmetric narrow-band level set.
46 /// @details All inactive values will be set to +| @a halfWidth | if outside
47 /// and -| @a halfWidth | if inside, where @a halfWidth is half the width
48 /// of the symmetric narrow band.
49 ///
50 /// @note This method is faster than changeBackground since it does not
51 /// perform tests to see if inactive values are equal to the old background value.
52 /// @note If a LeafManager is used the cached leaf nodes are reused,
53 /// resulting in slightly better overall performance.
54 ///
55 /// @param tree Tree (or LeafManager) that will have its background value changed
56 /// @param halfWidth half of the width of the symmetric narrow band
57 /// @param threaded enable or disable threading (threading is enabled by default)
58 /// @param grainSize used to control the threading granularity (default is 32)
59 ///
60 /// @throw ValueError if @a halfWidth is negative (as defined by math::isNegative)
61 template<typename TreeOrLeafManagerT>
62 inline void
64  TreeOrLeafManagerT& tree,
65  const typename TreeOrLeafManagerT::ValueType& halfWidth,
66  bool threaded = true,
67  size_t grainSize = 32);
68 
69 
70 /// @brief Replace the background values in all the nodes of a floating-point tree
71 /// containing a possibly asymmetric narrow-band level set.
72 /// @details All inactive values will be set to +| @a outsideWidth | if outside
73 /// and -| @a insideWidth | if inside, where @a outsideWidth is the outside
74 /// width of the narrow band and @a insideWidth is its inside width.
75 ///
76 /// @note This method is faster than changeBackground since it does not
77 /// perform tests to see if inactive values are equal to the old background value.
78 /// @note If a LeafManager is used the cached leaf nodes are reused,
79 /// resulting in slightly better overall performance.
80 ///
81 /// @param tree Tree (or LeafManager) that will have its background value changed
82 /// @param outsideWidth The width of the outside of the narrow band
83 /// @param insideWidth The width of the inside of the narrow band
84 /// @param threaded enable or disable threading (threading is enabled by default)
85 /// @param grainSize used to control the threading granularity (default is 32)
86 ///
87 /// @throw ValueError if @a outsideWidth is negative or @a insideWidth is
88 /// not negative (as defined by math::isNegative)
89 template<typename TreeOrLeafManagerT>
90 inline void
92  TreeOrLeafManagerT& tree,
93  const typename TreeOrLeafManagerT::ValueType& outsideWidth,
94  const typename TreeOrLeafManagerT::ValueType& insideWidth,
95  bool threaded = true,
96  size_t grainSize = 32);
97 
98 
99 //////////////////////////////////////////////////////
100 
101 
102 // Replaces the background value in a Tree of any type.
103 template<typename TreeOrLeafManagerT>
105 {
106 public:
107  typedef typename TreeOrLeafManagerT::ValueType ValueT;
108  typedef typename TreeOrLeafManagerT::RootNodeType RootT;
109  typedef typename TreeOrLeafManagerT::LeafNodeType LeafT;
110 
111 
112  ChangeBackgroundOp(const TreeOrLeafManagerT& tree, const ValueT& newValue)
113  : mOldValue(tree.root().background())
114  , mNewValue(newValue)
115  {
116  }
117  void operator()(RootT& root) const
118  {
119  for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
120  root.setBackground(mNewValue, false);
121  }
122  void operator()(LeafT& node) const
123  {
124  for (typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
125  }
126  template<typename NodeT>
127  void operator()(NodeT& node) const
128  {
129  typename NodeT::NodeMaskType mask = node.getValueOffMask();
130  for (typename NodeT::ValueOnIter it(mask.beginOn(), &node); it; ++it) this->set(it);
131  }
132 private:
133 
134  template<typename IterT>
135  inline void set(IterT& iter) const
136  {
137  if (math::isApproxEqual(*iter, mOldValue)) {
138  iter.setValue(mNewValue);
139  } else if (math::isApproxEqual(*iter, math::negative(mOldValue))) {
140  iter.setValue(math::negative(mNewValue));
141  }
142  }
143  const ValueT mOldValue, mNewValue;
144 };// ChangeBackgroundOp
145 
146 
147 // Replaces the background value in a Tree assumed to represent a
148 // level set. It is generally faster than ChangeBackgroundOp.
149 // Note that is follows the sign-convention that outside is positive
150 // and inside is negative!
151 template<typename TreeOrLeafManagerT>
153 {
154 public:
155  typedef typename TreeOrLeafManagerT::ValueType ValueT;
156  typedef typename TreeOrLeafManagerT::RootNodeType RootT;
157  typedef typename TreeOrLeafManagerT::LeafNodeType LeafT;
158 
159  /// @brief Constructor for asymmetric narrow-bands
160  ChangeLevelSetBackgroundOp(const ValueT& outside, const ValueT& inside)
161  : mOutside(outside)
162  , mInside(inside)
163  {
164  if (math::isNegative(mOutside)) {
165  OPENVDB_THROW(ValueError,
166  "ChangeLevelSetBackgroundOp: the outside value cannot be negative!");
167  }
168  if (!math::isNegative(mInside)) {
169  OPENVDB_THROW(ValueError,
170  "ChangeLevelSetBackgroundOp: the inside value must be negative!");
171  }
172  }
173  void operator()(RootT& root) const
174  {
175  for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
176  root.setBackground(mOutside, false);
177  }
178  void operator()(LeafT& node) const
179  {
180  for(typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
181  }
182  template<typename NodeT>
183  void operator()(NodeT& node) const
184  {
185  typedef typename NodeT::ValueOffIter IterT;
186  for (IterT it(node.getChildMask().beginOff(), &node); it; ++it) this->set(it);
187  }
188 private:
189 
190  template<typename IterT>
191  inline void set(IterT& iter) const
192  {
193  //this is safe since we know ValueType is_floating_point
194  ValueT& v = const_cast<ValueT&>(*iter);
195  v = v < 0 ? mInside : mOutside;
196  }
197  const ValueT mOutside, mInside;
198 };// ChangeLevelSetBackgroundOp
199 
200 
201 template<typename TreeOrLeafManagerT>
202 inline void
204  TreeOrLeafManagerT& tree,
205  const typename TreeOrLeafManagerT::ValueType& background,
206  bool threaded,
207  size_t grainSize)
208 {
209  tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
210  ChangeBackgroundOp<TreeOrLeafManagerT> op(tree, background);
211  linearTree.foreachTopDown(op, threaded, grainSize);
212 }
213 
214 
215 template<typename TreeOrLeafManagerT>
216 inline void
218  TreeOrLeafManagerT& tree,
219  const typename TreeOrLeafManagerT::ValueType& outsideValue,
220  const typename TreeOrLeafManagerT::ValueType& insideValue,
221  bool threaded,
222  size_t grainSize)
223 {
224  tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
225  ChangeLevelSetBackgroundOp<TreeOrLeafManagerT> op(outsideValue, insideValue);
226  linearTree.foreachTopDown(op, threaded, grainSize);
227 }
228 
229 
230 // If the narrow-band is symmetric only one background value is required
231 template<typename TreeOrLeafManagerT>
232 inline void
234  TreeOrLeafManagerT& tree,
235  const typename TreeOrLeafManagerT::ValueType& background,
236  bool threaded,
237  size_t grainSize)
238 {
240  tree, background, math::negative(background), threaded, grainSize);
241 }
242 
243 } // namespace tools
244 } // namespace OPENVDB_VERSION_NAME
245 } // namespace openvdb
246 
247 #endif // OPENVDB_TOOLS_CHANGEBACKGROUND_HAS_BEEN_INCLUDED
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:127
void changeBackground(TreeOrLeafManagerT &tree, const typename TreeOrLeafManagerT::ValueType &background, bool threaded=true, size_t grainSize=32)
Replace the background value in all the nodes of a tree.
void changeLevelSetBackground(TreeOrLeafManagerT &tree, const typename TreeOrLeafManagerT::ValueType &halfWidth, bool threaded=true, size_t grainSize=32)
Replace the background value in all the nodes of a floating-point tree containing a symmetric narrow-...
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:178
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:368
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays, one for each level of the tree.
Definition: NodeManager.h:30
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:407
GLint GLuint mask
Definition: glcorearb.h:123
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
const GLdouble * v
Definition: glcorearb.h:836
ChangeLevelSetBackgroundOp(const ValueT &outside, const ValueT &inside)
Constructor for asymmetric narrow-bands.
ChangeBackgroundOp(const TreeOrLeafManagerT &tree, const ValueT &newValue)
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:114
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:631
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
void changeAsymmetricLevelSetBackground(TreeOrLeafManagerT &tree, const typename TreeOrLeafManagerT::ValueType &outsideWidth, const typename TreeOrLeafManagerT::ValueType &insideWidth, bool threaded=true, size_t grainSize=32)
Replace the background values in all the nodes of a floating-point tree containing a possibly asymmet...