OpenVDB  11.0.0
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 #include <openvdb/openvdb.h>
18 
19 
20 namespace openvdb {
22 namespace OPENVDB_VERSION_NAME {
23 namespace tools {
24 
25 /// @brief Replace the background value in all the nodes of a tree.
26 /// @details The sign of the background value is preserved, and only
27 /// inactive values equal to the old background value are replaced.
28 ///
29 /// @note If a LeafManager is used the cached leaf nodes are reused,
30 /// resulting in slightly better overall performance.
31 ///
32 /// @param tree Tree (or LeafManager) that will have its background value changed
33 /// @param background the new background value
34 /// @param threaded enable or disable threading (threading is enabled by default)
35 /// @param grainSize used to control the threading granularity (default is 32)
36 template<typename TreeOrLeafManagerT>
37 void
39  TreeOrLeafManagerT& tree,
40  const typename TreeOrLeafManagerT::ValueType& background,
41  bool threaded = true,
42  size_t grainSize = 32);
43 
44 
45 /// @brief Replace the background value in all the nodes of a floating-point tree
46 /// containing a symmetric narrow-band level set.
47 /// @details All inactive values will be set to +| @a halfWidth | if outside
48 /// and -| @a halfWidth | if inside, where @a halfWidth is half the width
49 /// of the symmetric narrow band.
50 ///
51 /// @note This method is faster than changeBackground since it does not
52 /// perform tests to see if inactive values are equal to the old background value.
53 /// @note If a LeafManager is used the cached leaf nodes are reused,
54 /// resulting in slightly better overall performance.
55 ///
56 /// @param tree Tree (or LeafManager) that will have its background value changed
57 /// @param halfWidth half of the width of the symmetric narrow band
58 /// @param threaded enable or disable threading (threading is enabled by default)
59 /// @param grainSize used to control the threading granularity (default is 32)
60 ///
61 /// @throw ValueError if @a halfWidth is negative (as defined by math::isNegative)
62 template<typename TreeOrLeafManagerT>
63 void
65  TreeOrLeafManagerT& tree,
66  const typename TreeOrLeafManagerT::ValueType& halfWidth,
67  bool threaded = true,
68  size_t grainSize = 32);
69 
70 
71 /// @brief Replace the background values in all the nodes of a floating-point tree
72 /// containing a possibly asymmetric narrow-band level set.
73 /// @details All inactive values will be set to +| @a outsideWidth | if outside
74 /// and -| @a insideWidth | if inside, where @a outsideWidth is the outside
75 /// width of the narrow band and @a insideWidth is its inside width.
76 ///
77 /// @note This method is faster than changeBackground since it does not
78 /// perform tests to see if inactive values are equal to the old background value.
79 /// @note If a LeafManager is used the cached leaf nodes are reused,
80 /// resulting in slightly better overall performance.
81 ///
82 /// @param tree Tree (or LeafManager) that will have its background value changed
83 /// @param outsideWidth The width of the outside of the narrow band
84 /// @param insideWidth The width of the inside of the narrow band
85 /// @param threaded enable or disable threading (threading is enabled by default)
86 /// @param grainSize used to control the threading granularity (default is 32)
87 ///
88 /// @throw ValueError if @a outsideWidth is negative or @a insideWidth is
89 /// not negative (as defined by math::isNegative)
90 template<typename TreeOrLeafManagerT>
91 void
93  TreeOrLeafManagerT& tree,
94  const typename TreeOrLeafManagerT::ValueType& outsideWidth,
95  const typename TreeOrLeafManagerT::ValueType& insideWidth,
96  bool threaded = true,
97  size_t grainSize = 32);
98 
99 
100 //////////////////////////////////////////////////////
101 
102 
103 // Replaces the background value in a Tree of any type.
104 template<typename TreeOrLeafManagerT>
106 {
107 public:
108  typedef typename TreeOrLeafManagerT::ValueType ValueT;
109  typedef typename TreeOrLeafManagerT::RootNodeType RootT;
110  typedef typename TreeOrLeafManagerT::LeafNodeType LeafT;
111 
112 
113  ChangeBackgroundOp(const TreeOrLeafManagerT& tree, const ValueT& newValue)
114  : mOldValue(tree.root().background())
115  , mNewValue(newValue)
116  {
117  }
118  void operator()(RootT& root) const
119  {
120  for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
121  root.setBackground(mNewValue, false);
122  }
123  void operator()(LeafT& node) const
124  {
125  for (typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
126  }
127  template<typename NodeT>
128  void operator()(NodeT& node) const
129  {
130  typename NodeT::NodeMaskType mask = node.getValueOffMask();
131  for (typename NodeT::ValueOnIter it(mask.beginOn(), &node); it; ++it) this->set(it);
132  }
133 private:
134 
135  template<typename IterT>
136  inline void set(IterT& iter) const
137  {
138  if (math::isApproxEqual(*iter, mOldValue)) {
139  iter.setValue(mNewValue);
140  } else if (math::isApproxEqual(*iter, math::negative(mOldValue))) {
141  iter.setValue(math::negative(mNewValue));
142  }
143  }
144  const ValueT mOldValue, mNewValue;
145 };// ChangeBackgroundOp
146 
147 
148 // Replaces the background value in a Tree assumed to represent a
149 // level set. It is generally faster than ChangeBackgroundOp.
150 // Note that is follows the sign-convention that outside is positive
151 // and inside is negative!
152 template<typename TreeOrLeafManagerT>
154 {
155 public:
156  typedef typename TreeOrLeafManagerT::ValueType ValueT;
157  typedef typename TreeOrLeafManagerT::RootNodeType RootT;
158  typedef typename TreeOrLeafManagerT::LeafNodeType LeafT;
159 
160  /// @brief Constructor for asymmetric narrow-bands
161  ChangeLevelSetBackgroundOp(const ValueT& outside, const ValueT& inside)
162  : mOutside(outside)
163  , mInside(inside)
164  {
165  if (math::isNegative(mOutside)) {
167  "ChangeLevelSetBackgroundOp: the outside value cannot be negative!");
168  }
169  if (!math::isNegative(mInside)) {
171  "ChangeLevelSetBackgroundOp: the inside value must be negative!");
172  }
173  }
174  void operator()(RootT& root) const
175  {
176  for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
177  root.setBackground(mOutside, false);
178  }
179  void operator()(LeafT& node) const
180  {
181  for(typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
182  }
183  template<typename NodeT>
184  void operator()(NodeT& node) const
185  {
186  typedef typename NodeT::ValueOffIter IterT;
187  for (IterT it(node.getChildMask().beginOff(), &node); it; ++it) this->set(it);
188  }
189 private:
190 
191  template<typename IterT>
192  inline void set(IterT& iter) const
193  {
194  //this is safe since we know ValueType is_floating_point
195  ValueT& v = const_cast<ValueT&>(*iter);
196  v = v < 0 ? mInside : mOutside;
197  }
198  const ValueT mOutside, mInside;
199 };// ChangeLevelSetBackgroundOp
200 
201 
202 template<typename TreeOrLeafManagerT>
203 void
205  TreeOrLeafManagerT& tree,
206  const typename TreeOrLeafManagerT::ValueType& background,
207  bool threaded,
208  size_t grainSize)
209 {
210  tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
211  ChangeBackgroundOp<TreeOrLeafManagerT> op(tree, background);
212  linearTree.foreachTopDown(op, threaded, grainSize);
213 }
214 
215 
216 template<typename TreeOrLeafManagerT>
217 void
219  TreeOrLeafManagerT& tree,
220  const typename TreeOrLeafManagerT::ValueType& outsideValue,
221  const typename TreeOrLeafManagerT::ValueType& insideValue,
222  bool threaded,
223  size_t grainSize)
224 {
225  tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
226  ChangeLevelSetBackgroundOp<TreeOrLeafManagerT> op(outsideValue, insideValue);
227  linearTree.foreachTopDown(op, threaded, grainSize);
228 }
229 
230 
231 // If the narrow-band is symmetric only one background value is required
232 template<typename TreeOrLeafManagerT>
233 void
235  TreeOrLeafManagerT& tree,
236  const typename TreeOrLeafManagerT::ValueType& background,
237  bool threaded,
238  size_t grainSize)
239 {
241  tree, background, math::negative(background), threaded, grainSize);
242 }
243 
244 
245 ////////////////////////////////////////
246 
247 
248 // Explicit Template Instantiation
249 
250 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
251 
252 #ifdef OPENVDB_INSTANTIATE_CHANGEBACKGROUND
254 #endif
255 
256 #define _FUNCTION(TreeT) \
257  void changeBackground(TreeT&, const TreeT::ValueType&, bool, size_t)
259 #undef _FUNCTION
260 
261 #define _FUNCTION(TreeT) \
262  void changeBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, bool, size_t)
264 #undef _FUNCTION
265 
266 #define _FUNCTION(TreeT) \
267  void changeLevelSetBackground(TreeT&, const TreeT::ValueType&, bool, size_t)
269 #undef _FUNCTION
270 
271 #define _FUNCTION(TreeT) \
272  void changeLevelSetBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, bool, size_t)
274 #undef _FUNCTION
275 
276 #define _FUNCTION(TreeT) \
277  void changeAsymmetricLevelSetBackground(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t)
279 #undef _FUNCTION
280 
281 #define _FUNCTION(TreeT) \
282  void changeAsymmetricLevelSetBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t)
284 #undef _FUNCTION
285 
286 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
287 
288 
289 } // namespace tools
290 } // namespace OPENVDB_VERSION_NAME
291 } // namespace openvdb
292 
293 #endif // OPENVDB_TOOLS_CHANGEBACKGROUND_HAS_BEEN_INCLUDED
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
Definition: Exceptions.h:65
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.
Definition: ChangeBackground.h:204
Definition: ChangeBackground.h:105
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:160
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
ChangeLevelSetBackgroundOp(const ValueT &outside, const ValueT &inside)
Constructor for asymmetric narrow-bands.
Definition: ChangeBackground.h:161
TreeOrLeafManagerT::ValueType ValueT
Definition: ChangeBackground.h:156
void operator()(NodeT &node) const
Definition: ChangeBackground.h:128
TreeOrLeafManagerT::LeafNodeType LeafT
Definition: ChangeBackground.h:110
TreeOrLeafManagerT::LeafNodeType LeafT
Definition: ChangeBackground.h:158
TreeOrLeafManagerT::RootNodeType RootT
Definition: ChangeBackground.h:109
void operator()(NodeT &node) const
Definition: ChangeBackground.h:184
ChangeBackgroundOp(const TreeOrLeafManagerT &tree, const ValueT &newValue)
Definition: ChangeBackground.h:113
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:406
TreeOrLeafManagerT::ValueType ValueT
Definition: ChangeBackground.h:108
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-...
Definition: ChangeBackground.h:234
Definition: Exceptions.h:13
void operator()(RootT &root) const
Definition: ChangeBackground.h:118
TreeOrLeafManagerT::RootNodeType RootT
Definition: ChangeBackground.h:157
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
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:367
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition: version.h.in:157
void operator()(LeafT &node) const
Definition: ChangeBackground.h:123
Definition: ChangeBackground.h:153
void operator()(LeafT &node) const
Definition: ChangeBackground.h:179
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.in:121
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...
Definition: ChangeBackground.h:218
void operator()(RootT &root) const
Definition: ChangeBackground.h:174
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:128