GCC Code Coverage Report


Directory: ./
File: openvdb/openvdb/tools/Activate.h
Date: 2022-07-25 17:40:05
Exec Total Coverage
Lines: 50 50 100.0%
Functions: 64 200 32.0%
Branches: 44 54 81.5%

Line Branch Exec Source
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file Activate.h
5 ///
6 /// @brief Implementation of topological activation/deactivation
7 ///
8 /// @author Ken Museth
9 ///
10
11 #ifndef OPENVDB_TOOLS_ACTIVATE_HAS_BEEN_INCLUDED
12 #define OPENVDB_TOOLS_ACTIVATE_HAS_BEEN_INCLUDED
13
14 #include <openvdb/Types.h>
15 #include <openvdb/Grid.h>
16 #include <openvdb/math/Math.h> // for isApproxEqual()
17 #include <openvdb/tree/NodeManager.h>
18 #include <openvdb/openvdb.h>
19 #include <openvdb/points/PointDataGrid.h>
20
21
22 namespace openvdb {
23 OPENVDB_USE_VERSION_NAMESPACE
24 namespace OPENVDB_VERSION_NAME {
25 namespace tools {
26
27 /// @brief Mark as active any inactive tiles or voxels in the given grid or tree
28 /// whose values are equal to @a value (optionally to within the given @a tolerance).
29 template<typename GridOrTree>
30 void activate(
31 GridOrTree&,
32 const typename GridOrTree::ValueType& value,
33
2/4
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
✓ Branch 7 taken 1 times.
✗ Branch 8 not taken.
3 const typename GridOrTree::ValueType& tolerance = zeroVal<typename GridOrTree::ValueType>(),
34 const bool threaded = true
35 );
36
37
38 /// @brief Mark as inactive any active tiles or voxels in the given grid or tree
39 /// whose values are equal to @a value (optionally to within the given @a tolerance).
40 template<typename GridOrTree>
41 void deactivate(
42 GridOrTree&,
43 const typename GridOrTree::ValueType& value,
44
1/2
✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
2 const typename GridOrTree::ValueType& tolerance = zeroVal<typename GridOrTree::ValueType>(),
45 const bool threaded = true
46 );
47
48
49 ////////////////////////////////////////
50
51
52 /// @cond OPENVDB_DOCS_INTERNAL
53
54 namespace activate_internal {
55
56 template<typename TreeT, bool IgnoreTolerance = false>
57 struct ActivateOp
58 {
59 public:
60 using RootT = typename TreeT::RootNodeType;
61 using LeafT = typename TreeT::LeafNodeType;
62 using ValueT = typename TreeT::ValueType;
63
64 21 explicit ActivateOp(const ValueT& value,
65 3 const ValueT& tolerance = zeroVal<ValueT>())
66 : mValue(value)
67 21 , mTolerance(tolerance) { }
68
69 inline bool check(const ValueT& value) const {
70 // math::isApproxEqual is marginally more expensive,
71 // so opt to do direct comparison if tolerance is ignored
72 335867 if (IgnoreTolerance) return value == mValue;
73 return math::isApproxEqual(value, mValue, mTolerance);
74 }
75
76 42 bool operator()(RootT& root, size_t) const
77 {
78
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 21 times.
94 for (auto it = root.beginValueOff(); it; ++it) {
79
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
8 if (check(*it)) it.setValueOn(/*on=*/true);
80 }
81 42 return true;
82 }
83
84 template<typename NodeT>
85 118 bool operator()(NodeT& node, size_t) const
86 {
87 // only iterate if there are inactive tiles
88
1/2
✓ Branch 0 taken 59 times.
✗ Branch 1 not taken.
118 if (!node.isValueMaskOn()) {
89
2/2
✓ Branch 0 taken 729080 times.
✓ Branch 1 taken 59 times.
1458278 for (auto it = node.beginValueOff(); it; ++it) {
90
2/2
✓ Branch 0 taken 36863 times.
✓ Branch 1 taken 405505 times.
995184 if (check(*it)) it.setValueOn(/*on=*/true);
91 }
92 }
93 // return false if there are no child nodes below this node
94 118 return !node.isChildMaskOff();
95 }
96
97 19270 bool operator()(LeafT& leaf, size_t) const
98 {
99 // early-exit if there are no inactive values
100
1/2
✓ Branch 0 taken 9635 times.
✗ Branch 1 not taken.
19270 if (leaf.isValueMaskOn()) return true;
101
2/2
✓ Branch 0 taken 4929207 times.
✓ Branch 1 taken 9635 times.
9877684 for (auto it = leaf.beginValueOff(); it; ++it) {
102
2/2
✓ Branch 0 taken 516 times.
✓ Branch 1 taken 5108 times.
6665130 if (check(*it)) it.setValueOn(/*on=*/true);
103 }
104 19270 return true;
105 }
106
107 private:
108 const ValueT mValue;
109 const ValueT mTolerance;
110 };// ActivateOp
111
112 template<typename TreeT, bool IgnoreTolerance = false>
113 struct DeactivateOp
114 {
115 public:
116 using RootT = typename TreeT::RootNodeType;
117 using LeafT = typename TreeT::LeafNodeType;
118 using ValueT = typename TreeT::ValueType;
119
120 21 explicit DeactivateOp(const ValueT& value,
121 2 const ValueT& tolerance = zeroVal<ValueT>())
122 : mValue(value)
123 21 , mTolerance(tolerance) { }
124
125 inline bool check(const ValueT& value) const {
126 15 if (IgnoreTolerance) return value == mValue;
127 return math::isApproxEqual(value, mValue, mTolerance);
128 }
129
130 42 bool operator()(RootT& root, size_t) const
131 {
132
2/2
✓ Branch 1 taken 5 times.
✓ Branch 2 taken 21 times.
94 for (auto it = root.beginValueOn(); it; ++it) {
133
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
8 if (check(*it)) it.setValueOn(/*on=*/false);
134 }
135 42 return true;
136 }
137
138 template<typename NodeT>
139 118 bool operator()(NodeT& node, size_t) const
140 {
141 // only iterate if there are active tiles
142
2/2
✓ Branch 0 taken 29 times.
✓ Branch 1 taken 30 times.
118 if (!node.isValueMaskOff()) {
143
2/2
✓ Branch 0 taken 55233 times.
✓ Branch 1 taken 29 times.
110524 for (auto it = node.beginValueOn(); it; ++it) {
144
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
110450 if (check(*it)) it.setValueOn(/*on=*/false);
145 }
146 }
147 // return false if there are no child nodes below this node
148 118 return !node.isChildMaskOff();
149 }
150
151 19270 bool operator()(LeafT& leaf, size_t) const
152 {
153 // early-exit if there are no active values
154
2/2
✓ Branch 0 taken 9634 times.
✓ Branch 1 taken 1 times.
19270 if (leaf.isValueMaskOff()) return true;
155
2/2
✓ Branch 0 taken 3330863 times.
✓ Branch 1 taken 9634 times.
6680994 for (auto it = leaf.beginValueOn(); it; ++it) {
156
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 7 times.
6653912 if (check(*it)) it.setValueOn(/*on=*/false);
157 }
158 19268 return true;
159 }
160
161 private:
162 const ValueT mValue;
163 const ValueT mTolerance;
164 };// DeactivateOp
165
166 } // namespace activate_internal
167
168 /// @endcond
169
170
171 ////////////////////////////////////////
172
173
174 template<typename GridOrTree>
175
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 9 times.
42 void activate(GridOrTree& gridOrTree,
176 const typename GridOrTree::ValueType& value,
177 const typename GridOrTree::ValueType& tolerance,
178 const bool threaded)
179 {
180 using Adapter = TreeAdapter<GridOrTree>;
181 using TreeType = typename Adapter::TreeType;
182 using ValueType = typename TreeType::ValueType;
183
184 TreeType& tree = Adapter::tree(gridOrTree);
185
186 42 tree::DynamicNodeManager<TreeType> nodeManager(tree);
187
188
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5 times.
32 if (tolerance == zeroVal<ValueType>()) {
189 6 activate_internal::ActivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
190
1/2
✓ Branch 1 taken 14 times.
✗ Branch 2 not taken.
28 nodeManager.foreachTopDown(op, threaded);
191 } else {
192 activate_internal::ActivateOp<TreeType> op(value, tolerance);
193
1/2
✓ Branch 1 taken 7 times.
✗ Branch 2 not taken.
14 nodeManager.foreachTopDown(op, threaded);
194 }
195 }
196
197
198 template<typename GridOrTree>
199
2/2
✓ Branch 0 taken 13 times.
✓ Branch 1 taken 8 times.
42 void deactivate(GridOrTree& gridOrTree,
200 const typename GridOrTree::ValueType& value,
201 const typename GridOrTree::ValueType& tolerance,
202 const bool threaded)
203 {
204 using Adapter = TreeAdapter<GridOrTree>;
205 using TreeType = typename Adapter::TreeType;
206 using ValueType = typename TreeType::ValueType;
207
208 TreeType& tree = Adapter::tree(gridOrTree);
209
210 42 tree::DynamicNodeManager<TreeType> nodeManager(tree);
211
212
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 5 times.
32 if (tolerance == zeroVal<ValueType>()) {
213 4 activate_internal::DeactivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
214
1/2
✓ Branch 1 taken 13 times.
✗ Branch 2 not taken.
26 nodeManager.foreachTopDown(op, threaded);
215 } else {
216 activate_internal::DeactivateOp<TreeType> op(value, tolerance);
217
1/2
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
16 nodeManager.foreachTopDown(op, threaded);
218 }
219 }
220
221
222 ////////////////////////////////////////
223
224
225 // Explicit Template Instantiation
226
227 #ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
228
229 #ifdef OPENVDB_INSTANTIATE_ACTIVATE
230 #include <openvdb/util/ExplicitInstantiation.h>
231 #endif
232
233 #define _FUNCTION(TreeT) \
234 void activate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
235 OPENVDB_ALL_TREE_INSTANTIATE(_FUNCTION)
236 #undef _FUNCTION
237
238 #define _FUNCTION(TreeT) \
239 void activate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
240 OPENVDB_ALL_TREE_INSTANTIATE(_FUNCTION)
241 #undef _FUNCTION
242
243 #define _FUNCTION(TreeT) \
244 void deactivate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
245 OPENVDB_ALL_TREE_INSTANTIATE(_FUNCTION)
246 #undef _FUNCTION
247
248 #define _FUNCTION(TreeT) \
249 void deactivate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
250 OPENVDB_ALL_TREE_INSTANTIATE(_FUNCTION)
251 #undef _FUNCTION
252
253 #endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
254
255
256 } // namespace tools
257 } // namespace OPENVDB_VERSION_NAME
258 } // namespace openvdb
259
260 #endif // OPENVDB_TOOLS_ACTIVATE_HAS_BEEN_INCLUDED
261