OpenVDB  5.0.0
PointMask.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_MASK_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
39 
40 #include <openvdb/openvdb.h>
41 #include <openvdb/tools/ValueTransformer.h> // valxform::SumOp
42 
43 #include "PointDataGrid.h"
44 #include "IndexFilter.h"
45 
46 #include <tbb/combinable.h>
47 
48 #include <type_traits>
49 #include <vector>
50 
51 
52 namespace openvdb {
54 namespace OPENVDB_VERSION_NAME {
55 namespace points {
56 
57 
63 template <typename PointDataGridT,
64  typename MaskT = typename PointDataGridT::template ValueConverter<bool>::Type>
65 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
66  typename MaskT::Ptr>::type
67 convertPointsToMask(const PointDataGridT& grid,
68  const std::vector<Name>& includeGroups = std::vector<Name>(),
69  const std::vector<Name>& excludeGroups = std::vector<Name>());
70 
71 
78 template <typename PointDataGridT,
79  typename MaskT = typename PointDataGridT::template ValueConverter<bool>::Type>
80 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
81  typename MaskT::Ptr>::type
82 convertPointsToMask(const PointDataGridT& grid,
83  const openvdb::math::Transform& transform,
84  const std::vector<Name>& includeGroups = std::vector<Name>(),
85  const std::vector<Name>& excludeGroups = std::vector<Name>());
86 
87 
89 
90 
91 namespace point_mask_internal {
92 
95 template<typename GridT>
97 {
98  using CombinableT = typename tbb::combinable<GridT>;
99 
100  using TreeT = typename GridT::TreeType;
101  using LeafT = typename TreeT::LeafNodeType;
102  using ValueType = typename TreeT::ValueType;
104 
105  GridCombinerOp(GridT& grid)
106  : mTree(grid.tree()) {}
107 
108  void operator()(const GridT& grid)
109  {
110  for (auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
111  auto* newLeaf = mTree.probeLeaf(leaf->origin());
112  if (!newLeaf) {
113  // if the leaf doesn't yet exist in the new tree, steal it
114  auto& tree = const_cast<GridT&>(grid).tree();
115  mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
116  zeroVal<ValueType>(), false));
117  }
118  else {
119  // otherwise increment existing values
120  for (auto iter = leaf->cbeginValueOn(); iter; ++iter) {
121  newLeaf->modifyValue(iter.getCoord(), SumOp(*iter));
122  }
123  }
124  }
125  }
126 
127 private:
128  TreeT& mTree;
129 }; // struct GridCombinerOp
130 
131 
133 template <typename GridT, typename PointDataGridT, typename FilterT>
135 {
136  using TreeT = typename GridT::TreeType;
138  using ValueT = typename TreeT::LeafNodeType::ValueType;
139 
140  PointsToScalarOp(const PointDataGridT& grid,
141  const FilterT& filter)
142  : mPointDataAccessor(grid.getConstAccessor())
143  , mFilter(filter) { }
144 
145  void operator()(const typename LeafManagerT::LeafRange& range) const {
146 
147  for (auto leaf = range.begin(); leaf; ++leaf) {
148 
149  const auto* const pointLeaf =
150  mPointDataAccessor.probeConstLeaf(leaf->origin());
151 
152  // assumes matching topology
153  assert(pointLeaf);
154 
155  for (auto value = leaf->beginValueOn(); value; ++value) {
156  const Index64 count = points::iterCount(
157  pointLeaf->beginIndexVoxel(value.getCoord(), mFilter));
158  if (count > Index64(0)) {
159  value.setValue(static_cast<ValueT>(count));}
160  else {
161  // disable any empty voxels
162  value.setValueOn(false);
163  }
164  }
165  }
166  }
167 
168 private:
169  const typename PointDataGridT::ConstAccessor mPointDataAccessor;
170  const FilterT& mFilter;
171 }; // struct PointsToScalarOp
172 
173 
176 template <typename GridT, typename PointDataGridT, typename FilterT>
178 {
180  using ValueType = typename GridT::TreeType::LeafNodeType::ValueType;
183 
185  const math::Transform& transform,
186  const FilterT& filter,
187  CombinableT& combinable)
188  : mNewTransform(newTransform)
189  , mTransform(transform)
190  , mFilter(filter)
191  , mCombinable(combinable) { }
192 
193  void operator()(const typename LeafManagerT::LeafRange& range) const
194  {
195  auto& grid = mCombinable.local();
196  auto& countTree = grid.tree();
198 
199  for (auto leaf = range.begin(); leaf; ++leaf) {
200 
201  auto handle = HandleT::create(leaf->constAttributeArray("P"));
202 
203  for (auto iter = leaf->beginIndexOn(mFilter); iter; iter++) {
204  const Vec3d position = mTransform.indexToWorld(handle->get(*iter) +
205  iter.getCoord().asVec3d());
206  const Coord ijk = mNewTransform.worldToIndexCellCentered(position);
207 
209  }
210  }
211  }
212 
213 private:
214  const openvdb::math::Transform& mNewTransform;
215  const openvdb::math::Transform& mTransform;
216  const FilterT& mFilter;
217  CombinableT& mCombinable;
218 }; // struct PointsToTransformedScalarOp
219 
220 
221 template<typename PointDataGridT, typename GridT>
222 inline typename GridT::Ptr convertPointsToScalar(
223  const PointDataGridT& points,
224  const std::vector<Name>& includeGroups,
225  const std::vector<Name>& excludeGroups)
226 {
228 
229  using GridTreeT = typename GridT::TreeType;
230  using ValueT = typename GridTreeT::ValueType;
231 
232  // copy the topology from the points grid
233 
234  typename GridTreeT::Ptr tree(new GridTreeT(points.constTree(),
235  false, openvdb::TopologyCopy()));
236  typename GridT::Ptr grid = GridT::create(tree);
237  grid->setTransform(points.transform().copy());
238 
239  // early exit if no leaves
240 
241  if (points.constTree().leafCount() == 0) return grid;
242 
243  const bool useGroup = !includeGroups.empty() || !excludeGroups.empty();
244 
245  // early exit if mask and no group logic
246 
247  if (std::is_same<ValueT, bool>::value && !useGroup) return grid;
248 
249  // evaluate point group filters to produce a subset of the generated mask
250 
251  tree::LeafManager<GridTreeT> leafManager(*tree);
252 
253  if (useGroup) {
254  // build mask from points in parallel only where filter evaluates to true
255  const auto leaf = points.constTree().cbeginLeaf();
256  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
258  points, filter);
259  tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
260  }
261  else {
262  NullFilter filter;
264  points, filter);
265  tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
266  }
267 
268  return grid;
269 }
270 
271 
272 template<typename PointDataGridT, typename GridT>
273 inline typename GridT::Ptr convertPointsToScalar(
274  const PointDataGridT& points,
275  const openvdb::math::Transform& transform,
276  const std::vector<Name>& includeGroups,
277  const std::vector<Name>& excludeGroups)
278 {
281 
282  using CombinerOpT = GridCombinerOp<GridT>;
283  using CombinableT = typename GridCombinerOp<GridT>::CombinableT;
284 
285  // use the simpler method if the requested transform matches the existing one
286 
287  const openvdb::math::Transform& pointsTransform = points.constTransform();
288 
289  if (transform == pointsTransform) {
290  return convertPointsToScalar<PointDataGridT, GridT>(
291  points, includeGroups, excludeGroups);
292  }
293 
294  typename GridT::Ptr grid = GridT::create();
295  grid->setTransform(transform.copy());
296 
297  // early exit if no leaves
298 
299  if (points.constTree().leafCount() == 0) return grid;
300 
301  // compute mask grids in parallel using new transform
302 
303  CombinableT combiner;
304 
306 
307  const bool useGroup = !includeGroups.empty() || !excludeGroups.empty();
308 
309  if (useGroup) {
310  const auto leaf = points.constTree().cbeginLeaf();
311  MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
313  transform, pointsTransform, filter, combiner);
314  tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
315  }
316  else {
317  NullFilter filter;
319  transform, pointsTransform, filter, combiner);
320  tbb::parallel_for(leafManager.leafRange(), pointsToScalarOp);
321  }
322 
323  // combine the mask grids into one
324 
325  CombinerOpT combineOp(*grid);
326  combiner.combine_each(combineOp);
327 
328  return grid;
329 }
330 
331 
332 } // namespace point_mask_internal
333 
334 
336 
337 
338 template<typename PointDataGridT, typename MaskT>
339 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
340  typename MaskT::Ptr>::type
342  const PointDataGridT& points,
343  const std::vector<Name>& includeGroups,
344  const std::vector<Name>& excludeGroups)
345 {
346  return point_mask_internal::convertPointsToScalar<PointDataGridT, MaskT>(
347  points, includeGroups, excludeGroups);
348 }
349 
350 
351 template<typename PointDataGridT, typename MaskT>
352 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
353  typename MaskT::Ptr>::type
355  const PointDataGridT& points,
356  const openvdb::math::Transform& transform,
357  const std::vector<Name>& includeGroups,
358  const std::vector<Name>& excludeGroups)
359 {
360  return point_mask_internal::convertPointsToScalar<PointDataGridT, MaskT>(
361  points, transform, includeGroups, excludeGroups);
362 }
363 
364 
366 
367 
368 } // namespace points
369 } // namespace OPENVDB_VERSION_NAME
370 } // namespace openvdb
371 
372 #endif // OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
373 
374 // Copyright (c) 2012-2017 DreamWorks Animation LLC
375 // All rights reserved. This software is distributed under the
376 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
PointsToScalarOp(const PointDataGridT &grid, const FilterT &filter)
Definition: PointMask.h:140
typename GridT::TreeType TreeT
Definition: PointMask.h:136
void modifyValue(const Coord &xyz, const ModifyOp &op)
Apply a functor to the value of the voxel at the given coordinates and mark the voxel as active...
Definition: ValueAccessor.h:321
typename TreeT::LeafNodeType LeafT
Definition: PointMask.h:101
uint64_t Index64
Definition: Types.h:59
Definition: ValueTransformer.h:277
LeafRange leafRange(size_t grainsize=1) const
Return a TBB-compatible LeafRange.
Definition: LeafManager.h:386
typename GridT::TreeType::LeafNodeType::ValueType ValueType
Definition: PointMask.h:180
A no-op filter that can be used when iterating over all indices.
Definition: IndexIterator.h:62
Definition: ValueAccessor.h:219
typename tree::LeafManager< TreeT > LeafManagerT
Definition: PointMask.h:137
Vec3< double > Vec3d
Definition: Vec3.h:679
typename GridCombinerOp< GridT >::CombinableT CombinableT
Definition: PointMask.h:182
Signed (x, y, z) 32-bit integer coordinates.
Definition: Coord.h:51
GridCombinerOp(GridT &grid)
Definition: PointMask.h:105
Definition: LeafManager.h:127
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointMask.h:145
Iterator begin() const
Definition: LeafManager.h:181
Compute scalar grid from PointDataGrid while evaluating the point filter.
Definition: PointMask.h:134
typename TreeT::LeafNodeType::ValueType ValueT
Definition: PointMask.h:138
Index filters primarily designed to be used with a FilterIndexIter.
Definition: Transform.h:66
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:136
Index64 iterCount(const IterT &iter)
Count up the number of times the iterator can iterate.
Definition: IndexIterator.h:313
Definition: Exceptions.h:39
typename GridT::TreeType TreeT
Definition: PointMask.h:100
void operator()(const typename LeafManagerT::LeafRange &range) const
Definition: PointMask.h:193
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
GridT::Ptr convertPointsToScalar(const PointDataGridT &points, const openvdb::math::Transform &transform, const std::vector< Name > &includeGroups, const std::vector< Name > &excludeGroups)
Definition: PointMask.h:273
std::enable_if< std::is_same< typename MaskT::ValueType, bool >::value, typename MaskT::Ptr >::type convertPointsToMask(const PointDataGridT &grid, const openvdb::math::Transform &transform, const std::vector< Name > &includeGroups=std::vector< Name >(), const std::vector< Name > &excludeGroups=std::vector< Name >())
Extract a Mask Grid from a Point Data Grid using a new transform.
Definition: PointMask.h:354
Definition: IndexFilter.h:104
typename TreeT::ValueType ValueType
Definition: PointMask.h:102
Tag dispatch class that distinguishes topology copy constructors from deep copy constructors.
Definition: Types.h:508
Definition: AttributeArray.h:644
Attribute-owned data structure for points. Point attributes are stored in leaf nodes and ordered by v...
typename tbb::combinable< GridT > CombinableT
Definition: PointMask.h:98
PointsToTransformedScalarOp(const math::Transform &newTransform, const math::Transform &transform, const FilterT &filter, CombinableT &combinable)
Definition: PointMask.h:184
Combines multiple grids into one by stealing leaf nodes and summing voxel values This class is design...
Definition: PointMask.h:96
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:188
void operator()(const GridT &grid)
Definition: PointMask.h:108
Compute scalar grid from PointDataGrid using a different transform and while evaluating the point fil...
Definition: PointMask.h:177