9 #ifndef OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_IMPL_HAS_BEEN_INCLUDED 10 #define OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_IMPL_HAS_BEEN_INCLUDED 19 namespace point_rasterize_internal {
23 template <
typename FilterT>
24 struct RasterGroupTraits
26 using NewFilterT = FilterT;
27 static NewFilterT resolve(
const FilterT& filter,
const points::AttributeSet&)
35 struct RasterGroupTraits<RasterGroups>
37 using NewFilterT = points::MultiGroupFilter;
38 static NewFilterT resolve(
const RasterGroups& groups,
const points::AttributeSet& attributeSet)
40 return NewFilterT(groups.includeNames, groups.excludeNames, attributeSet);
46 template <
typename T>
struct BoolTraits {
static const bool IsBool =
false; };
47 template <>
struct BoolTraits<
bool> {
static const bool IsBool =
true; };
48 template <>
struct BoolTraits<ValueMask> {
static const bool IsBool =
true; };
53 explicit TrueOp(
double scale) : mOn(scale > 0.0) { }
54 template<
typename ValueType>
55 void operator()(ValueType& v)
const { v =
static_cast<ValueType
>(mOn); }
59 template <
typename ValueT>
60 typename std::enable_if<std::is_integral<typename ValueTraits<ValueT>::ElementType>::value, ValueT>::type
61 castValue(
const double value)
67 template <
typename ValueT>
68 typename std::enable_if<!std::is_integral<typename ValueTraits<ValueT>::ElementType>::value, ValueT>::type
69 castValue(
const double value)
71 return static_cast<ValueT
>(value);
75 template <
typename ValueT>
76 typename std::enable_if<!ValueTraits<ValueT>::IsVec,
bool>::type
77 greaterThan(
const ValueT& value,
const float threshold)
79 return value >=
static_cast<ValueT
>(threshold);
83 template <
typename ValueT>
84 typename std::enable_if<ValueTraits<ValueT>::IsVec,
bool>::type
85 greaterThan(
const ValueT& value,
const float threshold)
87 return static_cast<double>(value.lengthSqr()) >= threshold*threshold;
91 template <
typename AttributeT,
typename HandleT,
typename Str
idedHandleT>
92 typename std::enable_if<!ValueTraits<AttributeT>::IsVec, AttributeT>::type
93 getAttributeScale(HandleT& handlePtr, StridedHandleT&, Index index)
96 return handlePtr->get(index);
102 template <
typename AttributeT,
typename HandleT,
typename Str
idedHandleT>
103 typename std::enable_if<ValueTraits<AttributeT>::IsVec, AttributeT>::type
104 getAttributeScale(HandleT& handlePtr, StridedHandleT& stridedHandlePtr, Index index)
107 return handlePtr->get(index);
108 }
else if (stridedHandlePtr) {
110 stridedHandlePtr->get(index, 0),
111 stridedHandlePtr->get(index, 1),
112 stridedHandlePtr->get(index, 2));
114 return AttributeT(1);
118 template <
typename ValueT>
121 template <
typename AttributeT>
122 static ValueT mul(
const ValueT& a,
const AttributeT& b)
129 struct MultiplyOp<
bool>
131 template <
typename AttributeT>
132 static bool mul(
const bool& a,
const AttributeT& b)
134 return a && (b != zeroVal<AttributeT>());
138 template <
typename PointDataGridT,
typename AttributeT,
typename GridT,
142 using TreeT =
typename GridT::TreeType;
143 using LeafT =
typename TreeT::LeafNodeType;
144 using ValueT =
typename TreeT::ValueType;
145 using PointLeafT =
typename PointDataGridT::TreeType::LeafNodeType;
146 using PointIndexT =
typename PointLeafT::ValueType;
147 using CombinableT = tbb::combinable<GridT>;
148 using SumOpT = tools::valxform::SumOp<ValueT>;
149 using MaxOpT = tools::valxform::MaxOp<ValueT>;
150 using PositionHandleT = openvdb::points::AttributeHandle<Vec3f>;
151 using VelocityHandleT = openvdb::points::AttributeHandle<Vec3f>;
152 using RadiusHandleT = openvdb::points::AttributeHandle<float>;
155 static const int interruptThreshold = 32*32*32;
158 const PointDataGridT& grid,
159 const std::vector<Index64>& offsets,
160 const size_t attributeIndex,
161 const Name& velocityAttribute,
162 const Name& radiusAttribute,
163 CombinableT& combinable,
164 CombinableT* weightCombinable,
165 const bool dropBuffers,
167 const FilterT& filter,
168 const bool computeMax,
169 const bool alignedTransform,
170 const bool staticCamera,
171 const FrustumRasterizerSettings& settings,
172 const FrustumRasterizerMask& mask,
173 util::NullInterrupter* interrupt)
176 , mAttributeIndex(attributeIndex)
177 , mVelocityAttribute(velocityAttribute)
178 , mRadiusAttribute(radiusAttribute)
179 , mCombinable(combinable)
180 , mWeightCombinable(weightCombinable)
181 , mDropBuffers(dropBuffers)
184 , mComputeMax(computeMax)
185 , mAlignedTransform(alignedTransform)
186 , mStaticCamera(staticCamera)
187 , mSettings(settings)
189 , mInterrupter(interrupt) { }
191 template <
typename Po
intOpT>
192 static void rasterPoint(
const Coord& ijk,
const double scale,
193 const AttributeT& attributeScale, PointOpT&
op)
195 op(ijk, scale, attributeScale);
198 template <
typename Po
intOpT>
199 static void rasterPoint(
const Vec3d& position,
const double scale,
200 const AttributeT& attributeScale, PointOpT&
op)
202 Coord ijk = Coord::round(position);
203 op(ijk, scale, attributeScale);
206 template <
typename SphereOpT>
207 static void rasterVoxelSphere(
const Vec3d& position,
const double scale,
208 const AttributeT& attributeScale,
const float radius, util::NullInterrupter* interrupter, SphereOpT&
op)
211 Coord ijk = Coord::round(position);
212 int &i = ijk[0], &j = ijk[1], &k = ijk[2];
217 const bool interrupt = interrupter && (imax-imin)*(jmax-jmin)*(kmax-kmin) > interruptThreshold;
219 for (i = imin; i <= imax; ++i) {
220 if (interrupt && interrupter->wasInterrupted())
break;
222 for (j = jmin; j <= jmax; ++j) {
223 if (interrupt && interrupter->wasInterrupted())
break;
224 const auto x2y2 =
math::Pow2(j - position[1]) + x2;
225 for (k = kmin; k <= kmax; ++k) {
226 const auto x2y2z2 = x2y2 +
math::Pow2(k - position[2]);
227 op(ijk, scale, attributeScale, x2y2z2, radius*radius);
233 template <
typename SphereOpT>
234 static void rasterApproximateFrustumSphere(
const Vec3d& position,
const double scale,
235 const AttributeT& attributeScale,
const float radiusWS,
236 const math::Transform& frustum,
const CoordBBox* clipBBox,
237 util::NullInterrupter* interrupter, SphereOpT& op)
239 Vec3d voxelSize = frustum.voxelSize(position);
241 CoordBBox frustumBBox(Coord::floor(position-radius), Coord::ceil(position+radius));
245 frustumBBox.intersect(*clipBBox);
248 Vec3i outMin = frustumBBox.min().asVec3i();
249 Vec3i outMax = frustumBBox.max().asVec3i();
251 const bool interrupt = interrupter && frustumBBox.volume() > interruptThreshold;
256 int &x = outXYZ.
x(), &y = outXYZ.y(), &z = outXYZ.z();
257 for (x = outMin.x(); x <= outMax.x(); ++x) {
258 if (interrupt && interrupter->wasInterrupted())
break;
260 for (y = outMin.y(); y <= outMax.y(); ++y) {
261 if (interrupt && interrupter->wasInterrupted())
break;
263 for (z = outMin.z(); z <= outMax.z(); ++z) {
268 Vec3d offset = (xyz - position) * voxelSize;
270 double distanceSqr = offset.
dot(offset);
272 op(outXYZ, scale, attributeScale, distanceSqr, radiusWS*radiusWS);
278 template <
typename SphereOpT>
279 static void rasterFrustumSphere(
const Vec3d& position,
const double scale,
280 const AttributeT& attributeScale,
const float radiusWS,
281 const math::Transform& frustum,
const CoordBBox* clipBBox,
282 util::NullInterrupter* interrupter, SphereOpT& op)
284 const Vec3d positionWS = frustum.indexToWorld(position);
286 BBoxd inputBBoxWS(positionWS-radiusWS, positionWS+radiusWS);
292 frustumMin, frustumMax);
293 CoordBBox frustumBBox(Coord::floor(frustumMin), Coord::ceil(frustumMax));
297 frustumBBox.intersect(*clipBBox);
300 Vec3i outMin = frustumBBox.min().asVec3i();
301 Vec3i outMax = frustumBBox.max().asVec3i();
303 const bool interrupt = interrupter && frustumBBox.volume() > interruptThreshold;
308 int &x = outXYZ.
x(), &y = outXYZ.y(), &z = outXYZ.z();
309 for (x = outMin.x(); x <= outMax.x(); ++x) {
310 if (interrupt && interrupter->wasInterrupted())
break;
312 for (y = outMin.y(); y <= outMax.y(); ++y) {
313 if (interrupt && interrupter->wasInterrupted())
break;
315 for (z = outMin.z(); z <= outMax.z(); ++z) {
318 Vec3R xyzWS = frustum.indexToWorld(xyz);
320 double xDist = xyzWS.
x() - positionWS.x();
321 double yDist = xyzWS.y() - positionWS.y();
322 double zDist = xyzWS.z() - positionWS.z();
324 double distanceSqr = xDist*xDist+yDist*yDist+zDist*zDist;
325 op(outXYZ, scale, attributeScale, distanceSqr, radiusWS*radiusWS);
331 void operator()(
const PointLeafT& leaf,
size_t)
const 333 if (mInterrupter && mInterrupter->wasInterrupted()) {
334 thread::cancelGroupExecution();
338 using AccessorT = tree::ValueAccessor<typename GridT::TreeType>;
339 using MaskAccessorT = tree::ValueAccessor<const MaskTree>;
341 constexpr
bool isBool = BoolTraits<ValueT>::IsBool;
342 const bool isFrustum = !mSettings.transform->isLinear();
344 const bool useRaytrace = mSettings.velocityMotionBlur || !mStaticCamera;
345 const bool useRadius = mSettings.useRadius;
346 const float radiusScale = mSettings.radiusScale;
347 const float radiusThreshold = std::sqrt(3.0f);
349 const float threshold = mSettings.threshold;
350 const bool scaleByVoxelVolume = !useRadius && mSettings.scaleByVoxelVolume;
352 const float shutterStartDt = mSettings.camera.shutterStart()/mSettings.framesPerSecond;
353 const float shutterEndDt = mSettings.camera.shutterEnd()/mSettings.framesPerSecond;
354 const int motionSteps =
std::max(1, mSettings.motionSamples-1);
356 std::vector<Vec3d> motionPositions(motionSteps+1,
Vec3d());
357 std::vector<Vec2s> frustumRadiusSizes(motionSteps+1,
Vec2s());
359 const auto& pointsTransform = mGrid.constTransform();
361 const float voxelSize =
static_cast<float>(mSettings.transform->voxelSize()[0]);
363 auto& grid = mCombinable.local();
364 auto& tree = grid.tree();
365 const auto& transform = *(mSettings.transform);
367 grid.setTransform(mSettings.transform->copy());
369 AccessorT valueAccessor(tree);
371 std::unique_ptr<MaskAccessorT> maskAccessor;
372 auto maskTree = mMask.getTreePtr();
373 if (maskTree) maskAccessor.reset(
new MaskAccessorT(*maskTree));
375 const CoordBBox* clipBBox = !mMask.clipBBox().empty() ? &mMask.clipBBox() :
nullptr;
377 std::unique_ptr<AccessorT> weightAccessor;
378 if (mWeightCombinable) {
379 auto& weightGrid = mWeightCombinable->local();
380 auto& weightTree = weightGrid.tree();
381 weightAccessor.reset(
new AccessorT(weightTree));
387 std::unique_ptr<TreeT> tempTree;
388 std::unique_ptr<TreeT> tempWeightTree;
389 std::unique_ptr<AccessorT> tempValueAccessor;
390 std::unique_ptr<AccessorT> tempWeightAccessor;
391 if (useRadius && !mComputeMax) {
392 tempTree.reset(
new TreeT(tree.background()));
393 tempValueAccessor.reset(
new AccessorT(*tempTree));
394 if (weightAccessor) {
395 tempWeightTree.reset(
new TreeT(weightAccessor->tree().background()));
396 tempWeightAccessor.reset(
new AccessorT(*tempWeightTree));
403 auto doModifyVoxelOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale,
404 const bool isTemp,
const bool forceSum)
406 if (mMask && !mMask.valid(ijk, maskAccessor.get()))
return;
409 if (!math::isZero<AttributeT>(attributeScale) && !math::isNegative<AttributeT>(attributeScale)) {
410 valueAccessor.modifyValue(ijk, TrueOp(scale));
413 ValueT weightValue = castValue<ValueT>(
scale);
414 ValueT newValue = MultiplyOp<ValueT>::mul(weightValue, attributeScale);
415 if (scaleByVoxelVolume) {
416 newValue /=
static_cast<ValueT
>(transform.voxelSize(ijk.asVec3d()).product());
418 if (point_rasterize_internal::greaterThan(newValue, threshold)) {
420 tempValueAccessor->modifyValue(ijk, MaxOpT(newValue));
421 if (tempWeightAccessor) {
422 tempWeightAccessor->modifyValue(ijk, MaxOpT(weightValue));
425 if (mComputeMax && !forceSum) {
426 valueAccessor.modifyValue(ijk, MaxOpT(newValue));
428 valueAccessor.modifyValue(ijk, SumOpT(newValue));
430 if (weightAccessor) {
431 weightAccessor->modifyValue(ijk, SumOpT(weightValue));
439 auto modifyVoxelOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale)
441 doModifyVoxelOp(ijk, scale, attributeScale,
false,
false);
445 auto sumVoxelOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale)
447 doModifyVoxelOp(ijk, scale, attributeScale,
false,
true);
453 auto doModifyVoxelByDistanceOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale,
454 const double distanceSqr,
const double radiusSqr,
const bool isTemp)
456 if (distanceSqr >= radiusSqr)
return;
458 valueAccessor.modifyValue(ijk, TrueOp(scale));
460 double distance = std::sqrt(distanceSqr);
461 double radius = std::sqrt(radiusSqr);
462 double result = 1.0 - distance/radius;
463 doModifyVoxelOp(ijk, result * scale, attributeScale, isTemp,
false);
468 auto modifyVoxelByDistanceOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale,
469 const double distanceSqr,
const double radiusSqr)
471 doModifyVoxelByDistanceOp(ijk, scale, attributeScale, distanceSqr, radiusSqr,
false);
475 auto modifyTempVoxelByDistanceOp = [&](
const Coord& ijk,
const double scale,
const AttributeT& attributeScale,
476 const double distanceSqr,
const double radiusSqr)
478 doModifyVoxelByDistanceOp(ijk, scale, attributeScale, distanceSqr, radiusSqr,
true);
481 typename points::AttributeHandle<AttributeT>::Ptr attributeHandle;
483 typename points::AttributeHandle<ElementT>::Ptr stridedAttributeHandle;
485 if (mAttributeIndex != points::AttributeSet::INVALID_POS) {
486 const auto& attributeArray = leaf.constAttributeArray(mAttributeIndex);
487 if (attributeArray.stride() == 3) {
488 stridedAttributeHandle = points::AttributeHandle<ElementT>::create(attributeArray);
490 attributeHandle = points::AttributeHandle<AttributeT>::create(attributeArray);
494 size_t positionIndex = leaf.attributeSet().find(
"P");
495 size_t velocityIndex = leaf.attributeSet().find(mVelocityAttribute);
496 size_t radiusIndex = leaf.attributeSet().find(mRadiusAttribute);
498 auto positionHandle = PositionHandleT::create(
499 leaf.constAttributeArray(positionIndex));
500 auto velocityHandle = (useRaytrace && leaf.hasAttribute(velocityIndex)) ?
501 VelocityHandleT::create(leaf.constAttributeArray(velocityIndex)) :
502 VelocityHandleT::Ptr();
503 auto radiusHandle = (useRadius && leaf.hasAttribute(radiusIndex)) ?
504 RadiusHandleT::create(leaf.constAttributeArray(radiusIndex)) :
505 RadiusHandleT::Ptr();
507 for (
auto iter = leaf.beginIndexOn(mFilter); iter; ++iter) {
512 const AttributeT attributeScale = getAttributeScale<AttributeT>(
513 attributeHandle, stridedAttributeHandle, *iter);
515 float radiusWS = 1.0f, radius = 1.0f;
517 radiusWS *= radiusScale;
518 if (radiusHandle) radiusWS *= radiusHandle->get(*iter);
521 }
else if (voxelSize > 0.0f) {
522 radius = radiusWS / voxelSize;
528 bool doRadius = useRadius;
529 if (!isFrustum && radius < radiusThreshold) {
533 float increment = shutterEndDt - shutterStartDt;
538 bool doRaytrace = useRaytrace;
540 if (increment < openvdb::math::Delta<float>::value()) {
543 if (velocityHandle) velocity = velocityHandle->get(*iter);
544 if (mStaticCamera && velocity.lengthSqr() < openvdb::math::Delta<float>::value()) {
550 if (motionSteps > 1) increment /= float(motionSteps);
552 Vec3d position = positionHandle->get(*iter) + iter.getCoord().asVec3d();
556 position = pointsTransform.indexToWorld(position);
558 for (
int motionStep = 0; motionStep <= motionSteps; motionStep++) {
560 float offset = motionStep == motionSteps ? shutterEndDt :
561 (shutterStartDt + increment *
static_cast<float>(motionStep));
562 Vec3d samplePosition = position + velocity * offset;
564 const math::Transform* sampleTransform = &transform;
565 if (!mSettings.camera.isStatic()) {
566 sampleTransform = &mSettings.camera.transform(motionStep);
567 if (mSettings.camera.hasWeight(motionStep)) {
568 const float weight = mSettings.camera.weight(motionStep);
569 const Vec3d referencePosition = transform.worldToIndex(samplePosition);
570 const Vec3d adjustedPosition = sampleTransform->worldToIndex(samplePosition);
571 motionPositions[motionStep] = referencePosition + (adjustedPosition - referencePosition) * weight;
573 motionPositions[motionStep] = sampleTransform->worldToIndex(samplePosition);
576 motionPositions[motionStep] = sampleTransform->worldToIndex(samplePosition);
578 if (doRadius && isFrustum) {
579 Vec3d left = sampleTransform->worldToIndex(samplePosition -
Vec3d(radiusWS, 0, 0));
580 Vec3d right = sampleTransform->worldToIndex(samplePosition +
Vec3d(radiusWS, 0, 0));
581 float width =
static_cast<float>((right - left).length());
582 Vec3d top = sampleTransform->worldToIndex(samplePosition +
Vec3d(0, radiusWS, 0));
583 Vec3d bottom = sampleTransform->worldToIndex(samplePosition -
Vec3d(0, radiusWS, 0));
584 float height =
static_cast<float>((top - bottom).length());
585 frustumRadiusSizes[motionStep].
x() = width;
586 frustumRadiusSizes[motionStep].y() = height;
590 double totalDistance = 0.0;
591 for (
size_t i = 0; i < motionPositions.size()-1; i++) {
592 Vec3d direction = motionPositions[i+1] - motionPositions[i];
593 double distance = direction.
length();
594 totalDistance += distance;
597 double distanceWeight = totalDistance > 0.0 ? 1.0 / totalDistance : 1.0;
599 if (doRadius && !mComputeMax) {
601 for (
auto leaf = tempTree->beginLeaf(); leaf; ++leaf) {
602 leaf->setValuesOff();
604 if (tempWeightAccessor) {
605 for (
auto leaf = tempWeightTree->beginLeaf(); leaf; ++leaf) {
606 leaf->setValuesOff();
611 for (
int motionStep = 0; motionStep < motionSteps; motionStep++) {
613 Vec3d startPosition = motionPositions[motionStep];
614 Vec3d endPosition = motionPositions[motionStep+1];
616 Vec3d direction(endPosition - startPosition);
617 double distance = direction.length();
622 float maxRadius = radius;
624 if (doRadius && isFrustum) {
625 const Vec2s& startRadius = frustumRadiusSizes[motionStep];
626 const Vec2s& endRadius = frustumRadiusSizes[motionStep+1];
628 if (startRadius[0] < radiusThreshold && startRadius[1] < radiusThreshold &&
629 endRadius[0] < radiusThreshold && endRadius[1] < radiusThreshold) {
634 maxRadius =
std::max(startRadius[0], startRadius[1]);
635 maxRadius =
std::max(maxRadius, endRadius[0]);
636 maxRadius =
std::max(maxRadius, endRadius[1]);
641 distanceWeight =
std::min(distanceWeight, 1.0);
648 double spherePacking = mSettings.accurateSphereMotionBlur ? 4.0 : 2.0;
650 const int steps =
std::max(2,
math::Ceil(distance * spherePacking /
double(maxRadius)) + 1);
652 Vec3d sample(startPosition);
653 const Vec3d offset(direction / (steps-1));
655 for (
int step = 0; step < steps; step++) {
658 if (mSettings.accurateFrustumRadius) {
659 this->rasterFrustumSphere(sample, mScale * distanceWeight,
660 attributeScale, radiusWS, transform, clipBBox, mInterrupter, modifyVoxelByDistanceOp);
662 this->rasterApproximateFrustumSphere(sample, mScale * distanceWeight,
663 attributeScale, radiusWS, transform, clipBBox, mInterrupter, modifyVoxelByDistanceOp);
666 if (mSettings.accurateFrustumRadius) {
667 this->rasterFrustumSphere(sample, mScale * distanceWeight,
668 attributeScale, radiusWS, transform, clipBBox, mInterrupter, modifyTempVoxelByDistanceOp);
670 this->rasterApproximateFrustumSphere(sample, mScale * distanceWeight,
671 attributeScale, radiusWS, transform, clipBBox, mInterrupter, modifyTempVoxelByDistanceOp);
676 this->rasterVoxelSphere(sample, mScale * distanceWeight,
677 attributeScale, radius, mInterrupter, modifyVoxelByDistanceOp);
679 this->rasterVoxelSphere(sample, mScale * distanceWeight,
680 attributeScale, radius, mInterrupter, modifyTempVoxelByDistanceOp);
683 if (step < (steps-1)) sample += offset;
684 else sample = endPosition;
688 mDdaRay.setMinTime(math::Delta<double>::value());
689 mDdaRay.setMaxTime(
std::max(distance, math::Delta<double>::value()*2.0));
692 direction.normalize();
693 mDdaRay.setDir(direction);
696 mDdaRay.setEye(startPosition +
Vec3d(0.5));
700 mDdaRay.clip(*clipBBox);
705 bool forceSum = motionStep > 0;
709 const Coord& voxel = mDda.voxel();
710 double delta = (mDda.next() - mDda.time()) * distanceWeight;
712 this->rasterPoint(voxel, mScale * delta,
713 attributeScale, sumVoxelOp);
716 this->rasterPoint(voxel, mScale * delta,
717 attributeScale, modifyVoxelOp);
719 if (!mDda.step())
break;
724 if (doRadius && !mComputeMax) {
726 for (
auto iter = tempTree->cbeginValueOn(); iter; ++iter) {
727 valueAccessor.modifyValue(iter.getCoord(), SumOpT(*iter));
731 if (weightAccessor) {
732 for (
auto iter = tempWeightTree->cbeginValueOn(); iter; ++iter) {
733 weightAccessor->modifyValue(iter.getCoord(), SumOpT(*iter));
739 if (!mAlignedTransform) {
740 position = transform.worldToIndex(
741 pointsTransform.indexToWorld(position));
746 if (mSettings.accurateFrustumRadius) {
747 this->rasterFrustumSphere(position, mScale, attributeScale,
748 radiusWS, transform, clipBBox, mInterrupter, modifyVoxelByDistanceOp);
750 this->rasterApproximateFrustumSphere(position, mScale, attributeScale,
751 radiusWS, transform, clipBBox, mInterrupter, modifyVoxelByDistanceOp);
754 this->rasterVoxelSphere(position, mScale, attributeScale,
755 radius, mInterrupter, modifyVoxelByDistanceOp);
758 this->rasterPoint(position, mScale, attributeScale, modifyVoxelOp);
767 typename PointLeafT::Buffer emptyBuffer(PartialCreate(), zeroVal<PointIndexT>());
768 (
const_cast<PointLeafT&
>(leaf)).swap(emptyBuffer);
775 mutable math::Ray<double> mDdaRay;
776 mutable math::DDA<openvdb::math::Ray<double>> mDda;
777 const PointDataGridT& mGrid;
778 const std::vector<Index64>& mOffsets;
779 const size_t mAttributeIndex;
780 const Name mVelocityAttribute;
781 const Name mRadiusAttribute;
782 CombinableT& mCombinable;
783 CombinableT* mWeightCombinable;
784 const bool mDropBuffers;
786 const FilterT& mFilter;
787 const bool mComputeMax;
788 const bool mAlignedTransform;
789 const bool mStaticCamera;
790 const FrustumRasterizerSettings& mSettings;
791 const FrustumRasterizerMask& mMask;
792 util::NullInterrupter* mInterrupter;
798 template<
typename Gr
idT>
799 struct GridCombinerOp
801 using CombinableT =
typename tbb::combinable<GridT>;
803 using TreeT =
typename GridT::TreeType;
804 using LeafT =
typename TreeT::LeafNodeType;
805 using ValueType =
typename TreeT::ValueType;
806 using SumOpT = tools::valxform::SumOp<typename TreeT::ValueType>;
807 using MaxOpT = tools::valxform::MaxOp<typename TreeT::ValueType>;
809 GridCombinerOp(GridT& grid,
bool sum)
813 void operator()(
const GridT& grid)
815 for (
auto leaf = grid.tree().beginLeaf(); leaf; ++leaf) {
816 auto* newLeaf = mTree.probeLeaf(leaf->origin());
819 auto& tree =
const_cast<GridT&
>(grid).tree();
820 mTree.addLeaf(tree.template stealNode<LeafT>(leaf->origin(),
821 zeroVal<ValueType>(),
false));
826 for (
auto iter = leaf->cbeginValueOn(); iter; ++iter) {
827 newLeaf->modifyValue(iter.offset(), SumOpT(ValueType(*iter)));
830 for (
auto iter = leaf->cbeginValueOn(); iter; ++iter) {
831 newLeaf->modifyValue(iter.offset(), MaxOpT(ValueType(*iter)));
844 template<
typename Gr
idT>
845 struct CombinableTraits {
846 using OpT = GridCombinerOp<GridT>;
847 using T =
typename OpT::CombinableT;
851 template <
typename Po
intDataGr
idT>
852 class GridToRasterize
855 using GridPtr =
typename PointDataGridT::Ptr;
856 using GridConstPtr =
typename PointDataGridT::ConstPtr;
857 using PointDataTreeT =
typename PointDataGridT::TreeType;
858 using PointDataLeafT =
typename PointDataTreeT::LeafNodeType;
860 GridToRasterize(
GridPtr& grid,
bool stream,
861 const FrustumRasterizerSettings& settings,
862 const FrustumRasterizerMask& mask)
865 , mSettings(settings)
868 GridToRasterize(GridConstPtr& grid,
const FrustumRasterizerSettings& settings,
869 const FrustumRasterizerMask& mask)
872 , mSettings(settings)
875 const typename PointDataGridT::TreeType& tree()
const 877 return mGrid->constTree();
880 void setLeafPercentage(
int percentage)
885 int leafPercentage()
const 887 return mLeafPercentage;
892 return mGrid->memUsage() + mLeafOffsets.capacity();
895 template <
typename AttributeT,
typename Gr
idT,
typename FilterT>
897 typename CombinableTraits<GridT>::T& combiner,
typename CombinableTraits<GridT>::T* weightCombiner,
898 const float scale,
const FilterT& groupFilter,
const bool computeMax,
const bool reduceMemory,
899 util::NullInterrupter* interrupter)
901 using point_rasterize_internal::RasterizeOp;
903 const auto& velocityAttribute = mSettings.velocityMotionBlur ?
904 mSettings.velocityAttribute :
"";
905 const auto& radiusAttribute = mSettings.useRadius ?
906 mSettings.radiusAttribute :
"";
908 bool isPositionAttribute = attribute ==
"P";
909 bool isVelocityAttribute = attribute == mSettings.velocityAttribute;
910 bool isRadiusAttribute = attribute == mSettings.radiusAttribute;
913 const auto& attributeSet = mGrid->constTree().cbeginLeaf()->attributeSet();
914 const size_t attributeIndex = attributeSet.find(attribute);
915 const bool attributeExists = attributeIndex != points::AttributeSet::INVALID_POS;
920 const auto* attributeArray = attributeSet.getConst(attributeIndex);
921 const Index stride =
bool(attributeArray) ? attributeArray->stride() :
Index(1);
922 const auto& actualValueType = attributeSet.descriptor().valueType(attributeIndex);
923 const auto requestedValueType =
Name(typeNameAsString<AttributeT>());
924 const bool packVector = stride == 3 &&
930 requestedValueType == typeNameAsString<Vec3I>()));
931 if (!packVector && actualValueType != requestedValueType) {
933 "Attribute type requested for rasterization \"" << requestedValueType <<
"\"" 934 " must match attribute value type \"" << actualValueType <<
"\"");
938 tree::LeafManager<PointDataTreeT> leafManager(mGrid->tree());
941 const bool dropBuffers = mStream && reduceMemory;
944 using ResolvedFilterT =
typename point_rasterize_internal::RasterGroupTraits<FilterT>::NewFilterT;
945 auto resolvedFilter = point_rasterize_internal::RasterGroupTraits<FilterT>::resolve(
946 groupFilter, attributeSet);
949 if (mLeafOffsets.empty()) {
951 false, mSettings.threaded);
956 if (attributeExists && !isPositionAttribute && !isVelocityAttribute && !isRadiusAttribute) {
958 [&](PointDataLeafT& leaf,
size_t ) {
959 leaf.attributeArray(attributeIndex).setStreaming(
true);
965 size_t positionIndex = attributeSet.find(
"P");
967 [&](PointDataLeafT& leaf,
size_t ) {
968 leaf.attributeArray(positionIndex).setStreaming(
true);
971 if (mSettings.velocityMotionBlur || !mSettings.camera.isStatic()) {
972 size_t velocityIndex = attributeSet.find(velocityAttribute);
973 if (velocityIndex != points::AttributeSet::INVALID_POS) {
975 [&](PointDataLeafT& leaf,
size_t ) {
976 leaf.attributeArray(velocityIndex).setStreaming(
true);
981 if (mSettings.useRadius) {
982 size_t radiusIndex = attributeSet.find(radiusAttribute);
983 if (radiusIndex != points::AttributeSet::INVALID_POS) {
985 [&](PointDataLeafT& leaf,
size_t ) {
986 leaf.attributeArray(radiusIndex).setStreaming(
true);
994 const bool alignedTransform = *(mSettings.transform) == mGrid->constTransform();
996 RasterizeOp<PointDataGridT, AttributeT, GridT, ResolvedFilterT> rasterizeOp(
997 *mGrid, mLeafOffsets, attributeIndex, velocityAttribute, radiusAttribute, combiner, weightCombiner,
998 dropBuffers, scale, resolvedFilter, computeMax, alignedTransform, mSettings.camera.isStatic(),
999 mSettings, mMask, interrupter);
1000 leafManager.foreach(rasterizeOp, mSettings.threaded);
1003 if (reduceMemory && !mLeafOffsets.empty()) {
1004 mLeafOffsets.clear();
1006 mLeafOffsets.shrink_to_fit();
1013 const FrustumRasterizerSettings& mSettings;
1014 const FrustumRasterizerMask& mMask;
1015 int mLeafPercentage = -1;
1016 std::vector<Index64> mLeafOffsets;
1020 template <
typename ValueT>
1021 typename std::enable_if<!ValueTraits<ValueT>::IsVec, ValueT>::type
1022 computeWeightedValue(
const ValueT& value,
const ValueT& weight)
1024 constexpr
bool isSignedInt = std::is_integral<ValueT>() && std::is_signed<ValueT>();
1028 return zeroVal<ValueT>();
1030 return value / weight;
1035 template <
typename ValueT>
1036 typename std::enable_if<ValueTraits<ValueT>::IsVec, ValueT>::type
1037 computeWeightedValue(
const ValueT& value,
const ValueT& weight)
1041 constexpr
bool isSignedInt = std::is_integral<ElementT>() && std::is_signed<ElementT>();
1043 ValueT result(value);
1044 for (
int i=0; i<ValueTraits<ValueT>::Size; ++i) {
1047 result[i] = zeroVal<ElementT>();
1049 result[i] = value[i] / weight[i];
1064 : mTransforms{transform}
1069 return mTransforms.size() <= 1;
1074 mTransforms.clear();
1080 mTransforms.push_back(transform);
1081 mWeights.push_back(weight);
1086 return mTransforms.size();
1092 if (mTransforms.size() >= 2) {
1093 const auto&
transform = mTransforms.front();
1095 for (
const auto& testTransform : mTransforms) {
1101 while (mTransforms.size() > 1) {
1102 mTransforms.pop_back();
1107 if (!mWeights.empty()) {
1109 for (
Index i = 0; i < mWeights.size(); i++) {
1115 if (!hasWeight) mWeights.clear();
1121 if (mWeights.empty())
return false;
1128 if (mWeights.empty()) {
1138 if (mTransforms.size() == 1) {
1139 return mTransforms.front();
1142 return mTransforms[i];
1149 return mTransforms.front();
1155 return mTransforms.back();
1160 mShutterStart = start;
1166 return mShutterStart;
1181 const bool clipToFrustum,
1182 const bool invertMask)
1185 , mInvert(invertMask)
1196 mMask->setTransform(transform.
copy());
1197 tools::resampleToMatch<tools::PointSampler>(*mask, *mMask);
1204 if (!bbox.
empty()) {
1207 CoordBBox coordBBox(Coord::floor(bbox.
min()),
1208 Coord::ceil(bbox.
max()));
1209 tempMask->sparseFill(coordBBox,
true,
true);
1213 bboxMask->setTransform(mMask ? mMask->transformPtr() : transform.
copy());
1214 tools::resampleToMatch<tools::PointSampler>(*tempMask, *bboxMask);
1218 mMask->topologyUnion(*bboxMask);
1224 if (clipToFrustum) {
1225 auto frustumMap = transform.template constMap<math::NonlinearFrustumMap>();
1227 const auto& frustumBBox = frustumMap->getBBox();
1228 mClipBBox.reset(Coord::floor(frustumBBox.min()),
1229 Coord::ceil(frustumBBox.max()));
1234 FrustumRasterizerMask::operator
bool()
const 1236 return mMask || !mClipBBox.empty();
1254 const bool maskValue = acc ? acc->
isValueOn(ijk) :
true;
1255 const bool insideMask = mInvert ? !maskValue : maskValue;
1256 const bool insideFrustum = mClipBBox.empty() ?
true : mClipBBox.isInside(ijk);
1257 return insideMask && insideFrustum;
1264 template <
typename Po
intDataGr
idT>
1268 : mSettings(settings)
1270 , mInterrupter(interrupt)
1274 "Using velocity motion blur during rasterization requires a velocity attribute.");
1278 template <
typename Po
intDataGr
idT>
1283 if (!grid || grid->tree().empty())
return;
1286 mPointGrids.emplace_back(grid, mSettings, mMask);
1289 template <
typename Po
intDataGr
idT>
1294 if (!grid || grid->tree().empty())
return;
1296 mPointGrids.emplace_back(grid, stream, mSettings, mMask);
1299 template <
typename Po
intDataGr
idT>
1303 mPointGrids.clear();
1306 template <
typename Po
intDataGr
idT>
1310 return mPointGrids.size();
1313 template <
typename Po
intDataGr
idT>
1317 size_t mem =
sizeof(*this) +
sizeof(mPointGrids);
1318 for (
const auto& grid : mPointGrids) {
1319 mem += grid.memUsage();
1324 template <
typename Po
intDataGr
idT>
1325 template <
typename FilterT>
1328 RasterMode mode,
bool reduceMemory,
float scale,
const FilterT& filter)
1331 auto density = rasterizeAttribute<FloatGrid, float>(
"", mode, reduceMemory,
scale, filter);
1333 density->setName(
"density");
1337 template <
typename Po
intDataGr
idT>
1338 template <
typename FilterT>
1343 auto density = rasterizeAttribute<FloatGrid, float>(attribute, mode, reduceMemory,
scale, filter);
1345 density->setName(
"density");
1349 template <
typename Po
intDataGr
idT>
1350 template <
typename FilterT>
1353 const Name& attribute,
RasterMode mode,
bool reduceMemory,
float scale,
const FilterT& filter)
1359 for (
const auto& points : mPointGrids) {
1360 auto leaf = points.tree().cbeginLeaf();
1361 const auto& descriptor = leaf->attributeSet().descriptor();
1362 const size_t targetIndex = descriptor.find(attribute);
1365 const auto* attributeArray = leaf->attributeSet().getConst(attribute);
1366 if (!attributeArray)
continue;
1367 stride = attributeArray->stride();
1368 sourceType = descriptor.valueType(targetIndex);
1369 if (!sourceType.empty())
break;
1374 if (sourceType.empty())
return {};
1377 using GridT =
typename PointDataGridT::template ValueConverter<float>::Type;
1378 return rasterizeAttribute<GridT, float>(attribute, mode, reduceMemory,
scale, filter);
1381 #ifndef ONLY_RASTER_FLOAT 1384 using GridT =
typename PointDataGridT::template ValueConverter<Vec3f>::Type;
1385 return rasterizeAttribute<GridT, Vec3f>(attribute, mode, reduceMemory,
scale, filter);
1388 using GridT =
typename PointDataGridT::template ValueConverter<Vec3d>::Type;
1389 return rasterizeAttribute<GridT, Vec3d>(attribute, mode, reduceMemory,
scale, filter);
1392 using GridT =
typename PointDataGridT::template ValueConverter<Vec3i>::Type;
1393 return rasterizeAttribute<GridT, Vec3i>(attribute, mode, reduceMemory,
scale, filter);
1396 return rasterizeAttribute<GridT, int16_t>(attribute, mode, reduceMemory,
scale, filter);
1399 return rasterizeAttribute<GridT, int32_t>(attribute, mode, reduceMemory,
scale, filter);
1401 using GridT =
typename PointDataGridT::template ValueConverter<Int64>::Type;
1402 return rasterizeAttribute<GridT, int64_t>(attribute, mode, reduceMemory,
scale, filter);
1404 using GridT =
typename PointDataGridT::template ValueConverter<double>::Type;
1405 return rasterizeAttribute<GridT, double>(attribute, mode, reduceMemory,
scale, filter);
1407 using GridT =
typename PointDataGridT::template ValueConverter<bool>::Type;
1408 return rasterizeAttribute<GridT, bool>(attribute, mode, reduceMemory,
true, filter);
1411 std::ostringstream ostr;
1412 ostr <<
"Cannot rasterize attribute of type - " << sourceType;
1413 if (stride > 1) ostr <<
" x " << stride;
1418 template <
typename Po
intDataGr
idT>
1419 template <
typename Gr
idT,
typename AttributeT,
typename FilterT>
1422 bool reduceMemory,
float scale,
const FilterT& filter)
1424 if (attribute ==
"P") {
1428 auto grid = GridT::create();
1429 grid->setName(attribute);
1430 grid->setTransform(mSettings.
transform->copy());
1432 this->performRasterization<AttributeT>(*grid, mode, attribute, reduceMemory,
scale, filter);
1437 template <
typename Po
intDataGr
idT>
1438 template <
typename Gr
idT,
typename FilterT>
1442 using ValueT =
typename GridT::ValueType;
1444 static_assert(point_rasterize_internal::BoolTraits<ValueT>::IsBool,
1445 "Value type of mask to be rasterized must be bool or ValueMask.");
1448 grid->setName(
"mask");
1453 template <
typename Po
intDataGr
idT>
1454 template <
typename AttributeT,
typename Gr
idT,
typename FilterT>
1458 float scale,
const FilterT& filter)
1460 using openvdb::points::point_mask_internal::GridCombinerOp;
1461 using point_rasterize_internal::computeWeightedValue;
1463 using TreeT =
typename GridT::TreeType;
1464 using LeafT =
typename TreeT::LeafNodeType;
1465 using ValueT =
typename TreeT::ValueType;
1466 using CombinerOpT =
typename point_rasterize_internal::CombinableTraits<GridT>::OpT;
1467 using CombinableT =
typename point_rasterize_internal::CombinableTraits<GridT>::T;
1471 std::stringstream ss;
1472 ss <<
"Rasterizing Points ";
1474 ss <<
"with Motion Blur ";
1477 ss <<
"to Linear Volume";
1479 ss <<
"to Frustum Volume";
1481 mInterrupter->
start(ss.str().c_str());
1489 "Cannot use maximum mode when rasterizing vector attributes.");
1492 if ((useMaximum || useWeight) && point_rasterize_internal::BoolTraits<ValueT>::IsBool) {
1494 "Cannot use maximum or average modes when rasterizing bool attributes.");
1497 CombinableT combiner;
1498 CombinableT weightCombiner;
1499 CombinableT* weightCombinerPtr = useWeight ? &weightCombiner :
nullptr;
1505 if (mPointGrids.size() == 1) {
1506 mPointGrids[0].setLeafPercentage(100);
1511 std::vector<Index64> leafCounts;
1512 leafCounts.reserve(mPointGrids.size());
1513 for (
auto& points : mPointGrids) {
1514 leafCount += points.tree().leafCount();
1515 leafCounts.push_back(leafCount);
1519 if (leafCount ==
Index64(0)) leafCount++;
1522 for (
size_t i = 0; i < leafCounts.size(); i++) {
1523 int percentage =
static_cast<int>(
math::Round((static_cast<float>(leafCounts[i]))/
1524 static_cast<float>(leafCount)));
1525 mPointGrids[i].setLeafPercentage(percentage);
1532 for (
auto& points : mPointGrids) {
1534 points.template rasterize<AttributeT, GridT>(
1550 combiner.combine_each(combineOp);
1556 auto weightGrid = GridT::create(ValueT(1));
1557 CombinerOpT weightCombineOp(*weightGrid,
true);
1558 weightCombiner.combine_each(weightCombineOp);
1562 [&](LeafT& leaf,
size_t ) {
1563 auto weightAccessor = weightGrid->getConstAccessor();
1564 for (
auto iter = leaf.beginValueOn(); iter; ++iter) {
1565 auto weight = weightAccessor.getValue(iter.getCoord());
1566 iter.setValue(computeWeightedValue(iter.getValue(), weight));
1572 if (mInterrupter) mInterrupter->
end();
1580 #endif // OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_IMPL_HAS_BEEN_INCLUDED void clear()
Clear all PointDataGrids in the rasterizer.
Definition: PointRasterizeFrustumImpl.h:1301
const char * typeNameAsString< double >()
Definition: Types.h:521
void clear()
Definition: PointRasterizeFrustumImpl.h:1072
FrustumRasterizer(const FrustumRasterizerSettings &settings, const FrustumRasterizerMask &mask=FrustumRasterizerMask(), util::NullInterrupter *interrupt=nullptr)
main constructor
Definition: PointRasterizeFrustumImpl.h:1265
const math::Transform & lastTransform() const
Definition: PointRasterizeFrustumImpl.h:1152
Type Pow2(Type x)
Return x2.
Definition: Math.h:548
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:367
GridBase::Ptr rasterizeAttribute(const Name &attribute, RasterMode mode=RasterMode::ACCUMULATE, bool reduceMemory=false, float scale=1.0f, const FilterT &filter=FilterT())
Definition: PointRasterizeFrustumImpl.h:1352
const char * typeNameAsString< Vec3i >()
Definition: Types.h:534
Index64 pointOffsets(std::vector< Index64 > &pointOffsets, const PointDataTreeT &tree, const FilterT &filter=NullFilter(), const bool inCoreOnly=false, const bool threaded=true)
Populate an array of cumulative point offsets per leaf node.
Definition: PointCountImpl.h:52
const Vec3T & max() const
Return a const reference to the maximum point of this bounding box.
Definition: BBox.h:64
The Value Accessor Implementation and API methods. The majoirty of the API matches the API of a compa...
Definition: ValueAccessor.h:68
const math::Transform & firstTransform() const
Definition: PointRasterizeFrustumImpl.h:1146
#define OPENVDB_THROW(exception, message)
Definition: Exceptions.h:74
void addPoints(GridConstPtr &points)
Append a PointDataGrid to the rasterizer (but don't rasterize yet).
Definition: PointRasterizeFrustumImpl.h:1280
FloatGrid::Ptr rasterizeDensity(const openvdb::Name &attribute, RasterMode mode=RasterMode::MAXIMUM, bool reduceMemory=false, float scale=1.0f, const FilterT &filter=FilterT())
Definition: PointRasterizeFrustumImpl.h:1340
Definition: PointRasterizeFrustum.h:112
void simplify()
Definition: PointRasterizeFrustumImpl.h:1089
uint64_t Index64
Definition: Types.h:53
typename PointDataGridT::ConstPtr GridConstPtr
Definition: PointRasterizeFrustum.h:168
const char * typeNameAsString< int32_t >()
Definition: Types.h:526
bool hasWeight(Index i) const
Definition: PointRasterizeFrustumImpl.h:1119
const char * typeNameAsString< int64_t >()
Definition: Types.h:528
size_t memUsage() const
Return memory usage of the rasterizer.
Definition: PointRasterizeFrustumImpl.h:1315
const Vec3T & min() const
Return a const reference to the minimum point of this bounding box.
Definition: BBox.h:62
RasterCamera camera
Definition: PointRasterizeFrustum.h:96
static Ptr create()
Return a new grid with background value zero.
Definition: Grid.h:1343
SharedPtr< const Tree > ConstPtr
Definition: Tree.h:198
math::BBox< Vec3d > BBoxd
Definition: Types.h:84
size_t size() const
Return number of PointDataGrids in the rasterizer.
Definition: PointRasterizeFrustumImpl.h:1308
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:406
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
bool isFinite(const float x)
Return true if x is finite.
Definition: Math.h:375
openvdb::GridBase::Ptr GridPtr
Definition: Utils.h:35
bool isStatic() const
Definition: PointRasterizeFrustumImpl.h:1067
Index32 Index
Definition: Types.h:54
Definition: AttributeSet.h:42
Vec3< double > Vec3d
Definition: Vec3.h:665
Base class for interrupters.
Definition: NullInterrupter.h:25
FrustumRasterizerMask()=default
GridT::Ptr rasterizeMask(bool reduceMemory=false, const FilterT &filter=FilterT())
Definition: PointRasterizeFrustumImpl.h:1440
SharedPtr< T > ConstPtrCast(const SharedPtr< U > &ptr)
Return a new shared pointer that points to the same object as the given pointer but with possibly dif...
Definition: Types.h:126
Definition: Exceptions.h:65
typename PointDataGridT::Ptr GridPtr
Definition: PointRasterizeFrustum.h:167
virtual void end()
Signal the end of an interruptible operation.
Definition: NullInterrupter.h:34
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition: Vec3.h:86
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:349
Vec2< float > Vec2s
Definition: Vec2.h:532
#define OPENVDB_ASSERT(X)
Definition: Assert.h:41
math::Transform::Ptr transform
Definition: PointRasterizeFrustum.h:95
MaskTree::ConstPtr getTreePtr() const
Definition: PointRasterizeFrustumImpl.h:1240
RasterMode
How to composite points into a volume.
Definition: PointRasterizeFrustum.h:30
bool threaded
Definition: PointRasterizeFrustum.h:102
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition: Mat.h:615
const math::Transform & transform(Index i) const
Definition: PointRasterizeFrustumImpl.h:1136
int Floor(float x)
Return the floor of x.
Definition: Math.h:848
OPENVDB_API void calculateBounds(const Transform &t, const Vec3d &minWS, const Vec3d &maxWS, Vec3d &minIS, Vec3d &maxIS)
Calculate an axis-aligned bounding box in index space from an axis-aligned bounding box in world spac...
SharedPtr< Grid > Ptr
Definition: Grid.h:573
void setShutter(float start, float end)
Definition: PointRasterizeFrustumImpl.h:1158
Definition: Exceptions.h:13
float weight(Index i) const
Definition: PointRasterizeFrustumImpl.h:1126
virtual void start(const char *name=nullptr)
Definition: NullInterrupter.h:32
void rasterize(const PointDataTreeOrGridT &points, TransferT &transfer, const FilterT &filter=NullFilter(), InterrupterT *interrupter=nullptr)
Perform potentially complex rasterization from a user defined transfer scheme.
Definition: PointTransfer.h:557
virtual bool wasInterrupted(int percent=-1)
Definition: NullInterrupter.h:39
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:856
const char * typeNameAsString< bool >()
Definition: Types.h:517
const char * typeNameAsString< float >()
Definition: Types.h:520
FloatGrid::Ptr rasterizeUniformDensity(RasterMode mode=RasterMode::MAXIMUM, bool reduceMemory=false, float scale=1.0f, const FilterT &filter=FilterT())
Definition: PointRasterizeFrustumImpl.h:1327
Efficient rasterization of one or more VDB Points grids into a linear or frustum volume with the opti...
Definition: PointRasterizeFrustum.h:164
void foreach(const LeafOp &op, bool threaded=true, size_t grainSize=1)
Threaded method that applies a user-supplied functor to each leaf node in the LeafManager.
Definition: LeafManager.h:484
void appendTransform(const math::Transform &, float weight=1.0f)
Definition: PointRasterizeFrustumImpl.h:1078
size_t size() const
Definition: PointRasterizeFrustumImpl.h:1084
Definition: Exceptions.h:64
This class manages a linear array of pointers to a given tree's leaf nodes, as well as optional auxil...
Definition: LeafManager.h:85
float shutterEnd() const
Definition: PointRasterizeFrustumImpl.h:1169
bool valid(const Coord &ijk, AccessorT *acc) const
Definition: PointRasterizeFrustumImpl.h:1252
const CoordBBox & clipBBox() const
Definition: PointRasterizeFrustumImpl.h:1246
Name velocityAttribute
Definition: PointRasterizeFrustum.h:106
std::string Name
Definition: Name.h:19
T length() const
Length of the vector.
Definition: Vec3.h:201
const char * typeNameAsString< int16_t >()
Definition: Types.h:524
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:819
float shutterStart() const
Definition: PointRasterizeFrustumImpl.h:1164
bool velocityMotionBlur
Definition: PointRasterizeFrustum.h:101
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
Vec3< int32_t > Vec3i
Definition: Vec3.h:662
const char * typeNameAsString< Vec3d >()
Definition: Types.h:536
T dot(const Vec3< T > &v) const
Dot product.
Definition: Vec3.h:192
const char * typeNameAsString< Vec3f >()
Definition: Types.h:535
Container class that associates a tree with a transform and metadata.
Definition: Grid.h:28
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:261
math::Vec3< Real > Vec3R
Definition: Types.h:72
Tree< typename RootNodeType::template ValueConverter< Int32 >::Type > Type
Definition: Tree.h:220
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition: ValueAccessor.h:480
typename T::ValueType ElementType
Definition: Types.h:302
A group of shared settings to be used in the Volume Rasterizer.
Definition: PointRasterizeFrustum.h:87
bool empty() const
Return true if this bounding box is empty, i.e., it has no (positive) volume.
Definition: BBox.h:196
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:218