OpenVDB 9.0.0
Activate.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 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()
18#include <openvdb/openvdb.h>
20
21
22namespace openvdb {
24namespace OPENVDB_VERSION_NAME {
25namespace 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).
29template<typename GridOrTree>
30void activate(
31 GridOrTree&,
32 const typename GridOrTree::ValueType& value,
33 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).
40template<typename GridOrTree>
41void deactivate(
42 GridOrTree&,
43 const typename GridOrTree::ValueType& value,
44 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
54namespace activate_internal {
55
56template<typename TreeT, bool IgnoreTolerance = false>
57struct ActivateOp
58{
59public:
60 using RootT = typename TreeT::RootNodeType;
61 using LeafT = typename TreeT::LeafNodeType;
62 using ValueT = typename TreeT::ValueType;
63
64 explicit ActivateOp(const ValueT& value,
65 const ValueT& tolerance = zeroVal<ValueT>())
66 : mValue(value)
67 , 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 if (IgnoreTolerance) return value == mValue;
73 return math::isApproxEqual(value, mValue, mTolerance);
74 }
75
76 bool operator()(RootT& root, size_t) const
77 {
78 for (auto it = root.beginValueOff(); it; ++it) {
79 if (check(*it)) it.setValueOn(/*on=*/true);
80 }
81 return true;
82 }
83
84 template<typename NodeT>
85 bool operator()(NodeT& node, size_t) const
86 {
87 // only iterate if there are inactive tiles
88 if (!node.isValueMaskOn()) {
89 for (auto it = node.beginValueOff(); it; ++it) {
90 if (check(*it)) it.setValueOn(/*on=*/true);
91 }
92 }
93 // return false if there are no child nodes below this node
94 return !node.isChildMaskOff();
95 }
96
97 bool operator()(LeafT& leaf, size_t) const
98 {
99 // early-exit if there are no inactive values
100 if (leaf.isValueMaskOn()) return true;
101 for (auto it = leaf.beginValueOff(); it; ++it) {
102 if (check(*it)) it.setValueOn(/*on=*/true);
103 }
104 return true;
105 }
106
107private:
108 const ValueT mValue;
109 const ValueT mTolerance;
110};// ActivateOp
111
112template<typename TreeT, bool IgnoreTolerance = false>
113struct DeactivateOp
114{
115public:
116 using RootT = typename TreeT::RootNodeType;
117 using LeafT = typename TreeT::LeafNodeType;
118 using ValueT = typename TreeT::ValueType;
119
120 explicit DeactivateOp(const ValueT& value,
121 const ValueT& tolerance = zeroVal<ValueT>())
122 : mValue(value)
123 , mTolerance(tolerance) { }
124
125 inline bool check(const ValueT& value) const {
126 if (IgnoreTolerance) return value == mValue;
127 return math::isApproxEqual(value, mValue, mTolerance);
128 }
129
130 bool operator()(RootT& root, size_t) const
131 {
132 for (auto it = root.beginValueOn(); it; ++it) {
133 if (check(*it)) it.setValueOn(/*on=*/false);
134 }
135 return true;
136 }
137
138 template<typename NodeT>
139 bool operator()(NodeT& node, size_t) const
140 {
141 // only iterate if there are active tiles
142 if (!node.isValueMaskOff()) {
143 for (auto it = node.beginValueOn(); it; ++it) {
144 if (check(*it)) it.setValueOn(/*on=*/false);
145 }
146 }
147 // return false if there are no child nodes below this node
148 return !node.isChildMaskOff();
149 }
150
151 bool operator()(LeafT& leaf, size_t) const
152 {
153 // early-exit if there are no active values
154 if (leaf.isValueMaskOff()) return true;
155 for (auto it = leaf.beginValueOn(); it; ++it) {
156 if (check(*it)) it.setValueOn(/*on=*/false);
157 }
158 return true;
159 }
160
161private:
162 const ValueT mValue;
163 const ValueT mTolerance;
164};// DeactivateOp
165
166} // namespace activate_internal
167
168/// @endcond
169
170
171////////////////////////////////////////
172
173
174template<typename GridOrTree>
175void 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 tree::DynamicNodeManager<TreeType> nodeManager(tree);
187
188 if (tolerance == zeroVal<ValueType>()) {
189 activate_internal::ActivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
190 nodeManager.foreachTopDown(op, threaded);
191 } else {
192 activate_internal::ActivateOp<TreeType> op(value, tolerance);
193 nodeManager.foreachTopDown(op, threaded);
194 }
195}
196
197
198template<typename GridOrTree>
199void 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 tree::DynamicNodeManager<TreeType> nodeManager(tree);
211
212 if (tolerance == zeroVal<ValueType>()) {
213 activate_internal::DeactivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
214 nodeManager.foreachTopDown(op, threaded);
215 } else {
216 activate_internal::DeactivateOp<TreeType> op(value, tolerance);
217 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
231#endif
232
233#define _FUNCTION(TreeT) \
234 void activate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
236#undef _FUNCTION
237
238#define _FUNCTION(TreeT) \
239 void activate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
241#undef _FUNCTION
242
243#define _FUNCTION(TreeT) \
244 void deactivate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
246#undef _FUNCTION
247
248#define _FUNCTION(TreeT) \
249 void deactivate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
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
ValueT value
Definition: GridBuilder.h:1287
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Definition: NodeManager.h:890
void foreachTopDown(const NodeOp &op, bool threaded=true, size_t leafGrainSize=1, size_t nonLeafGrainSize=1)
Threaded method that applies a user-supplied functor to all the nodes in the tree.
Definition: NodeManager.h:976
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
void deactivate(GridOrTree &, const typename GridOrTree::ValueType &value, const typename GridOrTree::ValueType &tolerance=zeroVal< typename GridOrTree::ValueType >(), const bool threaded=true)
Mark as inactive any active tiles or voxels in the given grid or tree whose values are equal to value...
Definition: Activate.h:199
void activate(GridOrTree &, const typename GridOrTree::ValueType &value, const typename GridOrTree::ValueType &tolerance=zeroVal< typename GridOrTree::ValueType >(), const bool threaded=true)
Mark as active any inactive tiles or voxels in the given grid or tree whose values are equal to value...
Definition: Activate.h:175
Definition: Exceptions.h:13
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1071
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
#define OPENVDB_ALL_TREE_INSTANTIATE(Function)
Definition: version.h.in:151