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 
19 
20 namespace openvdb {
22 namespace OPENVDB_VERSION_NAME {
23 namespace tools {
24 
25 /// @brief Mark as active any inactive tiles or voxels in the given grid or tree
26 /// whose values are equal to @a value (optionally to within the given @a tolerance).
27 template<typename GridOrTree>
28 inline void activate(
29  GridOrTree&,
30  const typename GridOrTree::ValueType& value,
31  const typename GridOrTree::ValueType& tolerance = zeroVal<typename GridOrTree::ValueType>(),
32  const bool threaded = true
33 );
34 
35 
36 /// @brief Mark as inactive any active tiles or voxels in the given grid or tree
37 /// whose values are equal to @a value (optionally to within the given @a tolerance).
38 template<typename GridOrTree>
39 inline void deactivate(
40  GridOrTree&,
41  const typename GridOrTree::ValueType& value,
42  const typename GridOrTree::ValueType& tolerance = zeroVal<typename GridOrTree::ValueType>(),
43  const bool threaded = true
44 );
45 
46 
47 ////////////////////////////////////////
48 
49 
50 /// @cond OPENVDB_DOCS_INTERNAL
51 
52 namespace activate_internal {
53 
54 template<typename TreeT, bool IgnoreTolerance = false>
55 struct ActivateOp
56 {
57 public:
58  using RootT = typename TreeT::RootNodeType;
59  using LeafT = typename TreeT::LeafNodeType;
60  using ValueT = typename TreeT::ValueType;
61 
62  explicit ActivateOp(const ValueT& value,
63  const ValueT& tolerance = zeroVal<ValueT>())
64  : mValue(value)
65  , mTolerance(tolerance) { }
66 
67  inline bool check(const ValueT& value) const {
68  // math::isApproxEqual is marginally more expensive,
69  // so opt to do direct comparison if tolerance is ignored
70  if (IgnoreTolerance) return value == mValue;
71  return math::isApproxEqual(value, mValue, mTolerance);
72  }
73 
74  bool operator()(RootT& root, size_t) const
75  {
76  for (auto it = root.beginValueOff(); it; ++it) {
77  if (check(*it)) it.setValueOn(/*on=*/true);
78  }
79  return true;
80  }
81 
82  template<typename NodeT>
83  bool operator()(NodeT& node, size_t) const
84  {
85  // only iterate if there are inactive tiles
86  if (!node.isValueMaskOn()) {
87  for (auto it = node.beginValueOff(); it; ++it) {
88  if (check(*it)) it.setValueOn(/*on=*/true);
89  }
90  }
91  // return false if there are no child nodes below this node
92  return !node.isChildMaskOff();
93  }
94 
95  bool operator()(LeafT& leaf, size_t) const
96  {
97  // early-exit if there are no inactive values
98  if (leaf.isValueMaskOn()) return true;
99  for (auto it = leaf.beginValueOff(); it; ++it) {
100  if (check(*it)) it.setValueOn(/*on=*/true);
101  }
102  return true;
103  }
104 
105 private:
106  const ValueT mValue;
107  const ValueT mTolerance;
108 };// ActivateOp
109 
110 template<typename TreeT, bool IgnoreTolerance = false>
111 struct DeactivateOp
112 {
113 public:
114  using RootT = typename TreeT::RootNodeType;
115  using LeafT = typename TreeT::LeafNodeType;
116  using ValueT = typename TreeT::ValueType;
117 
118  explicit DeactivateOp(const ValueT& value,
119  const ValueT& tolerance = zeroVal<ValueT>())
120  : mValue(value)
121  , mTolerance(tolerance) { }
122 
123  inline bool check(const ValueT& value) const {
124  if (IgnoreTolerance) return value == mValue;
125  return math::isApproxEqual(value, mValue, mTolerance);
126  }
127 
128  bool operator()(RootT& root, size_t) const
129  {
130  for (auto it = root.beginValueOn(); it; ++it) {
131  if (check(*it)) it.setValueOn(/*on=*/false);
132  }
133  return true;
134  }
135 
136  template<typename NodeT>
137  bool operator()(NodeT& node, size_t) const
138  {
139  // only iterate if there are active tiles
140  if (!node.isValueMaskOff()) {
141  for (auto it = node.beginValueOn(); it; ++it) {
142  if (check(*it)) it.setValueOn(/*on=*/false);
143  }
144  }
145  // return false if there are no child nodes below this node
146  return !node.isChildMaskOff();
147  }
148 
149  bool operator()(LeafT& leaf, size_t) const
150  {
151  // early-exit if there are no active values
152  if (leaf.isValueMaskOff()) return true;
153  for (auto it = leaf.beginValueOn(); it; ++it) {
154  if (check(*it)) it.setValueOn(/*on=*/false);
155  }
156  return true;
157  }
158 
159 private:
160  const ValueT mValue;
161  const ValueT mTolerance;
162 };// DeactivateOp
163 
164 } // namespace activate_internal
165 
166 /// @endcond
167 
168 
169 ////////////////////////////////////////
170 
171 
172 template<typename GridOrTree>
173 inline void
174 activate(GridOrTree& gridOrTree, const typename GridOrTree::ValueType& value,
175  const typename GridOrTree::ValueType& tolerance,
176  const bool threaded)
177 {
178  using Adapter = TreeAdapter<GridOrTree>;
179  using TreeType = typename Adapter::TreeType;
180  using ValueType = typename TreeType::ValueType;
181 
182  TreeType& tree = Adapter::tree(gridOrTree);
183 
184  tree::DynamicNodeManager<TreeType> nodeManager(tree);
185 
186  if (tolerance == zeroVal<ValueType>()) {
187  activate_internal::ActivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
188  nodeManager.foreachTopDown(op, threaded);
189  } else {
190  activate_internal::ActivateOp<TreeType> op(value, tolerance);
191  nodeManager.foreachTopDown(op, threaded);
192  }
193 }
194 
195 
196 template<typename GridOrTree>
197 inline void
198 deactivate(GridOrTree& gridOrTree, const typename GridOrTree::ValueType& value,
199  const typename GridOrTree::ValueType& tolerance,
200  const bool threaded)
201 {
202  using Adapter = TreeAdapter<GridOrTree>;
203  using TreeType = typename Adapter::TreeType;
204  using ValueType = typename TreeType::ValueType;
205 
206  TreeType& tree = Adapter::tree(gridOrTree);
207 
208  tree::DynamicNodeManager<TreeType> nodeManager(tree);
209 
210  if (tolerance == zeroVal<ValueType>()) {
211  activate_internal::DeactivateOp<TreeType, /*IgnoreTolerance=*/true> op(value);
212  nodeManager.foreachTopDown(op, threaded);
213  } else {
214  activate_internal::DeactivateOp<TreeType> op(value, tolerance);
215  nodeManager.foreachTopDown(op, threaded);
216  }
217 }
218 
219 } // namespace tools
220 } // namespace OPENVDB_VERSION_NAME
221 } // namespace openvdb
222 
223 #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:198
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:178
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1070
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
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...
GLsizei const GLfloat * value
Definition: glcorearb.h:823
int check(unformattable)
Definition: core.h:1421
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:174
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:114