Loading...
Searching...
No Matches
GU_VDBPointTools.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
//
/// @file GU_VDBPointTools.h
/// @author FX R&D OpenVDB team
///
/// @brief Collection of PointIndexGrid helpers for Houdini
#ifndef GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED
#define GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED
#if defined(SESI_OPENVDB)
#include "GU_Detail.h"
#include "GU_DetailHandle.h"
#include "GU_PackedContext.h"
#include "GU_PackedFragment.h"
#include "GU_PackedGeometry.h"
#include "GU_PrimPacked.h"
#else
#include <GU/GU_Detail.h>
#include <GU/GU_DetailHandle.h>
#include <GU/GU_PackedContext.h>
#include <GU/GU_PackedFragment.h>
#include <GU/GU_PackedGeometry.h>
#include <GU/GU_PrimPacked.h>
#endif
#include <GA/GA_ElementGroup.h>
#include <UT/UT_SharedPtr.h>
#include <UT/UT_VectorTypes.h>
#include <openvdb/Platform.h>
#include <openvdb/tools/PointIndexGrid.h>
#include <openvdb/tools/ParticleAtlas.h>
#include <openvdb/tools/PointsToMask.h>
#include <vector>
/// @brief Houdini point attribute wrapper
template<typename VectorType>
struct GU_VDBPointList
{
using Ptr = UT_SharedPtr<GU_VDBPointList>;
using ConstPtr = UT_SharedPtr<const GU_VDBPointList>;
using PosType = VectorType;
using ScalarType = typename PosType::value_type;
GU_VDBPointList(const GU_Detail& detail, const GA_PointGroup* group = nullptr)
: mPositionHandle(detail.getP())
, mVelocityHandle()
, mRadiusHandle()
, mIndexMap(&detail.getP()->getIndexMap())
, mOffsets()
, mSize(mIndexMap->indexSize())
{
if (group) {
mSize = group->entries();
mOffsets.reserve(mSize);
GA_Offset start, end;
GA_Range range(*group);
for (GA_Iterator it = range.begin(); it.blockAdvance(start, end); ) {
for (GA_Offset off = start; off < end; ++off) {
mOffsets.push_back(off);
}
}
getOffset = &GU_VDBPointList::offsetFromGroupMap;
} else if (mIndexMap->isTrivialMap()) {
getOffset = &GU_VDBPointList::offsetFromIndexCast;
} else {
getOffset = &GU_VDBPointList::offsetFromGeoMap;
}
// Bind optional attributes
GA_ROAttributeRef velRef = detail.findFloatTuple(GA_ATTRIB_POINT, GEO_STD_ATTRIB_VELOCITY, 3);
if (velRef.isValid()) {
mVelocityHandle.bind(velRef.getAttribute());
}
GA_ROAttributeRef radRef = detail.findFloatTuple(GA_ATTRIB_POINT, GEO_STD_ATTRIB_PSCALE);
if (radRef.isValid()) {
mRadiusHandle.bind(radRef.getAttribute());
}
}
static Ptr create(const GU_Detail& detail, const GA_PointGroup* group = nullptr)
{
return Ptr(new GU_VDBPointList(detail, group));
}
size_t size() const { return mSize; }
bool hasVelocity() const { return mVelocityHandle.isValid(); }
bool hasRadius() const { return mRadiusHandle.isValid(); }
// Index access methods
void getPos(size_t n, PosType& xyz) const {
getPosFromOffset((this->*getOffset)(n), xyz);
}
void getVelocity(size_t n, PosType& v) const {
getVelocityFromOffset((this->*getOffset)(n), v);
}
void getRadius(size_t n, ScalarType& r) const {
getRadiusFromOffset((this->*getOffset)(n), r);
}
// Offset access methods
GA_Offset offsetFromIndex(size_t n) const {
return (this->*getOffset)(n);
}
void getPosFromOffset(const GA_Offset offset, PosType& xyz) const {
const UT_Vector3 data = mPositionHandle.get(offset);
xyz[0] = ScalarType(data[0]);
xyz[1] = ScalarType(data[1]);
xyz[2] = ScalarType(data[2]);
}
void getVelocityFromOffset(const GA_Offset offset, PosType& v) const {
const UT_Vector3 data = mVelocityHandle.get(offset);
v[0] = ScalarType(data[0]);
v[1] = ScalarType(data[1]);
v[2] = ScalarType(data[2]);
}
void getRadiusFromOffset(const GA_Offset offset, ScalarType& r) const {
r = ScalarType(mRadiusHandle.get(offset));
}
private:
// Disallow copying
GU_VDBPointList(const GU_VDBPointList&);
GU_VDBPointList& operator=(const GU_VDBPointList&);
GA_Offset (GU_VDBPointList::* getOffset)(const size_t) const;
GA_Offset offsetFromGeoMap(const size_t n) const {
return mIndexMap->offsetFromIndex(GA_Index(n));
}
GA_Offset offsetFromGroupMap(const size_t n) const {
return mOffsets[n];
}
GA_Offset offsetFromIndexCast(const size_t n) const {
return GA_Offset(n);
}
GA_ROHandleV3 mPositionHandle, mVelocityHandle;
GA_ROHandleF mRadiusHandle;
GA_IndexMap const * const mIndexMap;
std::vector<GA_Offset> mOffsets;
size_t mSize;
}; // GU_VDBPointList
////////////////////////////////////////
// PointIndexGrid utility methods
namespace GU_VDBPointToolsInternal {
template<typename PointArrayType>
struct IndexToOffsetOp {
IndexToOffsetOp(const PointArrayType& points): mPointList(&points) {}
template <typename LeafT>
void operator()(LeafT &leaf, size_t /*leafIndex*/) const {
typename LeafT::IndexArray& indices = leaf.indices();
for (size_t n = 0, N = indices.size(); n < N; ++n) {
indices[n] = static_cast<typename LeafT::ValueType::IntType>(
mPointList->offsetFromIndex(GA_Index{indices[n]}));
}
}
PointArrayType const * const mPointList;
};
struct PackedMaskConstructor
{
PackedMaskConstructor(const std::vector<const GA_Primitive*>& prims,
const openvdb::math::Transform& xform)
: mPrims(prims.empty() ? nullptr : &prims.front())
, mXForm(xform)
, mMaskGrid(new openvdb::MaskGrid(false))
{
mMaskGrid->setTransform(mXForm.copy());
}
PackedMaskConstructor(PackedMaskConstructor& rhs, tbb::split)
: mPrims(rhs.mPrims)
, mXForm(rhs.mXForm)
, mMaskGrid(new openvdb::MaskGrid(false))
{
mMaskGrid->setTransform(mXForm.copy());
}
openvdb::MaskGrid::Ptr getMaskGrid() { return mMaskGrid; }
void join(PackedMaskConstructor& rhs) { mMaskGrid->tree().topologyUnion(rhs.mMaskGrid->tree()); }
void operator()(const tbb::blocked_range<size_t>& range)
{
GU_PackedContext packedcontext;
for (size_t n = range.begin(), N = range.end(); n < N; ++n) {
const GA_Primitive *prim = mPrims[n];
if (!prim || !GU_PrimPacked::isPackedPrimitive(*prim)) continue;
const GU_PrimPacked * pprim = static_cast<const GU_PrimPacked*>(prim);
GU_Detail tmpdetail;
const GU_Detail *detailtouse;
GU_DetailHandleAutoReadLock readlock(pprim->getPackedDetail(packedcontext));
UT_Matrix4D mat;
pprim->getFullTransform4(mat);
if (mat.isIdentity() && readlock.isValid() && readlock.getGdp()) {
detailtouse = readlock.getGdp();
} else {
pprim->unpackWithContext(tmpdetail, packedcontext);
detailtouse = &tmpdetail;
}
GU_VDBPointList<openvdb::Vec3R> points(*detailtouse);
openvdb::MaskGrid::Ptr grid = openvdb::tools::createPointMask(points, mXForm);
mMaskGrid->tree().topologyUnion(grid->tree());
}
}
private:
GA_Primitive const * const * const mPrims;
openvdb::math::Transform mXForm;
openvdb::MaskGrid::Ptr mMaskGrid;
}; // struct PackedMaskConstructor
inline void
getPackedPrimitiveOffsets(const GU_Detail& detail, std::vector<const GA_Primitive*>& primitives)
{
const GA_Size numPacked = GU_PrimPacked::countPackedPrimitives(detail);
primitives.clear();
primitives.reserve(size_t(numPacked));
if (numPacked != GA_Size(0)) {
GA_Offset start, end;
GA_Range range = detail.getPrimitiveRange();
const GA_PrimitiveList& primList = detail.getPrimitiveList();
for (GA_Iterator it = range.begin(); it.blockAdvance(start, end); ) {
for (GA_Offset off = start; off < end; ++off) {
const GA_Primitive *prim = primList.get(off);
if (prim && GU_PrimPacked::isPackedPrimitive(*prim)) {
primitives.push_back(prim);
}
}
}
}
}
} // namespace GU_VDBPointToolsInternal
////////////////////////////////////////
/// @brief Utility method to construct a GU_VDBPointList.
/// @details The GU_VDBPointList is compatible with the PointIndexGrid and ParticleAtals structures.
inline GU_VDBPointList<openvdb::Vec3s>::Ptr
GUvdbCreatePointList(const GU_Detail& detail, const GA_PointGroup* pointGroup = nullptr)
{
return GU_VDBPointList<openvdb::Vec3s>::create(detail, pointGroup);
}
/// @brief Utility method to change point indices into Houdini geometry offsets.
/// @note PointIndexGrid's that store Houdini geometry offsets are not
/// safe to write to disk, offsets are not guaranteed to be immutable
/// under defragmentation operations or I/O.
template<typename PointIndexTreeType, typename PointArrayType>
inline void
GUvdbConvertIndexToOffset(PointIndexTreeType& tree, const PointArrayType& points)
{
openvdb::tree::LeafManager<PointIndexTreeType> leafnodes(tree);
leafnodes.foreach(GU_VDBPointToolsInternal::IndexToOffsetOp<PointArrayType>(points));
}
/// @brief Utility method to construct a PointIndexGrid.
/// @details The PointIndexGrid supports fast spatial queries for points.
inline openvdb::tools::PointIndexGrid::Ptr
GUvdbCreatePointIndexGrid(
const openvdb::math::Transform& xform,
const GU_Detail& detail,
const GA_PointGroup* pointGroup = nullptr)
{
GU_VDBPointList<openvdb::Vec3s> points(detail, pointGroup);
return openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
}
/// @brief Utility method to construct a PointIndexGrid.
/// @details The PointIndexGrid supports fast spatial queries for points.
template<typename PointArrayType>
inline openvdb::tools::PointIndexGrid::Ptr
GUvdbCreatePointIndexGrid(const openvdb::math::Transform& xform, const PointArrayType& points)
{
return openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
}
/// @brief Utility method to construct a ParticleAtals.
/// @details The ParticleAtals supports fast spatial queries for particles.
template<typename ParticleArrayType>
inline openvdb::tools::ParticleIndexAtlas::Ptr
GUvdbCreateParticleAtlas(const double minVoxelSize, const ParticleArrayType& particles)
{
using ParticleIndexAtlas = openvdb::tools::ParticleIndexAtlas;
ParticleIndexAtlas::Ptr atlas(new ParticleIndexAtlas());
if (particles.hasRadius()) {
atlas->construct(particles, minVoxelSize);
}
return atlas;
}
/// @brief Utility method to construct a boolean PointMaskGrid
/// @details This method supports packed points.
inline openvdb::MaskGrid::Ptr
GUvdbCreatePointMaskGrid(
const openvdb::math::Transform& xform,
const GU_Detail& detail,
const GA_PointGroup* pointGroup = nullptr)
{
std::vector<const GA_Primitive*> packed;
GU_VDBPointToolsInternal::getPackedPrimitiveOffsets(detail, packed);
if (!packed.empty()) {
GU_VDBPointToolsInternal::PackedMaskConstructor op(packed, xform);
tbb::parallel_reduce(tbb::blocked_range<size_t>(0, packed.size()), op);
return op.getMaskGrid();
}
GU_VDBPointList<openvdb::Vec3R> points(detail, pointGroup);
return openvdb::tools::createPointMask(points, xform);
}
/// @brief Utility method to construct a PointIndexGrid that stores
/// Houdini geometry offsets.
///
/// @note PointIndexGrid's that store Houdini geometry offsets are not
/// safe to write to disk, offsets are not guaranteed to be immutable
/// under defragmentation operations or I/O.
inline openvdb::tools::PointIndexGrid::Ptr
GUvdbCreatePointOffsetGrid(
const openvdb::math::Transform& xform,
const GU_Detail& detail,
const GA_PointGroup* pointGroup = nullptr)
{
GU_VDBPointList<openvdb::Vec3s> points(detail, pointGroup);
openvdb::tools::PointIndexGrid::Ptr grid =
openvdb::tools::createPointIndexGrid<openvdb::tools::PointIndexGrid>(points, xform);
GUvdbConvertIndexToOffset(grid->tree(), points);
return grid;
}
#endif // GU_VDBPOINTTOOLS_H_HAS_BEEN_INCLUDED
GUvdbCreatePointList
GU_VDBPointList< openvdb::Vec3s >::Ptr GUvdbCreatePointList(const GU_Detail &detail, const GA_PointGroup *pointGroup=nullptr)
Utility method to construct a GU_VDBPointList.
Definition GU_VDBPointTools.h:283
GUvdbCreatePointIndexGrid
openvdb::tools::PointIndexGrid::Ptr GUvdbCreatePointIndexGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=nullptr)
Utility method to construct a PointIndexGrid.
Definition GU_VDBPointTools.h:305
GUvdbCreatePointMaskGrid
openvdb::MaskGrid::Ptr GUvdbCreatePointMaskGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=nullptr)
Utility method to construct a boolean PointMaskGrid.
Definition GU_VDBPointTools.h:345
GUvdbCreatePointOffsetGrid
openvdb::tools::PointIndexGrid::Ptr GUvdbCreatePointOffsetGrid(const openvdb::math::Transform &xform, const GU_Detail &detail, const GA_PointGroup *pointGroup=nullptr)
Utility method to construct a PointIndexGrid that stores Houdini geometry offsets.
Definition GU_VDBPointTools.h:371
GUvdbConvertIndexToOffset
void GUvdbConvertIndexToOffset(PointIndexTreeType &tree, const PointArrayType &points)
Utility method to change point indices into Houdini geometry offsets.
Definition GU_VDBPointTools.h:295
GUvdbCreateParticleAtlas
openvdb::tools::ParticleIndexAtlas::Ptr GUvdbCreateParticleAtlas(const double minVoxelSize, const ParticleArrayType &particles)
Utility method to construct a ParticleAtals.
Definition GU_VDBPointTools.h:329
ParticleAtlas.h
Space-partitioning acceleration structure for particles, points with radius. Partitions particle indi...
Platform.h
PointIndexGrid.h
Space-partitioning acceleration structure for points. Partitions the points into voxels to accelerate...
PointsToMask.h
This tool produces a grid where every voxel that contains a point is active. It employs thread-local ...
openvdb::v10_0::Grid< MaskTree >::Ptr
SharedPtr< Grid > Ptr
Definition Grid.h:573
GU_VDBPointToolsInternal
Definition GU_VDBPointTools.h:170
GU_VDBPointToolsInternal::getPackedPrimitiveOffsets
void getPackedPrimitiveOffsets(const GU_Detail &detail, std::vector< const GA_Primitive * > &primitives)
Definition GU_VDBPointTools.h:249
detail
Definition VoxToNanoVDB.h:14
openvdb
Definition Exceptions.h:13
GU_VDBPointList
Houdini point attribute wrapper.
Definition GU_VDBPointTools.h:42
GU_VDBPointList::offsetFromIndex
GA_Offset offsetFromIndex(size_t n) const
Definition GU_VDBPointTools.h:115
GU_VDBPointList::size
size_t size() const
Definition GU_VDBPointTools.h:94
GU_VDBPointList::getVelocityFromOffset
void getVelocityFromOffset(const GA_Offset offset, PosType &v) const
Definition GU_VDBPointTools.h:126
GU_VDBPointList::hasRadius
bool hasRadius() const
Definition GU_VDBPointTools.h:97
GU_VDBPointList::PosType
VectorType PosType
Definition GU_VDBPointTools.h:46
GU_VDBPointList::getPos
void getPos(size_t n, PosType &xyz) const
Definition GU_VDBPointTools.h:101
GU_VDBPointList::getPosFromOffset
void getPosFromOffset(const GA_Offset offset, PosType &xyz) const
Definition GU_VDBPointTools.h:119
GU_VDBPointList::ScalarType
typename PosType::value_type ScalarType
Definition GU_VDBPointTools.h:47
GU_VDBPointList::GU_VDBPointList
GU_VDBPointList(const GU_Detail &detail, const GA_PointGroup *group=nullptr)
Definition GU_VDBPointTools.h:49
GU_VDBPointList::create
static Ptr create(const GU_Detail &detail, const GA_PointGroup *group=nullptr)
Definition GU_VDBPointTools.h:89
GU_VDBPointList::hasVelocity
bool hasVelocity() const
Definition GU_VDBPointTools.h:96
GU_VDBPointList::ConstPtr
UT_SharedPtr< const GU_VDBPointList > ConstPtr
Definition GU_VDBPointTools.h:44
GU_VDBPointList::getRadius
void getRadius(size_t n, ScalarType &r) const
Definition GU_VDBPointTools.h:109
GU_VDBPointList::getVelocity
void getVelocity(size_t n, PosType &v) const
Definition GU_VDBPointTools.h:105
GU_VDBPointList::getRadiusFromOffset
void getRadiusFromOffset(const GA_Offset offset, ScalarType &r) const
Definition GU_VDBPointTools.h:133
GU_VDBPointList::Ptr
UT_SharedPtr< GU_VDBPointList > Ptr
Definition GU_VDBPointTools.h:43
GU_VDBPointToolsInternal::IndexToOffsetOp
Definition GU_VDBPointTools.h:173
GU_VDBPointToolsInternal::IndexToOffsetOp::mPointList
PointArrayType const *const mPointList
Definition GU_VDBPointTools.h:184
GU_VDBPointToolsInternal::IndexToOffsetOp::IndexToOffsetOp
IndexToOffsetOp(const PointArrayType &points)
Definition GU_VDBPointTools.h:174
GU_VDBPointToolsInternal::IndexToOffsetOp::operator()
void operator()(LeafT &leaf, size_t) const
Definition GU_VDBPointTools.h:177
GU_VDBPointToolsInternal::PackedMaskConstructor
Definition GU_VDBPointTools.h:189
GU_VDBPointToolsInternal::PackedMaskConstructor::operator()
void operator()(const tbb::blocked_range< size_t > &range)
Definition GU_VDBPointTools.h:211
GU_VDBPointToolsInternal::PackedMaskConstructor::PackedMaskConstructor
PackedMaskConstructor(const std::vector< const GA_Primitive * > &prims, const openvdb::math::Transform &xform)
Definition GU_VDBPointTools.h:190
GU_VDBPointToolsInternal::PackedMaskConstructor::PackedMaskConstructor
PackedMaskConstructor(PackedMaskConstructor &rhs, tbb::split)
Definition GU_VDBPointTools.h:199
GU_VDBPointToolsInternal::PackedMaskConstructor::join
void join(PackedMaskConstructor &rhs)
Definition GU_VDBPointTools.h:209
GU_VDBPointToolsInternal::PackedMaskConstructor::getMaskGrid
openvdb::MaskGrid::Ptr getMaskGrid()
Definition GU_VDBPointTools.h:207