GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/tools/ChangeBackground.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 36 39 92.3%
Functions: 34 181 18.8%
Branches: 29 90 32.2%

Line Branch Exec Source
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
20 namespace openvdb {
21 OPENVDB_USE_VERSION_NAMESPACE
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
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)
62 template<typename TreeOrLeafManagerT>
63 void
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)
90 template<typename TreeOrLeafManagerT>
91 void
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.
104 template<typename TreeOrLeafManagerT>
105 class ChangeBackgroundOp
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 74 , mNewValue(newValue)
116 {
117 }
118 148 void operator()(RootT& root) const
119 {
120
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 74 times.
296 for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
121 148 root.setBackground(mNewValue, false);
122 }
123 366 void operator()(LeafT& node) const
124 {
125
2/2
✓ Branch 0 taken 56659 times.
✓ Branch 1 taken 183 times.
113684 for (typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
126 }
127 template<typename NodeT>
128 4 void operator()(NodeT& node) const
129 {
130 4 typename NodeT::NodeMaskType mask = node.getValueOffMask();
131
2/2
✓ Branch 1 taken 36680 times.
✓ Branch 2 taken 2 times.
73368 for (typename NodeT::ValueOnIter it(mask.beginOn(), &node); it; ++it) this->set(it);
132 }
133 private:
134
135 template<typename IterT>
136
0/2
✗ Branch 0 not taken.
✗ Branch 1 not taken.
186678 inline void set(IterT& iter) const
137 {
138
3/3
✓ Branch 0 taken 36673 times.
✓ Branch 1 taken 45934 times.
✓ Branch 2 taken 10732 times.
186678 if (math::isApproxEqual(*iter, mOldValue)) {
139 91854 iter.setValue(mNewValue);
140
1/3
✓ Branch 0 taken 10739 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
21478 } else if (math::isApproxEqual(*iter, math::negative(mOldValue))) {
141 21464 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>
153 class ChangeLevelSetBackgroundOp
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 28 ChangeLevelSetBackgroundOp(const ValueT& outside, const ValueT& inside)
162 : mOutside(outside)
163 28 , mInside(inside)
164 {
165
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
28 if (math::isNegative(mOutside)) {
166 OPENVDB_THROW(ValueError,
167 "ChangeLevelSetBackgroundOp: the outside value cannot be negative!");
168 }
169
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
28 if (!math::isNegative(mInside)) {
170 OPENVDB_THROW(ValueError,
171 "ChangeLevelSetBackgroundOp: the inside value must be negative!");
172 }
173 }
174 28 void operator()(RootT& root) const
175 {
176
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 14 times.
56 for (typename RootT::ValueOffIter it = root.beginValueOff(); it; ++it) this->set(it);
177 28 root.setBackground(mOutside, false);
178 }
179 52576 void operator()(LeafT& node) const
180 {
181
2/2
✓ Branch 0 taken 6798795 times.
✓ Branch 1 taken 26288 times.
13650166 for(typename LeafT::ValueOffIter it = node.beginValueOff(); it; ++it) this->set(it);
182 }
183 template<typename NodeT>
184 392 void operator()(NodeT& node) const
185 {
186 typedef typename NodeT::ValueOffIter IterT;
187
2/2
✓ Branch 1 taken 3586286 times.
✓ Branch 2 taken 196 times.
7173356 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
10/32
✗ Branch 0 not taken.
✗ Branch 1 not taken.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✗ Branch 6 not taken.
✗ Branch 7 not taken.
✓ Branch 9 taken 214577 times.
✓ Branch 10 taken 312934 times.
✓ Branch 12 taken 1125 times.
✓ Branch 13 taken 34111 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 294903 times.
✗ Branch 18 not taken.
✗ Branch 19 not taken.
✗ Branch 21 not taken.
✗ Branch 22 not taken.
✗ Branch 24 not taken.
✗ Branch 25 not taken.
✓ Branch 27 taken 2362868 times.
✓ Branch 28 taken 3908416 times.
✓ Branch 30 taken 18689 times.
✓ Branch 31 taken 321195 times.
✗ Branch 33 not taken.
✓ Branch 34 taken 2916263 times.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
✗ Branch 39 not taken.
✗ Branch 40 not taken.
✗ Branch 42 not taken.
✗ Branch 43 not taken.
✗ Branch 45 not taken.
✗ Branch 46 not taken.
10385081 v = v < 0 ? mInside : mOutside;
197 }
198 const ValueT mOutside, mInside;
199 };// ChangeLevelSetBackgroundOp
200
201
202 template<typename TreeOrLeafManagerT>
203 void
204 148 changeBackground(
205 TreeOrLeafManagerT& tree,
206 const typename TreeOrLeafManagerT::ValueType& background,
207 bool threaded,
208 size_t grainSize)
209 {
210 296 tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
211 ChangeBackgroundOp<TreeOrLeafManagerT> op(tree, background);
212
1/2
✓ Branch 1 taken 74 times.
✗ Branch 2 not taken.
148 linearTree.foreachTopDown(op, threaded, grainSize);
213 }
214
215
216 template<typename TreeOrLeafManagerT>
217 void
218 28 changeAsymmetricLevelSetBackground(
219 TreeOrLeafManagerT& tree,
220 const typename TreeOrLeafManagerT::ValueType& outsideValue,
221 const typename TreeOrLeafManagerT::ValueType& insideValue,
222 bool threaded,
223 size_t grainSize)
224 {
225 56 tree::NodeManager<TreeOrLeafManagerT> linearTree(tree);
226
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 ChangeLevelSetBackgroundOp<TreeOrLeafManagerT> op(outsideValue, insideValue);
227
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 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
234 10 changeLevelSetBackground(
235 TreeOrLeafManagerT& tree,
236 const typename TreeOrLeafManagerT::ValueType& background,
237 bool threaded,
238 size_t grainSize)
239 {
240 10 changeAsymmetricLevelSetBackground(
241 10 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
294