22#ifndef OPENVDB_TOOLS_POINT_SCATTER_HAS_BEEN_INCLUDED 
   23#define OPENVDB_TOOLS_POINT_SCATTER_HAS_BEEN_INCLUDED 
   29#include <tbb/parallel_sort.h> 
   30#include <tbb/parallel_for.h> 
   41template<
typename PointAccessorType,
 
   42         typename RandomGenerator,
 
   43         typename InterruptType = util::NullInterrupter>
 
   44class BasePointScatter;
 
   84template<
typename PointAccessorType,
 
   85         typename RandomGenerator,
 
   86         typename InterruptType = util::NullInterrupter>
 
   96                        RandomGenerator& randGen,
 
  100        , mTargetPointCount(pointCount)
 
  101        , mPointsPerVolume(0.0f)
 
 
  105                        float pointsPerVolume,
 
  106                        RandomGenerator& randGen,
 
  110        , mTargetPointCount(0)
 
  111        , mPointsPerVolume(pointsPerVolume)
 
 
  116    template<
typename Gr
idT>
 
  119        mVoxelCount = grid.activeVoxelCount();
 
  120        if (mVoxelCount == 0) 
return false;
 
  122        const auto voxelVolume = grid.transform().voxelVolume();
 
  123        if (mPointsPerVolume > 0) {
 
  124            BaseT::start(
"Uniform scattering with fixed point density");
 
  125            mTargetPointCount = 
Index64(mPointsPerVolume * voxelVolume * 
double(mVoxelCount));
 
  126        } 
else if (mTargetPointCount > 0) {
 
  127            BaseT::start(
"Uniform scattering with fixed point count");
 
  128            mPointsPerVolume = float(mTargetPointCount) / float(voxelVolume * 
double(mVoxelCount));
 
  133        std::unique_ptr<Index64[]> idList{
new Index64[mTargetPointCount]};
 
  135        for (
Index64 i=0; i<mTargetPointCount; ++i) idList[i] = rand();
 
  136        tbb::parallel_sort(idList.get(), idList.get() + mTargetPointCount);
 
  139        const Vec3R offset(0.5, 0.5, 0.5);
 
  140        typename GridT::ValueOnCIter valueIter = grid.cbeginValueOn();
 
  142        for (
Index64 i=0, n=valueIter.getVoxelCount() ; i != mTargetPointCount; ++i) {
 
  144            const Index64 voxelId = idList[i];
 
  145            while ( n <= voxelId ) {
 
  147                n += valueIter.getVoxelCount();
 
  149            if (valueIter.isVoxelValue()) {
 
  152                valueIter.getBoundingBox(bbox);
 
 
  164    void print(
const std::string &name, std::ostream& os = std::cout)
 const 
  166        os << 
"Uniformly scattered " << mPointCount << 
" points into " << mVoxelCount
 
  167           << 
" active voxels in \"" << name << 
"\" corresponding to " 
  168           << mPointsPerVolume << 
" points per volume." << std::endl;
 
 
  176    using BaseT::mPointCount;
 
  177    using BaseT::mVoxelCount;
 
  179    float mPointsPerVolume;
 
 
  185template<
typename PointAccessorType,
 
  186         typename RandomGenerator,
 
  196                             float pointsPerVoxel,
 
  197                             RandomGenerator& randGen,
 
  201        , mPointsPerVoxel(pointsPerVoxel)
 
 
  206    template<
typename Gr
idT>
 
  209        using ValueIter = 
typename GridT::ValueOnCIter;
 
  210        if (mPointsPerVoxel < 1.0e-6) 
return false;
 
  211        mVoxelCount = grid.activeVoxelCount();
 
  212        if (mVoxelCount == 0) 
return false;
 
  213        BaseT::start(
"Dense uniform scattering with fixed point count");
 
  215        const Vec3R offset(0.5, 0.5, 0.5);
 
  218        const double delta = mPointsPerVoxel - float(ppv);
 
  221        for (ValueIter iter = grid.cbeginValueOn(); iter; ++iter) {
 
  223            if (iter.isVoxelValue()) {
 
  224                const Vec3R dmin = iter.getCoord() - offset;
 
  228                iter.getBoundingBox(bbox);
 
  230                const Vec3R dmin = bbox.
min() - offset;
 
  231                const double d = mPointsPerVoxel * float(iter.getVoxelCount());
 
 
  244    void print(
const std::string &name, std::ostream& os = std::cout)
 const 
  246        os << 
"Dense uniformly scattered " << mPointCount << 
" points into " << mVoxelCount
 
  247           << 
" active voxels in \"" << name << 
"\" corresponding to " 
  248           << mPointsPerVoxel << 
" points per voxel." << std::endl;
 
 
  254    using BaseT::mPointCount;
 
  255    using BaseT::mVoxelCount;
 
  256    float mPointsPerVoxel;
 
 
  267template<
typename PointAccessorType,
 
  268         typename RandomGenerator,
 
  278                           float pointsPerVolume,
 
  279                           RandomGenerator& randGen,
 
  283        , mPointsPerVolume(pointsPerVolume)
 
 
  289    template<
typename Gr
idT>
 
  292        if (mPointsPerVolume <= 0.0f) 
return false;
 
  293        mVoxelCount = grid.activeVoxelCount();
 
  294        if (mVoxelCount == 0) 
return false;
 
  295        BaseT::start(
"Non-uniform scattering with local point density");
 
  296        const Vec3d dim = grid.voxelSize();
 
  297        const double volumePerVoxel = dim[0]*dim[1]*dim[2],
 
  298                     pointsPerVoxel = mPointsPerVolume * volumePerVoxel;
 
  300        const Vec3R offset(0.5, 0.5, 0.5);
 
  301        for (
typename GridT::ValueOnCIter iter = grid.cbeginValueOn(); iter; ++iter) {
 
  303            const double d = double(*iter) * pointsPerVoxel * double(iter.getVoxelCount());
 
  304            const int n = int(d);
 
  305            if (iter.isVoxelValue()) { 
 
  306                const Vec3R dmin =iter.getCoord() - offset;
 
  310                iter.getBoundingBox(bbox);
 
  312                const Vec3R dmin = bbox.
min() - offset;
 
 
  323    void print(
const std::string &name, std::ostream& os = std::cout)
 const 
  325        os << 
"Non-uniformly scattered " << mPointCount << 
" points into " << mVoxelCount
 
  326           << 
" active voxels in \"" << name << 
"\"." << std::endl;
 
 
  332    using BaseT::mPointCount;
 
  333    using BaseT::mVoxelCount;
 
  334    float mPointsPerVolume;
 
 
  339template<
typename PointAccessorType,
 
  340         typename RandomGenerator,
 
  341         typename InterruptType>
 
  361                     RandomGenerator& randGen,
 
 
  396    template <
typename Gr
idT>
 
  402        mPoints.add(grid.indexToWorld(pos));
 
 
  406    template <
typename Gr
idT>
 
  410                        dmin[1] + size[1]*this->
getRand(),
 
  411                        dmin[2] + size[2]*this->
getRand());
 
  412        mPoints.add(grid.indexToWorld(pos));
 
 
 
General-purpose arithmetic and comparison routines, most of which accept arbitrary value types (or at...
Axis-aligned bounding box of signed integer coordinates.
Definition Coord.h:252
Coord extents() const
Definition Coord.h:385
const Coord & min() const
Definition Coord.h:324
Signed (x, y, z) 32-bit integer coordinates.
Definition Coord.h:26
Simple generator of random numbers over the range [0, 1)
Definition Math.h:167
Simple random integer generator.
Definition Math.h:203
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
Vec3< double > Vec3d
Definition Vec3.h:665
int Floor(float x)
Return the floor of x.
Definition Math.h:848
Definition AttributeArray.h:42
bool wasInterrupted(T *i, int percent=-1)
Definition NullInterrupter.h:49
math::Vec3< Real > Vec3R
Definition Types.h:72
uint64_t Index64
Definition Types.h:53
Definition Exceptions.h:13
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