HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointCount.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2018 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 /// @file points/PointCount.h
32 ///
33 /// @author Dan Bailey
34 ///
35 /// @brief Methods for counting points in VDB Point grids.
36 
37 #ifndef OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/openvdb.h>
41 
42 #include "PointDataGrid.h"
43 #include "PointMask.h"
44 #include "IndexFilter.h"
45 
46 #include <tbb/parallel_reduce.h>
47 
48 #include <vector>
49 
50 
51 namespace openvdb {
53 namespace OPENVDB_VERSION_NAME {
54 namespace points {
55 
56 
57 /// @brief Count the total number of points in a PointDataTree
58 /// @param tree the PointDataTree in which to count the points
59 /// @param filter an optional index filter
60 /// @param inCoreOnly if true, points in out-of-core leaf nodes are not counted
61 /// @param threaded enable or disable threading (threading is enabled by default)
62 template <typename PointDataTreeT, typename FilterT = NullFilter>
63 inline Index64 pointCount( const PointDataTreeT& tree,
64  const FilterT& filter = NullFilter(),
65  const bool inCoreOnly = false,
66  const bool threaded = true);
67 
68 
69 /// @brief Populate an array of cumulative point offsets per leaf node.
70 /// @param pointOffsets array of offsets to be populated
71 /// @param tree the PointDataTree from which to populate the offsets
72 /// @param filter an optional index filter
73 /// @param inCoreOnly if true, points in out-of-core leaf nodes are ignored
74 /// @param threaded enable or disable threading (threading is enabled by default)
75 /// @return The final cumulative point offset.
76 template <typename PointDataTreeT, typename FilterT = NullFilter>
77 inline Index64 pointOffsets(std::vector<Index64>& pointOffsets,
78  const PointDataTreeT& tree,
79  const FilterT& filter = NullFilter(),
80  const bool inCoreOnly = false,
81  const bool threaded = true);
82 
83 
84 /// @brief Generate a new grid with voxel values to store the number of points per voxel
85 /// @param grid the PointDataGrid to use to compute the count grid
86 /// @param filter an optional index filter
87 /// @note The return type of the grid must be an integer or floating-point scalar grid.
88 template <typename PointDataGridT,
89  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
90  typename FilterT = NullFilter>
91 inline typename GridT::Ptr
92 pointCountGrid( const PointDataGridT& grid,
93  const FilterT& filter = NullFilter());
94 
95 
96 /// @brief Generate a new grid that uses the supplied transform with voxel values to store the
97 /// number of points per voxel.
98 /// @param grid the PointDataGrid to use to compute the count grid
99 /// @param transform the transform to use to compute the count grid
100 /// @param filter an optional index filter
101 /// @note The return type of the grid must be an integer or floating-point scalar grid.
102 template <typename PointDataGridT,
103  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
104  typename FilterT = NullFilter>
105 inline typename GridT::Ptr
106 pointCountGrid( const PointDataGridT& grid,
107  const openvdb::math::Transform& transform,
108  const FilterT& filter = NullFilter());
109 
110 
111 ////////////////////////////////////////
112 
113 
114 template <typename PointDataTreeT, typename FilterT>
115 Index64 pointCount(const PointDataTreeT& tree,
116  const FilterT& filter,
117  const bool inCoreOnly,
118  const bool threaded)
119 {
120  using LeafManagerT = tree::LeafManager<const PointDataTreeT>;
121  using LeafRangeT = typename LeafManagerT::LeafRange;
122 
123  auto countLambda =
124  [&filter, &inCoreOnly] (const LeafRangeT& range, Index64 sum) -> Index64 {
125  for (const auto& leaf : range) {
126  if (inCoreOnly && leaf.buffer().isOutOfCore()) continue;
127  auto state = filter.state(leaf);
128  if (state == index::ALL) {
129  sum += leaf.pointCount();
130  } else if (state != index::NONE) {
131  sum += iterCount(leaf.beginIndexAll(filter));
132  }
133  }
134  return sum;
135  };
136 
137  LeafManagerT leafManager(tree);
138  if (threaded) {
139  return tbb::parallel_reduce(leafManager.leafRange(), Index64(0), countLambda,
140  [] (Index64 n, Index64 m) -> Index64 { return n + m; });
141  }
142  else {
143  return countLambda(leafManager.leafRange(), Index64(0));
144  }
145 }
146 
147 
148 template <typename PointDataTreeT, typename FilterT>
149 Index64 pointOffsets( std::vector<Index64>& pointOffsets,
150  const PointDataTreeT& tree,
151  const FilterT& filter,
152  const bool inCoreOnly,
153  const bool threaded)
154 {
155  using LeafT = typename PointDataTreeT::LeafNodeType;
156  using LeafManagerT = typename tree::LeafManager<const PointDataTreeT>;
157 
158  // allocate and zero values in point offsets array
159 
160  pointOffsets.assign(tree.leafCount(), Index64(0));
161 
162  // compute total points per-leaf
163 
164  LeafManagerT leafManager(tree);
165  leafManager.foreach(
166  [&pointOffsets, &filter, &inCoreOnly](const LeafT& leaf, size_t pos) {
167  if (inCoreOnly && leaf.buffer().isOutOfCore()) return;
168  auto state = filter.state(leaf);
169  if (state == index::ALL) {
170  pointOffsets[pos] = leaf.pointCount();
171  } else if (state != index::NONE) {
172  pointOffsets[pos] = iterCount(leaf.beginIndexAll(filter));
173  }
174  },
175  threaded);
176 
177  // turn per-leaf totals into cumulative leaf totals
178 
179  Index64 pointOffset(pointOffsets[0]);
180  for (size_t n = 1; n < pointOffsets.size(); n++) {
181  pointOffset += pointOffsets[n];
182  pointOffsets[n] = pointOffset;
183  }
184 
185  return pointOffset;
186 }
187 
188 
189 template <typename PointDataGridT, typename GridT, typename FilterT>
190 typename GridT::Ptr
191 pointCountGrid( const PointDataGridT& points,
192  const FilterT& filter)
193 {
196  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
197 
198  // This is safe because the PointDataGrid can only be modified by the deformer
200  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
201 
202  return point_mask_internal::convertPointsToScalar<GridT>(
203  nonConstPoints, filter);
204 }
205 
206 
207 template <typename PointDataGridT, typename GridT, typename FilterT>
208 typename GridT::Ptr
209 pointCountGrid( const PointDataGridT& points,
210  const openvdb::math::Transform& transform,
211  const FilterT& filter)
212 {
215  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
216 
217  // This is safe because the PointDataGrid can only be modified by the deformer
219  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
220 
221  NullDeformer deformer;
222  return point_mask_internal::convertPointsToScalar<GridT>(
223  nonConstPoints, transform, filter, deformer);
224 }
225 
226 
227 ////////////////////////////////////////
228 
229 
230 // deprecated functions
231 
232 
233 template <typename PointDataTreeT>
235 inline Index64 pointCount(const PointDataTreeT& tree, const bool inCoreOnly)
236 {
238  return pointCount(tree, filter, inCoreOnly);
239 }
240 
241 
242 template <typename PointDataTreeT>
244 inline Index64 activePointCount(const PointDataTreeT& tree, const bool inCoreOnly = true)
245 {
247  return pointCount(tree, filter, inCoreOnly);
248 }
249 
250 
251 template <typename PointDataTreeT>
253 inline Index64 inactivePointCount(const PointDataTreeT& tree, const bool inCoreOnly = true)
254 {
256  return pointCount(tree, filter, inCoreOnly);
257 }
258 
259 
260 template <typename PointDataTreeT>
262 inline Index64 groupPointCount(const PointDataTreeT& tree, const Name& name,
263  const bool inCoreOnly = true)
264 {
265  auto iter = tree.cbeginLeaf();
266  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
267  return Index64(0);
268  }
269  GroupFilter filter(name, iter->attributeSet());
270  return pointCount(tree, filter, inCoreOnly);
271 }
272 
273 
274 template <typename PointDataTreeT>
276 inline Index64 activeGroupPointCount(const PointDataTreeT& tree, const Name& name,
277  const bool inCoreOnly = true)
278 {
279  auto iter = tree.cbeginLeaf();
280  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
281  return Index64(0);
282  }
284  return pointCount(tree, filter, inCoreOnly);
285 }
286 
287 
288 template <typename PointDataTreeT>
290 inline Index64 inactiveGroupPointCount(const PointDataTreeT& tree, const Name& name,
291  const bool inCoreOnly = true)
292 {
293  auto iter = tree.cbeginLeaf();
294  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
295  return Index64(0);
296  }
298  return pointCount(tree, filter, inCoreOnly);
299 }
300 
301 
302 template <typename PointDataTreeT>
304 inline Index64 getPointOffsets(std::vector<Index64>& offsets, const PointDataTreeT& tree,
305  const std::vector<Name>& includeGroups,
306  const std::vector<Name>& excludeGroups,
307  const bool inCoreOnly = false)
308 {
309  MultiGroupFilter filter(includeGroups, excludeGroups, tree.cbeginLeaf()->attributeSet());
310  return pointOffsets(offsets, tree, filter, inCoreOnly);
311 }
312 
313 
314 template <typename PointDataGridT,
315  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type>
317 inline typename GridT::Ptr
318 pointCountGrid(const PointDataGridT& grid,
319  const std::vector<Name>& includeGroups,
320  const std::vector<Name>& excludeGroups)
321 {
322  auto leaf = grid.tree().cbeginLeaf();
323  if (!leaf) return GridT::create(0);
324  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
325  return pointCountGrid(grid, filter);
326 }
327 
328 
329 template <typename PointDataGridT,
330  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type>
332 inline typename GridT::Ptr
333 pointCountGrid(const PointDataGridT& grid,
334  const openvdb::math::Transform& transform,
335  const std::vector<Name>& includeGroups,
336  const std::vector<Name>& excludeGroups)
337 {
338  auto leaf = grid.tree().cbeginLeaf();
339  if (!leaf) return GridT::create(0);
340  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
341  return pointCountGrid(grid, transform, filter);
342 }
343 
344 
345 ////////////////////////////////////////
346 
347 
348 } // namespace points
349 } // namespace OPENVDB_VERSION_NAME
350 } // namespace openvdb
351 
352 #endif // OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
353 
354 // Copyright (c) 2012-2018 DreamWorks Animation LLC
355 // All rights reserved. This software is distributed under the
356 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Definition: ImfName.h:53
GLenum GLint * range
Definition: glcorearb.h:1924
OPENVDB_DEPRECATED Index64 activeGroupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=true)
Definition: PointCount.h:276
GridT::Ptr pointCountGrid(const PointDataGridT &grid, const FilterT &filter=NullFilter())
Generate a new grid with voxel values to store the number of points per voxel.
Definition: PointCount.h:191
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:189
Index filters primarily designed to be used with a FilterIndexIter.
Index filtering on active / inactive state of host voxel.
Definition: IndexFilter.h:131
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:77
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:944
GLuint GLsizei const GLuint const GLintptr * offsets
Definition: glcorearb.h:2620
OPENVDB_DEPRECATED Index64 getPointOffsets(std::vector< Index64 > &offsets, const PointDataTreeT &tree, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups, const bool inCoreOnly=false)
Definition: PointCount.h:304
GLdouble n
Definition: glcorearb.h:2007
OPENVDB_DEPRECATED Index64 activePointCount(const PointDataTreeT &tree, const bool inCoreOnly=true)
Definition: PointCount.h:244
#define OPENVDB_DEPRECATED
Definition: Platform.h:49
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
Tree< typename RootNodeType::template ValueConverter< Int32 >::Type > Type
Definition: Tree.h:224
Index64 pointCount(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Count the total number of points in a PointDataTree.
Definition: PointCount.h:115
GLuint const GLchar * name
Definition: glcorearb.h:785
GA_API const UT_StringHolder transform
Index filtering on group membership.
No-op deformer (adheres to the deformer interface documented in PointMove.h)
Definition: PointMask.h:91
ValueMaskFilter< true > ActiveFilter
Definition: IndexFilter.h:156
OPENVDB_DEPRECATED Index64 inactivePointCount(const PointDataTreeT &tree, const bool inCoreOnly=true)
Definition: PointCount.h:253
GLsizei const GLfloat * value
Definition: glcorearb.h:823
OPENVDB_DEPRECATED Index64 groupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=true)
Definition: PointCount.h:262
Methods for extracting masks from VDB Point grids.
Index64 pointOffsets(std::vector< Index64 > &pointOffsets, const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Populate an array of cumulative point offsets per leaf node.
Definition: PointCount.h:149
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
OPENVDB_DEPRECATED Index64 inactiveGroupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=true)
Definition: PointCount.h:290
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:135
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glcorearb.h:1296
ValueMaskFilter< false > InactiveFilter
Definition: IndexFilter.h:157