OpenVDB  5.0.0
PointCount.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2017 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 //
30 
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" // GridCombinerOp
44 #include "IndexFilter.h"
45 
46 #include <tbb/parallel_reduce.h>
47 
48 #include <type_traits>
49 #include <vector>
50 
51 
52 namespace openvdb {
54 namespace OPENVDB_VERSION_NAME {
55 namespace points {
56 
57 
61 template <typename PointDataTreeT>
62 Index64 pointCount(const PointDataTreeT& tree, const bool inCoreOnly = false);
63 
64 
68 template <typename PointDataTreeT>
69 Index64 activePointCount(const PointDataTreeT& tree, const bool inCoreOnly = false);
70 
71 
75 template <typename PointDataTreeT>
76 Index64 inactivePointCount(const PointDataTreeT& tree, const bool inCoreOnly = false);
77 
78 
86 template <typename PointDataTreeT>
87 Index64 getPointOffsets(std::vector<Index64>& pointOffsets, const PointDataTreeT& tree,
88  const std::vector<Name>& includeGroups = std::vector<Name>(),
89  const std::vector<Name>& excludeGroups = std::vector<Name>(),
90  const bool inCoreOnly = false);
91 
92 
97 template <typename PointDataTreeT>
98 Index64 groupPointCount(const PointDataTreeT& tree, const Name& name,
99  const bool inCoreOnly = false);
100 
101 
106 template <typename PointDataTreeT>
107 Index64 activeGroupPointCount(const PointDataTreeT& tree, const Name& name,
108  const bool inCoreOnly = false);
109 
110 
115 template <typename PointDataTreeT>
116 Index64 inactiveGroupPointCount(const PointDataTreeT& tree, const Name& name,
117  const bool inCoreOnly = false);
118 
119 
125 template <typename PointDataGridT,
126  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type>
127 inline typename std::enable_if< std::is_integral<typename GridT::ValueType>::value ||
128  std::is_floating_point<typename GridT::ValueType>::value,
129  typename GridT::Ptr>::type
130 pointCountGrid(const PointDataGridT& grid,
131  const std::vector<Name>& includeGroups = std::vector<Name>(),
132  const std::vector<Name>& excludeGroups = std::vector<Name>());
133 
134 
142 template <typename PointDataGridT,
143  typename GridT = typename PointDataGridT::template ValueConverter<Int32>::Type>
144 inline typename std::enable_if< std::is_integral<typename GridT::ValueType>::value ||
145  std::is_floating_point<typename GridT::ValueType>::value,
146  typename GridT::Ptr>::type
147 pointCountGrid(const PointDataGridT& grid,
148  const openvdb::math::Transform& transform,
149  const std::vector<Name>& includeGroups = std::vector<Name>(),
150  const std::vector<Name>& excludeGroups = std::vector<Name>());
151 
152 
154 
155 
156 namespace point_count_internal {
157 
158 template < typename PointDataTreeT,
159  typename ValueIterT,
160  typename FilterT>
162 {
164 
165  PointCountOp(const FilterT& filter,
166  const bool inCoreOnly = false)
167  : mFilter(filter)
168  , mInCoreOnly(inCoreOnly) { }
169 
170  Index64 operator()(const typename LeafManagerT::LeafRange& range, Index64 size) const {
171 
172  for (auto leaf = range.begin(); leaf; ++leaf) {
173  if (mInCoreOnly && leaf->buffer().isOutOfCore()) continue;
174  auto iter = leaf->template beginIndex<ValueIterT, FilterT>(mFilter);
175  size += iterCount(iter);
176  }
177 
178  return size;
179  }
180 
181  static Index64 join(Index64 size1, Index64 size2) {
182  return size1 + size2;
183  }
184 
185 private:
186  const FilterT& mFilter;
187  const bool mInCoreOnly;
188 }; // struct PointCountOp
189 
190 
191 template <typename PointDataTreeT, typename FilterT, typename ValueIterT>
192 Index64 threadedFilterPointCount( const PointDataTreeT& tree,
193  const FilterT& filter,
194  const bool inCoreOnly = false)
195 {
197 
198  typename tree::LeafManager<const PointDataTreeT> leafManager(tree);
199  const PointCountOp pointCountOp(filter, inCoreOnly);
200  return tbb::parallel_reduce(leafManager.leafRange(), Index64(0), pointCountOp, PointCountOp::join);
201 }
202 
203 
204 template <typename PointDataTreeT, typename FilterT>
205 Index64 filterPointCount(const PointDataTreeT& tree,
206  const FilterT& filter,
207  const bool inCoreOnly = false)
208 {
209  using ValueIterT = typename PointDataTreeT::LeafNodeType::ValueAllCIter;
210  return threadedFilterPointCount< PointDataTreeT, FilterT, ValueIterT>(tree, filter, inCoreOnly);
211 }
212 
213 
214 template <typename PointDataTreeT, typename FilterT>
215 Index64 filterActivePointCount( const PointDataTreeT& tree,
216  const FilterT& filter,
217  const bool inCoreOnly = false)
218 {
219  using ValueIterT = typename PointDataTreeT::LeafNodeType::ValueOnCIter;
220  return threadedFilterPointCount< PointDataTreeT, FilterT, ValueIterT>(tree, filter, inCoreOnly);
221 }
222 
223 
224 template <typename PointDataTreeT, typename FilterT>
225 Index64 filterInactivePointCount( const PointDataTreeT& tree,
226  const FilterT& filter,
227  const bool inCoreOnly = false)
228 {
229  using ValueIterT = typename PointDataTreeT::LeafNodeType::ValueOffCIter;
230  return threadedFilterPointCount< PointDataTreeT, FilterT, ValueIterT>(tree, filter, inCoreOnly);
231 }
232 
233 
234 } // namespace point_count_internal
235 
236 
238 
239 
240 template <typename PointDataTreeT>
241 Index64 pointCount(const PointDataTreeT& tree, const bool inCoreOnly)
242 {
243  (void) inCoreOnly;
244  Index64 size = 0;
245  for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
246  if (inCoreOnly && iter->buffer().isOutOfCore()) continue;
247  size += iter->pointCount();
248  }
249  return size;
250 }
251 
252 
253 template <typename PointDataTreeT>
254 Index64 activePointCount(const PointDataTreeT& tree, const bool inCoreOnly)
255 {
256  (void) inCoreOnly;
257  Index64 size = 0;
258  for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
259  if (inCoreOnly && iter->buffer().isOutOfCore()) continue;
260  size += iter->onPointCount();
261  }
262  return size;
263 }
264 
265 
266 template <typename PointDataTreeT>
267 Index64 inactivePointCount(const PointDataTreeT& tree, const bool inCoreOnly)
268 {
269  (void) inCoreOnly;
270  Index64 size = 0;
271  for (auto iter = tree.cbeginLeaf(); iter; ++iter) {
272  if (inCoreOnly && iter->buffer().isOutOfCore()) continue;
273  size += iter->offPointCount();
274  }
275  return size;
276 }
277 
278 
279 template <typename PointDataTreeT>
280 Index64 groupPointCount(const PointDataTreeT& tree, const Name& name, const bool inCoreOnly)
281 {
282  auto iter = tree.cbeginLeaf();
283  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
284  return Index64(0);
285  }
286  GroupFilter groupFilter(name, iter->attributeSet());
287  return point_count_internal::filterPointCount<PointDataTreeT, GroupFilter>(tree, groupFilter, inCoreOnly);
288 }
289 
290 
291 template <typename PointDataTreeT>
292 Index64 activeGroupPointCount(const PointDataTreeT& tree, const Name& name, const bool inCoreOnly)
293 {
294  auto iter = tree.cbeginLeaf();
295  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
296  return Index64(0);
297  }
298  GroupFilter groupFilter(name, iter->attributeSet());
299  return point_count_internal::filterActivePointCount<PointDataTreeT, GroupFilter>(tree, groupFilter, inCoreOnly);
300 }
301 
302 
303 template <typename PointDataTreeT>
304 Index64 inactiveGroupPointCount(const PointDataTreeT& tree, const Name& name, const bool inCoreOnly)
305 {
306  auto iter = tree.cbeginLeaf();
307  if (!iter || !iter->attributeSet().descriptor().hasGroup(name)) {
308  return Index64(0);
309  }
310  GroupFilter groupFilter(name, iter->attributeSet());
311  return point_count_internal::filterInactivePointCount<PointDataTreeT, GroupFilter>(tree, groupFilter, inCoreOnly);
312 }
313 
314 
315 template <typename PointDataTreeT>
316 Index64 getPointOffsets(std::vector<Index64>& pointOffsets, const PointDataTreeT& tree,
317  const std::vector<Name>& includeGroups, const std::vector<Name>& excludeGroups,
318  const bool inCoreOnly)
319 {
320  using LeafNode = typename PointDataTreeT::LeafNodeType;
321 
322  const bool useGroup = includeGroups.size() > 0 || excludeGroups.size() > 0;
323 
324  tree::LeafManager<const PointDataTreeT> leafManager(tree);
325  const size_t leafCount = leafManager.leafCount();
326 
327  pointOffsets.reserve(leafCount);
328 
329  Index64 pointOffset = 0;
330  for (size_t n = 0; n < leafCount; n++)
331  {
332  const LeafNode& leaf = leafManager.leaf(n);
333 
334  // skip out-of-core leafs
335  if (inCoreOnly && leaf.buffer().isOutOfCore()) {
336  pointOffsets.push_back(pointOffset);
337  continue;
338  }
339 
340  if (useGroup) {
341  auto iter = leaf.beginValueOn();
342  MultiGroupFilter filter(includeGroups, excludeGroups, leaf.attributeSet());
343  filter.reset(leaf);
345  pointOffset += iterCount(filterIndexIter);
346  }
347  else {
348  pointOffset += leaf.onPointCount();
349  }
350  pointOffsets.push_back(pointOffset);
351  }
352  return pointOffset;
353 }
354 
355 
356 template <typename PointDataGridT, typename GridT>
357 inline typename std::enable_if< std::is_integral<typename GridT::ValueType>::value ||
358  std::is_floating_point<typename GridT::ValueType>::value,
359  typename GridT::Ptr>::type
360 pointCountGrid(const PointDataGridT& points,
361  const std::vector<Name>& includeGroups,
362  const std::vector<Name>& excludeGroups)
363 {
364  return point_mask_internal::convertPointsToScalar<PointDataGridT, GridT>(
365  points, includeGroups, excludeGroups);
366 }
367 
368 
369 template <typename PointDataGridT, typename GridT>
370 inline typename std::enable_if< std::is_integral<typename GridT::ValueType>::value ||
371  std::is_floating_point<typename GridT::ValueType>::value,
372  typename GridT::Ptr>::type
373 pointCountGrid(const PointDataGridT& points,
374  const openvdb::math::Transform& transform,
375  const std::vector<Name>& includeGroups,
376  const std::vector<Name>& excludeGroups)
377 {
378  return point_mask_internal::convertPointsToScalar<PointDataGridT, GridT>(
379  points, transform, includeGroups, excludeGroups);
380 }
381 
382 
384 
385 
386 } // namespace points
387 } // namespace OPENVDB_VERSION_NAME
388 } // namespace openvdb
389 
390 #endif // OPENVDB_POINTS_POINT_COUNT_HAS_BEEN_INCLUDED
391 
392 // Copyright (c) 2012-2017 DreamWorks Animation LLC
393 // All rights reserved. This software is distributed under the
394 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Index64 pointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total points in the PointDataTree.
Definition: PointCount.h:241
typename tree::LeafManager< const PointDataTreeT > LeafManagerT
Definition: PointCount.h:163
Index64 filterInactivePointCount(const PointDataTreeT &tree, const FilterT &filter, const bool inCoreOnly=false)
Definition: PointCount.h:225
Index64 inactiveGroupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=false)
Total inactive points in the group in the PointDataTree.
Definition: PointCount.h:304
size_t leafCount() const
Return the number of leaf nodes.
Definition: LeafManager.h:328
uint64_t Index64
Definition: Types.h:59
Index64 groupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=false)
Total points in the group in the PointDataTree.
Definition: PointCount.h:280
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:386
Index64 threadedFilterPointCount(const PointDataTreeT &tree, const FilterT &filter, const bool inCoreOnly=false)
Definition: PointCount.h:192
Index64 inactivePointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total inactive points in the PointDataTree.
Definition: PointCount.h:267
Tree< typename RootNodeType::template ValueConverter< Int32 >::Type > Type
Definition: Tree.h:224
Index filters primarily designed to be used with a FilterIndexIter.
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
Index64 activeGroupPointCount(const PointDataTreeT &tree, const Name &name, const bool inCoreOnly=false)
Total active points in the group in the PointDataTree.
Definition: PointCount.h:292
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:313
Definition: Exceptions.h:39
LeafType & leaf(size_t leafIdx) const
Return a pointer to the leaf node at index leafIdx in the array.
Definition: LeafManager.h:359
std::enable_if< std::is_integral< typename GridT::ValueType >::value||std::is_floating_point< typename GridT::ValueType >::value, typename GridT::Ptr >::type pointCountGrid(const PointDataGridT &grid, const openvdb::math::Transform &transform, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >())
Generate a new grid that uses the supplied transform with voxel values to store the number of points ...
Definition: PointCount.h:373
This class manages a linear array of pointers to a given tree&#39;s leaf nodes, as well as optional auxil...
Definition: LeafManager.h:110
A forward iterator over array indices with filtering IteratorT can be either IndexIter or ValueIndexI...
Definition: IndexIterator.h:144
Methods for extracting masks from VDB Point grids.
std::string Name
Definition: Name.h:44
Definition: IndexFilter.h:104
PointCountOp(const FilterT &filter, const bool inCoreOnly=false)
Definition: PointCount.h:165
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
Index filtering on group membership.
Definition: AttributeGroup.h:159
Index64 filterActivePointCount(const PointDataTreeT &tree, const FilterT &filter, const bool inCoreOnly=false)
Definition: PointCount.h:215
void reset(const LeafT &leaf)
Definition: IndexFilter.h:146
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
Index64 filterPointCount(const PointDataTreeT &tree, const FilterT &filter, const bool inCoreOnly=false)
Definition: PointCount.h:205
Index64 operator()(const typename LeafManagerT::LeafRange &range, Index64 size) const
Definition: PointCount.h:170
Index64 activePointCount(const PointDataTreeT &tree, const bool inCoreOnly=false)
Total active points in the PointDataTree.
Definition: PointCount.h:254
Index64 getPointOffsets(std::vector< Index64 > &pointOffsets, const PointDataTreeT &tree, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >(), const bool inCoreOnly=false)
Populate an array of cumulative point offsets per leaf node.
Definition: PointCount.h:316
static Index64 join(Index64 size1, Index64 size2)
Definition: PointCount.h:181