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,
26 struct TrilinearTransfer :
27 public VolumeTransfer<TreeType>,
28 public FilteredTransfer<FilterT>
30 using BaseT = VolumeTransfer<TreeType>;
31 using FilterTransferT = FilteredTransfer<FilterT>;
33 using PositionHandleT = points::AttributeHandle<Vec3f, PositionCodecT>;
34 using SourceHandleT = points::AttributeHandle<SourceValueT, SourceCodecT>;
38 using SourceElementT =
typename ValueTraits<SourceValueT>::ElementType;
39 using RealT = SourceElementT;
42 "Trilinear rasterization only supports floating point values.");
44 static const Index NUM_VALUES = TreeType::LeafNodeType::NUM_VALUES;
46 TrilinearTransfer(
const size_t pidx,
51 , FilterTransferT(filter)
58 TrilinearTransfer(
const TrilinearTransfer& other)
60 , FilterTransferT(other)
68 static inline RealT
value(
const RealT
x)
70 const RealT abs_x = std::fabs(x);
71 if (abs_x < RealT(1.0))
return RealT(1.0) - abs_x;
76 inline Int32 range(
const Coord&,
size_t)
const {
return this->
range(); }
82 mWeights.fill(openvdb::zeroVal<WeightT>());
85 inline bool startPointLeaf(
const PointDataTree::LeafNodeType& leaf)
87 this->FilterTransferT::startPointLeaf(leaf);
88 mPHandle.reset(
new PositionHandleT(leaf.constAttributeArray(mPIdx)));
89 mSHandle.reset(
new SourceHandleT(leaf.constAttributeArray(mSIdx)));
93 inline bool endPointLeaf(
const PointDataTree::LeafNodeType&) {
return true; }
98 typename PositionHandleT::UniquePtr mPHandle;
99 typename SourceHandleT::UniquePtr mSHandle;
100 std::array<WeightT, NUM_VALUES> mWeights;
103 template <
typename TreeType,
104 typename PositionCodecT,
105 typename SourceValueT,
106 typename SourceCodecT,
108 struct StaggeredTransfer :
109 public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT, FilterT>
111 using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT, FilterT>;
112 using RealT =
typename BaseT::RealT;
115 static_assert(VecTraits<typename TreeType::ValueType>::IsVec,
116 "Target Tree must be a vector tree for staggered rasterization");
118 static const Index DIM = TreeType::LeafNodeType::DIM;
119 static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
121 StaggeredTransfer(
const size_t pidx,
125 :
BaseT(pidx, sidx, filter, tree) {}
127 void rasterizePoint(
const Coord& ijk,
133 CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
134 intersectBox.intersect(bounds);
135 if (intersectBox.empty())
return;
140 const math::Vec3<RealT>
P(this->mPHandle->get(
id));
141 const SourceValueT
s(this->mSHandle->get(
id));
143 math::Vec3<RealT> centerw, macw;
145 const Coord&
a(intersectBox.min());
146 const Coord&
b(intersectBox.max());
147 for (Coord
c =
a;
c.x() <=
b.x(); ++
c.x()) {
149 const Index i = ((
c.x() & (DIM-1u)) << 2*LOG2DIM);
150 const RealT x =
static_cast<RealT
>(
c.x()-ijk.x());
152 macw.x() =
value(
P.x() - (x-RealT(0.5)));
154 for (
c.y() =
a.y();
c.y() <=
b.y(); ++
c.y()) {
155 const Index ij = i + ((
c.y() & (DIM-1u)) << LOG2DIM);
156 const RealT
y =
static_cast<RealT
>(
c.y()-ijk.y());
158 macw.y() =
value(
P.y() - (y-RealT(0.5)));
160 for (
c.z() =
a.z();
c.z() <=
b.z(); ++
c.z()) {
163 if (!
mask.isOn(offset))
continue;
164 const RealT
z =
static_cast<RealT
>(
c.z()-ijk.z());
166 macw.z() =
value(
P.z() - (z-RealT(0.5)));
168 const math::Vec3<RealT>
r {
169 (macw[0] * centerw[1] * centerw[2]),
170 (macw[1] * centerw[0] * centerw[2]),
171 (macw[2] * centerw[0] * centerw[1])
181 inline bool finalize(
const Coord&,
const size_t)
186 for (
auto iter =
mask.beginOn(); iter; ++iter) {
187 const Index offset = iter.pos();
188 const auto&
w = this->mWeights[
offset];
199 template <
typename TreeType,
200 typename PositionCodecT,
201 typename SourceValueT,
202 typename SourceCodecT,
204 struct CellCenteredTransfer :
205 public TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT, FilterT>
207 using BaseT = TrilinearTransfer<TreeType, PositionCodecT, SourceValueT, SourceCodecT, FilterT>;
208 using RealT =
typename BaseT::RealT;
211 static const Index DIM = TreeType::LeafNodeType::DIM;
212 static const Index LOG2DIM = TreeType::LeafNodeType::LOG2DIM;
214 CellCenteredTransfer(
const size_t pidx,
218 :
BaseT(pidx, sidx, filter, tree) {}
220 void rasterizePoint(
const Coord& ijk,
226 const Vec3f P(this->mPHandle->get(
id));
230 if (
P.x() < 0.0f) intersectBox.min().x() -= 1;
231 else intersectBox.max().x() += 1;
232 if (
P.y() < 0.0f) intersectBox.min().y() -= 1;
233 else intersectBox.max().y() += 1;
234 if (
P.z() < 0.0f) intersectBox.min().z() -= 1;
235 else intersectBox.max().z() += 1;
238 intersectBox.intersect(bounds);
239 if (intersectBox.empty())
return;
244 const SourceValueT
s(this->mSHandle->get(
id));
245 math::Vec3<RealT> centerw;
247 const Coord&
a(intersectBox.min());
248 const Coord&
b(intersectBox.max());
249 for (Coord
c =
a;
c.x() <=
b.x(); ++
c.x()) {
250 const Index i = ((
c.x() & (DIM-1u)) << 2*LOG2DIM);
251 const RealT x =
static_cast<RealT
>(
c.x()-ijk.x());
254 for (
c.y() =
a.y();
c.y() <=
b.y(); ++
c.y()) {
255 const Index ij = i + ((
c.y() & (DIM-1u)) << LOG2DIM);
256 const RealT y =
static_cast<RealT
>(
c.y()-ijk.y());
259 for (
c.z() =
a.z();
c.z() <=
b.z(); ++
c.z()) {
261 const Index offset = ij + (
c.z() & (DIM-1u));
262 if (!
mask.isOn(offset))
continue;
263 const RealT z =
static_cast<RealT
>(
c.z()-ijk.z());
270 const RealT weight = centerw.product();
272 this->mWeights[
offset] += weight;
278 inline bool finalize(
const Coord&,
const size_t)
283 for (
auto iter =
mask.beginOn(); iter; ++iter) {
284 const Index offset = iter.pos();
285 const auto&
w = this->mWeights[
offset];
300 typename PositionCodecT,
302 typename PointDataTreeT>
305 typename TrilinearTraits<ValueT, Staggered>::template TreeT<PointDataTreeT>::Ptr
314 using TraitsT = TrilinearTraits<ValueT, Staggered>;
315 using TargetTreeT =
typename TraitsT::template TreeT<PointDataTree>;
316 using TransferT =
typename std::conditional<
Staggered,
317 StaggeredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT, FilterT>,
318 CellCenteredTransfer<TargetTreeT, PositionCodecT, ValueT, CodecT, FilterT>
321 typename TargetTreeT::Ptr tree = std::make_shared<TargetTreeT>();
323 tree->topologyUnion(points);
328 tree->topologyUnion(*
mask);
331 TransferT transfer(pidx, sidx, filter, *tree);
335 rasterize<PointDataTreeT, TransferT>(
points, transfer);
345 template <
bool Staggered,
348 typename PointDataTreeT>
352 const FilterT& filter)
355 using TargetTreeT =
typename TraitsT::template TreeT<PointDataTree>;
357 const auto iter = points.cbeginLeaf();
358 if (!iter)
return typename TargetTreeT::Ptr(
new TargetTreeT);
361 const size_t pidx = descriptor.find(
"P");
362 const size_t sidx = descriptor.find(attribute);
364 OPENVDB_THROW(RuntimeError,
"Failed to find position attribute");
367 OPENVDB_THROW(RuntimeError,
"Failed to find source attribute");
370 const NamePair& ptype = descriptor.type(pidx);
371 const NamePair& stype = descriptor.type(sidx);
375 <Staggered, ValueT,
NullCodec, NullCodec>
403 #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