OpenVDB 11.0.0
Loading...
Searching...
No Matches
PointCountImpl.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: MPL-2.0
3
4/// @author Dan Bailey
5///
6/// @file PointCountImpl.h
7///
8
9#ifndef OPENVDB_POINTS_POINT_COUNT_IMPL_HAS_BEEN_INCLUDED
10#define OPENVDB_POINTS_POINT_COUNT_IMPL_HAS_BEEN_INCLUDED
11
12namespace openvdb {
14namespace OPENVDB_VERSION_NAME {
15namespace points {
16
17template <typename PointDataTreeT, typename FilterT>
18Index64 pointCount(const PointDataTreeT& tree,
19 const FilterT& filter,
20 const bool inCoreOnly,
21 const bool threaded)
22{
23 using LeafManagerT = tree::LeafManager<const PointDataTreeT>;
24 using LeafRangeT = typename LeafManagerT::LeafRange;
25
26 auto countLambda =
27 [&filter, &inCoreOnly] (const LeafRangeT& range, Index64 sum) -> Index64 {
28 for (const auto& leaf : range) {
29 if (inCoreOnly && leaf.buffer().isOutOfCore()) continue;
30 auto state = filter.state(leaf);
31 if (state == index::ALL) {
32 sum += leaf.pointCount();
33 } else if (state != index::NONE) {
34 sum += iterCount(leaf.beginIndexAll(filter));
35 }
36 }
37 return sum;
38 };
39
40 LeafManagerT leafManager(tree);
41 if (threaded) {
42 return tbb::parallel_reduce(leafManager.leafRange(), Index64(0), countLambda,
43 [] (Index64 n, Index64 m) -> Index64 { return n + m; });
44 }
45 else {
46 return countLambda(leafManager.leafRange(), Index64(0));
47 }
48}
49
50
51template <typename PointDataTreeT, typename FilterT>
52Index64 pointOffsets( std::vector<Index64>& pointOffsets,
53 const PointDataTreeT& tree,
54 const FilterT& filter,
55 const bool inCoreOnly,
56 const bool threaded)
57{
58 using LeafT = typename PointDataTreeT::LeafNodeType;
59 using LeafManagerT = typename tree::LeafManager<const PointDataTreeT>;
60
61 // allocate and zero values in point offsets array
62
63 pointOffsets.assign(tree.leafCount(), Index64(0));
64 if (pointOffsets.empty()) return 0;
65
66 // compute total points per-leaf
67
68 LeafManagerT leafManager(tree);
69 leafManager.foreach(
70 [&pointOffsets, &filter, &inCoreOnly](const LeafT& leaf, size_t pos) {
71 if (inCoreOnly && leaf.buffer().isOutOfCore()) return;
72 auto state = filter.state(leaf);
73 if (state == index::ALL) {
74 pointOffsets[pos] = leaf.pointCount();
75 } else if (state != index::NONE) {
76 pointOffsets[pos] = iterCount(leaf.beginIndexAll(filter));
77 }
78 },
79 threaded);
80
81 // turn per-leaf totals into cumulative leaf totals
82
83 Index64 pointOffset(pointOffsets[0]);
84 for (size_t n = 1; n < pointOffsets.size(); n++) {
85 pointOffset += pointOffsets[n];
86 pointOffsets[n] = pointOffset;
87 }
88
89 return pointOffset;
90}
91
92
93template <typename PointDataGridT, typename GridT, typename FilterT>
94typename GridT::Ptr
95pointCountGrid( const PointDataGridT& points,
96 const FilterT& filter)
97{
98 static_assert(std::is_integral<typename GridT::ValueType>::value ||
99 std::is_floating_point<typename GridT::ValueType>::value,
100 "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
101
102 using PointDataTreeT = typename PointDataGridT::TreeType;
103 using TreeT = typename GridT::TreeType;
104
105 typename TreeT::Ptr tree =
106 point_mask_internal::convertPointsToScalar<TreeT, PointDataTreeT, FilterT>
107 (points.tree(), filter);
108
109 typename GridT::Ptr grid(new GridT(tree));
110 grid->setTransform(points.transform().copy());
111 return grid;
112}
113
114
115template <typename PointDataGridT, typename GridT, typename FilterT>
116typename GridT::Ptr
117pointCountGrid( const PointDataGridT& points,
118 const openvdb::math::Transform& transform,
119 const FilterT& filter)
120{
121 static_assert( std::is_integral<typename GridT::ValueType>::value ||
122 std::is_floating_point<typename GridT::ValueType>::value,
123 "openvdb::points::pointCountGrid must return an integer or floating-point scalar grid");
124
125 // This is safe because the PointDataGrid can only be modified by the deformer
127 auto& nonConstPoints = const_cast<typename AdapterT::NonConstGridType&>(points);
128
129 NullDeformer deformer;
130 return point_mask_internal::convertPointsToScalar<GridT>(
131 nonConstPoints, transform, filter, deformer);
132}
133
134
135////////////////////////////////////////
136
137
138} // namespace points
139} // namespace OPENVDB_VERSION_NAME
140} // namespace openvdb
141
142#endif // OPENVDB_POINTS_POINT_COUNT_IMPL_HAS_BEEN_INCLUDED
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 PointCountImpl.h:52
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 PointCountImpl.h:18
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 PointCountImpl.h:95
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:74
#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