HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 
22 namespace openvdb {
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  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  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  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 
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  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 
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 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  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 
198 template<typename GridOrTree>
199 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  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
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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:239
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1059
#define OPENVDB_ALL_TREE_INSTANTIATE(Function)
Definition: version.h:178
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:406
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
NodeManager produces linear arrays of all tree nodes allowing for efficient threading and bottom-up p...
Definition: core.h:1131
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
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:119
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...