OpenVDB 12.0.0
 
Loading...
Searching...
No Matches
Activate.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-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 // Skip child nodes, they'll be processed separately
91 // (InteralNode ValueOff iterators don't automatically
92 // skip these).
93 if (node.isChildMaskOn(it.pos())) continue;
94 if (check(*it)) it.setValueOn(/*on=*/true);
95 }
96 }
97 // return false if there are no child nodes below this node
98 return !node.isChildMaskOff();
99 }
100
101 bool operator()(LeafT& leaf, size_t) const
102 {
103 // early-exit if there are no inactive values
104 if (leaf.isValueMaskOn()) return true;
105 for (auto it = leaf.beginValueOff(); it; ++it) {
106 if (check(*it)) it.setValueOn(/*on=*/true);
107 }
108 return true;
109 }
110
111private:
112 const ValueT mValue;
113 const ValueT mTolerance;
114};// ActivateOp
115
116template<typename TreeT, bool IgnoreTolerance = false>
117struct DeactivateOp
118{
119public:
120 using RootT = typename TreeT::RootNodeType;
121 using LeafT = typename TreeT::LeafNodeType;
122 using ValueT = typename TreeT::ValueType;
123
124 explicit DeactivateOp(const ValueT& value,
125 const ValueT& tolerance = zeroVal<ValueT>())
126 : mValue(value)
127 , mTolerance(tolerance) { }
128
129 inline bool check(const ValueT& value) const {
130 if (IgnoreTolerance) return value == mValue;
131 return math::isApproxEqual(value, mValue, mTolerance);
132 }
133
134 bool operator()(RootT& root, size_t) const
135 {
136 for (auto it = root.beginValueOn(); it; ++it) {
137 if (check(*it)) it.setValueOn(/*on=*/false);
138 }
139 return true;
140 }
141
142 template<typename NodeT>
143 bool operator()(NodeT& node, size_t) const
144 {
145 // only iterate if there are active tiles
146 if (!node.isValueMaskOff()) {
147 for (auto it = node.beginValueOn(); it; ++it) {
148 if (check(*it)) it.setValueOn(/*on=*/false);
149 }
150 }
151 // return false if there are no child nodes below this node
152 return !node.isChildMaskOff();
153 }
154
155 bool operator()(LeafT& leaf, size_t) const
156 {
157 // early-exit if there are no active values
158 if (leaf.isValueMaskOff()) return true;
159 for (auto it = leaf.beginValueOn(); it; ++it) {
160 if (check(*it)) it.setValueOn(/*on=*/false);
161 }
162 return true;
163 }
164
165private:
166 const ValueT mValue;
167 const ValueT mTolerance;
168};// DeactivateOp
169
170} // namespace activate_internal
171
172/// @endcond
173
174
175////////////////////////////////////////
176
177
178template<typename GridOrTree>
179void activate(GridOrTree& gridOrTree,
180 const typename GridOrTree::ValueType& value,
181 const typename GridOrTree::ValueType& tolerance,
182 const bool threaded)
183{
184 using Adapter = TreeAdapter<GridOrTree>;
185 using TreeType = typename Adapter::TreeType;
186 using ValueType = typename TreeType::ValueType;
187
188 TreeType& tree = Adapter::tree(gridOrTree);
189
191
192 if (tolerance == zeroVal<ValueType>()) {
193 activate_internal::ActivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
194 nodeManager.foreachTopDown(op, threaded);
195 } else {
196 activate_internal::ActivateOp<TreeType> op(value, tolerance);
197 nodeManager.foreachTopDown(op, threaded);
198 }
199}
200
201
202template<typename GridOrTree>
203void deactivate(GridOrTree& gridOrTree,
204 const typename GridOrTree::ValueType& value,
205 const typename GridOrTree::ValueType& tolerance,
206 const bool threaded)
207{
208 using Adapter = TreeAdapter<GridOrTree>;
209 using TreeType = typename Adapter::TreeType;
210 using ValueType = typename TreeType::ValueType;
211
212 TreeType& tree = Adapter::tree(gridOrTree);
213
215
216 if (tolerance == zeroVal<ValueType>()) {
217 activate_internal::DeactivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
218 nodeManager.foreachTopDown(op, threaded);
219 } else {
220 activate_internal::DeactivateOp<TreeType> op(value, tolerance);
221 nodeManager.foreachTopDown(op, threaded);
222 }
223}
224
225
226////////////////////////////////////////
227
228
229// Explicit Template Instantiation
230
231#ifdef OPENVDB_USE_EXPLICIT_INSTANTIATION
232
233#ifdef OPENVDB_INSTANTIATE_ACTIVATE
235#endif
236
237#define _FUNCTION(TreeT) \
238 void activate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
240#undef _FUNCTION
241
242#define _FUNCTION(TreeT) \
243 void activate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
245#undef _FUNCTION
246
247#define _FUNCTION(TreeT) \
248 void deactivate(TreeT&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
250#undef _FUNCTION
251
252#define _FUNCTION(TreeT) \
253 void deactivate(Grid<TreeT>&, const TreeT::ValueType&, const TreeT::ValueType&, const bool)
255#undef _FUNCTION
256
257#endif // OPENVDB_USE_EXPLICIT_INSTANTIATION
258
259
260} // namespace tools
261} // namespace OPENVDB_VERSION_NAME
262} // namespace openvdb
263
264#endif // OPENVDB_TOOLS_ACTIVATE_HAS_BEEN_INCLUDED
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:891
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:977
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
Definition Activate.h:25
OutGridT XformOp & op
Definition ValueTransformer.h:140
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:203
OutGridT XformOp bool threaded
Definition ValueTransformer.h:140
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:179
Definition PointDataGrid.h:170
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
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:1060
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:218
#define OPENVDB_ALL_TREE_INSTANTIATE(Function)
Definition version.h.in:166