OpenVDB  0.104.0
GridOperators.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012 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 //
32 
33 #ifndef OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
34 #define OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
35 
36 #include <openvdb/Grid.h>
37 #include <openvdb/math/Operators.h>
38 #include <openvdb/math/Stencils.h>
39 #include <openvdb/tree/LeafManager.h>
40 #include <openvdb/tree/ValueAccessor.h>
41 #include <tbb/parallel_for.h>
42 #include <tbb/blocked_range.h>
43 
44 
45 namespace openvdb {
47 namespace OPENVDB_VERSION_NAME {
48 namespace tools {
49 
54 template<typename VectorGridType> struct VectorToScalarConverter {
55  typedef typename VectorGridType::ValueType::value_type VecComponentValueT;
56  typedef typename VectorGridType::template ValueConverter<VecComponentValueT>::Type Type;
57 };
58 
63 template<typename ScalarGridType> struct ScalarToVectorConverter {
65  typedef typename ScalarGridType::template ValueConverter<VectorValueT>::Type Type;
66 };
67 
68 
71 template<typename GridType> inline
72 typename GridType::Ptr
73 curl(const GridType& grid, bool threaded = true);
74 
75 
79 template<typename GridType> inline
81 divergence(const GridType& grid, bool threaded = true);
82 
83 
87 template<typename GridType> inline
89 gradient(const GridType& grid, bool threaded = true);
90 
91 
94 template<typename GridType> inline
95 typename GridType::Ptr
96 laplacian(const GridType& grid, bool threaded = true);
97 
98 
101 template<typename GridType> inline
102 typename GridType::Ptr
103 meanCurvature(const GridType& grid, bool threaded = true);
104 
105 
108 template<typename GridType> inline
109 typename GridType::Ptr
110 magnitude(const GridType& grid, bool threaded = true);
111 
112 
115 template<typename GridType> inline
116 typename GridType::Ptr
117 normalize(const GridType& grid, bool threaded = true);
118 
120 
121 
122 namespace {
123 
132 template<typename InGridT, typename OutGridT, typename MapT, typename OperatorT>
133 class GridOperator
134 {
135 public:
136  typedef typename OutGridT::TreeType OutTreeT;
137  typedef typename OutTreeT::LeafNodeType OutLeafT;
138  typedef typename tree::LeafManager<OutTreeT> LeafManagerT;
139  typedef typename LeafManagerT::RangeType RangeT;
140 
141  GridOperator(const InGridT& grid, const MapT& map):
142  mAcc(grid.getConstAccessor()), mMap(map), mLeafs(NULL)
143  {
144  }
145  virtual ~GridOperator() {}
146  typename OutGridT::Ptr process(bool threaded = true)
147  {
148  // Derive background value of the output grid
149  typename InGridT::TreeType tmp(mAcc.getTree()->getBackground());
150  typename OutGridT::ValueType backg = OperatorT::result(mMap, tmp, math::Coord(0));
151  // output tree = topology copy of input tree!
152  typename OutTreeT::Ptr tree(new OutTreeT(*mAcc.getTree(), backg, TopologyCopy()));
153  // create grid with output tree and unit transform
154  typename OutGridT::Ptr result(new OutGridT(tree));
155  // transform of output grid = transform of input grid
156  result->setTransform(math::Transform::Ptr(new math::Transform( mMap.copy() )));
157 
158  mLeafs = new LeafManagerT(*tree);
159  if (threaded) {
160  tbb::parallel_for(mLeafs->getRange(), *this);
161  } else {
162  (*this)(mLeafs->getRange());
163  }
164  delete mLeafs; mLeafs=NULL;
165 
166  return result;
167  }
168 
175  void operator()(const RangeT& range) const
176  {
177  assert(mLeafs);
178  for (size_t n=range.begin(), e=range.end(); n != e; ++n) {
179  OutLeafT& leaf = mLeafs->leaf(n);
180  for (typename OutLeafT::ValueOnIter iter = leaf.beginValueOn(); iter; ++iter) {
181  iter.setValue(OperatorT::result(mMap, mAcc, iter.getCoord()));
182  }
183  }
184  }
185 
186 protected:
187  typedef typename InGridT::ConstAccessor AccessorT;
188 
189  mutable AccessorT mAcc;
190  const MapT& mMap;
191  LeafManagerT* mLeafs;
192 }; // end of GridOperator class
193 
194 } //end of anonymous namespace
195 
196 
198 
199 
201 template<typename GridT>
202 class Curl
203 {
204 public:
205  typedef GridT InGridType;
206  typedef GridT OutGridType;
207  Curl(const GridT& grid): mInputGrid(grid) {}
208  virtual ~Curl() {}
209  typename GridT::Ptr process(bool threaded = true)
210  {
211  Functor functor(mInputGrid, threaded);
212  processTypedMap(mInputGrid.transform(), functor);
213  return functor.mOutputGrid;
214  }
215 
216 protected:
217  struct Functor
218  {
219  Functor(const GridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
220  template<typename MapT>
221  void operator()(const MapT& map)
222  {
223  typedef math::Curl<MapT, math::CD_2ND> OpT;
224  GridOperator<GridT, GridT, MapT, OpT> op(mInputGrid, map);
225  mOutputGrid = op.process(mThreaded); // cache the result
226  }
227  const bool mThreaded;
228  const GridT& mInputGrid;
229  typename GridT::Ptr mOutputGrid;
230  }; // Private Functor
231 
232  const GridT& mInputGrid;
233 }; // end of Curl class
234 
235 
237 
238 
240 template<typename InGridT>
242 {
243 public:
244  typedef InGridT InGridType;
246 
247  Divergence(const InGridT& grid): mInputGrid(grid) {}
248  virtual ~Divergence() {}
249  typename OutGridType::Ptr process(bool threaded = true)
250  {
251  if( mInputGrid.getGridClass() == GRID_STAGGERED ) {
252  Functor<math::FD_1ST> functor(mInputGrid, threaded);
253  processTypedMap(mInputGrid.transform(), functor);
254  return functor.mOutputGrid;
255  }
256  else {
257  Functor<math::CD_2ND> functor(mInputGrid, threaded);
258  processTypedMap(mInputGrid.transform(), functor);
259  return functor.mOutputGrid;
260  }
261  }
262 
263 protected:
264  template<math::DScheme DiffScheme>
265  struct Functor
266  {
267  Functor(const InGridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
268  template<typename MapT>
269  void operator()(const MapT& map)
270  {
272  GridOperator<InGridType, OutGridType, MapT, OpT> op(mInputGrid, map);
273  mOutputGrid = op.process(mThreaded); // cache the result
274  }
275  const bool mThreaded;
277  typename OutGridType::Ptr mOutputGrid;
278  }; // Private Functor
279 
281 }; // end of Divergence class
282 
283 
285 
286 
288 template<typename InGridT>
289 class Gradient
290 {
291 public:
292  typedef InGridT InGridType;
294 
295  Gradient(const InGridT& grid): mInputGrid(grid) {}
296  virtual ~Gradient() {}
297  typename OutGridType::Ptr process(bool threaded = true)
298  {
299  Functor functor(mInputGrid, threaded);
300  processTypedMap(mInputGrid.transform(), functor);
301  return functor.mOutputGrid;
302  }
303 
304 protected:
305  struct Functor
306  {
307  Functor(const InGridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
308  template<typename MapT>
309  void operator()(const MapT& map)
310  {
312  GridOperator<InGridType, OutGridType, MapT, OpT> op(mInputGrid, map);
313  mOutputGrid = op.process(mThreaded); // cache the result
314  }
315  const bool mThreaded;
316  const InGridT& mInputGrid;
317  typename OutGridType::Ptr mOutputGrid;
318  }; // Private Functor
319 
320  const InGridT& mInputGrid;
321 }; // end of Gradient class
322 
323 
325 
326 
328 template<typename GridT>
330 {
331 public:
332  typedef GridT InGridType;
333  typedef GridT OutGridType;
334  Laplacian(const GridT& grid): mInputGrid(grid) {}
335  virtual ~Laplacian() {}
336  typename GridT::Ptr process(bool threaded = true)
337  {
338  Functor functor(mInputGrid, threaded);
339  processTypedMap(mInputGrid.transform(), functor);
340  return functor.mOutputGrid;
341  }
342 
343 protected:
344  struct Functor
345  {
346  Functor(const GridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
347  template<typename MapT>
348  void operator()(const MapT& map)
349  {
351  GridOperator<GridT, GridT, MapT, OpT> op(mInputGrid, map);
352  mOutputGrid = op.process(mThreaded); // cache the result
353  }
354  const bool mThreaded;
355  const GridT& mInputGrid;
356  typename GridT::Ptr mOutputGrid;
357  }; // Private Functor
358 
359  const GridT& mInputGrid;
360 }; // end of Laplacian class
361 
362 
364 
365 
366 template<typename GridT>
368 {
369 public:
370  typedef GridT InGridType;
371  typedef GridT OutGridType;
372  MeanCurvature(const GridT& grid): mInputGrid(grid) {}
373  virtual ~MeanCurvature() {}
374  typename GridT::Ptr process(bool threaded = true)
375  {
376  Functor functor(mInputGrid, threaded);
377  processTypedMap(mInputGrid.transform(), functor);
378  return functor.mOutputGrid;
379  }
380 
381 protected:
382  struct Functor
383  {
384  Functor(const GridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
385  template<typename MapT>
386  void operator()(const MapT& map)
387  {
389  GridOperator<GridT, GridT, MapT, OpT> op(mInputGrid, map);
390  mOutputGrid = op.process(mThreaded); // cache the result
391  }
392  const bool mThreaded;
393  const GridT& mInputGrid;
394  typename GridT::Ptr mOutputGrid;
395  }; // Private Functor
396 
397  const GridT& mInputGrid;
398 }; // end of MeanCurvature class
399 
400 
402 
403 template<typename InGridT>
405 {
406 public:
407  typedef InGridT InGridType;
409  Magnitude(const InGridType& grid): mInputGrid(grid) {}
410  virtual ~Magnitude() {}
411  typename OutGridType::Ptr process(bool threaded = true)
412  {
413  Functor functor(mInputGrid, threaded);
414  processTypedMap(mInputGrid.transform(), functor);
415  return functor.mOutputGrid;
416  }
417 
418 protected:
419  struct OpT
420  {
421  template<typename MapT, typename AccT>
422  static typename OutGridType::ValueType
423  result(const MapT&, const AccT& acc, const Coord& xyz) { return acc.getValue(xyz).length();}
424  };
425  struct Functor
426  {
427  Functor(const InGridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
428  template<typename MapT>
429  void operator()(const MapT& map)
430  {
431  GridOperator<InGridType, OutGridType, MapT, OpT> op(mInputGrid, map);
432  mOutputGrid = op.process(mThreaded); // cache the result
433  }
434  const bool mThreaded;
436  typename OutGridType::Ptr mOutputGrid;
437  }; // Private Functor
438 
440 }; // end of Magnitude class
441 
442 
444 
445 
446 template<typename GridT>
448 {
449 public:
450  typedef GridT InGridType;
451  typedef GridT OutGridType;
452  Normalize(const GridT& grid): mInputGrid(grid) {}
453  virtual ~Normalize() {}
454  typename GridT::Ptr process(bool threaded = true)
455  {
456  Functor functor(mInputGrid, threaded);
457  processTypedMap(mInputGrid.transform(), functor);
458  return functor.mOutputGrid;
459  }
460 
461 protected:
462  struct OpT
463  {
464  template<typename MapT, typename AccT>
465  static typename OutGridType::ValueType
466  result(const MapT&, const AccT& acc, const Coord& xyz)
467  {
468  typename OutGridType::ValueType vec = acc.getValue(xyz);
469  if ( !vec.normalize() ) vec.setZero();
470  return vec;
471  }
472  };
473  struct Functor
474  {
475  Functor(const GridT& grid, bool threaded): mThreaded(threaded), mInputGrid(grid) {}
476  template<typename MapT>
477  void operator()(const MapT& map)
478  {
479  GridOperator<GridT, GridT, MapT, OpT> op(mInputGrid, map);
480  mOutputGrid = op.process(mThreaded); // cache the result
481  }
482  const bool mThreaded;
483  const GridT& mInputGrid;
484  typename GridT::Ptr mOutputGrid;
485  }; // Private Functor
486 
487  const GridT& mInputGrid;
488 }; // end of Normalize class
489 
491 
492 
493 template<typename GridType> inline
494 typename GridType::Ptr
495 curl(const GridType& grid, bool threaded)
496 {
497  Curl<GridType> op(grid);
498  return op.process(threaded);
499 }
500 
501 template<typename GridType> inline
502 typename VectorToScalarConverter<GridType>::Type::Ptr
503 divergence(const GridType& grid, bool threaded)
504 {
505  Divergence<GridType> op(grid);
506  return op.process(threaded);
507 }
508 
509 template<typename GridType> inline
510 typename ScalarToVectorConverter<GridType>::Type::Ptr
511 gradient(const GridType& grid, bool threaded)
512 {
513  Gradient<GridType> op(grid);
514  return op.process(threaded);
515 }
516 
517 template<typename GridType> inline
518 typename GridType::Ptr
519 laplacian(const GridType& grid, bool threaded)
520 {
521  Laplacian<GridType> op(grid);
522  return op.process(threaded);
523 }
524 
525 template<typename GridType> inline
526 typename GridType::Ptr
527 meanCurvature(const GridType& grid, bool threaded)
528 {
529  MeanCurvature<GridType> op(grid);
530  return op.process(threaded);
531 }
532 
533 template<typename GridType> inline
534 typename GridType::Ptr
535 magnitude(const GridType& grid, bool threaded)
536 {
537  Magnitude<GridType> op(grid);
538  return op.process(threaded);
539 }
540 
541 template<typename GridType> inline
542 typename GridType::Ptr
543 normalize(const GridType& grid, bool threaded)
544 {
545  Normalize<GridType> op(grid);
546  return op.process(threaded);
547 }
548 
549 } // namespace tools
550 } // namespace OPENVDB_VERSION_NAME
551 } // namespace openvdb
552 
553 #endif // OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
554 
555 // Copyright (c) 2012 DreamWorks Animation LLC
556 // All rights reserved. This software is distributed under the
557 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )