HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PointsToMask.h
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2012-2017 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 //
29 ///////////////////////////////////////////////////////////////////////////
30 
31 /// @author Ken Museth
32 ///
33 /// @file tools/PointsToMask.h
34 ///
35 /// @brief This tool produces a grid where every voxel that contains a
36 /// point is active. It employes thread-local storage for best performance.
37 ///
38 /// The @c PointListT template argument below refers to any class
39 /// with the following interface (see unittest/TestPointsToMask.cc
40 /// and SOP_OpenVDB_From_Particles.cc for practical examples):
41 /// @code
42 ///
43 /// class PointList {
44 /// ...
45 /// public:
46 ///
47 /// // Return the total number of particles in list.
48 /// size_t size() const;
49 ///
50 /// // Get the world space position of the nth particle.
51 /// void getPos(size_t n, Vec3R& xyz) const;
52 /// };
53 /// @endcode
54 ///
55 /// @note See unittest/TestPointsToMask.cc for an example.
56 ///
57 /// The @c InterruptT template argument below refers to any class
58 /// with the following interface:
59 /// @code
60 /// class Interrupter {
61 /// ...
62 /// public:
63 /// void start(const char* name = nullptr) // called when computations begin
64 /// void end() // called when computations end
65 /// bool wasInterrupted(int percent = -1) // return true to break computation
66 /// };
67 /// @endcode
68 ///
69 /// @note If no template argument is provided for this InterruptT
70 /// the util::NullInterrupter is used which implies that all
71 /// interrupter calls are no-ops (i.e. incurs no computational overhead).
72 
73 #ifndef OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
74 #define OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
75 
76 #include <tbb/enumerable_thread_specific.h>
77 #include <tbb/parallel_for.h>
78 #include <tbb/parallel_reduce.h>
79 #include <tbb/blocked_range.h>
80 #include <openvdb/openvdb.h> // for MaskGrid
81 #include <openvdb/Grid.h>
82 #include <openvdb/Types.h>
84 
85 
86 namespace openvdb {
88 namespace OPENVDB_VERSION_NAME {
89 namespace tools {
90 
91 // Forward declaration of main class
92 template<typename GridT = MaskGrid, typename InterrupterT = util::NullInterrupter>
94 
95 /// @brief Makes every voxel of the @c grid active if it contains a point.
96 ///
97 /// @param points points that active the voxels of @c grid
98 /// @param grid on out its voxels with points are active
99 template<typename PointListT, typename GridT>
100 inline void
101 maskPoints(const PointListT& points, GridT& grid)
102 {
104  tmp.addPoints(points);
105 }
106 
107 /// @brief Return a MaskGrid where each binary voxel value
108 /// is on if the voxel contains one (or more) points (i.e.
109 /// the 3D position of a point is closer to this voxel than
110 /// any other voxels).
111 ///
112 /// @param points points that active the voxels in the returned grid.
113 /// @param xform transform from world space to voxels in grid space.
114 template<typename PointListT>
115 inline MaskGrid::Ptr
116 createPointMask(const PointListT& points, const math::Transform& xform)
117 {
118  MaskGrid::Ptr grid = createGrid<MaskGrid>( false );
119  grid->setTransform( xform.copy() );
120  maskPoints( points, *grid );
121  return grid;
122 }
123 
124 ////////////////////////////////////////
125 
126 /// @brief Makes every voxel of a grid active if it contains a point.
127 template<typename GridT, typename InterrupterT>
128 class PointsToMask
129 {
130 public:
131  typedef typename GridT::ValueType ValueT;
132 
133  /// @brief Constructor from a grid and optional interrupter
134  ///
135  /// @param grid Grid whoes voxels will have their state activated by points.
136  /// @param interrupter Optional interrupter to prematurely terminate execution.
137  explicit PointsToMask(GridT& grid, InterrupterT* interrupter = nullptr)
138  : mGrid(&grid)
139  , mInterrupter(interrupter)
140  {
141  }
142 
143  /// @brief Activates the state of any voxel in the input grid that contains a point.
144  ///
145  /// @param points List of points that active the voxels in the input grid.
146  /// @param grainSize Set the grain-size used for multi-threading. A value of 0
147  /// disables multi-threading!
148  template<typename PointListT>
149  void addPoints(const PointListT& points, size_t grainSize = 1024)
150  {
151  if (mInterrupter) mInterrupter->start("PointsToMask: adding points");
152  if (grainSize > 0) {
153 #ifdef OPENVDB_3_ABI_COMPATIBLE
154  typename GridT::Ptr examplar = mGrid->copy(CP_NEW);
155 #else
156  typename GridT::Ptr examplar = mGrid->copyWithNewTree();
157 #endif
158  PoolType pool( *examplar );//thread local storage pool of grids
159  AddPoints<PointListT> tmp(points, pool, grainSize, *this );
160  if ( this->interrupt() ) return;
161  ReducePool reducePool(pool, mGrid, size_t(0));
162  } else {
163  const math::Transform& xform = mGrid->transform();
164  typename GridT::Accessor acc = mGrid->getAccessor();
165  Vec3R wPos;
166  for (size_t i = 0, n = points.size(); i < n; ++i) {
167  if ( this->interrupt() ) break;
168  points.getPos(i, wPos);
169  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
170  }
171  }
172  if (mInterrupter) mInterrupter->end();
173  }
174 
175 private:
176  // Disallow copy construction and copy by assignment!
177  PointsToMask(const PointsToMask&);// not implemented
178  PointsToMask& operator=(const PointsToMask&);// not implemented
179 
180  bool interrupt() const
181  {
182  if (mInterrupter && util::wasInterrupted(mInterrupter)) {
183  tbb::task::self().cancel_group_execution();
184  return true;
185  }
186  return false;
187  }
188 
189  // Private struct that implements concurrent thread-local
190  // insersion of points into a grid
191  typedef tbb::enumerable_thread_specific<GridT> PoolType;
192  template<typename PointListT> struct AddPoints;
193 
194  // Private class that implements concurrent reduction of a thread-local pool
195  struct ReducePool;
196 
197  GridT* mGrid;
198  InterrupterT* mInterrupter;
199 };// PointsToMask
200 
201 // Private member class that implements concurrent thread-local
202 // insersion of points into a grid
203 template<typename GridT, typename InterrupterT>
204 template<typename PointListT>
205 struct PointsToMask<GridT, InterrupterT>::AddPoints
206 {
207  AddPoints(const PointListT& points,
208  PoolType& pool,
209  size_t grainSize,
210  const PointsToMask& parent)
211  : mPoints(&points)
212  , mParent(&parent)
213  , mPool(&pool)
214  {
215  tbb::parallel_for(tbb::blocked_range<size_t>(0, mPoints->size(), grainSize), *this);
216  }
217  void operator()(const tbb::blocked_range<size_t>& range) const
218  {
219  if (mParent->interrupt()) return;
220  GridT& grid = mPool->local();
221  const math::Transform& xform = grid.transform();
222  typename GridT::Accessor acc = grid.getAccessor();
223  Vec3R wPos;
224  for (size_t i=range.begin(), n=range.end(); i!=n; ++i) {
225  mPoints->getPos(i, wPos);
226  acc.setValueOn( xform.worldToIndexCellCentered( wPos ) );
227  }
228  }
229  const PointListT* mPoints;
230  const PointsToMask* mParent;
231  PoolType* mPool;
232 
233 };// end of private member class AddPoints
234 
235 // Private member class that implements concurrent reduction of a thread-local pool
236 template<typename GridT, typename InterrupterT>
237 struct PointsToMask<GridT, InterrupterT>::ReducePool
238 {
239  typedef std::vector<GridT*> VecT;
240  typedef typename VecT::iterator IterT;
241  typedef tbb::blocked_range<IterT> RangeT;
242 
243  ReducePool(PoolType& pool, GridT* grid, size_t grainSize = 1)
244  : mOwnsGrid(false)
245  , mGrid(grid)
246  {
247  if ( grainSize == 0 ) {
248  typedef typename PoolType::const_iterator IterT;
249  for (IterT i=pool.begin(); i!=pool.end(); ++i) mGrid->topologyUnion( *i );
250  } else {
251  VecT grids( pool.size() );
252  typename PoolType::iterator i = pool.begin();
253  for (size_t j=0; j != pool.size(); ++i, ++j) grids[j] = &(*i);
254  tbb::parallel_reduce( RangeT( grids.begin(), grids.end(), grainSize ), *this );
255  }
256  }
257 
258  ReducePool(const ReducePool&, tbb::split)
259  : mOwnsGrid(true)
260  , mGrid(new GridT())
261  {
262  }
263 
264  ~ReducePool() { if (mOwnsGrid) delete mGrid; }
265 
266  void operator()(const RangeT& r)
267  {
268  for (IterT i=r.begin(); i!=r.end(); ++i) mGrid->topologyUnion( *(*i) );
269  }
270 
271  void join(ReducePool& other) { mGrid->topologyUnion(*other.mGrid); }
272 
273  const bool mOwnsGrid;
274  GridT* mGrid;
275 };// end of private member class ReducePool
276 
277 } // namespace tools
278 } // namespace OPENVDB_VERSION_NAME
279 } // namespace openvdb
280 
281 #endif // OPENVDB_TOOLS_POINTSTOMASK_HAS_BEEN_INCLUDED
282 
283 // Copyright (c) 2012-2017 DreamWorks Animation LLC
284 // All rights reserved. This software is distributed under the
285 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
GLenum GLint * range
Definition: glcorearb.h:1924
math::Vec3< Real > Vec3R
Definition: Types.h:75
PointsToMask(GridT &grid, InterrupterT *interrupter=nullptr)
Constructor from a grid and optional interrupter.
Definition: PointsToMask.h:137
void maskPoints(const PointListT &points, GridT &grid)
Makes every voxel of the grid active if it contains a point.
Definition: PointsToMask.h:101
Makes every voxel of a grid active if it contains a point.
Definition: PointsToMask.h:93
png_uint_32 i
Definition: png.h:2877
ReducePool(PoolType &pool, GridT *grid, size_t grainSize=1)
Definition: PointsToMask.h:243
GLdouble n
Definition: glcorearb.h:2007
Calculate an axis-aligned bounding box in index space from a bounding sphere in world space...
Definition: Transform.h:66
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:116
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Coord worldToIndexCellCentered(const Vec3d &xyz) const
Apply this transformation to the given coordinates.
Definition: Transform.h:138
GLboolean r
Definition: glcorearb.h:1221
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
bool wasInterrupted(T *i, int percent=-1)
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:149