9#ifndef OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED 
   10#define OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED 
   19namespace rasterize_trilinear_internal {
 
   21template <
typename TreeType,
 
   22          typename PositionCodecT,
 
   23          typename SourceValueT,
 
   24          typename SourceCodecT>
 
   25struct TrilinearTransfer : 
public VolumeTransfer<TreeType>
 
   27    using BaseT = VolumeTransfer<TreeType>;
 
   28    using WeightT = 
typename TreeType::ValueType;
 
   29    using PositionHandleT = points::AttributeHandle<Vec3f, PositionCodecT>;
 
   30    using SourceHandleT = points::AttributeHandle<SourceValueT, SourceCodecT>;
 
   34    using SourceElementT = 
typename ValueTraits<SourceValueT>::ElementType;
 
   35    using RealT = SourceElementT;
 
   37    static_assert(std::is_floating_point<SourceElementT>::value,
 
   38        "Trilinear rasterization only supports floating point values.");
 
   40    static const Index NUM_VALUES = TreeType::LeafNodeType::NUM_VALUES;
 
   42    TrilinearTransfer(
const size_t pidx,
 
   43        const size_t sidx, TreeType& tree)
 
   51    TrilinearTransfer(
const TrilinearTransfer& other)
 
   60    static inline RealT value(
const RealT x)
 
   62        const RealT abs_x = std::fabs(x);
 
   63        if (abs_x < RealT(1.0)) 
return RealT(1.0) - abs_x;
 
   67    inline static Int32 range() { 
return 1; }
 
   68    inline Int32 range(
const Coord&, 
size_t)
 const { 
return this->range(); }
 
   70    inline void initialize(
const Coord& origin, 
const size_t idx, 
const CoordBBox& bounds)
 
   72        this->BaseT::initialize(origin, idx, bounds);
 
   76    inline bool startPointLeaf(
const PointDataTree::LeafNodeType& leaf)
 
   78        mPHandle.reset(
new PositionHandleT(leaf.constAttributeArray(mPIdx)));
 
   79        mSHandle.reset(
new SourceHandleT(leaf.constAttributeArray(mSIdx)));
 
   83    inline bool endPointLeaf(
const PointDataTree::LeafNodeType&) { 
return true; }
 
   88    typename PositionHandleT::UniquePtr mPHandle;
 
   89    typename SourceHandleT::UniquePtr mSHandle;
 
   90    std::array<WeightT, NUM_VALUES> mWeights;
 
   93template <
typename TreeType,
 
   94          typename PositionCodecT,
 
   95          typename SourceValueT,
 
   96          typename SourceCodecT>
 
   97struct StaggeredTransfer :
 
   98    public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>
 
  100    using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>;
 
  101    using RealT = 
typename BaseT::RealT;
 
  104    static_assert(VecTraits<typename TreeType::ValueType>::IsVec,
 
  105        "Target Tree must be a vector tree for staggered rasterization");
 
  107    static const Index DIM = TreeType::LeafNodeType::DIM;
 
  108    static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
 
  110    StaggeredTransfer(
const size_t pidx,
 
  111        const size_t sidx, TreeType& tree)
 
  112        : BaseT(pidx, sidx, tree) {}
 
  114    void rasterizePoint(
const Coord& ijk,
 
  116                    const CoordBBox& bounds)
 
  118        CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
 
  119        intersectBox.intersect(bounds);
 
  120        if (intersectBox.empty()) 
return;
 
  122        auto* 
const data = this->buffer();
 
  123        const auto& mask = *(this->mask());
 
  125        const math::Vec3<RealT> P(this->mPHandle->get(
id));
 
  126        const SourceValueT s(this->mSHandle->get(
id));
 
  128        math::Vec3<RealT> centerw, macw;
 
  130        const Coord& a(intersectBox.min());
 
  131        const Coord& b(intersectBox.max());
 
  132        for (Coord c = a; c.x() <= b.x(); ++c.x()) {
 
  134            const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM); 
 
  135            const RealT x = 
static_cast<RealT
>(c.x()-ijk.x()); 
 
  136            centerw[0] = value(P.x() - x); 
 
  137            macw.x() = value(P.x() - (x-RealT(0.5))); 
 
  139            for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
 
  140                const Index ij = i + ((c.y() & (DIM-1u)) << LOG2DIM);
 
  141                const RealT y = 
static_cast<RealT
>(c.y()-ijk.y());
 
  142                centerw[1] = value(P.y() - y);
 
  143                macw.y() = value(P.y() - (y-RealT(0.5)));
 
  145                for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
 
  147                    const Index offset = ij + (c.z() & (DIM-1u));
 
  148                    if (!mask.isOn(offset)) 
continue;
 
  149                    const RealT z = 
static_cast<RealT
>(c.z()-ijk.z());
 
  150                    centerw[2] = value(P.z() - z);
 
  151                    macw.z() = value(P.z() - (z-RealT(0.5)));
 
  153                    const math::Vec3<RealT> r {
 
  154                        (macw[0] * centerw[1] * centerw[2]),
 
  155                        (macw[1] * centerw[0] * centerw[2]),
 
  156                        (macw[2] * centerw[0] * centerw[1])
 
  159                    data[offset] += s * r;
 
  160                    this->mWeights[offset] += r;
 
  166    inline bool finalize(
const Coord&, 
const size_t)
 
  168        auto* 
const data = this->buffer();
 
  169        const auto& mask = *(this->mask());
 
  171        for (
auto iter = mask.beginOn(); iter; ++iter) {
 
  172            const Index offset = iter.pos();
 
  173            const auto& w = this->mWeights[offset];
 
  174            auto& v = data[offset];
 
  175            if (!math::isZero(w[0])) v[0] /= w[0];
 
  176            if (!math::isZero(w[1])) v[1] /= w[1];
 
  177            if (!math::isZero(w[2])) v[2] /= w[2];
 
  184template <
typename TreeType,
 
  185          typename PositionCodecT,
 
  186          typename SourceValueT,
 
  187          typename SourceCodecT>
 
  188struct CellCenteredTransfer :
 
  189    public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>
 
  191    using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT>;
 
  192    using RealT = 
typename BaseT::RealT;
 
  195    static const Index DIM = TreeType::LeafNodeType::DIM;
 
  196    static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
 
  198    CellCenteredTransfer(
const size_t pidx,
 
  199        const size_t sidx, TreeType& tree)
 
  200        : BaseT(pidx, sidx, tree) {}
 
  202    void rasterizePoint(
const Coord& ijk,
 
  204                    const CoordBBox& bounds)
 
  206        const Vec3f P(this->mPHandle->get(
id));
 
  209        CoordBBox intersectBox(ijk, ijk);
 
  210        if (P.x() < 0.0f) intersectBox.min().x() -= 1;
 
  211        else              intersectBox.max().x() += 1;
 
  212        if (P.y() < 0.0f) intersectBox.min().y() -= 1;
 
  213        else              intersectBox.max().y() += 1;
 
  214        if (P.z() < 0.0f) intersectBox.min().z() -= 1;
 
  215        else              intersectBox.max().z() += 1;
 
  218        intersectBox.intersect(bounds);
 
  219        if (intersectBox.empty()) 
return;
 
  221        auto* 
const data = this->buffer();
 
  222        const auto& mask = *(this->mask());
 
  224        const SourceValueT s(this->mSHandle->get(
id));
 
  225        math::Vec3<RealT> centerw;
 
  227        const Coord& a(intersectBox.min());
 
  228        const Coord& b(intersectBox.max());
 
  229        for (Coord c = a; c.x() <= b.x(); ++c.x()) {
 
  230            const Index i = ((c.x() & (DIM-1u)) << 2*LOG2DIM); 
 
  231            const RealT x = 
static_cast<RealT
>(c.x()-ijk.x()); 
 
  232            centerw[0] = value(P.x() - x); 
 
  234            for (c.y() = a.y(); c.y() <= b.y(); ++c.y()) {
 
  235                const Index ij = i + ((c.y() & (DIM-1u)) << LOG2DIM);
 
  236                const RealT y = 
static_cast<RealT
>(c.y()-ijk.y());
 
  237                centerw[1] = value(P.y() - y);
 
  239                for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
 
  241                    const Index offset = ij + (c.z() & (DIM-1u));
 
  242                    if (!mask.isOn(offset)) 
continue;
 
  243                    const RealT z = 
static_cast<RealT
>(c.z()-ijk.z());
 
  244                    centerw[2] = value(P.z() - z);
 
  250                    const RealT weight = centerw.product();
 
  251                    data[offset] += s * weight;
 
  252                    this->mWeights[offset] += weight;
 
  258    inline bool finalize(
const Coord&, 
const size_t)
 
  260        auto* 
const data = this->buffer();
 
  261        const auto& mask = *(this->mask());
 
  263        for (
auto iter = mask.beginOn(); iter; ++iter) {
 
  264            const Index offset = iter.pos();
 
  265            const auto& w = this->mWeights[offset];
 
  266            auto& v = data[offset];
 
  267            if (!math::isZero(w)) v /= w;
 
  280    typename PositionCodecT,
 
  282    typename PointDataTreeT>
 
  285typename TrilinearTraits<ValueT, Staggered>::template TreeT<PointDataTreeT>::Ptr
 
  292           const FilterT& filter)
 
  294    using TraitsT = TrilinearTraits<ValueT, Staggered>;
 
  295    using TargetTreeT = 
typename TraitsT::template TreeT<PointDataTree>;
 
  296    using TransferT = 
typename std::conditional<
Staggered,
 
  297            StaggeredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT>,
 
  298            CellCenteredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT>
 
  301    typename TargetTreeT::Ptr tree(
new TargetTreeT);
 
  302    if (std::is_same<FilterT, NullFilter>::value) {
 
  303        tree->topologyUnion(points);
 
  306        using MaskTreeT = 
typename PointDataTreeT::template ValueConverter<ValueMask>::Type;
 
  307        auto mask = convertPointsToMask<PointDataTreeT, MaskTreeT>(points, filter);
 
  308        tree->topologyUnion(*mask);
 
  311    TransferT transfer(pidx, sidx, *tree);
 
  312    tools::dilateActiveValues(*tree, transfer.range(),
 
  313        tools::NN_FACE_EDGE_VERTEX, tools::EXPAND_TILES);
 
  315    rasterize<PointDataTreeT, TransferT>(points, transfer, filter);
 
  328    typename PointDataTreeT>
 
  331           const std::string& attribute,
 
  332           const FilterT& filter)
 
  335    using TargetTreeT = 
typename TraitsT::template TreeT<PointDataTree>;
 
  337    const auto iter = 
points.cbeginLeaf();
 
  338    if (!iter) 
return typename TargetTreeT::Ptr(
new TargetTreeT);
 
  341    const size_t pidx = descriptor.
find(
"P");
 
  342    const size_t sidx = descriptor.
find(attribute);
 
  354            return rasterize_trilinear_internal::rasterizeTrilinear
 
  356                    (
points, pidx, sidx, filter);
 
  359            return rasterize_trilinear_internal::rasterizeTrilinear
 
  361                    (
points, pidx, sidx, filter);
 
  366            return rasterize_trilinear_internal::rasterizeTrilinear
 
  368                    (
points, pidx, sidx, filter);
 
  371            return rasterize_trilinear_internal::rasterizeTrilinear
 
  373                    (
points, pidx, sidx, filter);
 
 
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
Definition Exceptions.h:63
An immutable object that stores name, type and AttributeSet position for a constant collection of att...
Definition AttributeSet.h:311
size_t find(const std::string &name) const
Return the position of the attribute array whose name is name, or INVALID_POS if no match is found.
const NamePair & type(size_t pos) const
Return the name of the attribute array's type.
@ INVALID_POS
Definition AttributeSet.h:42
@ Staggered
Definition NanoVDB.h:293
Definition AttributeArray.h:42
auto rasterizeTrilinear(const PointDataTreeT &points, const std::string &attribute, const FilterT &filter=NullFilter())
Perform weighted trilinear rasterization of all points within a voxel. This method takes and returns ...
Definition PointRasterizeTrilinearImpl.h:330
Index32 Index
Definition Types.h:54
std::pair< Name, Name > NamePair
Definition AttributeArray.h:40
math::Vec3< float > Vec3f
Definition Types.h:74
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types....
constexpr T zeroVal()
Return the value of type T that corresponds to zero.
Definition Math.h:70
int32_t Int32
Definition Types.h:56
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
Definition AttributeArray.h:437
static const char * name()
Definition AttributeArray.h:443
Definition PointRasterizeTrilinear.h:37
Definition AttributeArray.h:433
#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