37 #ifndef OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
38 #define OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
46 #include <tbb/combinable.h>
48 #include <type_traits>
63 template <
typename PointDataGridT,
64 typename MaskT =
typename PointDataGridT::template ValueConverter<bool>::Type,
65 typename FilterT = NullFilter>
66 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
67 typename MaskT::Ptr>::type
69 const FilterT& filter = NullFilter(),
70 bool threaded =
true);
79 template <
typename PointDataGridT,
80 typename MaskT =
typename PointDataGridT::template ValueConverter<bool>::Type,
81 typename FilterT = NullFilter>
82 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
83 typename MaskT::Ptr>::type
85 const openvdb::math::Transform& transform,
86 const FilterT& filter = NullFilter(),
87 bool threaded =
true);
93 template <
typename LeafT>
94 void reset(LeafT&,
size_t = 0) { }
96 template <
typename IterT>
102 template <
typename DeformerT>
105 static const bool IndexSpace =
false;
112 namespace point_mask_internal {
114 template <
typename LeafT>
115 void voxelSum(LeafT& leaf,
const Index offset,
const typename LeafT::ValueType& value)
123 template <
typename T, Index Log2Dim>
127 leaf.
setOffsetOn(offset, leaf.getValue(offset) + value);
133 template<
typename Gr
idT>
138 using TreeT =
typename GridT::TreeType;
139 using LeafT =
typename TreeT::LeafNodeType;
144 : mTree(grid.tree()) {}
148 for (
auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
149 auto* newLeaf = mTree.probeLeaf(leaf->origin());
152 auto& tree =
const_cast<GridT&
>(grid).tree();
153 mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
154 zeroVal<ValueType>(),
false));
158 for (
auto iter = leaf->cbeginValueOn(); iter; ++iter) {
171 template <
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT>
174 using LeafT =
typename GridT::TreeType::LeafNodeType;
175 using ValueT =
typename LeafT::ValueType;
178 const FilterT& filter)
179 : mPointDataAccessor(grid.getConstAccessor())
180 , mFilter(filter) { }
184 const auto*
const pointLeaf =
185 mPointDataAccessor.probeConstLeaf(leaf.origin());
190 for (
auto value = leaf.beginValueOn(); value; ++value) {
192 pointLeaf->beginIndexVoxel(value.getCoord(), mFilter));
194 value.setValue(
ValueT(count));
197 value.setValueOn(
false);
203 const typename PointDataGridT::ConstAccessor mPointDataAccessor;
204 const FilterT& mFilter;
210 template <
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT,
typename DeformerT>
214 using ValueT =
typename GridT::TreeType::ValueType;
220 const FilterT& filter,
221 const DeformerT& deformer,
223 : mTargetTransform(targetTransform)
224 , mSourceTransform(sourceTransform)
226 , mDeformer(deformer)
227 , mCombinable(combinable) { }
231 DeformerT deformer(mDeformer);
233 auto& grid = mCombinable.local();
234 auto& countTree = grid.tree();
237 deformer.reset(leaf, idx);
239 auto handle = HandleT::create(leaf.constAttributeArray(
"P"));
241 for (
auto iter = leaf.beginIndexOn(mFilter); iter; iter++) {
245 Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d();
251 deformer.template apply<decltype(iter)>(position, iter);
252 position = mSourceTransform.indexToWorld(position);
255 position = mSourceTransform.indexToWorld(position);
256 deformer.template apply<decltype(iter)>(position, iter);
261 const Coord ijk = mTargetTransform.worldToIndexCellCentered(position);
272 const openvdb::math::Transform& mTargetTransform;
273 const openvdb::math::Transform& mSourceTransform;
274 const FilterT& mFilter;
275 const DeformerT& mDeformer;
276 CombinableT& mCombinable;
280 template<
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT>
282 const PointDataGridT& points,
283 const FilterT& filter,
284 bool threaded =
true)
288 using GridTreeT =
typename GridT::TreeType;
289 using ValueT =
typename GridTreeT::ValueType;
293 typename GridTreeT::Ptr tree(
new GridTreeT(points.constTree(),
294 false, openvdb::TopologyCopy()));
295 typename GridT::Ptr grid = GridT::create(tree);
296 grid->setTransform(points.transform().copy());
300 if (points.constTree().leafCount() == 0)
return grid;
304 if (std::is_same<ValueT, bool>::value && filter.state() ==
index::ALL)
return grid;
314 leafManager.
foreach(pointsToScalarOp, threaded);
319 leafManager.
foreach(pointsToScalarOp, threaded);
326 template<
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT,
typename DeformerT>
328 PointDataGridT& points,
329 const openvdb::math::Transform& transform,
330 const FilterT& filter,
331 const DeformerT& deformer,
332 bool threaded =
true)
342 const openvdb::math::Transform& pointsTransform = points.constTransform();
344 if (transform == pointsTransform && std::is_same<NullDeformer, DeformerT>()) {
345 return convertPointsToScalar<GridT>(points, filter, threaded);
348 typename GridT::Ptr grid = GridT::create();
349 grid->setTransform(transform.copy());
353 if (points.constTree().leafCount() == 0)
return grid;
357 CombinableT combiner;
364 transform, pointsTransform, nullFilter, deformer, combiner);
365 leafManager.
foreach(pointsToScalarOp, threaded);
368 transform, pointsTransform, filter, deformer, combiner);
369 leafManager.
foreach(pointsToScalarOp, threaded);
374 CombinerOpT combineOp(*grid);
375 combiner.combine_each(combineOp);
387 template<
typename Po
intDataGr
idT,
typename MaskT,
typename FilterT>
388 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
389 typename MaskT::Ptr>::type
391 const PointDataGridT& points,
392 const FilterT& filter,
395 return point_mask_internal::convertPointsToScalar<MaskT>(
396 points, filter, threaded);
400 template<
typename Po
intDataGr
idT,
typename MaskT,
typename FilterT>
401 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
402 typename MaskT::Ptr>::type
404 const PointDataGridT& points,
405 const openvdb::math::Transform& transform,
406 const FilterT& filter,
411 auto& nonConstPoints =
const_cast<typename AdapterT::NonConstGridType&
>(points);
414 return point_mask_internal::convertPointsToScalar<MaskT>(
415 nonConstPoints, transform, filter, deformer, threaded);
425 template <
typename PointDataGridT,
426 typename MaskT =
typename PointDataGridT::template ValueConverter<bool>::Type>
428 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
429 typename MaskT::Ptr>::type
431 const std::vector<Name>& includeGroups,
432 const std::vector<Name>& excludeGroups)
434 auto leaf = grid.tree().cbeginLeaf();
435 if (!leaf)
return MaskT::create();
436 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
441 template <
typename PointDataGridT,
442 typename MaskT =
typename PointDataGridT::template ValueConverter<bool>::Type>
444 inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
445 typename MaskT::Ptr>::type
447 const openvdb::math::Transform& transform,
448 const std::vector<Name>& includeGroups,
449 const std::vector<Name>& excludeGroups)
451 auto leaf = grid.tree().cbeginLeaf();
452 if (!leaf)
return MaskT::create();
453 MultiGroupFilter filter(includeGroups, excludeGroups, leaf->attributeSet());
462 #endif // OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED