HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PointCount.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 points/PointCount.h
5 ///
6 /// @author Dan Bailey
7 ///
8 /// @brief Methods for counting points in VDB Point grids.
9 
10 #ifndef OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
11 #define OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
12 
13 #include <openvdb/openvdb.h>
14 
15 #include "PointDataGrid.h"
16 #include "PointMask.h"
17 #include "IndexFilter.h"
18 
19 #include <tbb/parallel_reduce.h>
20 
21 #include <vector>
22 
23 
24 namespace openvdb {
26 namespace OPENVDB_VERSION_NAME {
27 namespace points {
28 
29 
30 /// @brief Count the total number of points in a PointDataTree
31 /// @param tree the PointDataTree in which to count the points
32 /// @param filter an optional index filter
33 /// @param inCoreOnly if true, points in out-of-core leaf nodes are not counted
34 /// @param threaded enable or disable threading (threading is enabled by default)
35 template <typename PointDataTreeT, typename FilterT = NullFilter>
36 inline Index64 pointCount( const PointDataTreeT& tree,
37  const FilterT& filter = NullFilter(),
38  const bool inCoreOnly = false,
39  const bool threaded = true);
40 
41 
42 /// @brief Populate an array of cumulative point offsets per leaf node.
43 /// @param pointOffsets array of offsets to be populated
44 /// @param tree the PointDataTree from which to populate the offsets
45 /// @param filter an optional index filter
46 /// @param inCoreOnly if true, points in out-of-core leaf nodes are ignored
47 /// @param threaded enable or disable threading (threading is enabled by default)
48 /// @return The final cumulative point offset.
49 template <typename PointDataTreeT, typename FilterT = NullFilter>
50 inline Index64 pointOffsets(std::vector<Index64>& pointOffsets,
51  const PointDataTreeT& tree,
52  const FilterT& filter = NullFilter(),
53  const bool inCoreOnly = false,
54  const bool threaded = true);
55 
56 
57 /// @brief Generate a new grid with voxel values to store the number of points per voxel
58 /// @param grid the PointDataGrid to use to compute the count grid
59 /// @param filter an optional index filter
60 /// @note The return type of the grid must be an integer or floating-point scalar grid.
61 template <typename PointDataGridT,
62  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
63  typename FilterT = NullFilter>
64 inline typename GridT::Ptr
65 pointCountGrid( const PointDataGridT& grid,
66  const FilterT& filter = NullFilter());
67 
68 
69 /// @brief Generate a new grid that uses the supplied transform with voxel values to store the
70 /// number of points per voxel.
71 /// @param grid the PointDataGrid to use to compute the count grid
72 /// @param transform the transform to use to compute the count grid
73 /// @param filter an optional index filter
74 /// @note The return type of the grid must be an integer or floating-point scalar grid.
75 template <typename PointDataGridT,
76  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
77  typename FilterT = NullFilter>
78 inline typename GridT::Ptr
79 pointCountGrid( const PointDataGridT& grid,
80  const openvdb::math::Transform& transform,
81  const FilterT& filter = NullFilter());
82 
83 
84 ////////////////////////////////////////
85 
86 
87 template <typename PointDataTreeT, typename FilterT>
88 Index64 pointCount(const PointDataTreeT& tree,
89  const FilterT& filter,
90  const bool inCoreOnly,
91  const bool threaded)
92 {
93  using LeafManagerT = tree::LeafManager<const PointDataTreeT>;
94  using LeafRangeT = typename LeafManagerT::LeafRange;
95 
96  auto countLambda =
97  [&filter, &inCoreOnly] (const LeafRangeT& range, Index64 sum) -> Index64 {
98  for (const auto& leaf : range) {
99  if (inCoreOnly && leaf.buffer().isOutOfCore()) continue;
100  auto state = filter.state(leaf);
101  if (state == index::ALL) {
102  sum += leaf.pointCount();
103  } else if (state != index::NONE) {
104  sum += iterCount(leaf.beginIndexAll(filter));
105  }
106  }
107  return sum;
108  };
109 
110  LeafManagerT leafManager(tree);
111  if (threaded) {
112  return tbb::parallel_reduce(leafManager.leafRange(), Index64(0), countLambda,
113  [] (Index64 n, Index64 m) -> Index64 { return n + m; });
114  }
115  else {
116  return countLambda(leafManager.leafRange(), Index64(0));
117  }
118 }
119 
120 
121 template <typename PointDataTreeT, typename FilterT>
122 Index64 pointOffsets( std::vector<Index64>& pointOffsets,
123  const PointDataTreeT& tree,
124  const FilterT& filter,
125  const bool inCoreOnly,
126  const bool threaded)
127 {
128  using LeafT = typename PointDataTreeT::LeafNodeType;
129  using LeafManagerT = typename tree::LeafManager<const PointDataTreeT>;
130 
131  // allocate and zero values in point offsets array
132 
133  pointOffsets.assign(tree.leafCount(), Index64(0));
134 
135  // compute total points per-leaf
136 
137  LeafManagerT leafManager(tree);
138  leafManager.foreach(
139  [&pointOffsets, &filter, &inCoreOnly](const LeafT& leaf, size_t pos) {
140  if (inCoreOnly && leaf.buffer().isOutOfCore()) return;
141  auto state = filter.state(leaf);
142  if (state == index::ALL) {
143  pointOffsets[pos] = leaf.pointCount();
144  } else if (state != index::NONE) {
145  pointOffsets[pos] = iterCount(leaf.beginIndexAll(filter));
146  }
147  },
148  threaded);
149 
150  // turn per-leaf totals into cumulative leaf totals
151 
152  Index64 pointOffset(pointOffsets[0]);
153  for (size_t n = 1; n < pointOffsets.size(); n++) {
154  pointOffset += pointOffsets[n];
155  pointOffsets[n] = pointOffset;
156  }
157 
158  return pointOffset;
159 }
160 
161 
162 template <typename PointDataGridT, typename GridT, typename FilterT>
163 typename GridT::Ptr
164 pointCountGrid( const PointDataGridT& points,
165  const FilterT& filter)
166 {
169  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
170 
171  // This is safe because the PointDataGrid can only be modified by the deformer
173  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
174 
175  return point_mask_internal::convertPointsToScalar<GridT>(
176  nonConstPoints, filter);
177 }
178 
179 
180 template <typename PointDataGridT, typename GridT, typename FilterT>
181 typename GridT::Ptr
182 pointCountGrid( const PointDataGridT& points,
183  const openvdb::math::Transform& transform,
184  const FilterT& filter)
185 {
188  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
189 
190  // This is safe because the PointDataGrid can only be modified by the deformer
192  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
193 
194  NullDeformer deformer;
195  return point_mask_internal::convertPointsToScalar<GridT>(
196  nonConstPoints, transform, filter, deformer);
197 }
198 
199 
200 ////////////////////////////////////////
201 
202 
203 } // namespace points
204 } // namespace OPENVDB_VERSION_NAME
205 } // namespace openvdb
206 
207 #endif // OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
GLenum GLint * range
Definition: glew.h:3500
GLuint GLenum GLenum transform
Definition: glew.h:14742
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:164
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:166
Index filters primarily designed to be used with a FilterIndexIter.
const GLdouble * m
Definition: glew.h:9124
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1068
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter
Definition: glew.h:2981
GLsizei n
Definition: glew.h:4040
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:82
Tree< typename RootNodeType::template ValueConverter< Int32 >::Type > Type
Definition: Tree.h:195
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:88
No-op deformer (adheres to the deformer interface documented in PointMove.h)
Definition: PointMask.h:64
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3446
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:122
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:112
GLsizei const GLfloat * value
Definition: glew.h:1849
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...