9 #ifndef OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED 
   10 #define OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED 
   19 namespace rasterize_trilinear_internal {
 
   21 template <
typename TreeType,
 
   22           typename PositionCodecT,
 
   23           typename SourceValueT,
 
   24           typename SourceCodecT>
 
   25 struct TrilinearTransfer : 
public VolumeTransfer<TreeType>
 
   27     using BaseT = VolumeTransfer<TreeType>;
 
   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;
 
   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;
 
   68     inline Int32 range(
const Coord&, 
size_t)
 const { 
return this->
range(); }
 
   73         mWeights.fill(openvdb::zeroVal<WeightT>());
 
   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;
 
   93 template <
typename TreeType,
 
   94           typename PositionCodecT,
 
   95           typename SourceValueT,
 
   96           typename SourceCodecT>
 
   97 struct 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,
 
  118         CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
 
  119         intersectBox.intersect(bounds);
 
  120         if (intersectBox.empty()) 
return;
 
  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()); 
 
  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());
 
  143                 macw.y() = 
value(
P.y() - (y-RealT(0.5)));
 
  145                 for (
c.z() = 
a.z(); 
c.z() <= 
b.z(); ++
c.z()) {
 
  148                     if (!
mask.isOn(offset)) 
continue;
 
  149                     const RealT 
z = 
static_cast<RealT
>(
c.z()-ijk.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])
 
  166     inline bool finalize(
const Coord&, 
const size_t)
 
  171         for (
auto iter = 
mask.beginOn(); iter; ++iter) {
 
  172             const Index offset = iter.pos();
 
  173             const auto& 
w = this->mWeights[
offset];
 
  184 template <
typename TreeType,
 
  185           typename PositionCodecT,
 
  186           typename SourceValueT,
 
  187           typename SourceCodecT>
 
  188 struct 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,
 
  206         const Vec3f P(this->mPHandle->get(
id));
 
  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;
 
  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()); 
 
  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());
 
  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());
 
  250                     const RealT weight = centerw.product();
 
  252                     this->mWeights[
offset] += weight;
 
  258     inline bool finalize(
const Coord&, 
const size_t)
 
  263         for (
auto iter = 
mask.beginOn(); iter; ++iter) {
 
  264             const Index offset = iter.pos();
 
  265             const auto& 
w = this->mWeights[
offset];
 
  280     typename PositionCodecT,
 
  282     typename PointDataTreeT>
 
  285 typename TrilinearTraits<ValueT, Staggered>::template TreeT<PointDataTreeT>::Ptr
 
  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);
 
  303         tree->topologyUnion(points);
 
  308         tree->topologyUnion(*
mask);
 
  311     TransferT transfer(pidx, sidx, *tree);
 
  315     rasterize<PointDataTreeT, TransferT>(
points, transfer, 
filter);
 
  325 template <
bool Staggered,
 
  328     typename PointDataTreeT>
 
  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);
 
  344         OPENVDB_THROW(RuntimeError, 
"Failed to find position attribute");
 
  347         OPENVDB_THROW(RuntimeError, 
"Failed to find source attribute");
 
  350     const NamePair& ptype = descriptor.type(pidx);
 
  351     const NamePair& stype = descriptor.type(sidx);
 
  355                 <Staggered, ValueT, 
NullCodec, NullCodec>
 
  383 #endif //OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED 
GLdouble GLdouble GLint GLint const GLdouble * points
 
GLsizei const GLfloat * value
 
GLdouble GLdouble GLdouble z
 
GLboolean GLboolean GLboolean GLboolean a
 
#define OPENVDB_USE_VERSION_NAMESPACE
 
GA_API const UT_StringHolder P
 
#define OPENVDB_ASSERT(X)
 
static const char * name()
 
auto rasterizeTrilinear(const PointDataTreeT &points, const std::string &attribute, const FilterT &filter)
Perform weighted trilinear rasterization of all points within a voxel. This method takes and returns ...
 
LeafFnBase< CoordT, MaskT, LOG2DIM > BaseT
 
OPENVDB_API void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled). 
 
std::pair< Name, Name > NamePair
 
GLboolean GLboolean GLboolean b
 
OIIO_API bool attribute(string_view name, TypeDesc type, const void *val)
 
GLubyte GLubyte GLubyte GLubyte w
 
#define OPENVDB_VERSION_NAME
The version namespace name for this library version. 
 
bool isZero(const Type &x)
Return true if x is exactly equal to zero. 
 
#define OPENVDB_THROW(exception, message)
 
GLint GLint GLint GLint GLint GLint GLint GLbitfield GLenum filter