10#ifndef OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
11#define OPENVDB_POINTS_POINT_MASK_HAS_BEEN_INCLUDED
19#include <tbb/combinable.h>
34template <
typename PointDataTreeT,
35 typename MaskTreeT =
typename PointDataTreeT::template ValueConverter<bool>::Type,
36 typename FilterT = NullFilter>
37inline typename std::enable_if<std::is_base_of<TreeBase, PointDataTreeT>::value &&
38 std::is_same<typename MaskTreeT::ValueType, bool>::value,
typename MaskTreeT::Ptr>::type
40 const FilterT& filter = NullFilter(),
41 bool threaded =
true);
48template <
typename PointDataGridT,
49 typename MaskGridT =
typename PointDataGridT::template ValueConverter<bool>::Type,
50 typename FilterT = NullFilter>
51inline typename std::enable_if<std::is_base_of<GridBase, PointDataGridT>::value &&
52 std::is_same<typename MaskGridT::ValueType, bool>::value,
typename MaskGridT::Ptr>::type
54 const FilterT& filter = NullFilter(),
55 bool threaded =
true);
63template <
typename PointDataGridT,
64 typename MaskT =
typename PointDataGridT::template ValueConverter<bool>::Type,
65 typename FilterT = NullFilter>
66inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
67 typename MaskT::Ptr>::type
69 const openvdb::math::Transform& transform,
70 const FilterT& filter = NullFilter(),
71 bool threaded =
true);
76 template <
typename LeafT>
77 void reset(LeafT&,
size_t = 0) { }
79 template <
typename IterT>
80 void apply(Vec3d&, IterT&)
const { }
85template <
typename DeformerT>
88 static const bool IndexSpace =
false;
96namespace point_mask_internal {
98template <
typename LeafT>
99void voxelSum(LeafT& leaf,
const Index offset,
const typename LeafT::ValueType&
value)
107template <
typename T, Index Log2Dim>
108void voxelSum(PointDataLeafNode<T, Log2Dim>& leaf,
const Index offset,
109 const typename PointDataLeafNode<T, Log2Dim>::ValueType&
value)
111 leaf.setOffsetOn(offset, leaf.getValue(offset) +
value);
117template<
typename Gr
idT>
120 using CombinableT =
typename tbb::combinable<GridT>;
122 using TreeT =
typename GridT::TreeType;
123 using LeafT =
typename TreeT::LeafNodeType;
124 using ValueType =
typename TreeT::ValueType;
127 GridCombinerOp(GridT& grid)
128 : mTree(grid.tree()) {}
130 void operator()(
const GridT& grid)
132 for (
auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
133 auto* newLeaf = mTree.probeLeaf(leaf->origin());
136 auto& tree =
const_cast<GridT&
>(grid).tree();
137 mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
138 zeroVal<ValueType>(),
false));
142 for (
auto iter = leaf->cbeginValueOn(); iter; ++iter) {
143 voxelSum(*newLeaf, iter.offset(), ValueType(*iter));
155template <
typename TreeT,
typename Po
intDataTreeT,
typename FilterT>
156struct PointsToScalarOp
158 using LeafT =
typename TreeT::LeafNodeType;
159 using ValueT =
typename LeafT::ValueType;
161 static constexpr bool IsBool =
162 std::is_same<ValueT, bool>::value;
164 PointsToScalarOp(
const PointDataTreeT& tree,
165 const FilterT& filter)
166 : mPointDataAccessor(tree)
169 void operator()(LeafT& leaf,
size_t )
const
172 const auto*
const pointLeaf =
173 mPointDataAccessor.probeConstLeaf(leaf.origin());
177 const auto iter = pointLeaf->beginIndexVoxel(
value.getCoord(), mFilter);
179 if (!iter)
value.setValueOn(
false);
182 const Index64 count = points::iterCount(iter);
184 else value.setValueOn(
false);
190 const tree::ValueAccessor<const PointDataTreeT> mPointDataAccessor;
191 const FilterT& mFilter;
197template <
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT,
typename DeformerT>
198struct PointsToTransformedScalarOp
200 using PointDataLeafT =
typename PointDataGridT::TreeType::LeafNodeType;
201 using ValueT =
typename GridT::TreeType::ValueType;
202 using HandleT = AttributeHandle<Vec3f>;
203 using CombinableT =
typename GridCombinerOp<GridT>::CombinableT;
205 PointsToTransformedScalarOp(
const math::Transform& targetTransform,
206 const math::Transform& sourceTransform,
207 const FilterT& filter,
208 const DeformerT& deformer,
209 CombinableT& combinable)
210 : mTargetTransform(targetTransform)
211 , mSourceTransform(sourceTransform)
213 , mDeformer(deformer)
214 , mCombinable(combinable) { }
216 void operator()(
const PointDataLeafT& leaf,
size_t idx)
const
218 DeformerT deformer(mDeformer);
220 auto& grid = mCombinable.local();
221 auto& countTree = grid.tree();
222 tree::ValueAccessor<typename GridT::TreeType> accessor(countTree);
224 deformer.reset(leaf, idx);
226 auto handle = HandleT::create(leaf.constAttributeArray(
"P"));
228 for (
auto iter = leaf.beginIndexOn(mFilter); iter; iter++) {
232 Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d();
237 if (DeformerTraits<DeformerT>::IndexSpace) {
238 deformer.template apply<decltype(iter)>(position, iter);
239 position = mSourceTransform.indexToWorld(position);
242 position = mSourceTransform.indexToWorld(position);
243 deformer.template apply<decltype(iter)>(position, iter);
248 const Coord ijk = mTargetTransform.worldToIndexCellCentered(position);
252 auto* newLeaf = accessor.touchLeaf(ijk);
254 voxelSum(*newLeaf, newLeaf->coordToOffset(ijk), ValueT(1));
259 const openvdb::math::Transform& mTargetTransform;
260 const openvdb::math::Transform& mSourceTransform;
261 const FilterT& mFilter;
262 const DeformerT& mDeformer;
263 CombinableT& mCombinable;
267template<
typename TreeT,
typename Po
intDataTreeT,
typename FilterT>
268inline typename TreeT::Ptr convertPointsToScalar(
269 const PointDataTreeT& points,
270 const FilterT& filter,
271 bool threaded =
true)
273 using point_mask_internal::PointsToScalarOp;
275 using ValueT =
typename TreeT::ValueType;
279 typename TreeT::Ptr tree(
new TreeT(
false));
280 tree->topologyUnion(points);
284 if (points.leafCount() == 0)
return tree;
288 if (std::is_same<ValueT, bool>::value && filter.state() == index::ALL)
return tree;
292 tree::LeafManager<TreeT> leafManager(*tree);
294 if (filter.state() == index::ALL) {
295 NullFilter nullFilter;
296 PointsToScalarOp<TreeT, PointDataTreeT, NullFilter> pointsToScalarOp(
298 leafManager.foreach(pointsToScalarOp, threaded);
301 PointsToScalarOp<TreeT, PointDataTreeT, FilterT> pointsToScalarOp(
303 leafManager.foreach(pointsToScalarOp, threaded);
310template<
typename Gr
idT,
typename Po
intDataGr
idT,
typename FilterT,
typename DeformerT>
311inline typename GridT::Ptr convertPointsToScalar(
312 PointDataGridT& points,
313 const math::Transform& transform,
314 const FilterT& filter,
315 const DeformerT& deformer,
316 bool threaded =
true)
318 using point_mask_internal::PointsToTransformedScalarOp;
319 using point_mask_internal::GridCombinerOp;
321 using CombinerOpT = GridCombinerOp<GridT>;
322 using CombinableT =
typename GridCombinerOp<GridT>::CombinableT;
324 typename GridT::Ptr grid = GridT::create();
325 grid->setTransform(transform.copy());
329 const math::Transform& pointsTransform = points.constTransform();
331 if (transform == pointsTransform && std::is_same<NullDeformer, DeformerT>()) {
332 using TreeT =
typename GridT::TreeType;
333 typename TreeT::Ptr tree =
334 convertPointsToScalar<TreeT>(points.tree(), filter, threaded);
341 if (points.constTree().leafCount() == 0)
return grid;
345 CombinableT combiner;
347 tree::LeafManager<typename PointDataGridT::TreeType> leafManager(points.tree());
349 if (filter.state() == index::ALL) {
350 NullFilter nullFilter;
351 PointsToTransformedScalarOp<GridT, PointDataGridT, NullFilter, DeformerT> pointsToScalarOp(
352 transform, pointsTransform, nullFilter, deformer, combiner);
353 leafManager.foreach(pointsToScalarOp, threaded);
355 PointsToTransformedScalarOp<GridT, PointDataGridT, FilterT, DeformerT> pointsToScalarOp(
356 transform, pointsTransform, filter, deformer, combiner);
357 leafManager.foreach(pointsToScalarOp, threaded);
362 CombinerOpT combineOp(*grid);
363 combiner.combine_each(combineOp);
376template <
typename Po
intDataTreeT,
typename MaskTreeT,
typename FilterT>
377inline typename std::enable_if<std::is_base_of<TreeBase, PointDataTreeT>::value &&
378 std::is_same<typename MaskTreeT::ValueType, bool>::value,
typename MaskTreeT::Ptr>::type
380 const FilterT& filter,
383 return point_mask_internal::convertPointsToScalar<MaskTreeT>(
384 tree, filter, threaded);
388template<
typename Po
intDataGr
idT,
typename MaskGr
idT,
typename FilterT>
389inline typename std::enable_if<std::is_base_of<GridBase, PointDataGridT>::value &&
390 std::is_same<typename MaskGridT::ValueType, bool>::value,
typename MaskGridT::Ptr>::type
392 const PointDataGridT& points,
393 const FilterT& filter,
396 using PointDataTreeT =
typename PointDataGridT::TreeType;
397 using MaskTreeT =
typename MaskGridT::TreeType;
399 typename MaskTreeT::Ptr tree =
400 convertPointsToMask<PointDataTreeT, MaskTreeT, FilterT>
401 (points.tree(), filter, threaded);
403 typename MaskGridT::Ptr grid(
new MaskGridT(tree));
404 grid->setTransform(points.transform().copy());
409template<
typename Po
intDataGr
idT,
typename MaskT,
typename FilterT>
410inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
411 typename MaskT::Ptr>::type
413 const PointDataGridT& points,
414 const openvdb::math::Transform& transform,
415 const FilterT& filter,
420 auto& nonConstPoints =
const_cast<typename AdapterT::NonConstGridType&
>(points);
423 return point_mask_internal::convertPointsToScalar<MaskT>(
424 nonConstPoints, transform, filter, deformer, threaded);
ValueT value
Definition: GridBuilder.h:1290
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...
Vec3< double > Vec3d
Definition: Vec3.h:664
std::enable_if< std::is_base_of< TreeBase, PointDataTreeT >::value &&std::is_same< typenameMaskTreeT::ValueType, bool >::value, typenameMaskTreeT::Ptr >::type convertPointsToMask(const PointDataTreeT &tree, const FilterT &filter=NullFilter(), bool threaded=true)
Extract a Mask Tree from a Point Data Tree.
Definition: PointMask.h:379
Index32 Index
Definition: Types.h:54
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
#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