OpenVDB  3.2.0
PointsToMask.h
Go to the documentation of this file.
1 //
3 // Copyright (c) 2012-2016 DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
72 
73 #ifndef OPENVDB_TOOLS_POINT_MASK_GRID_HAS_BEEN_INCLUDED
74 #define OPENVDB_TOOLS_POINT_MASK_GRID_HAS_BEEN_INCLUDED
75 
76 #include <tbb/tbb_thread.h>
77 #include <tbb/task_scheduler_init.h>
78 #include <tbb/enumerable_thread_specific.h>
79 #include <tbb/parallel_for.h>
80 #include <tbb/parallel_reduce.h>
81 #include <tbb/blocked_range.h>
82 
83 #include <openvdb/openvdb.h>
84 #include <openvdb/Grid.h>
85 #include <openvdb/Types.h>
86 #include <openvdb/util/NullInterrupter.h>
87 
88 namespace openvdb {
90 namespace OPENVDB_VERSION_NAME {
91 namespace tools {
92 
93 // Forward declaration of main class
94 template<typename GridT = MaskGrid, typename InterrupterT = util::NullInterrupter>
96 
101 template<typename PointListT, typename GridT>
102 inline void
103 maskPoints(const PointListT& points, GridT& grid)
104 {
106  tmp.addPoints(points);
107 }
108 
116 template<typename PointListT>
117 inline MaskGrid::Ptr
118 createPointMask(const PointListT& points, const math::Transform& xform)
119 {
120  MaskGrid::Ptr grid = createGrid<MaskGrid>( false );
121  grid->setTransform( xform.copy() );
122  maskPoints( points, *grid );
123  return grid;
124 }
125 
127 
129 template<typename GridT, typename InterrupterT>
130 class PointsToMask
131 {
132 public:
133  typedef typename GridT::ValueType ValueT;
134 
139  explicit PointsToMask(GridT& grid, InterrupterT* interrupter = NULL)
140  : mGrid(&grid)
141  , mInterrupter(interrupter)
142  {
143  }
144 
150  template<typename PointListT>
151  void addPoints(const PointListT& points, size_t grainSize = 1024)
152  {
153  if (mInterrupter) mInterrupter->start("PointsToMask: adding points");
154  if (grainSize>0) {
155  typename GridT::Ptr examplar = mGrid->copy( CP_NEW );
156  PoolType pool( *examplar );//thread local storage pool of grids
157  AddPoints<PointListT> tmp(points, pool, grainSize, *this );
158  if ( this->interrupt() ) return;
159  ReducePool reducePool(pool, mGrid, size_t(0));
160  } else {
161  const math::Transform& xform = mGrid->transform();
162  typename GridT::Accessor acc = mGrid->getAccessor();
163  Vec3R wPos;
164  for (size_t i = 0, n = points.size(); i < n; ++i) {
165  if ( this->interrupt() ) break;
166  points.getPos(i, wPos);
167  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
168  }
169  }
170  if (mInterrupter) mInterrupter->end();
171  }
172 
173 private:
174  // Disallow copy construction and copy by assignment!
175  PointsToMask(const PointsToMask&);// not implemented
176  PointsToMask& operator=(const PointsToMask&);// not implemented
177 
178  bool interrupt() const
179  {
180  if (mInterrupter && util::wasInterrupted(mInterrupter)) {
181  tbb::task::self().cancel_group_execution();
182  return true;
183  }
184  return false;
185  }
186 
187  // Private struct that implements concurrent thread-local
188  // insersion of points into a grid
189  typedef tbb::enumerable_thread_specific<GridT> PoolType;
190  template<typename PointListT> struct AddPoints;
191 
192  // Private class that implements concurrent reduction of a thread-local pool
193  struct ReducePool;
194 
195  GridT* mGrid;
196  InterrupterT* mInterrupter;
197 };// PointsToMask
198 
199 // Private member class that implements concurrent thread-local
200 // insersion of points into a grid
201 template<typename GridT, typename InterrupterT>
202 template<typename PointListT>
203 struct PointsToMask<GridT, InterrupterT>::AddPoints
204 {
205  AddPoints(const PointListT& points,
206  PoolType& pool,
207  size_t grainSize,
208  const PointsToMask& parent)
209  : mPoints(&points)
210  , mParent(&parent)
211  , mPool(&pool)
212  {
213  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPoints->size(), grainSize), *this);
214  }
215  void operator()(const tbb::blocked_range<size_t>& range) const
216  {
217  if (mParent->interrupt()) return;
218  GridT& grid = mPool->local();
219  const math::Transform& xform = grid.transform();
220  typename GridT::Accessor acc = grid.getAccessor();
221  Vec3R wPos;
222  for (size_t i=range.begin(), n=range.end(); i!=n; ++i) {
223  mPoints->getPos(i, wPos);
224  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
225  }
226  }
227  const PointListT* mPoints;
228  const PointsToMask* mParent;
229  PoolType* mPool;
230 
231 };// end of private member class AddPoints
232 
233 // Private member class that implements concurrent reduction of a thread-local pool
234 template<typename GridT, typename InterrupterT>
235 struct PointsToMask<GridT, InterrupterT>::ReducePool
236 {
237  typedef std::vector<GridT*> VecT;
238  typedef typename VecT::iterator IterT;
239  typedef tbb::blocked_range<IterT> RangeT;
240 
241  ReducePool(PoolType& pool, GridT* grid, size_t grainSize = 1)
242  : mOwnsGrid(false)
243  , mGrid(grid)
244  {
245  if ( grainSize == 0 ) {
246  typedef typename PoolType::const_iterator IterT;
247  for (IterT i=pool.begin(); i!=pool.end(); ++i) mGrid->topologyUnion( *i );
248  } else {
249  VecT grids( pool.size() );
250  typename PoolType::iterator i = pool.begin();
251  for (size_t j=0; j != pool.size(); ++i, ++j) grids[j] = &(*i);
252  tbb::parallel_reduce( RangeT( grids.begin(), grids.end(), grainSize ), *this );
253  }
254  }
255 
256  ReducePool(const ReducePool&, tbb::split)
257  : mOwnsGrid(true)
258  , mGrid(new GridT())
259  {
260  }
261 
262  ~ReducePool() { if (mOwnsGrid) delete mGrid; }
263 
264  void operator()(const RangeT& r)
265  {
266  for (IterT i=r.begin(); i!=r.end(); ++i) mGrid->topologyUnion( *(*i) );
267  }
268 
269  void join(ReducePool& other) { mGrid->topologyUnion(*other.mGrid); }
270 
271  const bool mOwnsGrid;
272  GridT* mGrid;
273 };// end of private member class ReducePool
274 
275 } // namespace tools
276 } // namespace OPENVDB_VERSION_NAME
277 } // namespace openvdb
278 
279 #endif //OPENVDB_TOOLS_POINT_MASK_GRID_HAS_BEEN_INCLUDED
280 
281 // Copyright (c) 2012-2016 DreamWorks Animation LLC
282 // All rights reserved. This software is distributed under the
283 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
void operator()(const RangeT &r)
Definition: PointsToMask.h:264
tbb::blocked_range< IterT > RangeT
Definition: PointsToMask.h:239
VecT::iterator IterT
Definition: PointsToMask.h:238
PointsToMask(GridT &grid, InterrupterT *interrupter=NULL)
Constructor from a grid and optional interrupter.
Definition: PointsToMask.h:139
GridT * mGrid
Definition: PointsToMask.h:272
ReducePool(PoolType &pool, GridT *grid, size_t grainSize=1)
Definition: PointsToMask.h:241
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:138
boost::shared_ptr< Grid > Ptr
Definition: Grid.h:485
Ptr copy() const
Definition: Transform.h:77
ReducePool(const ReducePool &, tbb::split)
Definition: PointsToMask.h:256
void maskPoints(const PointListT &points, GridT &grid)
Makes every voxel of the grid active if it contains a point.
Definition: PointsToMask.h:103
#define OPENVDB_VERSION_NAME
Definition: version.h:43
~ReducePool()
Definition: PointsToMask.h:262
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:151
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:66
Definition: Exceptions.h:39
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:118
GridT::ValueType ValueT
Definition: PointsToMask.h:133
std::vector< GridT * > VecT
Definition: PointsToMask.h:237
void join(ReducePool &other)
Definition: PointsToMask.h:269
Makes every voxel of a grid active if it contains a point.
Definition: PointsToMask.h:95
const bool mOwnsGrid
Definition: PointsToMask.h:271
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Definition: Types.h:434
bool wasInterrupted(T *i, int percent=-1)
Definition: NullInterrupter.h:76