OpenVDB 10.0.1
Loading...
Searching...
No Matches
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
24namespace openvdb {
26namespace OPENVDB_VERSION_NAME {
27namespace 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)
35template <typename PointDataTreeT, typename FilterT = NullFilter>
36inline 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.
49template <typename PointDataTreeT, typename FilterT = NullFilter>
50inline 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.
61template <typename PointDataGridT,
62 typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
63 typename FilterT = NullFilter>
64inline typename GridT::Ptr
65pointCountGrid( 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.
75template <typename PointDataGridT,
76 typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type,
77 typename FilterT = NullFilter>
78inline typename GridT::Ptr
79pointCountGrid( const PointDataGridT& grid,
80 const openvdb::math::Transform& transform,
81 const FilterT& filter = NullFilter());
82
83
84////////////////////////////////////////
85
86
87template <typename PointDataTreeT, typename FilterT>
88Index64 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
121template <typename PointDataTreeT, typename FilterT>
122Index64 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
163template <typename PointDataGridT, typename GridT, typename FilterT>
164typename GridT::Ptr
165pointCountGrid( const PointDataGridT& points,
166 const FilterT& filter)
167{
168 static_assert(std::is_integral<typename GridT::ValueType>::value ||
169 std::is_floating_point<typename GridT::ValueType>::value,
170 "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
171
172 using PointDataTreeT = typename PointDataGridT::TreeType;
173 using TreeT = typename GridT::TreeType;
174
175 typename TreeT::Ptr tree =
176 point_mask_internal::convertPointsToScalar<TreeT, PointDataTreeT, FilterT>
177 (points.tree(), filter);
178
179 typename GridT::Ptr grid(new GridT(tree));
180 grid->setTransform(points.transform().copy());
181 return grid;
182}
183
184
185template <typename PointDataGridT, typename GridT, typename FilterT>
186typename GridT::Ptr
187pointCountGrid( const PointDataGridT& points,
188 const openvdb::math::Transform& transform,
189 const FilterT& filter)
190{
191 static_assert( std::is_integral<typename GridT::ValueType>::value ||
192 std::is_floating_point<typename GridT::ValueType>::value,
193 "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
194
195 // This is safe because the PointDataGrid can only be modified by the deformer
197 auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
198
199 NullDeformer deformer;
200 return point_mask_internal::convertPointsToScalar<GridT>(
201 nonConstPoints, transform, filter, deformer);
202}
203
204
205////////////////////////////////////////
206
207
208} // namespace points
209} // namespace OPENVDB_VERSION_NAME
210} // namespace openvdb
211
212#endif // OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
Index filters primarily designed to be used with a FilterIndexIter.
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Methods for extracting masks from VDB Point grids.
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
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 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
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:165
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:314
uint64_t Index64
Definition: Types.h:53
Definition: Exceptions.h:13
This adapter allows code that is templated on a Tree type to accept either a Tree type or a Grid type...
Definition: Grid.h:1060
No-op deformer (adheres to the deformer interface documented in PointMove.h)
Definition: PointMask.h:75
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212