OpenVDB  7.0.0
PointsToMask.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 
45 
46 #ifndef OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
47 #define OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
48 
49 #include <tbb/enumerable_thread_specific.h>
50 #include <tbb/parallel_for.h>
51 #include <tbb/parallel_reduce.h>
52 #include <tbb/blocked_range.h>
53 #include <openvdb/openvdb.h> // for MaskGrid
54 #include <openvdb/Grid.h>
55 #include <openvdb/Types.h>
57 #include <vector>
58 
59 
60 namespace openvdb {
62 namespace OPENVDB_VERSION_NAME {
63 namespace tools {
64 
65 // Forward declaration of main class
66 template<typename GridT = MaskGrid, typename InterrupterT = util::NullInterrupter>
68 
73 template<typename PointListT, typename GridT>
74 inline void
75 maskPoints(const PointListT& points, GridT& grid)
76 {
78  tmp.addPoints(points);
79 }
80 
88 template<typename PointListT>
89 inline MaskGrid::Ptr
90 createPointMask(const PointListT& points, const math::Transform& xform)
91 {
92  MaskGrid::Ptr grid = createGrid<MaskGrid>( false );
93  grid->setTransform( xform.copy() );
94  maskPoints( points, *grid );
95  return grid;
96 }
97 
99 
101 template<typename GridT, typename InterrupterT>
102 class PointsToMask
103 {
104 public:
105  using ValueT = typename GridT::ValueType;
106 
111  explicit PointsToMask(GridT& grid, InterrupterT* interrupter = nullptr)
112  : mGrid(&grid)
113  , mInterrupter(interrupter)
114  {
115  }
116 
122  template<typename PointListT>
123  void addPoints(const PointListT& points, size_t grainSize = 1024)
124  {
125  if (mInterrupter) mInterrupter->start("PointsToMask: adding points");
126  if (grainSize > 0) {
127  typename GridT::Ptr examplar = mGrid->copyWithNewTree();
128  PoolType pool( *examplar );//thread local storage pool of grids
129  AddPoints<PointListT> tmp(points, pool, grainSize, *this );
130  if ( this->interrupt() ) return;
131  ReducePool reducePool(pool, mGrid, size_t(0));
132  } else {
133  const math::Transform& xform = mGrid->transform();
134  typename GridT::Accessor acc = mGrid->getAccessor();
135  Vec3R wPos;
136  for (size_t i = 0, n = points.size(); i < n; ++i) {
137  if ( this->interrupt() ) break;
138  points.getPos(i, wPos);
139  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
140  }
141  }
142  if (mInterrupter) mInterrupter->end();
143  }
144 
145 private:
146  // Disallow copy construction and copy by assignment!
147  PointsToMask(const PointsToMask&);// not implemented
148  PointsToMask& operator=(const PointsToMask&);// not implemented
149 
150  bool interrupt() const
151  {
152  if (mInterrupter && util::wasInterrupted(mInterrupter)) {
153  tbb::task::self().cancel_group_execution();
154  return true;
155  }
156  return false;
157  }
158 
159  // Private struct that implements concurrent thread-local
160  // insersion of points into a grid
161  using PoolType = tbb::enumerable_thread_specific<GridT>;
162  template<typename PointListT> struct AddPoints;
163 
164  // Private class that implements concurrent reduction of a thread-local pool
165  struct ReducePool;
166 
167  GridT* mGrid;
168  InterrupterT* mInterrupter;
169 };// PointsToMask
170 
171 // Private member class that implements concurrent thread-local
172 // insersion of points into a grid
173 template<typename GridT, typename InterrupterT>
174 template<typename PointListT>
175 struct PointsToMask<GridT, InterrupterT>::AddPoints
176 {
177  AddPoints(const PointListT& points,
178  PoolType& pool,
179  size_t grainSize,
180  const PointsToMask& parent)
181  : mPoints(&points)
182  , mParent(&parent)
183  , mPool(&pool)
184  {
185  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPoints->size(), grainSize), *this);
186  }
187  void operator()(const tbb::blocked_range<size_t>& range) const
188  {
189  if (mParent->interrupt()) return;
190  GridT& grid = mPool->local();
191  const math::Transform& xform = grid.transform();
192  typename GridT::Accessor acc = grid.getAccessor();
193  Vec3R wPos;
194  for (size_t i=range.begin(), n=range.end(); i!=n; ++i) {
195  mPoints->getPos(i, wPos);
196  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
197  }
198  }
199  const PointListT* mPoints;
200  const PointsToMask* mParent;
201  PoolType* mPool;
202 
203 };// end of private member class AddPoints
204 
205 // Private member class that implements concurrent reduction of a thread-local pool
206 template<typename GridT, typename InterrupterT>
207 struct PointsToMask<GridT, InterrupterT>::ReducePool
208 {
209  using VecT = std::vector<GridT*>;
210  using IterT = typename VecT::iterator;
211  using RangeT = tbb::blocked_range<IterT>;
212 
213  ReducePool(PoolType& pool, GridT* grid, size_t grainSize = 1)
214  : mOwnsGrid(false)
215  , mGrid(grid)
216  {
217  if (grainSize == 0) {
218  for (typename PoolType::const_iterator i = pool.begin(); i != pool.end(); ++i) {
219  mGrid->topologyUnion(*i);
220  }
221  } else {
222  VecT grids( pool.size() );
223  typename PoolType::iterator i = pool.begin();
224  for (size_t j=0; j != pool.size(); ++i, ++j) grids[j] = &(*i);
225  tbb::parallel_reduce( RangeT( grids.begin(), grids.end(), grainSize ), *this );
226  }
227  }
228 
229  ReducePool(const ReducePool&, tbb::split)
230  : mOwnsGrid(true)
231  , mGrid(new GridT())
232  {
233  }
234 
235  ~ReducePool() { if (mOwnsGrid) delete mGrid; }
236 
237  void operator()(const RangeT& r)
238  {
239  for (IterT i=r.begin(); i!=r.end(); ++i) mGrid->topologyUnion( *(*i) );
240  }
241 
242  void join(ReducePool& other) { mGrid->topologyUnion(*other.mGrid); }
243 
244  const bool mOwnsGrid;
245  GridT* mGrid;
246 };// end of private member class ReducePool
247 
248 } // namespace tools
249 } // namespace OPENVDB_VERSION_NAME
250 } // namespace openvdb
251 
252 #endif // OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
SharedPtr< Grid > Ptr
Definition: Grid.h:574
typename GridT::ValueType ValueT
Definition: PointsToMask.h:105
ReducePool(const ReducePool &, tbb::split)
Definition: PointsToMask.h:229
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:123
typename VecT::iterator IterT
Definition: PointsToMask.h:210
Ptr copy() const
Definition: Transform.h:50
tbb::blocked_range< IterT > RangeT
Definition: PointsToMask.h:211
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:102
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:111
~ReducePool()
Definition: PointsToMask.h:235
GridT * mGrid
Definition: PointsToMask.h:245
Definition: Exceptions.h:13
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:49
const bool mOwnsGrid
Definition: PointsToMask.h:244
Definition: Transform.h:39
ReducePool(PoolType &pool, GridT *grid, size_t grainSize=1)
Definition: PointsToMask.h:213
PointsToMask(GridT &grid, InterrupterT *interrupter=nullptr)
Constructor from a grid and optional interrupter.
Definition: PointsToMask.h:111
void join(ReducePool &other)
Definition: PointsToMask.h:242
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:154
void maskPoints(const PointListT &points, GridT &grid)
Makes every voxel of the grid active if it contains a point.
Definition: PointsToMask.h:75
std::vector< GridT * > VecT
Definition: PointsToMask.h:209
void operator()(const RangeT &r)
Definition: PointsToMask.h:237
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:90
Makes every voxel of a grid active if it contains a point.
Definition: PointsToMask.h:67