OpenVDB  1.1.0
GridOperators.h
Go to the documentation of this file.
1 
2 //
3 // Copyright (c) 2012-2013 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 //
35 
36 #ifndef OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
37 #define OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
38 
39 #include <openvdb/Grid.h>
40 #include <openvdb/math/Operators.h>
41 #include <openvdb/util/NullInterrupter.h>
42 #include <openvdb/tree/LeafManager.h>
43 #include <openvdb/tree/ValueAccessor.h>
44 #include <tbb/parallel_for.h>
45 
46 
47 namespace openvdb {
49 namespace OPENVDB_VERSION_NAME {
50 namespace tools {
51 
56 template<typename VectorGridType> struct VectorToScalarConverter {
57  typedef typename VectorGridType::ValueType::value_type VecComponentValueT;
58  typedef typename VectorGridType::template ValueConverter<VecComponentValueT>::Type Type;
59 };
60 
65 template<typename ScalarGridType> struct ScalarToVectorConverter {
67  typedef typename ScalarGridType::template ValueConverter<VectorValueT>::Type Type;
68 };
69 
70 
79 template<typename GridType, typename InterruptT> inline
81 cpt(const GridType& grid, bool threaded, InterruptT* interrupt);
82 
83 template<typename GridType> inline
85 cpt(const GridType& grid, bool threaded = true)
86 {
87  return cpt<GridType, util::NullInterrupter>(grid, threaded, NULL);
88 }
89 
90 
93 template<typename GridType, typename InterruptT> inline
94 typename GridType::Ptr
95 curl(const GridType& grid, bool threaded, InterruptT* interrupt);
96 
97 template<typename GridType> inline
98 typename GridType::Ptr
99 curl(const GridType& grid, bool threaded = true)
100 {
101  return curl<GridType, util::NullInterrupter>(grid, threaded, NULL);
102 }
103 
107 template<typename GridType, typename InterruptT> inline
108 typename VectorToScalarConverter<GridType>::Type::Ptr
109 divergence(const GridType& grid, bool threaded, InterruptT* interrupt);
110 
111 template<typename GridType> inline
112 typename VectorToScalarConverter<GridType>::Type::Ptr
113 divergence(const GridType& grid, bool threaded = true)
114 {
115  return divergence<GridType, util::NullInterrupter>(grid, threaded, NULL);
116 }
117 
121 template<typename GridType, typename InterruptT> inline
122 typename ScalarToVectorConverter<GridType>::Type::Ptr
123 gradient(const GridType& grid, bool threaded, InterruptT* interrupt);
124 
125 template<typename GridType> inline
126 typename ScalarToVectorConverter<GridType>::Type::Ptr
127 gradient(const GridType& grid, bool threaded = true)
128 {
129  return gradient<GridType, util::NullInterrupter>(grid, threaded, NULL);
130 }
131 
132 
135 template<typename GridType, typename InterruptT> inline
136 typename GridType::Ptr
137 laplacian(const GridType& grid, bool threaded, InterruptT* interrupt);
138 
139 template<typename GridType> inline
140 typename GridType::Ptr
141 laplacian(const GridType& grid, bool threaded = true)
142 {
143  return laplacian<GridType, util::NullInterrupter>(grid, threaded, NULL);
144 }
145 
148 template<typename GridType, typename InterruptT> inline
149 typename GridType::Ptr
150 meanCurvature(const GridType& grid, bool threaded, InterruptT* interrupt);
151 
152 template<typename GridType> inline
153 typename GridType::Ptr
154 meanCurvature(const GridType& grid, bool threaded = true)
155 {
156  return meanCurvature<GridType, util::NullInterrupter>(grid, threaded, NULL);
157 }
158 
162 template<typename GridType, typename InterruptT> inline
163 typename VectorToScalarConverter<GridType>::Type::Ptr
164 magnitude(const GridType& grid, bool threaded, InterruptT* interrupt);
165 
166 template<typename GridType> inline
167 typename VectorToScalarConverter<GridType>::Type::Ptr
168 magnitude(const GridType& grid, bool threaded = true)
169 {
170  return magnitude<GridType, util::NullInterrupter>(grid, threaded, NULL);
171 }
172 
175 template<typename GridType, typename InterruptT> inline
176 typename GridType::Ptr
177 normalize(const GridType& grid, bool threaded, InterruptT* interrupt);
178 
179 template<typename GridType> inline
180 typename GridType::Ptr
181 normalize(const GridType& grid, bool threaded = true)
182 {
183  return normalize<GridType, util::NullInterrupter>(grid, threaded, NULL);
184 }
185 
187 
188 
189 namespace {
190 
200 template<typename InGridT, typename OutGridT, typename MapT,
201  typename OperatorT, typename InterruptT = util::NullInterrupter>
202 class GridOperator
203 {
204 public:
205  typedef typename OutGridT::TreeType OutTreeT;
206  typedef typename OutTreeT::LeafNodeType OutLeafT;
207  typedef typename tree::LeafManager<OutTreeT> LeafManagerT;
208 
209  GridOperator(const InGridT& grid, const MapT& map, InterruptT* interrupt = NULL):
210  mAcc(grid.getConstAccessor()), mMap(map), mInterrupt(interrupt)
211  {
212  }
213  virtual ~GridOperator() {}
214  typename OutGridT::Ptr process(bool threaded = true)
215  {
216  if (mInterrupt) mInterrupt->start("Processing grid");
217  // Derive background value of the output grid
218  typename InGridT::TreeType tmp(mAcc.getTree()->background());
219  typename OutGridT::ValueType backg = OperatorT::result(mMap, tmp, math::Coord(0));
220  // output tree = topology copy of input tree!
221  typename OutTreeT::Ptr tree(new OutTreeT(*mAcc.getTree(), backg, TopologyCopy()));
222  // create grid with output tree and unit transform
223  typename OutGridT::Ptr result(new OutGridT(tree));
224  // transform of output grid = transform of input grid
225  result->setTransform(math::Transform::Ptr(new math::Transform( mMap.copy() )));
226 
227  LeafManagerT leafManager(*tree);
228 
229  if (threaded) {
230  tbb::parallel_for(leafManager.leafRange(), *this);
231  } else {
232  (*this)(leafManager.leafRange());
233  }
234 
235  if (mInterrupt) mInterrupt->end();
236  return result;
237  }
238 
245  void operator()(const typename LeafManagerT::LeafRange& range) const
246  {
247  if (util::wasInterrupted(mInterrupt)) tbb::task::self().cancel_group_execution();
248 
249  for (typename LeafManagerT::LeafRange::Iterator leaf=range.begin(); leaf; ++leaf) {
250  for (typename OutLeafT::ValueOnIter value=leaf->beginValueOn(); value; ++value) {
251  value.setValue(OperatorT::result(mMap, mAcc, value.getCoord()));
252  }
253  }
254  }
255 
256 protected:
257 
258  typedef typename InGridT::ConstAccessor AccessorT;
259  mutable AccessorT mAcc;
260  const MapT& mMap;
261  InterruptT* mInterrupt;
262 }; // end of GridOperator class
263 
264 } //end of anonymous namespace
265 
266 
268 
269 
271 template<typename InGridT, typename InterruptT = util::NullInterrupter>
272 class Cpt
273 {
274 public:
275  typedef InGridT InGridType;
277 
278  Cpt(const InGridType& grid, InterruptT* interrupt = NULL):
279  mInputGrid(grid), mInterrupt(interrupt)
280  {
281  }
282  typename OutGridType::Ptr process(bool threaded = true, bool useWorldTransform = true)
283  {
284  Functor functor(mInputGrid, threaded, useWorldTransform, mInterrupt);
285  processTypedMap(mInputGrid.transform(), functor);
286  return functor.mOutputGrid;
287  }
288 private:
289  struct IsOpT
290  {
291  template<typename MapT, typename AccT>
292  static typename OutGridType::ValueType
293  result(const MapT& map, const AccT& acc, const Coord& xyz)
294  {
295  return math::CPT<MapT, math::CD_2ND>::result(map, acc, xyz);
296  }
297  };
298  struct WsOpT
299  {
300  template<typename MapT, typename AccT>
301  static typename OutGridType::ValueType
302  result(const MapT& map, const AccT& acc, const Coord& xyz)
303  {
304  return math::CPT_RANGE<MapT, math::CD_2ND>::result(map, acc, xyz);
305  }
306  };
307  struct Functor
308  {
309  Functor(const InGridType& grid, bool threaded, bool worldspace, InterruptT* interrupt):
310  mThreaded(threaded), mWorldSpace(worldspace), mInputGrid(grid), mInterrupt(interrupt){}
311  template<typename MapT>
312  void operator()(const MapT& map)
313  {
314  if (mWorldSpace) {
315  GridOperator<InGridType, OutGridType, MapT, WsOpT, InterruptT> op(mInputGrid, map, mInterrupt);
316  mOutputGrid = op.process(mThreaded); // cache the result
317  } else {
318  GridOperator<InGridType, OutGridType, MapT, IsOpT, InterruptT> op(mInputGrid, map, mInterrupt);
319  mOutputGrid = op.process(mThreaded); // cache the result
320  }
321  }
322  const bool mThreaded;
323  const bool mWorldSpace;
324  const InGridType& mInputGrid;
325  typename OutGridType::Ptr mOutputGrid;
326  InterruptT* mInterrupt;
327  };
328  const InGridType& mInputGrid;
329  InterruptT* mInterrupt;
330 }; // end of Cpt class
331 
332 
334 
335 
337 template<typename GridT, typename InterruptT = util::NullInterrupter>
338 class Curl
339 {
340 public:
341  typedef GridT InGridType;
342  typedef GridT OutGridType;
343  Curl(const GridT& grid, InterruptT* interrupt = NULL):
344  mInputGrid(grid), mInterrupt(interrupt)
345  {
346  }
347  typename GridT::Ptr process(bool threaded = true)
348  {
349  Functor functor(mInputGrid, threaded, mInterrupt);
350  processTypedMap(mInputGrid.transform(), functor);
351  return functor.mOutputGrid;
352  }
353 
354 private:
355  struct Functor
356  {
357  Functor(const GridT& grid, bool threaded, InterruptT* interrupt):
358  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt){}
359  template<typename MapT>
360  void operator()(const MapT& map)
361  {
362  typedef math::Curl<MapT, math::CD_2ND> OpT;
363  GridOperator<GridT, GridT, MapT, OpT, InterruptT> op(mInputGrid, map, mInterrupt);
364  mOutputGrid = op.process(mThreaded); // cache the result
365  }
366  const bool mThreaded;
367  const GridT& mInputGrid;
368  typename GridT::Ptr mOutputGrid;
369  InterruptT* mInterrupt;
370  }; // Private Functor
371 
372  const GridT& mInputGrid;
373  InterruptT* mInterrupt;
374 }; // end of Curl class
375 
376 
378 
379 
381 template<typename InGridT, typename InterruptT = util::NullInterrupter>
383 {
384 public:
385  typedef InGridT InGridType;
387 
388  Divergence(const InGridT& grid, InterruptT* interrupt = NULL):
389  mInputGrid(grid), mInterrupt(interrupt)
390  {
391  }
392  typename OutGridType::Ptr process(bool threaded = true)
393  {
394  if( mInputGrid.getGridClass() == GRID_STAGGERED ) {
395  Functor<math::FD_1ST> functor(mInputGrid, threaded, mInterrupt);
396  processTypedMap(mInputGrid.transform(), functor);
397  return functor.mOutputGrid;
398  }
399  else {
400  Functor<math::CD_2ND> functor(mInputGrid, threaded, mInterrupt);
401  processTypedMap(mInputGrid.transform(), functor);
402  return functor.mOutputGrid;
403  }
404  }
405 
406 protected:
407  template<math::DScheme DiffScheme>
408  struct Functor
409  {
410  Functor(const InGridT& grid, bool threaded, InterruptT* interrupt):
411  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
412  template<typename MapT>
413  void operator()(const MapT& map)
414  {
416  GridOperator<InGridType, OutGridType, MapT, OpT, InterruptT> op(mInputGrid, map, mInterrupt);
417  mOutputGrid = op.process(mThreaded); // cache the result
418  }
419  const bool mThreaded;
421  typename OutGridType::Ptr mOutputGrid;
422  InterruptT* mInterrupt;
423  }; // Private Functor
424 
426  InterruptT* mInterrupt;
427 }; // end of Divergence class
428 
429 
431 
432 
434 template<typename InGridT, typename InterruptT = util::NullInterrupter>
435 class Gradient
436 {
437 public:
438  typedef InGridT InGridType;
440 
441  Gradient(const InGridT& grid, InterruptT* interrupt = NULL):
442  mInputGrid(grid), mInterrupt(interrupt)
443  {
444  }
445  typename OutGridType::Ptr process(bool threaded = true)
446  {
447  Functor functor(mInputGrid, threaded, mInterrupt);
448  processTypedMap(mInputGrid.transform(), functor);
449  return functor.mOutputGrid;
450  }
451 
452 protected:
453  struct Functor
454  {
455  Functor(const InGridT& grid, bool threaded, InterruptT* interrupt):
456  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
457  template<typename MapT>
458  void operator()(const MapT& map)
459  {
461  GridOperator<InGridType, OutGridType, MapT, OpT, InterruptT> op(mInputGrid, map, mInterrupt);
462  mOutputGrid = op.process(mThreaded); // cache the result
463  }
464  const bool mThreaded;
465  const InGridT& mInputGrid;
466  typename OutGridType::Ptr mOutputGrid;
467  InterruptT* mInterrupt;
468  }; // Private Functor
469 
470  const InGridT& mInputGrid;
471  InterruptT* mInterrupt;
472 }; // end of Gradient class
473 
474 
476 
477 
479 template<typename GridT, typename InterruptT = util::NullInterrupter>
481 {
482 public:
483  typedef GridT InGridType;
484  typedef GridT OutGridType;
485  Laplacian(const GridT& grid, InterruptT* interrupt = NULL):
486  mInputGrid(grid), mInterrupt(interrupt)
487  {
488  }
489  typename GridT::Ptr process(bool threaded = true)
490  {
491  Functor functor(mInputGrid, threaded, mInterrupt);
492  processTypedMap(mInputGrid.transform(), functor);
493  return functor.mOutputGrid;
494  }
495 
496 protected:
497  struct Functor
498  {
499  Functor(const GridT& grid, bool threaded, InterruptT* interrupt):
500  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
501  template<typename MapT>
502  void operator()(const MapT& map)
503  {
505  GridOperator<GridT, GridT, MapT, OpT, InterruptT> op(mInputGrid, map);
506  mOutputGrid = op.process(mThreaded); // cache the result
507  }
508  const bool mThreaded;
509  const GridT& mInputGrid;
510  typename GridT::Ptr mOutputGrid;
511  InterruptT* mInterrupt;
512  }; // Private Functor
513 
514  const GridT& mInputGrid;
515  InterruptT* mInterrupt;
516 }; // end of Laplacian class
517 
518 
520 
521 
522 template<typename GridT, typename InterruptT = util::NullInterrupter>
524 {
525 public:
526  typedef GridT InGridType;
527  typedef GridT OutGridType;
528  MeanCurvature(const GridT& grid, InterruptT* interrupt = NULL):
529  mInputGrid(grid), mInterrupt(interrupt)
530  {
531  }
532  typename GridT::Ptr process(bool threaded = true)
533  {
534  Functor functor(mInputGrid, threaded, mInterrupt);
535  processTypedMap(mInputGrid.transform(), functor);
536  return functor.mOutputGrid;
537  }
538 
539 protected:
540  struct Functor
541  {
542  Functor(const GridT& grid, bool threaded, InterruptT* interrupt):
543  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
544  template<typename MapT>
545  void operator()(const MapT& map)
546  {
548  GridOperator<GridT, GridT, MapT, OpT, InterruptT> op(mInputGrid, map);
549  mOutputGrid = op.process(mThreaded); // cache the result
550  }
551  const bool mThreaded;
552  const GridT& mInputGrid;
553  typename GridT::Ptr mOutputGrid;
554  InterruptT* mInterrupt;
555  }; // Private Functor
556 
557  const GridT& mInputGrid;
558  InterruptT* mInterrupt;
559 }; // end of MeanCurvature class
560 
561 
563 
564 
565 template<typename InGridT, typename InterruptT = util::NullInterrupter>
567 {
568 public:
569  typedef InGridT InGridType;
571  Magnitude(const InGridType& grid, InterruptT* interrupt = NULL):
572  mInputGrid(grid), mInterrupt(interrupt)
573  {
574  }
575  typename OutGridType::Ptr process(bool threaded = true)
576  {
577  Functor functor(mInputGrid, threaded, mInterrupt);
578  processTypedMap(mInputGrid.transform(), functor);
579  return functor.mOutputGrid;
580  }
581 
582 protected:
583  struct OpT
584  {
585  template<typename MapT, typename AccT>
586  static typename OutGridType::ValueType
587  result(const MapT&, const AccT& acc, const Coord& xyz) { return acc.getValue(xyz).length();}
588  };
589  struct Functor
590  {
591  Functor(const InGridT& grid, bool threaded, InterruptT* interrupt):
592  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
593  template<typename MapT>
594  void operator()(const MapT& map)
595  {
596  GridOperator<InGridType, OutGridType, MapT, OpT, InterruptT> op(mInputGrid, map);
597  mOutputGrid = op.process(mThreaded); // cache the result
598  }
599  const bool mThreaded;
601  typename OutGridType::Ptr mOutputGrid;
602  InterruptT* mInterrupt;
603  }; // Private Functor
604 
606  InterruptT* mInterrupt;
607 }; // end of Magnitude class
608 
609 
611 
612 
613 template<typename GridT, typename InterruptT = util::NullInterrupter>
615 {
616 public:
617  typedef GridT InGridType;
618  typedef GridT OutGridType;
619  Normalize(const GridT& grid, InterruptT* interrupt = NULL):
620  mInputGrid(grid), mInterrupt(interrupt)
621  {
622  }
623  typename GridT::Ptr process(bool threaded = true)
624  {
625  Functor functor(mInputGrid, threaded, mInterrupt);
626  processTypedMap(mInputGrid.transform(), functor);
627  return functor.mOutputGrid;
628  }
629 
630 protected:
631  struct OpT
632  {
633  template<typename MapT, typename AccT>
634  static typename OutGridType::ValueType
635  result(const MapT&, const AccT& acc, const Coord& xyz)
636  {
637  typename OutGridType::ValueType vec = acc.getValue(xyz);
638  if ( !vec.normalize() ) vec.setZero();
639  return vec;
640  }
641  };
642  struct Functor
643  {
644  Functor(const GridT& grid, bool threaded, InterruptT* interrupt):
645  mThreaded(threaded), mInputGrid(grid), mInterrupt(interrupt) {}
646  template<typename MapT>
647  void operator()(const MapT& map)
648  {
649  GridOperator<GridT, GridT, MapT, OpT, InterruptT> op(mInputGrid, map);
650  mOutputGrid = op.process(mThreaded); // cache the result
651  }
652  const bool mThreaded;
653  const GridT& mInputGrid;
654  typename GridT::Ptr mOutputGrid;
655  InterruptT* mInterrupt;
656  }; // Private Functor
657 
658  const GridT& mInputGrid;
659  InterruptT* mInterrupt;
660 }; // end of Normalize class
661 
662 
664 
665 
666 template<typename GridType, typename InterruptT> inline
668 cpt(const GridType& grid, bool threaded, InterruptT* interrupt)
669 {
670  Cpt<GridType, InterruptT> op(grid, interrupt);
671  return op.process(threaded);
672 }
673 
674 template<typename GridType, typename InterruptT> inline
675 typename GridType::Ptr
676 curl(const GridType& grid, bool threaded, InterruptT* interrupt)
677 {
678  Curl<GridType, InterruptT> op(grid, interrupt);
679  return op.process(threaded);
680 }
681 
682 template<typename GridType, typename InterruptT> inline
683 typename VectorToScalarConverter<GridType>::Type::Ptr
684 divergence(const GridType& grid, bool threaded, InterruptT* interrupt)
685 {
686  Divergence<GridType, InterruptT> op(grid, interrupt);
687  return op.process(threaded);
688 }
689 
690 template<typename GridType, typename InterruptT> inline
691 typename ScalarToVectorConverter<GridType>::Type::Ptr
692 gradient(const GridType& grid, bool threaded, InterruptT* interrupt)
693 {
694  Gradient<GridType, InterruptT> op(grid, interrupt);
695  return op.process(threaded);
696 }
697 
698 template<typename GridType, typename InterruptT> inline
699 typename GridType::Ptr
700 laplacian(const GridType& grid, bool threaded, InterruptT* interrupt)
701 {
702  Laplacian<GridType, InterruptT> op(grid, interrupt);
703  return op.process(threaded);
704 }
705 
706 template<typename GridType, typename InterruptT> inline
707 typename GridType::Ptr
708 meanCurvature(const GridType& grid, bool threaded, InterruptT* interrupt)
709 {
710  MeanCurvature<GridType, InterruptT> op(grid, interrupt);
711  return op.process(threaded);
712 }
713 
714 template<typename GridType, typename InterruptT> inline
715 typename VectorToScalarConverter<GridType>::Type::Ptr
716 magnitude(const GridType& grid, bool threaded, InterruptT* interrupt)
717 {
718  Magnitude<GridType, InterruptT> op(grid, interrupt);
719  return op.process(threaded);
720 }
721 
722 template<typename GridType, typename InterruptT> inline
723 typename GridType::Ptr
724 normalize(const GridType& grid, bool threaded, InterruptT* interrupt)
725 {
726  Normalize<GridType, InterruptT> op(grid, interrupt);
727  return op.process(threaded);
728 }
729 
730 } // namespace tools
731 } // namespace OPENVDB_VERSION_NAME
732 } // namespace openvdb
733 
734 #endif // OPENVDB_TOOLS_GRID_OPERATORS_HAS_BEEN_INCLUDED
735 
736 // Copyright (c) 2012-2013 DreamWorks Animation LLC
737 // All rights reserved. This software is distributed under the
738 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )