Loading...
Searching...
No Matches
PointsToMask.h
Go to the documentation of this file.
// Copyright Contributors to the OpenVDB Project
// SPDX-License-Identifier: MPL-2.0
/// @author Ken Museth
///
/// @file tools/PointsToMask.h
///
/// @brief This tool produces a grid where every voxel that contains a
/// point is active. It employs thread-local storage for best performance.
///
/// The @c PointListT template argument below refers to any class
/// with the following interface (see unittest/TestPointsToMask.cc
/// and SOP_OpenVDB_From_Particles.cc for practical examples):
/// @code
///
/// class PointList {
/// ...
/// public:
///
/// // Return the total number of particles in list.
/// size_t size() const;
///
/// // Get the world space position of the nth particle.
/// void getPos(size_t n, Vec3R& xyz) const;
/// };
/// @endcode
///
/// @note See unittest/TestPointsToMask.cc for an example.
///
/// The @c InterruptT template argument below refers to any class
/// with the following interface:
/// @code
/// class Interrupter {
/// ...
/// public:
/// void start(const char* name = nullptr) // called when computations begin
/// void end() // called when computations end
/// bool wasInterrupted(int percent = -1) // return true to break computation
/// };
/// @endcode
///
/// @note If no template argument is provided for this InterruptT
/// the util::NullInterrupter is used which implies that all
/// interrupter calls are no-ops (i.e. incurs no computational overhead).
#ifndef OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
#define OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
#include <openvdb/openvdb.h> // for MaskGrid
#include <openvdb/Grid.h>
#include <openvdb/Types.h>
#include <openvdb/util/NullInterrupter.h>
#include <openvdb/thread/Threading.h>
#include <tbb/enumerable_thread_specific.h>
#include <tbb/parallel_for.h>
#include <tbb/parallel_reduce.h>
#include <tbb/blocked_range.h>
#include <vector>
namespace openvdb {
OPENVDB_USE_VERSION_NAMESPACE
namespace OPENVDB_VERSION_NAME {
namespace tools {
// Forward declaration of main class
template<typename GridT = MaskGrid, typename InterrupterT = util::NullInterrupter>
class PointsToMask;
/// @brief Makes every voxel of the @c grid active if it contains a point.
///
/// @param points points that active the voxels of @c grid
/// @param grid on out its voxels with points are active
template<typename PointListT, typename GridT>
inline void
maskPoints(const PointListT& points, GridT& grid)
{
PointsToMask<GridT, util::NullInterrupter> tmp(grid, nullptr);
tmp.addPoints(points);
}
/// @brief Return a MaskGrid where each binary voxel value
/// is on if the voxel contains one (or more) points (i.e.
/// the 3D position of a point is closer to this voxel than
/// any other voxels).
///
/// @param points points that active the voxels in the returned grid.
/// @param xform transform from world space to voxels in grid space.
template<typename PointListT>
inline MaskGrid::Ptr
createPointMask(const PointListT& points, const math::Transform& xform)
{
MaskGrid::Ptr grid = createGrid<MaskGrid>( false );
grid->setTransform( xform.copy() );
maskPoints( points, *grid );
return grid;
}
////////////////////////////////////////
/// @brief Makes every voxel of a grid active if it contains a point.
template<typename GridT, typename InterrupterT>
class PointsToMask
{
public:
using ValueT = typename GridT::ValueType;
/// @brief Constructor from a grid and optional interrupter
///
/// @param grid Grid whose voxels will have their state activated by points.
/// @param interrupter Optional interrupter to prematurely terminate execution.
explicit PointsToMask(GridT& grid, InterrupterT* interrupter = nullptr)
: mGrid(&grid)
, mInterrupter(interrupter)
{
}
/// @brief Activates the state of any voxel in the input grid that contains a point.
///
/// @param points List of points that active the voxels in the input grid.
/// @param grainSize Set the grain-size used for multi-threading. A value of 0
/// disables multi-threading!
template<typename PointListT, typename VecT = Vec3R>
void addPoints(const PointListT& points, size_t grainSize = 1024)
{
if (mInterrupter) mInterrupter->start("PointsToMask: adding points");
if (grainSize > 0) {
typename GridT::Ptr examplar = mGrid->copyWithNewTree();
PoolType pool( *examplar );//thread local storage pool of grids
AddPoints<PointListT, VecT> tmp(points, pool, grainSize, *this );
if ( this->interrupt() ) return;
ReducePool reducePool(pool, mGrid, size_t(0));
} else {
const math::Transform& xform = mGrid->transform();
typename GridT::Accessor acc = mGrid->getAccessor();
VecT wPos;
for (size_t i = 0, n = points.size(); i < n; ++i) {
if ( this->interrupt() ) break;
points.getPos(i, wPos);
acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
}
}
if (mInterrupter) mInterrupter->end();
}
private:
// Disallow copy construction and copy by assignment!
PointsToMask(const PointsToMask&);// not implemented
PointsToMask& operator=(const PointsToMask&);// not implemented
bool interrupt() const
{
if (mInterrupter && util::wasInterrupted(mInterrupter)) {
thread::cancelGroupExecution();
return true;
}
return false;
}
// Private struct that implements concurrent thread-local
// insersion of points into a grid
using PoolType = tbb::enumerable_thread_specific<GridT>;
template<typename PointListT, typename VecT = Vec3R> struct AddPoints;
// Private class that implements concurrent reduction of a thread-local pool
struct ReducePool;
GridT* mGrid;
InterrupterT* mInterrupter;
};// PointsToMask
// Private member class that implements concurrent thread-local
// insersion of points into a grid
template<typename GridT, typename InterrupterT>
template<typename PointListT, typename VecT>
struct PointsToMask<GridT, InterrupterT>::AddPoints
{
AddPoints(const PointListT& points,
PoolType& pool,
size_t grainSize,
const PointsToMask& parent)
: mPoints(&points)
, mParent(&parent)
, mPool(&pool)
{
tbb::parallel_for(tbb::blocked_range<size_t>(0, mPoints->size(), grainSize), *this);
}
void operator()(const tbb::blocked_range<size_t>& range) const
{
if (mParent->interrupt()) return;
GridT& grid = mPool->local();
const math::Transform& xform = grid.transform();
typename GridT::Accessor acc = grid.getAccessor();
VecT wPos;
for (size_t i=range.begin(), n=range.end(); i!=n; ++i) {
mPoints->getPos(i, wPos);
acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
}
}
const PointListT* mPoints;
const PointsToMask* mParent;
PoolType* mPool;
};// end of private member class AddPoints
// Private member class that implements concurrent reduction of a thread-local pool
template<typename GridT, typename InterrupterT>
struct PointsToMask<GridT, InterrupterT>::ReducePool
{
using VecT = std::vector<GridT*>;
using IterT = typename VecT::iterator;
using RangeT = tbb::blocked_range<IterT>;
ReducePool(PoolType& pool, GridT* grid, size_t grainSize = 1)
: mOwnsGrid(false)
, mGrid(grid)
{
if (grainSize == 0) {
for (typename PoolType::const_iterator i = pool.begin(); i != pool.end(); ++i) {
mGrid->topologyUnion(*i);
}
} else {
VecT grids( pool.size() );
typename PoolType::iterator i = pool.begin();
for (size_t j=0; j != pool.size(); ++i, ++j) grids[j] = &(*i);
tbb::parallel_reduce( RangeT( grids.begin(), grids.end(), grainSize ), *this );
}
}
ReducePool(const ReducePool&, tbb::split)
: mOwnsGrid(true)
, mGrid(new GridT())
{
}
~ReducePool() { if (mOwnsGrid) delete mGrid; }
void operator()(const RangeT& r)
{
for (IterT i=r.begin(); i!=r.end(); ++i) mGrid->topologyUnion( *(*i) );
}
void join(ReducePool& other) { mGrid->topologyUnion(*other.mGrid); }
const bool mOwnsGrid;
GridT* mGrid;
};// end of private member class ReducePool
} // namespace tools
} // namespace OPENVDB_VERSION_NAME
} // namespace openvdb
#endif // OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
Grid.h
NullInterrupter.h
openvdb::v10_0::Grid< MaskTree >::Ptr
SharedPtr< Grid > Ptr
Definition Grid.h:573
openvdb::v10_0::math::Transform
Definition Transform.h:40
openvdb::v10_0::math::Transform::worldToIndexCellCentered
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Definition Transform.h:111
openvdb::v10_0::math::Transform::copy
Ptr copy() const
Definition Transform.h:50
openvdb::v10_0::tools::PointsToMask
Makes every voxel of a grid active if it contains a point.
Definition PointsToMask.h:107
openvdb::v10_0::tools::PointsToMask::addPoints
void addPoints(const PointListT &points, size_t grainSize=1024)
Activates the state of any voxel in the input grid that contains a point.
Definition PointsToMask.h:127
openvdb::v10_0::tools::PointsToMask::ValueT
typename GridT::ValueType ValueT
Definition PointsToMask.h:109
openvdb::v10_0::tools::PointsToMask::PointsToMask
PointsToMask(GridT &grid, InterrupterT *interrupter=nullptr)
Constructor from a grid and optional interrupter.
Definition PointsToMask.h:115
openvdb::v10_0::points
Definition AttributeArray.h:41
openvdb::v10_0::tools::maskPoints
void maskPoints(const PointListT &points, GridT &grid)
Makes every voxel of the grid active if it contains a point.
Definition PointsToMask.h:79
openvdb::v10_0::tools::createPointMask
MaskGrid::Ptr createPointMask(const PointListT &points, const math::Transform &xform)
Return a MaskGrid where each binary voxel value is on if the voxel contains one (or more) points (i....
Definition PointsToMask.h:94
openvdb::v10_0::util::wasInterrupted
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
openvdb::v10_0::createGrid
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition Grid.h:1722
openvdb
Definition Exceptions.h:13
Types.h
openvdb.h
openvdb::v10_0::tools::PointsToMask::ReducePool
Definition PointsToMask.h:212
openvdb::v10_0::tools::PointsToMask::ReducePool::~ReducePool
~ReducePool()
Definition PointsToMask.h:239
openvdb::v10_0::tools::PointsToMask::ReducePool::IterT
typename VecT::iterator IterT
Definition PointsToMask.h:214
openvdb::v10_0::tools::PointsToMask::ReducePool::mOwnsGrid
const bool mOwnsGrid
Definition PointsToMask.h:248
openvdb::v10_0::tools::PointsToMask::ReducePool::mGrid
GridT * mGrid
Definition PointsToMask.h:249
openvdb::v10_0::tools::PointsToMask::ReducePool::operator()
void operator()(const RangeT &r)
Definition PointsToMask.h:241
openvdb::v10_0::tools::PointsToMask::ReducePool::VecT
std::vector< GridT * > VecT
Definition PointsToMask.h:213
openvdb::v10_0::tools::PointsToMask::ReducePool::ReducePool
ReducePool(const ReducePool &, tbb::split)
Definition PointsToMask.h:233
openvdb::v10_0::tools::PointsToMask::ReducePool::join
void join(ReducePool &other)
Definition PointsToMask.h:246
openvdb::v10_0::tools::PointsToMask::ReducePool::ReducePool
ReducePool(PoolType &pool, GridT *grid, size_t grainSize=1)
Definition PointsToMask.h:217
openvdb::v10_0::tools::PointsToMask::ReducePool::RangeT
tbb::blocked_range< IterT > RangeT
Definition PointsToMask.h:215
OPENVDB_VERSION_NAME
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
OPENVDB_USE_VERSION_NAMESPACE
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:212