OpenVDB  0.104.0
Grid.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 
31 #ifndef OPENVDB_GRID_HAS_BEEN_INCLUDED
32 #define OPENVDB_GRID_HAS_BEEN_INCLUDED
33 
34 #include <iostream>
35 #include <set>
36 #include <vector>
37 #include <boost/static_assert.hpp>
38 #include <boost/type_traits/remove_const.hpp>
39 #include <boost/type_traits/is_floating_point.hpp>
40 #include <openvdb/Types.h>
41 #include <openvdb/util/Name.h>
42 #include <openvdb/math/Transform.h>
43 #include <openvdb/tree/Tree.h>
44 #include <openvdb/metadata/MetaMap.h>
45 #include <openvdb/Exceptions.h>
46 
47 
48 namespace openvdb {
50 namespace OPENVDB_VERSION_NAME {
51 
53 
54 template<typename> class Grid; // forward declaration
55 
56 
61 template<typename GridType>
62 inline typename GridType::Ptr createGrid(const typename GridType::ValueType& background);
63 
64 
68 template<typename GridType>
69 inline typename GridType::Ptr createGrid();
70 
71 
76 template<typename TreePtrType>
78 
79 
94 template<typename GridType>
95 typename GridType::Ptr createLevelSet(
96  double voxelSize = 1.0, double halfWidth = LEVEL_SET_HALF_WIDTH);
97 
98 
100 
101 
104 {
105 public:
106  typedef boost::shared_ptr<GridBase> Ptr;
107  typedef boost::shared_ptr<const GridBase> ConstPtr;
108 
109  typedef Ptr (*GridFactory)();
110 
111 
112  virtual ~GridBase() {}
113 
116  virtual GridBase::Ptr copyGrid(CopyPolicy treePolicy = CP_SHARE) const = 0;
117 
119  virtual GridBase::Ptr deepCopyGrid() const = 0;
120 
121 
122  //
123  // Registry methods
124  //
126  static Ptr createGrid(const Name& type);
127 
129  static bool isRegistered(const Name &type);
130 
132  static void clearRegistry();
133 
134 
135  //
136  // Grid type methods
137  //
139  virtual Name type() const = 0;
141  virtual Name valueType() const = 0;
142 
144  template<typename GridType>
145  bool isType() const { return (this->type() == GridType::gridType()); }
146 
148 
149 
150  template<typename GridType>
151  static typename GridType::Ptr grid(const GridBase::Ptr&);
152  template<typename GridType>
153  static typename GridType::ConstPtr grid(const GridBase::ConstPtr&);
154  template<typename GridType>
155  static typename GridType::ConstPtr constGrid(const GridBase::Ptr&);
156  template<typename GridType>
157  static typename GridType::ConstPtr constGrid(const GridBase::ConstPtr&);
159 
161 
162 
163  TreeBase::Ptr baseTreePtr();
164  TreeBase::ConstPtr baseTreePtr() const { return this->constBaseTreePtr(); }
165  virtual TreeBase::ConstPtr constBaseTreePtr() const = 0;
167 
169 
170 
171 
172 
173  TreeBase& baseTree() { return const_cast<TreeBase&>(this->constBaseTree()); }
174  const TreeBase& baseTree() const { return this->constBaseTree(); }
175  const TreeBase& constBaseTree() const { return *(this->constBaseTreePtr()); }
177 
183  virtual void setTree(TreeBase::Ptr) = 0;
184 
186  virtual void newTree() = 0;
187 
189  virtual bool empty() const = 0;
191  virtual void clear() = 0;
192 
198  virtual void pruneGrid(float tolerance = 0.0) = 0;
199 
200 
201  //
202  // Metadata
203  //
205  std::string getName() const;
207  void setName(const std::string&);
208 
210  std::string getCreator() const;
212  void setCreator(const std::string&);
213 
216  bool saveFloatAsHalf() const;
217  void setSaveFloatAsHalf(bool);
218 
220  GridClass getGridClass() const;
222  void setGridClass(GridClass);
224  void clearGridClass();
225 
227  static std::string gridClassToString(GridClass);
229  static std::string gridClassToMenuName(GridClass);
233  static GridClass stringToGridClass(const std::string&);
234 
237  VecType getVectorType() const;
240  void setVectorType(VecType);
242  void clearVectorType();
243 
245  static std::string vecTypeToString(VecType);
248  static std::string vecTypeExamples(VecType);
251  static std::string vecTypeDescription(VecType);
252  static VecType stringToVecType(const std::string&);
253 
257  bool isInWorldSpace() const;
259  void setIsInWorldSpace(bool);
260 
261  // Standard metadata field names
262  // (These fields should normally not be accessed directly, but rather
263  // via the accessor methods above, when available.)
264  // Note: Visual C++ requires these declarations to be separate statements.
265  static const char* const META_GRID_CLASS;
266  static const char* const META_GRID_CREATOR;
267  static const char* const META_GRID_NAME;
268  static const char* const META_SAVE_HALF_FLOAT;
269  static const char* const META_IS_LOCAL_SPACE;
270  static const char* const META_VECTOR_TYPE;
271  static const char* const META_FILE_BBOX_MIN;
272  static const char* const META_FILE_BBOX_MAX;
273  static const char* const META_FILE_COMPRESSION;
274  static const char* const META_FILE_MEM_BYTES;
275  static const char* const META_FILE_VOXEL_COUNT;
276 
277 
278  //
279  // Statistics
280  //
282  virtual Index64 activeVoxelCount() const = 0;
283 
286  virtual CoordBBox evalActiveVoxelBoundingBox() const = 0;
287 
289  virtual Coord evalActiveVoxelDim() const = 0;
290 
292  virtual Index64 memUsage() const = 0;
293 
298  void addStatsMetadata();
303  MetaMap::Ptr getStatsMetadata() const;
304 
305 
306  //
307  // Transform methods
308  //
310 
311 
312  math::Transform::Ptr transformPtr() { return mTransform; }
313  math::Transform::ConstPtr transformPtr() const { return mTransform; }
314  math::Transform::ConstPtr constTransformPtr() const { return mTransform; }
316 
317 
318 
319 
320 
321  math::Transform& transform() { return *mTransform; }
322  const math::Transform& transform() const { return *mTransform; }
323  const math::Transform& constTransform() const { return *mTransform; }
325 
326 
327 
328 
329 
330  void setTransform(math::Transform::Ptr);
331 
333  Vec3d voxelSize() const { return transform().voxelSize(); }
334  OPENVDB_DEPRECATED Vec3d voxelDimensions() const { return transform().voxelSize(); }
337  Vec3d voxelSize(const Vec3d& xyz) const { return transform().voxelSize(xyz); }
338  OPENVDB_DEPRECATED Vec3d voxelDimensions(const Vec3d& xyz) const { return transform().voxelSize(xyz); }
340  bool hasUniformVoxels() const { return mTransform->hasUniformScale(); }
342 
343  Vec3d indexToWorld(const Vec3d& xyz) const { return transform().indexToWorld(xyz); }
344  Vec3d indexToWorld(const Coord& ijk) const { return transform().indexToWorld(ijk); }
346 
347  Vec3d worldToIndex(const Vec3d& xyz) const { return transform().worldToIndex(xyz); }
348 
349 
350  //
351  // I/O methods
352  //
355  virtual void readTopology(std::istream&) = 0;
358  virtual void writeTopology(std::ostream&) const = 0;
359 
361  virtual void readBuffers(std::istream&) = 0;
363  virtual void writeBuffers(std::ostream&) const = 0;
364 
366  void readTransform(std::istream& is) { transform().read(is); }
368  void writeTransform(std::ostream& os) const { transform().write(os); }
369 
371  virtual void print(std::ostream& = std::cout, int verboseLevel = 1) const = 0;
372 
373 
374 protected:
376  GridBase(): mTransform(math::Transform::createLinearTransform()) {}
377 
379  GridBase(const GridBase& other): MetaMap(other), mTransform(other.mTransform->copy()) {}
380 
382  GridBase(const GridBase& other, ShallowCopy): MetaMap(other), mTransform(other.mTransform) {}
383 
385  static void registerGrid(const Name& type, GridFactory);
387  static void unregisterGrid(const Name& type);
388 
389 
390 private:
391  math::Transform::Ptr mTransform;
392 }; // class GridBase
393 
394 
396 
397 
398 typedef std::vector<GridBase::Ptr> GridPtrVec;
399 typedef GridPtrVec::iterator GridPtrVecIter;
400 typedef GridPtrVec::const_iterator GridPtrVecCIter;
401 typedef boost::shared_ptr<GridPtrVec> GridPtrVecPtr;
402 
403 typedef std::vector<GridBase::ConstPtr> GridCPtrVec;
404 typedef GridCPtrVec::iterator GridCPtrVecIter;
405 typedef GridCPtrVec::const_iterator GridCPtrVecCIter;
406 typedef boost::shared_ptr<GridCPtrVec> GridCPtrVecPtr;
407 
408 typedef std::set<GridBase::Ptr> GridPtrSet;
409 typedef GridPtrSet::iterator GridPtrSetIter;
410 typedef GridPtrSet::const_iterator GridPtrSetCIter;
411 typedef boost::shared_ptr<GridPtrSet> GridPtrSetPtr;
412 
413 typedef std::set<GridBase::ConstPtr> GridCPtrSet;
414 typedef GridCPtrSet::iterator GridCPtrSetIter;
415 typedef GridCPtrSet::const_iterator GridCPtrSetCIter;
416 typedef boost::shared_ptr<GridCPtrSet> GridCPtrSetPtr;
417 
418 
421 {
422  GridNamePred(const Name& name): name(name) {}
423  bool operator()(const GridBase::ConstPtr& g) const { return g && g->getName() == name; }
425 };
426 
428 template<typename GridPtrContainerT>
429 inline typename GridPtrContainerT::value_type
430 findGridByName(const GridPtrContainerT& container, const Name& name)
431 {
432  typedef typename GridPtrContainerT::value_type GridPtrT;
433  typename GridPtrContainerT::const_iterator it =
434  std::find_if(container.begin(), container.end(), GridNamePred(name));
435  return (it == container.end() ? GridPtrT() : *it);
436 }
437 
439 template<typename KeyT, typename GridPtrT>
440 inline GridPtrT
441 findGridByName(const std::map<KeyT, GridPtrT>& container, const Name& name)
442 {
443  typedef std::map<KeyT, GridPtrT> GridPtrMapT;
444  for (typename GridPtrMapT::const_iterator it = container.begin(), end = container.end();
445  it != end; ++it)
446  {
447  const GridPtrT& grid = it->second;
448  if (grid && grid->getName() == name) return grid;
449  }
450  return GridPtrT();
451 }
453 
454 
456 
457 
459 template<typename _TreeType>
460 class Grid: public GridBase
461 {
462 public:
463  typedef boost::shared_ptr<Grid> Ptr;
464  typedef boost::shared_ptr<const Grid> ConstPtr;
465 
466  typedef _TreeType TreeType;
467  typedef typename _TreeType::Ptr TreePtrType;
468  typedef typename _TreeType::ConstPtr ConstTreePtrType;
469  typedef typename _TreeType::ValueType ValueType;
470 
473 
474  typedef typename _TreeType::ValueOnIter ValueOnIter;
475  typedef typename _TreeType::ValueOnCIter ValueOnCIter;
476  typedef typename _TreeType::ValueOffIter ValueOffIter;
477  typedef typename _TreeType::ValueOffCIter ValueOffCIter;
478  typedef typename _TreeType::ValueAllIter ValueAllIter;
479  typedef typename _TreeType::ValueAllCIter ValueAllCIter;
480 
487  template<typename OtherValueType>
488  struct ValueConverter {
490  };
491 
493  static Ptr create(const ValueType& background);
495  static Ptr create();
498  static Ptr create(TreePtrType);
501  static Ptr create(const GridBase& other);
502 
503 
505  Grid();
507  explicit Grid(const ValueType& background);
511  explicit Grid(TreePtrType);
513  Grid(const Grid&);
515  Grid(const Grid&, ShallowCopy);
518  Grid(const GridBase&);
519 
520  virtual ~Grid() {}
521 
523 
524 
525 
526 
527 
528 
529  Ptr copy(CopyPolicy treePolicy = CP_SHARE) const;
530  virtual GridBase::Ptr copyGrid(CopyPolicy treePolicy = CP_SHARE) const;
532 
533 
534  Ptr deepCopy() const { return Ptr(new Grid(*this)); }
535  virtual GridBase::Ptr deepCopyGrid() const { return this->deepCopy(); }
537 
539  virtual Name type() const { return this->gridType(); }
541  static Name gridType() { return TreeType::treeType(); }
542 
543 
544  //
545  // Voxel access methods
546  //
548  virtual Name valueType() const { return tree().valueType(); }
549 
551  ValueType background() const { return tree().getBackground(); }
553  void setBackground(const ValueType& val) { tree().setBackground(val); }
554 
556  virtual bool empty() const { return tree().empty(); }
558  virtual void clear() { tree().clear(); }
559 
561  Accessor getAccessor() { return Accessor(tree()); }
563 
564  ConstAccessor getAccessor() const { return ConstAccessor(tree()); }
565  ConstAccessor getConstAccessor() const { return ConstAccessor(tree()); }
567 
569 
570  ValueOnIter beginValueOn() { return tree().beginValueOn(); }
571  ValueOnCIter beginValueOn() const { return tree().cbeginValueOn(); }
572  ValueOnCIter cbeginValueOn() const { return tree().cbeginValueOn(); }
574 
575 
576  ValueOffIter beginValueOff() { return tree().beginValueOff(); }
577  ValueOffCIter beginValueOff() const { return tree().cbeginValueOff(); }
578  ValueOffCIter cbeginValueOff() const { return tree().cbeginValueOff(); }
580 
581 
582  ValueAllIter beginValueAll() { return tree().beginValueAll(); }
583  ValueAllCIter beginValueAll() const { return tree().cbeginValueAll(); }
584  ValueAllCIter cbeginValueAll() const { return tree().cbeginValueAll(); }
586 
588  void evalMinMax(ValueType& minVal, ValueType& maxVal) const;
589 
598  void fill(const CoordBBox& bbox, const ValueType& value, bool active = true);
599 
604  void signedFloodFill() { tree().signedFloodFill(); }
605 
610  void prune(const ValueType& tolerance = zeroVal<ValueType>()) { tree().prune(tolerance); }
612  virtual void pruneGrid(float tolerance = 0.0);
613 
617  void merge(Grid& other) { tree().merge(other.tree()); }
618 
626  template<typename OtherTreeType>
627  void topologyUnion(const Grid<OtherTreeType>& other) { tree().topologyUnion(other.tree()); }
630 
631  //
632  // Statistics
633  //
635  virtual Index64 activeVoxelCount() const { return tree().activeVoxelCount(); }
637  virtual CoordBBox evalActiveVoxelBoundingBox() const;
639  virtual Coord evalActiveVoxelDim() const;
640 
643  virtual Index64 memUsage() const { return tree().memUsage(); }
644 
645 
646  //
647  // Tree methods
648  //
650 
651 
652  TreePtrType treePtr() { return mTree; }
653  ConstTreePtrType treePtr() const { return mTree; }
654  ConstTreePtrType constTreePtr() const { return mTree; }
655  virtual TreeBase::ConstPtr constBaseTreePtr() const { return mTree; }
657 
658 
659 
660 
661 
662  TreeType& tree() { return *mTree; }
663  const TreeType& tree() const { return *mTree; }
664  const TreeType& constTree() const { return *mTree; }
666 
672  virtual void setTree(TreeBase::Ptr);
673 
676  virtual void newTree();
677 
678 
679  //
680  // I/O methods
681  //
684  virtual void readTopology(std::istream&);
687  virtual void writeTopology(std::ostream&) const;
688 
690  virtual void readBuffers(std::istream&);
692  virtual void writeBuffers(std::ostream&) const;
693 
695  virtual void print(std::ostream& = std::cout, int verboseLevel = 1) const;
696 
697 
698  //
699  // Registry methods
700  //
704  static void registerGrid() { GridBase::registerGrid(Grid::gridType(), Grid::factory); }
707 
708 
709 private:
711  Grid& operator=(const Grid& other);
712 
714  static GridBase::Ptr factory() { return Grid::create(); }
715 
716  TreePtrType mTree;
717 }; // class Grid
718 
719 
721 
722 
730 template<typename GridType>
731 inline typename GridType::Ptr
733 {
734  return GridBase::grid<GridType>(grid);
735 }
736 
737 
746 template<typename GridType>
747 inline typename GridType::ConstPtr
749 {
750  return GridBase::constGrid<GridType>(grid);
751 }
752 
753 
755 
756 
763 template<typename GridType>
764 inline typename GridType::Ptr
766 {
767  if (!grid || !grid->isType<GridType>()) return typename GridType::Ptr();
768  return gridPtrCast<GridType>(grid->deepCopyGrid());
769 }
770 
771 
772 template<typename GridType>
773 inline typename GridType::Ptr
775 {
776  if (!grid.isType<GridType>()) return typename GridType::Ptr();
777  return gridPtrCast<GridType>(grid.deepCopyGrid());
778 }
780 
781 
783 
784 
786 
787 
788 template<typename _TreeType>
790 {
791  typedef _TreeType TreeType;
792  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
793  typedef typename TreeType::Ptr TreePtrType;
794  typedef typename TreeType::ConstPtr ConstTreePtrType;
795  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
798  typedef typename GridType::Ptr GridPtrType;
801  typedef typename TreeType::ValueType ValueType;
802 
803  static TreeType& tree(TreeType& t) { return t; }
804  static TreeType& tree(GridType& g) { return g.tree(); }
805  static const TreeType& tree(const TreeType& t) { return t; }
806  static const TreeType& tree(const GridType& g) { return g.tree(); }
807  static const TreeType& constTree(TreeType& t) { return t; }
808  static const TreeType& constTree(GridType& g) { return g.constTree(); }
809  static const TreeType& constTree(const TreeType& t) { return t; }
810  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
811 };
812 
813 
815 template<typename _TreeType>
816 struct TreeAdapter<Grid<_TreeType> >
817 {
818  typedef _TreeType TreeType;
819  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
820  typedef typename TreeType::Ptr TreePtrType;
821  typedef typename TreeType::ConstPtr ConstTreePtrType;
822  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
825  typedef typename GridType::Ptr GridPtrType;
828  typedef typename TreeType::ValueType ValueType;
829 
830  static TreeType& tree(TreeType& t) { return t; }
831  static TreeType& tree(GridType& g) { return g.tree(); }
832  static const TreeType& tree(const TreeType& t) { return t; }
833  static const TreeType& tree(const GridType& g) { return g.tree(); }
834  static const TreeType& constTree(TreeType& t) { return t; }
835  static const TreeType& constTree(GridType& g) { return g.constTree(); }
836  static const TreeType& constTree(const TreeType& t) { return t; }
837  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
838 };
840 
841 
843 
844 
845 template<typename GridType>
846 inline typename GridType::Ptr
848 {
849  // The string comparison on type names is slower than a dynamic_pointer_cast, but
850  // it is safer when pointers cross dso boundaries, as they do in many Houdini nodes.
851  if (grid && grid->type() == GridType::gridType()) {
852  return boost::static_pointer_cast<GridType>(grid);
853  }
854  return typename GridType::Ptr();
855 }
856 
857 
858 template<typename GridType>
859 inline typename GridType::ConstPtr
861 {
862  return boost::const_pointer_cast<const GridType>(
863  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
864 }
865 
866 
867 template<typename GridType>
868 inline typename GridType::ConstPtr
870 {
871  return boost::const_pointer_cast<const GridType>(GridBase::grid<GridType>(grid));
872 }
873 
874 
875 template<typename GridType>
876 inline typename GridType::ConstPtr
878 {
879  return boost::const_pointer_cast<const GridType>(
880  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
881 }
882 
883 
884 inline TreeBase::Ptr
886 {
887  return boost::const_pointer_cast<TreeBase>(this->constBaseTreePtr());
888 }
889 
890 
891 inline void
893 {
894  if (!xform) OPENVDB_THROW(ValueError, "Transform pointer is null");
895  mTransform = xform;
896 }
897 
898 
900 
901 
902 template<typename TreeT>
903 inline Grid<TreeT>::Grid(): mTree(new TreeType)
904 {
905 }
906 
907 
908 template<typename TreeT>
909 inline Grid<TreeT>::Grid(const ValueType &background): mTree(new TreeType(background))
910 {
911 }
912 
913 
914 template<typename TreeT>
915 inline Grid<TreeT>::Grid(TreePtrType tree): mTree(tree)
916 {
917  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
918 }
919 
920 
921 template<typename TreeT>
922 inline Grid<TreeT>::Grid(const Grid& other):
923  GridBase(other),
924  mTree(boost::static_pointer_cast<TreeType>(other.mTree->copy()))
925 {
926 }
927 
928 
929 template<typename TreeT>
930 inline Grid<TreeT>::Grid(const Grid& other, ShallowCopy):
931  GridBase(other, ShallowCopy()),
932  mTree(other.mTree)
933 {
934 }
935 
936 
937 template<typename TreeT>
938 inline Grid<TreeT>::Grid(const GridBase& other):
939  GridBase(other),
940  mTree(new TreeType)
941 {
942 }
943 
944 
945 //static
946 template<typename TreeT>
947 inline typename Grid<TreeT>::Ptr
949 {
950  return Grid::create(zeroVal<ValueType>());
951 }
952 
953 
954 //static
955 template<typename TreeT>
956 inline typename Grid<TreeT>::Ptr
957 Grid<TreeT>::create(const ValueType& background)
958 {
959  return Ptr(new Grid(background));
960 }
961 
962 
963 //static
964 template<typename TreeT>
965 inline typename Grid<TreeT>::Ptr
967 {
968  return Ptr(new Grid(tree));
969 }
970 
971 
972 //static
973 template<typename TreeT>
974 inline typename Grid<TreeT>::Ptr
976 {
977  return Ptr(new Grid(other));
978 }
979 
980 
982 
983 
984 template<typename TreeT>
985 inline typename Grid<TreeT>::Ptr
986 Grid<TreeT>::copy(CopyPolicy treePolicy) const
987 {
988  Ptr ret;
989  switch (treePolicy) {
990  case CP_NEW:
991  ret.reset(new Grid(*this, ShallowCopy()));
992  ret->newTree();
993  break;
994  case CP_COPY:
995  ret.reset(new Grid(*this));
996  break;
997  case CP_SHARE:
998  ret.reset(new Grid(*this, ShallowCopy()));
999  break;
1000  }
1001  return ret;
1002 }
1003 
1004 
1005 template<typename TreeT>
1006 inline GridBase::Ptr
1008 {
1009  return this->copy(treePolicy);
1010 }
1011 
1012 
1014 
1015 
1016 template<typename TreeT>
1017 inline void
1019 {
1020  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
1021  if (tree->type() != TreeType::treeType()) {
1022  OPENVDB_THROW(TypeError, "Cannot assign a tree of type "
1023  + tree->type() + " to a grid of type " + this->type());
1024  }
1025  mTree = boost::static_pointer_cast<TreeType>(tree);
1026 }
1027 
1028 
1029 template<typename TreeT>
1030 inline void
1032 {
1033  mTree.reset(new TreeType(this->background()));
1034 }
1035 
1036 
1037 template<typename TreeT>
1038 inline void
1039 Grid<TreeT>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
1040 {
1041  tree().fill(bbox, value, active);
1042 }
1043 
1044 
1045 template<typename TreeT>
1046 inline void
1047 Grid<TreeT>::pruneGrid(float tolerance)
1048 {
1049  this->prune(ValueType(zeroVal<ValueType>() + tolerance));
1050 }
1051 
1052 
1053 template<typename TreeT>
1054 inline void
1056 {
1057  tree().evalMinMax(minVal, maxVal);
1058 }
1059 
1060 
1061 template<typename TreeT>
1062 inline CoordBBox
1064 {
1065  CoordBBox bbox;
1066  tree().evalActiveVoxelBoundingBox(bbox);
1067  return bbox;
1068 }
1069 
1070 
1071 template<typename TreeT>
1072 inline Coord
1074 {
1075  Coord dim;
1076  const bool nonempty = tree().evalActiveVoxelDim(dim);
1077  return (nonempty ? dim : Coord());
1078 }
1079 
1080 
1082 
1083 
1086 
1087 template<typename TreeT>
1088 inline void
1089 Grid<TreeT>::readTopology(std::istream& is)
1090 {
1091  tree().readTopology(is, saveFloatAsHalf());
1092 }
1093 
1094 
1095 template<typename TreeT>
1096 inline void
1097 Grid<TreeT>::writeTopology(std::ostream& os) const
1098 {
1099  tree().writeTopology(os, saveFloatAsHalf());
1100 }
1101 
1102 
1103 template<typename TreeT>
1104 inline void
1105 Grid<TreeT>::readBuffers(std::istream& is)
1106 {
1107  tree().readBuffers(is, saveFloatAsHalf());
1108 }
1109 
1110 
1111 template<typename TreeT>
1112 inline void
1113 Grid<TreeT>::writeBuffers(std::ostream& os) const
1114 {
1115  tree().writeBuffers(os, saveFloatAsHalf());
1116 }
1117 
1118 
1119 template<typename TreeT>
1120 inline void
1121 Grid<TreeT>::print(std::ostream& os, int verboseLevel) const
1122 {
1123  tree().print(os, verboseLevel);
1124 
1125  if (metaCount() > 0) {
1126  os << "Additional metadata:" << std::endl;
1127  for (ConstMetaIterator it = beginMeta(), end = endMeta(); it != end; ++it) {
1128  os << " " << it->first;
1129  if (it->second) {
1130  const std::string value = it->second->str();
1131  if (!value.empty()) os << ": " << value;
1132  }
1133  os << "\n";
1134  }
1135  }
1136 
1137  os << "Transform:" << std::endl;
1138  transform().print(os, /*indent=*/" ");
1139  os << std::endl;
1140 }
1141 
1142 
1144 
1145 
1146 template<typename GridType>
1147 inline typename GridType::Ptr
1148 createGrid(const typename GridType::ValueType& background)
1149 {
1150  return GridType::create(background);
1151 }
1152 
1153 
1154 template<typename GridType>
1155 inline typename GridType::Ptr
1157 {
1158  return GridType::create();
1159 }
1160 
1161 
1162 template<typename TreePtrType>
1164 createGrid(TreePtrType tree)
1165 {
1166  typedef typename TreePtrType::element_type TreeType;
1167  return Grid<TreeType>::create(tree);
1168 }
1169 
1170 
1171 template<typename GridType>
1172 typename GridType::Ptr
1173 createLevelSet(double voxelSize, double halfWidth)
1174 {
1175  typedef typename GridType::ValueType ValueType;
1176 
1177  // GridType::ValueType is required to be a floating-point scalar.
1178  BOOST_STATIC_ASSERT(boost::is_floating_point<ValueType>::value);
1179 
1180  typename GridType::Ptr grid = GridType::create(
1181  /*background=*/static_cast<ValueType>(voxelSize * halfWidth));
1182  grid->setTransform(math::Transform::createLinearTransform(voxelSize));
1183  grid->setGridClass(GRID_LEVEL_SET);
1184  return grid;
1185 }
1186 
1187 } // namespace OPENVDB_VERSION_NAME
1188 } // namespace openvdb
1189 
1190 #endif // OPENVDB_GRID_HAS_BEEN_INCLUDED
1191 
1192 // Copyright (c) 2012 DreamWorks Animation LLC
1193 // All rights reserved. This software is distributed under the
1194 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )