OpenVDB: openvdb/tools/ChangeBackground.h Source File

OpenVDB 9.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
16#include <openvdb/tree/NodeManager.h>
17#include <openvdb/openvdb.h>
18
19
20namespace openvdb {
21 OPENVDB_USE_VERSION_NAMESPACE
22namespace OPENVDB_VERSION_NAME {
23namespace 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)
36template<typename TreeOrLeafManagerT>
37void
38 changeBackground(
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)
62template<typename TreeOrLeafManagerT>
63void
64 changeLevelSetBackground(
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)
90template<typename TreeOrLeafManagerT>
91void
92 changeAsymmetricLevelSetBackground(
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.
104template<typename TreeOrLeafManagerT>
105 class ChangeBackgroundOp
106{
107public:
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 }
133private:
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!
152template<typename TreeOrLeafManagerT>
153 class ChangeLevelSetBackgroundOp
154{
155public:
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)) {
166 OPENVDB_THROW(ValueError,
167 "ChangeLevelSetBackgroundOp: the outside value cannot be negative!");
168 }
169 if (!math::isNegative(mInside)) {
170 OPENVDB_THROW(ValueError,
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 }
189private:
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
202template<typename TreeOrLeafManagerT>
203void
204changeBackground(
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
216template<typename TreeOrLeafManagerT>
217void
218changeAsymmetricLevelSetBackground(
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
232template<typename TreeOrLeafManagerT>
233void
234changeLevelSetBackground(
235 TreeOrLeafManagerT& tree,
236 const typename TreeOrLeafManagerT::ValueType& background,
237 bool threaded,
238 size_t grainSize)
239{
240 changeAsymmetricLevelSetBackground(
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
253#include <openvdb/util/ExplicitInstantiation.h>
254#endif
255
256#define _FUNCTION(TreeT) \
257 void changeBackground(TreeT&, const TreeT::ValueType&, bool, size_t)
258 OPENVDB_VOLUME_TREE_INSTANTIATE(_FUNCTION)
259#undef _FUNCTION
260
261#define _FUNCTION(TreeT) \
262 void changeBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, bool, size_t)
263 OPENVDB_VOLUME_TREE_INSTANTIATE(_FUNCTION)
264#undef _FUNCTION
265
266#define _FUNCTION(TreeT) \
267 void changeLevelSetBackground(TreeT&, const TreeT::ValueType&, bool, size_t)
268 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
269#undef _FUNCTION
270
271#define _FUNCTION(TreeT) \
272 void changeLevelSetBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, bool, size_t)
273 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
274#undef _FUNCTION
275
276#define _FUNCTION(TreeT) \
277 void changeAsymmetricLevelSetBackground(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t)
278 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
279#undef _FUNCTION
280
281#define _FUNCTION(TreeT) \
282 void changeAsymmetricLevelSetBackground(tree::LeafManager<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, bool, size_t)
283 OPENVDB_REAL_TREE_INSTANTIATE(_FUNCTION)
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
ExplicitInstantiation.h
Math.h
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
openvdb::v9_0::ValueError
Definition: Exceptions.h:65
openvdb::v9_0::tools::ChangeBackgroundOp
Definition: ChangeBackground.h:106
openvdb::v9_0::tools::ChangeBackgroundOp::ChangeBackgroundOp
ChangeBackgroundOp(const TreeOrLeafManagerT &tree, const ValueT &newValue)
Definition: ChangeBackground.h:113
openvdb::v9_0::tools::ChangeBackgroundOp::operator()
void operator()(NodeT &node) const
Definition: ChangeBackground.h:128
openvdb::v9_0::tools::ChangeBackgroundOp::operator()
void operator()(RootT &root) const
Definition: ChangeBackground.h:118
openvdb::v9_0::tools::ChangeBackgroundOp::ValueT
TreeOrLeafManagerT::ValueType ValueT
Definition: ChangeBackground.h:108
openvdb::v9_0::tools::ChangeBackgroundOp::LeafT
TreeOrLeafManagerT::LeafNodeType LeafT
Definition: ChangeBackground.h:110
openvdb::v9_0::tools::ChangeBackgroundOp::operator()
void operator()(LeafT &node) const
Definition: ChangeBackground.h:123
openvdb::v9_0::tools::ChangeBackgroundOp::RootT
TreeOrLeafManagerT::RootNodeType RootT
Definition: ChangeBackground.h:109
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp
Definition: ChangeBackground.h:154
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::operator()
void operator()(NodeT &node) const
Definition: ChangeBackground.h:184
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::operator()
void operator()(RootT &root) const
Definition: ChangeBackground.h:174
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::ValueT
TreeOrLeafManagerT::ValueType ValueT
Definition: ChangeBackground.h:156
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::ChangeLevelSetBackgroundOp
ChangeLevelSetBackgroundOp(const ValueT &outside, const ValueT &inside)
Constructor for asymmetric narrow-bands.
Definition: ChangeBackground.h:161
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::LeafT
TreeOrLeafManagerT::LeafNodeType LeafT
Definition: ChangeBackground.h:158
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::operator()
void operator()(LeafT &node) const
Definition: ChangeBackground.h:179
openvdb::v9_0::tools::ChangeLevelSetBackgroundOp::RootT
TreeOrLeafManagerT::RootNodeType RootT
Definition: ChangeBackground.h:157
openvdb::v9_0::tree::NodeManager
To facilitate threading over the nodes of a tree, cache node pointers in linear arrays,...
Definition: NodeManager.h:531
openvdb::v9_0::tree::NodeManager::foreachTopDown
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t grainSize=1)
Definition: NodeManager.h:631
openvdb::v9_0::math::isApproxEqual
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
openvdb::v9_0::math::isNegative
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:368
openvdb::v9_0::math::negative
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:127
openvdb::v9_0::tools::changeAsymmetricLevelSetBackground
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
openvdb::v9_0::tools::changeBackground
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
openvdb::v9_0::tools::changeLevelSetBackground
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
openvdb
Definition: Exceptions.h:13
OPENVDB_THROW
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
Types.h
NodeManager.h
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
openvdb.h
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
OPENVDB_REAL_TREE_INSTANTIATE
#define OPENVDB_REAL_TREE_INSTANTIATE(Function)
Definition: version.h.in:147
OPENVDB_VOLUME_TREE_INSTANTIATE
#define OPENVDB_VOLUME_TREE_INSTANTIATE(Function)
Definition: version.h.in:150