OpenVDB  9.0.1
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  if (pointOffsets.empty()) return 0;
135 
136  // compute total points per-leaf
137 
138  LeafManagerT leafManager(tree);
139  leafManager.foreach(
140  [&pointOffsets, &filter, &inCoreOnly](const LeafT& leaf, size_t pos) {
141  if (inCoreOnly && leaf.buffer().isOutOfCore()) return;
142  auto state = filter.state(leaf);
143  if (state == index::ALL) {
144  pointOffsets[pos] = leaf.pointCount();
145  } else if (state != index::NONE) {
146  pointOffsets[pos] = iterCount(leaf.beginIndexAll(filter));
147  }
148  },
149  threaded);
150 
151  // turn per-leaf totals into cumulative leaf totals
152 
153  Index64 pointOffset(pointOffsets[0]);
154  for (size_t n = 1; n < pointOffsets.size(); n++) {
155  pointOffset += pointOffsets[n];
156  pointOffsets[n] = pointOffset;
157  }
158 
159  return pointOffset;
160 }
161 
162 
163 template <typename PointDataGridT, typename GridT, typename FilterT>
164 typename GridT::Ptr
165 pointCountGrid( const PointDataGridT& points,
166  const FilterT& filter)
167 {
170  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
171 
172  // This is safe because the PointDataGrid can only be modified by the deformer
174  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
175 
176  return point_mask_internal::convertPointsToScalar<GridT>(
177  nonConstPoints, filter);
178 }
179 
180 
181 template <typename PointDataGridT, typename GridT, typename FilterT>
182 typename GridT::Ptr
183 pointCountGrid( const PointDataGridT& points,
184  const openvdb::math::Transform& transform,
185  const FilterT& filter)
186 {
189  "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
190 
191  // This is safe because the PointDataGrid can only be modified by the deformer
193  auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
194 
195  NullDeformer deformer;
196  return point_mask_internal::convertPointsToScalar<GridT>(
197  nonConstPoints, transform, filter, deformer);
198 }
199 
200 
201 ////////////////////////////////////////
202 
203 
204 } // namespace points
205 } // namespace OPENVDB_VERSION_NAME
206 } // namespace openvdb
207 
208 #endif // OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
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
GridT::Ptr pointCountGrid(const PointDataGridT &grid, const openvdb::math::Transform &transform, const FilterT &filter=NullFilter())
Generate a new grid that uses the supplied transform with voxel values to store the number of points ...
Definition: PointCount.h:183
Index filters primarily designed to be used with a FilterIndexIter.
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
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
ValueT value
Definition: GridBuilder.h:1287
Definition: IndexIterator.h:43
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:84
Methods for extracting masks from VDB Point grids.
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
Tree< typename RootNodeType::template ValueConverter< Int32 >::Type > Type
Definition: Tree.h:196
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
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
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202
Definition: IndexIterator.h:42