9#ifndef OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_IMPL_HAS_BEEN_INCLUDED
10#define OPENVDB_POINTS_POINT_RASTERIZE_FRUSTUM_IMPL_HAS_BEEN_INCLUDED
19namespace point_rasterize_internal {
23template <
typename FilterT>
24struct RasterGroupTraits
26 using NewFilterT = FilterT;
27 static NewFilterT resolve(
const FilterT& filter,
const points::AttributeSet&)
35struct 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);
46template <
typename T>
struct BoolTraits {
static const bool IsBool =
false; };
47template <>
struct BoolTraits<
bool> {
static const bool IsBool =
true; };
48template <>
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); }
59template <
typename ValueT>
60typename std::enable_if<std::is_integral<typename ValueTraits<ValueT>::ElementType>::value, ValueT>::type
61castValue(
const double value)
63 return ValueT(math::Ceil(value));
67template <
typename ValueT>
68typename std::enable_if<!std::is_integral<typename ValueTraits<ValueT>::ElementType>::value, ValueT>::type
69castValue(
const double value)
71 return static_cast<ValueT
>(value);
75template <
typename ValueT>
76typename std::enable_if<!ValueTraits<ValueT>::IsVec,
bool>::type
77greaterThan(
const ValueT& value,
const float threshold)
79 return value >=
static_cast<ValueT
>(threshold);
83template <
typename ValueT>
84typename std::enable_if<ValueTraits<ValueT>::IsVec,
bool>::type
85greaterThan(
const ValueT& value,
const float threshold)
87 return static_cast<double>(value.lengthSqr()) >= threshold*threshold;
91template <
typename AttributeT,
typename HandleT,
typename Str
idedHandleT>
92typename std::enable_if<!ValueTraits<AttributeT>::IsVec, AttributeT>::type
93getAttributeScale(HandleT& handlePtr, StridedHandleT&, Index index)
96 return handlePtr->get(index);
102template <
typename AttributeT,
typename HandleT,
typename Str
idedHandleT>
103typename std::enable_if<ValueTraits<AttributeT>::IsVec, AttributeT>::type
104getAttributeScale(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);
118template <
typename ValueT>
121 template <
typename AttributeT>
122 static ValueT mul(
const ValueT& a,
const AttributeT& b)
129struct MultiplyOp<
bool>
131 template <
typename AttributeT>
132 static bool mul(
const bool& a,
const AttributeT& b)
134 return a && (b != zeroVal<AttributeT>());
138template <
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];
213 const int imin=math::Floor(position[0]-radius), imax=math::Ceil(position[0]+radius);
214 const int jmin=math::Floor(position[1]-radius), jmax=math::Ceil(position[1]+radius);
215 const int kmin=math::Floor(position[2]-radius), kmax=math::Ceil(position[2]+radius);
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;
221 const auto x2 = math::Pow2(i - position[0]);
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);
291 math::calculateBounds(frustum, inputBBoxWS.min(), inputBBoxWS.max(),
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;
482 using ElementT =
typename ValueTraits<AttributeT>::ElementType;
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;
798template<
typename Gr
idT>
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)));
844template<
typename Gr
idT>
845struct CombinableTraits {
846 using OpT = GridCombinerOp<GridT>;
847 using T =
typename OpT::CombinableT;
851template <
typename Po
intDataGr
idT>
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)
882 mLeafPercentage = math::Clamp(percentage, 0, 100);
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 &&
925 ((actualValueType == typeNameAsString<float>() &&
926 requestedValueType == typeNameAsString<Vec3f>()) ||
927 (actualValueType == typeNameAsString<double>() &&
928 requestedValueType == typeNameAsString<Vec3d>()) ||
929 (actualValueType == typeNameAsString<int32_t>() &&
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()) {
950 openvdb::points::pointOffsets(mLeafOffsets, mGrid->constTree(), resolvedFilter,
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;
1020template <
typename ValueT>
1021typename std::enable_if<!ValueTraits<ValueT>::IsVec, ValueT>::type
1022computeWeightedValue(
const ValueT& value,
const ValueT& weight)
1024 constexpr bool isSignedInt = std::is_integral<ValueT>() && std::is_signed<ValueT>();
1026 if (!math::isFinite(weight) || math::isApproxZero(weight) ||
1027 (isSignedInt && math::isNegative(weight))) {
1028 return zeroVal<ValueT>();
1030 return value / weight;
1035template <
typename ValueT>
1036typename std::enable_if<ValueTraits<ValueT>::IsVec, ValueT>::type
1037computeWeightedValue(
const ValueT& value,
const ValueT& weight)
1039 using ElementT =
typename ValueTraits<ValueT>::ElementType;
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) {
1045 if (!math::isFinite(weight[i]) || math::isApproxZero(weight[i]) ||
1046 (isSignedInt && math::isNegative(weight[i]))) {
1047 result[i] = zeroVal<ElementT>();
1049 result[i] = value[i] / weight[i];
1069 return mTransforms.size() <= 1;
1074 mTransforms.clear();
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++) {
1121 if (mWeights.empty())
return false;
1123 return !openvdb::math::isApproxEqual(mWeights[i], 1.0f, 1e-3f);
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());
1204 if (!bbox.
empty()) {
1206 MaskGrid::Ptr tempMask = MaskGrid::create();
1207 CoordBBox coordBBox(Coord::floor(bbox.min()),
1208 Coord::ceil(bbox.max()));
1209 tempMask->sparseFill(coordBBox, true, true);
1212 MaskGrid::Ptr bboxMask = MaskGrid::create();
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();
1234FrustumRasterizerMask::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;
1264template <
typename Po
intDataGr
idT>
1268 : mSettings(settings)
1270 , mInterrupter(interrupt)
1272 if (mSettings.velocityAttribute.empty() && mSettings.velocityMotionBlur) {
1273 OPENVDB_THROW(ValueError,
1274 "Using velocity motion blur during rasterization requires a velocity attribute.");
1278template <
typename Po
intDataGr
idT>
1283 if (!grid || grid->tree().empty())
return;
1286 mPointGrids.emplace_back(grid, mSettings, mMask);
1289template <
typename Po
intDataGr
idT>
1294 if (!grid || grid->tree().empty())
return;
1296 mPointGrids.emplace_back(grid, stream, mSettings, mMask);
1299template <
typename Po
intDataGr
idT>
1303 mPointGrids.clear();
1306template <
typename Po
intDataGr
idT>
1310 return mPointGrids.size();
1313template <
typename Po
intDataGr
idT>
1317 size_t mem =
sizeof(*this) +
sizeof(mPointGrids);
1318 for (
const auto& grid : mPointGrids) {
1319 mem += grid.memUsage();
1324template <
typename Po
intDataGr
idT>
1325template <
typename FilterT>
1328 RasterMode mode,
bool reduceMemory,
float scale,
const FilterT& filter)
1333 density->setName(
"density");
1337template <
typename Po
intDataGr
idT>
1338template <
typename FilterT>
1345 density->setName(
"density");
1349template <
typename Po
intDataGr
idT>
1350template <
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;
1381#ifndef ONLY_RASTER_FLOAT
1384 using GridT =
typename PointDataGridT::template ValueConverter<Vec3f>::Type;
1388 using GridT =
typename PointDataGridT::template ValueConverter<Vec3d>::Type;
1392 using GridT =
typename PointDataGridT::template ValueConverter<Vec3i>::Type;
1395 using GridT =
typename PointDataGridT::template ValueConverter<Int32>::Type;
1398 using GridT =
typename PointDataGridT::template ValueConverter<Int32>::Type;
1401 using GridT =
typename PointDataGridT::template ValueConverter<Int64>::Type;
1404 using GridT =
typename PointDataGridT::template ValueConverter<double>::Type;
1407 using GridT =
typename PointDataGridT::template ValueConverter<bool>::Type;
1411 std::ostringstream ostr;
1412 ostr <<
"Cannot rasterize attribute of type - " << sourceType;
1413 if (stride > 1) ostr <<
" x " << stride;
1418template <
typename Po
intDataGr
idT>
1419template <
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);
1437template <
typename Po
intDataGr
idT>
1438template <
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");
1453template <
typename Po
intDataGr
idT>
1454template <
typename AttributeT,
typename Gr
idT,
typename FilterT>
1456FrustumRasterizer<PointDataGridT>::performRasterization(
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 ";
1473 if (!mSettings.camera.isStatic() || mSettings.velocityMotionBlur) {
1474 ss <<
"with Motion Blur ";
1476 if (mSettings.transform->isLinear()) {
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) {
1535 attribute, combiner, weightCombinerPtr, scale, filter, mode ==
RasterMode::MAXIMUM, reduceMemory, mInterrupter);
1542 mInterrupter->wasInterrupted(points.leafPercentage())) {
1550 combiner.combine_each(combineOp);
1556 auto weightGrid = GridT::create(ValueT(1));
1557 CombinerOpT weightCombineOp(*weightGrid,
true);
1558 weightCombiner.combine_each(weightCombineOp);
1560 tree::LeafManager<TreeT> leafManager(grid.tree());
1561 leafManager.foreach(
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));
1569 mSettings.threaded);
1572 if (mInterrupter) mInterrupter->end();
#define OPENVDB_ASSERT(X)
Definition Assert.h:41
static Coord ceil(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz+1 (node centered conversion).
Definition Coord.h:64
static Coord floor(const Vec3< T > &xyz)
Return the largest integer coordinates that are not greater than xyz (node centered conversion).
Definition Coord.h:57
SharedPtr< GridBase > Ptr
Definition Grid.h:80
SharedPtr< Grid > Ptr
Definition Grid.h:573
Definition Exceptions.h:64
Definition Exceptions.h:65
bool empty() const
Return true if this bounding box is empty, i.e., it has no (positive) volume.
Definition BBox.h:196
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
T & x()
Reference to the component, e.g. v.x() = 4.5f;.
Definition Vec3.h:86
T length() const
Length of the vector.
Definition Vec3.h:201
T dot(const Vec3< T > &v) const
Dot product.
Definition Vec3.h:192
@ INVALID_POS
Definition AttributeSet.h:42
typename PointDataGridT::ConstPtr GridConstPtr
Definition PointRasterizeFrustum.h:168
size_t memUsage() const
Return memory usage of the rasterizer.
Definition PointRasterizeFrustumImpl.h:1315
size_t size() const
Return number of PointDataGrids in the rasterizer.
Definition PointRasterizeFrustumImpl.h:1308
FrustumRasterizer(const FrustumRasterizerSettings &settings, const FrustumRasterizerMask &mask=FrustumRasterizerMask(), util::NullInterrupter *interrupt=nullptr)
main constructor
Definition PointRasterizeFrustumImpl.h:1265
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
void addPoints(GridConstPtr &points)
Append a PointDataGrid to the rasterizer (but don't rasterize yet).
Definition PointRasterizeFrustumImpl.h:1280
GridT::Ptr rasterizeMask(bool reduceMemory=false, const FilterT &filter=FilterT())
Definition PointRasterizeFrustumImpl.h:1440
typename PointDataGridT::Ptr GridPtr
Definition PointRasterizeFrustum.h:167
void clear()
Clear all PointDataGrids in the rasterizer.
Definition PointRasterizeFrustumImpl.h:1301
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
FloatGrid::Ptr rasterizeUniformDensity(RasterMode mode=RasterMode::MAXIMUM, bool reduceMemory=false, float scale=1.0f, const FilterT &filter=FilterT())
Definition PointRasterizeFrustumImpl.h:1327
float weight(Index i) const
Definition PointRasterizeFrustumImpl.h:1126
void simplify()
Definition PointRasterizeFrustumImpl.h:1089
const math::Transform & transform(Index i) const
Definition PointRasterizeFrustumImpl.h:1136
size_t size() const
Definition PointRasterizeFrustumImpl.h:1084
const math::Transform & firstTransform() const
Definition PointRasterizeFrustumImpl.h:1146
bool isStatic() const
Definition PointRasterizeFrustumImpl.h:1067
void setShutter(float start, float end)
Definition PointRasterizeFrustumImpl.h:1158
void appendTransform(const math::Transform &, float weight=1.0f)
Definition PointRasterizeFrustumImpl.h:1078
float shutterEnd() const
Definition PointRasterizeFrustumImpl.h:1169
bool hasWeight(Index i) const
Definition PointRasterizeFrustumImpl.h:1119
RasterCamera(const math::Transform &transform)
Definition PointRasterizeFrustumImpl.h:1063
void clear()
Definition PointRasterizeFrustumImpl.h:1072
const math::Transform & lastTransform() const
Definition PointRasterizeFrustumImpl.h:1152
float shutterStart() const
Definition PointRasterizeFrustumImpl.h:1164
SharedPtr< const Tree > ConstPtr
Definition Tree.h:198
bool isValueOn(const Coord &xyz) const
Return the active state of the voxel at the given coordinates.
Definition ValueAccessor.h:480
Vec2< float > Vec2s
Definition Vec2.h:532
MatType scale(const Vec3< typename MatType::value_type > &s)
Return a matrix that scales by s.
Definition Mat.h:615
Vec3< double > Vec3d
Definition Vec3.h:665
float Round(float x)
Return x rounded to the nearest integer.
Definition Math.h:819
Vec3< int32_t > Vec3i
Definition Vec3.h:662
Definition AttributeArray.h:42
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
RasterMode
How to composite points into a volume.
Definition PointRasterizeFrustum.h:31
@ MAXIMUM
Definition PointRasterizeFrustum.h:33
@ AVERAGE
Definition PointRasterizeFrustum.h:34
@ ACCUMULATE
Definition PointRasterizeFrustum.h:32
ValueAccessorImpl< TreeType, IsSafe, MutexType, openvdb::make_index_sequence< CacheLevels > > ValueAccessor
Default alias for a ValueAccessor. This is simply a helper alias for the generic definition but takes...
Definition ValueAccessor.h:86
std::string Name
Definition Name.h:19
Index32 Index
Definition Types.h:54
math::Vec3< float > Vec3f
Definition Types.h:74
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
math::BBox< Vec3d > BBoxd
Definition Types.h:84
Grid< MaskTree > MaskGrid
Definition openvdb.h:78
math::Vec3< Real > Vec3R
Definition Types.h:72
uint64_t Index64
Definition Types.h:53
const char * typeNameAsString()
Definition Types.h:516
openvdb::GridBase::Ptr GridPtr
Definition Utils.h:35
Definition Exceptions.h:13
#define OPENVDB_THROW(exception, message)
Definition Exceptions.h:74
static const bool IsVec
Definition Types.h:245
Definition PointRasterizeFrustum.h:113
FrustumRasterizerMask()=default
bool valid(const Coord &ijk, AccessorT *acc) const
Definition PointRasterizeFrustumImpl.h:1252
MaskTree::ConstPtr getTreePtr() const
Definition PointRasterizeFrustumImpl.h:1240
const CoordBBox & clipBBox() const
Definition PointRasterizeFrustumImpl.h:1246
A group of shared settings to be used in the Volume Rasterizer.
Definition PointRasterizeFrustum.h:88
Base class for interrupters.
Definition NullInterrupter.h:26
#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