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>;
32 using WeightT =
typename TreeType::ValueType;
33 using PositionHandleT = points::AttributeHandle<Vec3f, PositionCodecT>;
34 using SourceHandleT = points::AttributeHandle<SourceValueT, SourceCodecT>;
39 using RealT = SourceElementT;
41 static_assert(std::is_floating_point<SourceElementT>::value,
42 "Trilinear rasterization only supports floating point values.");
44 static const Index NUM_VALUES = TreeType::LeafNodeType::NUM_VALUES;
46 TrilinearTransfer(
const size_t pidx,
48 const FilterT& filter,
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;
75 inline static Int32 range() {
return 1; }
76 inline Int32 range(
const Coord&,
size_t)
const {
return this->range(); }
78 inline void initialize(
const Coord& origin,
const size_t idx,
const CoordBBox& bounds)
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;
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,
123 const FilterT& filter,
125 : BaseT(pidx, sidx, filter, tree) {}
127 void rasterizePoint(
const Coord& ijk,
129 const CoordBBox& bounds)
131 if (!BaseT::filter(
id))
return;
133 CoordBBox intersectBox(ijk.offsetBy(-1), ijk.offsetBy(1));
134 intersectBox.intersect(bounds);
135 if (intersectBox.empty())
return;
137 auto*
const data = this->buffer();
138 const auto& mask = *(this->mask());
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());
151 centerw[0] = value(P.x() - 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());
157 centerw[1] = value(P.y() - y);
158 macw.y() = value(P.y() - (y-RealT(0.5)));
160 for (c.z() = a.z(); c.z() <= b.z(); ++c.z()) {
162 const Index offset = ij + (c.z() & (DIM-1u));
163 if (!mask.isOn(offset))
continue;
164 const RealT z =
static_cast<RealT
>(c.z()-ijk.z());
165 centerw[2] = value(P.z() - 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])
174 data[offset] += s * r;
175 this->mWeights[offset] += r;
181 inline bool finalize(
const Coord&,
const size_t)
183 auto*
const data = this->buffer();
184 const auto& mask = *(this->mask());
186 for (
auto iter = mask.beginOn(); iter; ++iter) {
187 const Index offset = iter.pos();
188 const auto& w = this->mWeights[offset];
189 auto& v = data[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,
216 const FilterT& filter,
218 : BaseT(pidx, sidx, filter, tree) {}
220 void rasterizePoint(
const Coord& ijk,
222 const CoordBBox& bounds)
224 if (!BaseT::filter(
id))
return;
226 const Vec3f P(this->mPHandle->get(
id));
229 CoordBBox intersectBox(ijk, ijk);
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;
241 auto*
const data = this->buffer();
242 const auto& mask = *(this->mask());
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());
252 centerw[0] = value(P.x() - 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());
257 centerw[1] = value(P.y() - 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());
264 centerw[2] = value(P.z() - z);
270 const RealT weight = centerw.product();
271 data[offset] += s * weight;
272 this->mWeights[offset] += weight;
278 inline bool finalize(
const Coord&,
const size_t)
280 auto*
const data = this->buffer();
281 const auto& mask = *(this->mask());
283 for (
auto iter = mask.beginOn(); iter; ++iter) {
284 const Index offset = iter.pos();
285 const auto& w = this->mWeights[offset];
286 auto& v = data[offset];
300 typename PositionCodecT,
302 typename PointDataTreeT>
305 typename TrilinearTraits<ValueT, Staggered>::template TreeT<PointDataTreeT>::Ptr
312 const FilterT& filter)
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>();
322 if (std::is_same<FilterT, NullFilter>::value) {
323 tree->topologyUnion(points);
326 using MaskTreeT =
typename PointDataTreeT::template ValueConverter<ValueMask>::Type;
327 auto mask = convertPointsToMask<PointDataTreeT, MaskTreeT>(points, filter);
328 tree->topologyUnion(*mask);
331 TransferT transfer(pidx, sidx, filter, *tree);
335 rasterize<PointDataTreeT, TransferT>(points, transfer);
345 template <
bool Staggered,
348 typename PointDataTreeT>
351 const std::string& attribute,
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);
360 const AttributeSet::Descriptor& descriptor = iter->attributeSet().descriptor();
361 const size_t pidx = descriptor.find(
"P");
362 const size_t sidx = descriptor.find(attribute);
363 if (pidx == AttributeSet::INVALID_POS) {
366 if (sidx == AttributeSet::INVALID_POS) {
370 const NamePair& ptype = descriptor.type(pidx);
371 const NamePair& stype = descriptor.type(sidx);
372 if (ptype.second == NullCodec::name()) {
373 if (stype.second == NullCodec::name()) {
375 <Staggered, ValueT,
NullCodec, NullCodec>
376 (points, pidx, sidx, filter);
381 (points, pidx, sidx, filter);
385 if (stype.second == NullCodec::name()) {
388 (points, pidx, sidx, filter);
393 (points, pidx, sidx, filter);
403 #endif //OPENVDB_POINTS_RASTERIZE_TRILINEAR_IMPL_HAS_BEEN_INCLUDED int32_t Int32
Definition: Types.h:56
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
OPENVDB_IMPORT void initialize()
Global registration of native Grid, Transform, Metadata and Point attribute types. Also initializes blosc (if enabled).
Index32 Index
Definition: Types.h:54
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
Definition: Exceptions.h:63
math::Vec3< float > Vec3f
Definition: Types.h:74
static const bool IsVec
Definition: Types.h:316
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:337
Definition: Exceptions.h:13
std::pair< Name, Name > NamePair
Definition: AttributeArray.h:40
Definition: PointRasterizeTrilinear.h:36
typename T::ValueType ElementType
Definition: Types.h:373
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
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:350
Definition: AttributeArray.h:436
Definition: AttributeArray.h:433
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218