9#ifndef OPENVDB_POINTS_POINT_MASK_IMPL_HAS_BEEN_INCLUDED 
   10#define OPENVDB_POINTS_POINT_MASK_IMPL_HAS_BEEN_INCLUDED 
   19namespace point_mask_internal {
 
   21template <
typename LeafT>
 
   22void voxelSum(LeafT& leaf, 
const Index offset, 
const typename LeafT::ValueType& value)
 
   24    leaf.modifyValue(offset, tools::valxform::SumOp<typename LeafT::ValueType>(value));
 
   30template <
typename T, Index Log2Dim>
 
   31void voxelSum(PointDataLeafNode<T, Log2Dim>& leaf, 
const Index offset,
 
   32    const typename PointDataLeafNode<T, Log2Dim>::ValueType& value)
 
   34    leaf.setOffsetOn(offset, leaf.getValue(offset) + value);
 
   40template<
typename Gr
idT>
 
   43    using CombinableT = 
typename tbb::combinable<GridT>;
 
   45    using TreeT = 
typename GridT::TreeType;
 
   46    using LeafT = 
typename TreeT::LeafNodeType;
 
   47    using ValueType = 
typename TreeT::ValueType;
 
   48    using SumOp = tools::valxform::SumOp<typename TreeT::ValueType>;
 
   50    GridCombinerOp(GridT& grid)
 
   51        : mTree(grid.tree()) {}
 
   53    void operator()(
const GridT& grid)
 
   55        for (
auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
 
   56            auto* newLeaf = mTree.probeLeaf(leaf->origin());
 
   59                auto& tree = 
const_cast<GridT&
>(grid).tree();
 
   60                mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
 
   61                    zeroVal<ValueType>(), 
false));
 
   65                for (
auto iter = leaf->cbeginValueOn(); iter; ++iter) {
 
   66                    voxelSum(*newLeaf, iter.offset(), ValueType(*iter));
 
   78template <
typename TreeT, 
typename Po
intDataTreeT, 
typename FilterT>
 
   79struct PointsToScalarOp
 
   81    using LeafT = 
typename TreeT::LeafNodeType;
 
   82    using ValueT = 
typename LeafT::ValueType;
 
   84    static constexpr bool IsBool =
 
   85        std::is_same<ValueT, bool>::value;
 
   87    PointsToScalarOp(
const PointDataTreeT& tree,
 
   88                     const FilterT& filter)
 
   89        : mPointDataAccessor(tree)
 
   92    void operator()(LeafT& leaf, 
size_t )
 const 
   95        const auto* 
const pointLeaf =
 
   96            mPointDataAccessor.probeConstLeaf(leaf.origin());
 
   99        for (
auto value = leaf.beginValueOn(); value; ++value) {
 
  100            const auto iter = pointLeaf->beginIndexVoxel(value.getCoord(), mFilter);
 
  102                if (!iter) value.setValueOn(
false);
 
  105                const Index64 count = points::iterCount(iter);
 
  106                if (count > 
Index64(0)) value.setValue(ValueT(count));
 
  107                else                    value.setValueOn(
false);
 
  113    const tree::ValueAccessor<const PointDataTreeT> mPointDataAccessor;
 
  114    const FilterT& mFilter;
 
  120template <
typename Gr
idT, 
typename Po
intDataGr
idT, 
typename FilterT, 
typename DeformerT>
 
  121struct PointsToTransformedScalarOp
 
  123    using PointDataLeafT = 
typename PointDataGridT::TreeType::LeafNodeType;
 
  124    using ValueT = 
typename GridT::TreeType::ValueType;
 
  125    using HandleT = AttributeHandle<Vec3f>;
 
  126    using CombinableT = 
typename GridCombinerOp<GridT>::CombinableT;
 
  128    PointsToTransformedScalarOp(
const math::Transform& targetTransform,
 
  129                                const math::Transform& sourceTransform,
 
  130                                const FilterT& filter,
 
  131                                const DeformerT& deformer,
 
  132                                CombinableT& combinable)
 
  133        : mTargetTransform(targetTransform)
 
  134        , mSourceTransform(sourceTransform)
 
  136        , mDeformer(deformer)
 
  137        , mCombinable(combinable) { }
 
  139    void operator()(
const PointDataLeafT& leaf, 
size_t idx)
 const 
  141        DeformerT deformer(mDeformer);
 
  143        auto& grid = mCombinable.local();
 
  144        auto& countTree = grid.tree();
 
  145        tree::ValueAccessor<typename GridT::TreeType> accessor(countTree);
 
  147        deformer.reset(leaf, idx);
 
  149        auto handle = HandleT::create(leaf.constAttributeArray(
"P"));
 
  151        for (
auto iter = leaf.beginIndexOn(mFilter); iter; iter++) {
 
  155            Vec3d position = handle->get(*iter) + iter.getCoord().asVec3d();
 
  160            if (DeformerTraits<DeformerT>::IndexSpace) {
 
  161                deformer.template apply<decltype(iter)>(position, iter);
 
  162                position = mSourceTransform.indexToWorld(position);
 
  165                position = mSourceTransform.indexToWorld(position);
 
  166                deformer.template apply<decltype(iter)>(position, iter);
 
  171            const Coord ijk = mTargetTransform.worldToIndexCellCentered(position);
 
  175            auto* newLeaf = accessor.touchLeaf(ijk);
 
  177            voxelSum(*newLeaf, newLeaf->coordToOffset(ijk), ValueT(1));
 
  182    const openvdb::math::Transform& mTargetTransform;
 
  183    const openvdb::math::Transform& mSourceTransform;
 
  184    const FilterT& mFilter;
 
  185    const DeformerT& mDeformer;
 
  186    CombinableT& mCombinable;
 
  190template<
typename TreeT, 
typename Po
intDataTreeT, 
typename FilterT>
 
  191inline typename TreeT::Ptr convertPointsToScalar(
 
  192    const PointDataTreeT& points,
 
  193    const FilterT& filter,
 
  194    bool threaded = 
true)
 
  196    using point_mask_internal::PointsToScalarOp;
 
  198    using ValueT = 
typename TreeT::ValueType;
 
  202    typename TreeT::Ptr tree(
new TreeT(
false));
 
  203    tree->topologyUnion(points);
 
  207    if (points.leafCount() == 0) 
return tree;
 
  211    if (std::is_same<ValueT, bool>::value && filter.state() == index::ALL) 
return tree;
 
  215    tree::LeafManager<TreeT> leafManager(*tree);
 
  217    if (filter.state() == index::ALL) {
 
  218        NullFilter nullFilter;
 
  219        PointsToScalarOp<TreeT, PointDataTreeT, NullFilter> pointsToScalarOp(
 
  221        leafManager.foreach(pointsToScalarOp, threaded);
 
  224        PointsToScalarOp<TreeT, PointDataTreeT, FilterT> pointsToScalarOp(
 
  226        leafManager.foreach(pointsToScalarOp, threaded);
 
  233template<
typename Gr
idT, 
typename Po
intDataGr
idT, 
typename FilterT, 
typename DeformerT>
 
  234inline typename GridT::Ptr convertPointsToScalar(
 
  235    PointDataGridT& points,
 
  236    const math::Transform& transform,
 
  237    const FilterT& filter,
 
  238    const DeformerT& deformer,
 
  239    bool threaded = 
true)
 
  241    using point_mask_internal::PointsToTransformedScalarOp;
 
  242    using point_mask_internal::GridCombinerOp;
 
  244    using CombinerOpT = GridCombinerOp<GridT>;
 
  245    using CombinableT = 
typename GridCombinerOp<GridT>::CombinableT;
 
  247    typename GridT::Ptr grid = GridT::create();
 
  248    grid->setTransform(transform.copy());
 
  252    const math::Transform& pointsTransform = points.constTransform();
 
  254    if (transform == pointsTransform && std::is_same<NullDeformer, DeformerT>()) {
 
  255        using TreeT = 
typename GridT::TreeType;
 
  256        typename TreeT::Ptr tree =
 
  257            convertPointsToScalar<TreeT>(points.tree(), filter, threaded);
 
  264    if (points.constTree().leafCount() == 0)  
return grid;
 
  268    CombinableT combiner;
 
  270    tree::LeafManager<typename PointDataGridT::TreeType> leafManager(points.tree());
 
  272    if (filter.state() == index::ALL) {
 
  273        NullFilter nullFilter;
 
  274        PointsToTransformedScalarOp<GridT, PointDataGridT, NullFilter, DeformerT> pointsToScalarOp(
 
  275            transform, pointsTransform, nullFilter, deformer, combiner);
 
  276        leafManager.foreach(pointsToScalarOp, threaded);
 
  278        PointsToTransformedScalarOp<GridT, PointDataGridT, FilterT, DeformerT> pointsToScalarOp(
 
  279            transform, pointsTransform, filter, deformer, combiner);
 
  280        leafManager.foreach(pointsToScalarOp, threaded);
 
  285    CombinerOpT combineOp(*grid);
 
  286    combiner.combine_each(combineOp);
 
  299template <
typename Po
intDataTreeT, 
typename MaskTreeT, 
typename FilterT>
 
  300inline typename std::enable_if<std::is_base_of<TreeBase, PointDataTreeT>::value &&
 
  301    std::is_same<typename MaskTreeT::ValueType, bool>::value, 
typename MaskTreeT::Ptr>::type
 
  303    const FilterT& filter,
 
  306    return point_mask_internal::convertPointsToScalar<MaskTreeT>(
 
  307        tree, filter, threaded);
 
 
  311template<
typename Po
intDataGr
idT, 
typename MaskGr
idT, 
typename FilterT>
 
  312inline typename std::enable_if<std::is_base_of<GridBase, PointDataGridT>::value &&
 
  313    std::is_same<typename MaskGridT::ValueType, bool>::value, 
typename MaskGridT::Ptr>::type
 
  315    const PointDataGridT& 
points,
 
  316    const FilterT& filter,
 
  319    using PointDataTreeT = 
typename PointDataGridT::TreeType;
 
  320    using MaskTreeT = 
typename MaskGridT::TreeType;
 
  322    typename MaskTreeT::Ptr 
tree =
 
  324            (
points.tree(), filter, threaded);
 
  326    typename MaskGridT::Ptr grid(
new MaskGridT(
tree));
 
  327    grid->setTransform(
points.transform().copy());
 
 
  332template<
typename Po
intDataGr
idT, 
typename MaskT, 
typename FilterT>
 
  333inline typename std::enable_if<std::is_same<typename MaskT::ValueType, bool>::value,
 
  334    typename MaskT::Ptr>::type
 
  336    const PointDataGridT& 
points,
 
  337    const openvdb::math::Transform& transform,
 
  338    const FilterT& filter,
 
  343    auto& nonConstPoints = 
const_cast<typename AdapterT::NonConstGridType&
>(
points);
 
  346    return point_mask_internal::convertPointsToScalar<MaskT>(
 
  347        nonConstPoints, transform, filter, deformer, threaded);
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Vec3< double > Vec3d
Definition Vec3.h:665
Definition AttributeArray.h:42
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 PointMaskImpl.h:302
Definition PointDataGrid.h:170
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:218