OpenVDB  1.1.0
Grid.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 
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(); }
336  Vec3d voxelSize(const Vec3d& xyz) const { return transform().voxelSize(xyz); }
338  bool hasUniformVoxels() const { return mTransform->hasUniformScale(); }
340 
341  Vec3d indexToWorld(const Vec3d& xyz) const { return transform().indexToWorld(xyz); }
342  Vec3d indexToWorld(const Coord& ijk) const { return transform().indexToWorld(ijk); }
344 
345  Vec3d worldToIndex(const Vec3d& xyz) const { return transform().worldToIndex(xyz); }
346 
347 
348  //
349  // I/O methods
350  //
353  virtual void readTopology(std::istream&) = 0;
356  virtual void writeTopology(std::ostream&) const = 0;
357 
359  virtual void readBuffers(std::istream&) = 0;
361  virtual void writeBuffers(std::ostream&) const = 0;
362 
364  void readTransform(std::istream& is) { transform().read(is); }
366  void writeTransform(std::ostream& os) const { transform().write(os); }
367 
369  virtual void print(std::ostream& = std::cout, int verboseLevel = 1) const = 0;
370 
371 
372 protected:
374  GridBase(): mTransform(math::Transform::createLinearTransform()) {}
375 
377  GridBase(const GridBase& other): MetaMap(other), mTransform(other.mTransform->copy()) {}
378 
380  GridBase(const GridBase& other, ShallowCopy): MetaMap(other), mTransform(other.mTransform) {}
381 
383  static void registerGrid(const Name& type, GridFactory);
385  static void unregisterGrid(const Name& type);
386 
387 
388 private:
389  math::Transform::Ptr mTransform;
390 }; // class GridBase
391 
392 
394 
395 
396 typedef std::vector<GridBase::Ptr> GridPtrVec;
397 typedef GridPtrVec::iterator GridPtrVecIter;
398 typedef GridPtrVec::const_iterator GridPtrVecCIter;
399 typedef boost::shared_ptr<GridPtrVec> GridPtrVecPtr;
400 
401 typedef std::vector<GridBase::ConstPtr> GridCPtrVec;
402 typedef GridCPtrVec::iterator GridCPtrVecIter;
403 typedef GridCPtrVec::const_iterator GridCPtrVecCIter;
404 typedef boost::shared_ptr<GridCPtrVec> GridCPtrVecPtr;
405 
406 typedef std::set<GridBase::Ptr> GridPtrSet;
407 typedef GridPtrSet::iterator GridPtrSetIter;
408 typedef GridPtrSet::const_iterator GridPtrSetCIter;
409 typedef boost::shared_ptr<GridPtrSet> GridPtrSetPtr;
410 
411 typedef std::set<GridBase::ConstPtr> GridCPtrSet;
412 typedef GridCPtrSet::iterator GridCPtrSetIter;
413 typedef GridCPtrSet::const_iterator GridCPtrSetCIter;
414 typedef boost::shared_ptr<GridCPtrSet> GridCPtrSetPtr;
415 
416 
419 {
420  GridNamePred(const Name& name): name(name) {}
421  bool operator()(const GridBase::ConstPtr& g) const { return g && g->getName() == name; }
423 };
424 
426 template<typename GridPtrContainerT>
427 inline typename GridPtrContainerT::value_type
428 findGridByName(const GridPtrContainerT& container, const Name& name)
429 {
430  typedef typename GridPtrContainerT::value_type GridPtrT;
431  typename GridPtrContainerT::const_iterator it =
432  std::find_if(container.begin(), container.end(), GridNamePred(name));
433  return (it == container.end() ? GridPtrT() : *it);
434 }
435 
437 template<typename KeyT, typename GridPtrT>
438 inline GridPtrT
439 findGridByName(const std::map<KeyT, GridPtrT>& container, const Name& name)
440 {
441  typedef std::map<KeyT, GridPtrT> GridPtrMapT;
442  for (typename GridPtrMapT::const_iterator it = container.begin(), end = container.end();
443  it != end; ++it)
444  {
445  const GridPtrT& grid = it->second;
446  if (grid && grid->getName() == name) return grid;
447  }
448  return GridPtrT();
449 }
451 
452 
454 
455 
457 template<typename _TreeType>
458 class Grid: public GridBase
459 {
460 public:
461  typedef boost::shared_ptr<Grid> Ptr;
462  typedef boost::shared_ptr<const Grid> ConstPtr;
463 
464  typedef _TreeType TreeType;
465  typedef typename _TreeType::Ptr TreePtrType;
466  typedef typename _TreeType::ConstPtr ConstTreePtrType;
467  typedef typename _TreeType::ValueType ValueType;
468 
471 
472  typedef typename _TreeType::ValueOnIter ValueOnIter;
473  typedef typename _TreeType::ValueOnCIter ValueOnCIter;
474  typedef typename _TreeType::ValueOffIter ValueOffIter;
475  typedef typename _TreeType::ValueOffCIter ValueOffCIter;
476  typedef typename _TreeType::ValueAllIter ValueAllIter;
477  typedef typename _TreeType::ValueAllCIter ValueAllCIter;
478 
485  template<typename OtherValueType>
486  struct ValueConverter {
488  };
489 
491  static Ptr create(const ValueType& background);
493  static Ptr create();
496  static Ptr create(TreePtrType);
499  static Ptr create(const GridBase& other);
500 
501 
503  Grid();
505  explicit Grid(const ValueType& background);
509  explicit Grid(TreePtrType);
511  Grid(const Grid&);
513  Grid(const Grid&, ShallowCopy);
516  Grid(const GridBase&);
517 
518  virtual ~Grid() {}
519 
521 
522 
523 
524 
525 
526 
527  Ptr copy(CopyPolicy treePolicy = CP_SHARE) const;
528  virtual GridBase::Ptr copyGrid(CopyPolicy treePolicy = CP_SHARE) const;
530 
531 
532  Ptr deepCopy() const { return Ptr(new Grid(*this)); }
533  virtual GridBase::Ptr deepCopyGrid() const { return this->deepCopy(); }
535 
537  virtual Name type() const { return this->gridType(); }
539  static Name gridType() { return TreeType::treeType(); }
540 
541 
542  //
543  // Voxel access methods
544  //
546  virtual Name valueType() const { return tree().valueType(); }
547 
549  const ValueType& background() const { return mTree->background(); }
551  void setBackground(const ValueType& val) { tree().setBackground(val); }
552 
554  virtual bool empty() const { return tree().empty(); }
556  virtual void clear() { tree().clear(); }
557 
559  Accessor getAccessor() { return Accessor(tree()); }
561 
562  ConstAccessor getAccessor() const { return ConstAccessor(tree()); }
563  ConstAccessor getConstAccessor() const { return ConstAccessor(tree()); }
565 
567 
568  ValueOnIter beginValueOn() { return tree().beginValueOn(); }
569  ValueOnCIter beginValueOn() const { return tree().cbeginValueOn(); }
570  ValueOnCIter cbeginValueOn() const { return tree().cbeginValueOn(); }
572 
573 
574  ValueOffIter beginValueOff() { return tree().beginValueOff(); }
575  ValueOffCIter beginValueOff() const { return tree().cbeginValueOff(); }
576  ValueOffCIter cbeginValueOff() const { return tree().cbeginValueOff(); }
578 
579 
580  ValueAllIter beginValueAll() { return tree().beginValueAll(); }
581  ValueAllCIter beginValueAll() const { return tree().cbeginValueAll(); }
582  ValueAllCIter cbeginValueAll() const { return tree().cbeginValueAll(); }
584 
586  void evalMinMax(ValueType& minVal, ValueType& maxVal) const;
587 
596  void fill(const CoordBBox& bbox, const ValueType& value, bool active = true);
597 
603  void signedFloodFill() { tree().signedFloodFill(); }
604 
612  void signedFloodFill(const ValueType& outside, const ValueType& inside);
613 
618  void prune(const ValueType& tolerance = zeroVal<ValueType>()) { tree().prune(tolerance); }
620  virtual void pruneGrid(float tolerance = 0.0);
621 
625  void merge(Grid& other) { tree().merge(other.tree()); }
626 
640  template<typename OtherTreeType>
641  void topologyUnion(const Grid<OtherTreeType>& other) { tree().topologyUnion(other.tree()); }
644 
645  //
646  // Statistics
647  //
649  virtual Index64 activeVoxelCount() const { return tree().activeVoxelCount(); }
651  virtual CoordBBox evalActiveVoxelBoundingBox() const;
653  virtual Coord evalActiveVoxelDim() const;
654 
657  virtual Index64 memUsage() const { return tree().memUsage(); }
658 
659 
660  //
661  // Tree methods
662  //
664 
665 
666  TreePtrType treePtr() { return mTree; }
667  ConstTreePtrType treePtr() const { return mTree; }
668  ConstTreePtrType constTreePtr() const { return mTree; }
669  virtual TreeBase::ConstPtr constBaseTreePtr() const { return mTree; }
671 
672 
673 
674 
675 
676  TreeType& tree() { return *mTree; }
677  const TreeType& tree() const { return *mTree; }
678  const TreeType& constTree() const { return *mTree; }
680 
686  virtual void setTree(TreeBase::Ptr);
687 
690  virtual void newTree();
691 
692 
693  //
694  // I/O methods
695  //
698  virtual void readTopology(std::istream&);
701  virtual void writeTopology(std::ostream&) const;
702 
704  virtual void readBuffers(std::istream&);
706  virtual void writeBuffers(std::ostream&) const;
707 
709  virtual void print(std::ostream& = std::cout, int verboseLevel = 1) const;
710 
711 
712  //
713  // Registry methods
714  //
718  static void registerGrid() { GridBase::registerGrid(Grid::gridType(), Grid::factory); }
721 
722 
723 private:
725  Grid& operator=(const Grid& other);
726 
728  static GridBase::Ptr factory() { return Grid::create(); }
729 
730  TreePtrType mTree;
731 }; // class Grid
732 
733 
735 
736 
744 template<typename GridType>
745 inline typename GridType::Ptr
747 {
748  return GridBase::grid<GridType>(grid);
749 }
750 
751 
760 template<typename GridType>
761 inline typename GridType::ConstPtr
763 {
764  return GridBase::constGrid<GridType>(grid);
765 }
766 
767 
769 
770 
777 template<typename GridType>
778 inline typename GridType::Ptr
780 {
781  if (!grid || !grid->isType<GridType>()) return typename GridType::Ptr();
782  return gridPtrCast<GridType>(grid->deepCopyGrid());
783 }
784 
785 
786 template<typename GridType>
787 inline typename GridType::Ptr
789 {
790  if (!grid.isType<GridType>()) return typename GridType::Ptr();
791  return gridPtrCast<GridType>(grid.deepCopyGrid());
792 }
794 
795 
797 
798 
800 
801 
802 template<typename _TreeType>
804 {
805  typedef _TreeType TreeType;
806  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
807  typedef typename TreeType::Ptr TreePtrType;
808  typedef typename TreeType::ConstPtr ConstTreePtrType;
809  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
812  typedef typename GridType::Ptr GridPtrType;
815  typedef typename TreeType::ValueType ValueType;
816 
817  static TreeType& tree(TreeType& t) { return t; }
818  static TreeType& tree(GridType& g) { return g.tree(); }
819  static const TreeType& tree(const TreeType& t) { return t; }
820  static const TreeType& tree(const GridType& g) { return g.tree(); }
821  static const TreeType& constTree(TreeType& t) { return t; }
822  static const TreeType& constTree(GridType& g) { return g.constTree(); }
823  static const TreeType& constTree(const TreeType& t) { return t; }
824  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
825 };
826 
827 
829 template<typename _TreeType>
830 struct TreeAdapter<Grid<_TreeType> >
831 {
832  typedef _TreeType TreeType;
833  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
834  typedef typename TreeType::Ptr TreePtrType;
835  typedef typename TreeType::ConstPtr ConstTreePtrType;
836  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
839  typedef typename GridType::Ptr GridPtrType;
842  typedef typename TreeType::ValueType ValueType;
843 
844  static TreeType& tree(TreeType& t) { return t; }
845  static TreeType& tree(GridType& g) { return g.tree(); }
846  static const TreeType& tree(const TreeType& t) { return t; }
847  static const TreeType& tree(const GridType& g) { return g.tree(); }
848  static const TreeType& constTree(TreeType& t) { return t; }
849  static const TreeType& constTree(GridType& g) { return g.constTree(); }
850  static const TreeType& constTree(const TreeType& t) { return t; }
851  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
852 };
854 
855 
857 
858 
859 template<typename GridType>
860 inline typename GridType::Ptr
862 {
863  // The string comparison on type names is slower than a dynamic_pointer_cast, but
864  // it is safer when pointers cross dso boundaries, as they do in many Houdini nodes.
865  if (grid && grid->type() == GridType::gridType()) {
866  return boost::static_pointer_cast<GridType>(grid);
867  }
868  return typename GridType::Ptr();
869 }
870 
871 
872 template<typename GridType>
873 inline typename GridType::ConstPtr
875 {
876  return boost::const_pointer_cast<const GridType>(
877  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
878 }
879 
880 
881 template<typename GridType>
882 inline typename GridType::ConstPtr
884 {
885  return boost::const_pointer_cast<const GridType>(GridBase::grid<GridType>(grid));
886 }
887 
888 
889 template<typename GridType>
890 inline typename GridType::ConstPtr
892 {
893  return boost::const_pointer_cast<const GridType>(
894  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
895 }
896 
897 
898 inline TreeBase::Ptr
900 {
901  return boost::const_pointer_cast<TreeBase>(this->constBaseTreePtr());
902 }
903 
904 
905 inline void
907 {
908  if (!xform) OPENVDB_THROW(ValueError, "Transform pointer is null");
909  mTransform = xform;
910 }
911 
912 
914 
915 
916 template<typename TreeT>
917 inline Grid<TreeT>::Grid(): mTree(new TreeType)
918 {
919 }
920 
921 
922 template<typename TreeT>
923 inline Grid<TreeT>::Grid(const ValueType &background): mTree(new TreeType(background))
924 {
925 }
926 
927 
928 template<typename TreeT>
929 inline Grid<TreeT>::Grid(TreePtrType tree): mTree(tree)
930 {
931  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
932 }
933 
934 
935 template<typename TreeT>
936 inline Grid<TreeT>::Grid(const Grid& other):
937  GridBase(other),
938  mTree(boost::static_pointer_cast<TreeType>(other.mTree->copy()))
939 {
940 }
941 
942 
943 template<typename TreeT>
944 inline Grid<TreeT>::Grid(const Grid& other, ShallowCopy):
945  GridBase(other, ShallowCopy()),
946  mTree(other.mTree)
947 {
948 }
949 
950 
951 template<typename TreeT>
952 inline Grid<TreeT>::Grid(const GridBase& other):
953  GridBase(other),
954  mTree(new TreeType)
955 {
956 }
957 
958 
959 //static
960 template<typename TreeT>
961 inline typename Grid<TreeT>::Ptr
963 {
964  return Grid::create(zeroVal<ValueType>());
965 }
966 
967 
968 //static
969 template<typename TreeT>
970 inline typename Grid<TreeT>::Ptr
971 Grid<TreeT>::create(const ValueType& background)
972 {
973  return Ptr(new Grid(background));
974 }
975 
976 
977 //static
978 template<typename TreeT>
979 inline typename Grid<TreeT>::Ptr
981 {
982  return Ptr(new Grid(tree));
983 }
984 
985 
986 //static
987 template<typename TreeT>
988 inline typename Grid<TreeT>::Ptr
990 {
991  return Ptr(new Grid(other));
992 }
993 
994 
996 
997 
998 template<typename TreeT>
999 inline typename Grid<TreeT>::Ptr
1001 {
1002  Ptr ret;
1003  switch (treePolicy) {
1004  case CP_NEW:
1005  ret.reset(new Grid(*this, ShallowCopy()));
1006  ret->newTree();
1007  break;
1008  case CP_COPY:
1009  ret.reset(new Grid(*this));
1010  break;
1011  case CP_SHARE:
1012  ret.reset(new Grid(*this, ShallowCopy()));
1013  break;
1014  }
1015  return ret;
1016 }
1017 
1018 
1019 template<typename TreeT>
1020 inline GridBase::Ptr
1022 {
1023  return this->copy(treePolicy);
1024 }
1025 
1026 
1028 
1029 
1030 template<typename TreeT>
1031 inline void
1033 {
1034  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
1035  if (tree->type() != TreeType::treeType()) {
1036  OPENVDB_THROW(TypeError, "Cannot assign a tree of type "
1037  + tree->type() + " to a grid of type " + this->type());
1038  }
1039  mTree = boost::static_pointer_cast<TreeType>(tree);
1040 }
1041 
1042 
1043 template<typename TreeT>
1044 inline void
1046 {
1047  mTree.reset(new TreeType(this->background()));
1048 }
1049 
1050 
1051 template<typename TreeT>
1052 inline void
1053 Grid<TreeT>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
1054 {
1055  tree().fill(bbox, value, active);
1056 }
1057 
1058 
1059 template<typename TreeT>
1060 inline void
1061 Grid<TreeT>::signedFloodFill(const ValueType& outside, const ValueType& inside)
1062 {
1063  tree().signedFloodFill(outside, inside);
1064 }
1065 
1066 
1067 template<typename TreeT>
1068 inline void
1069 Grid<TreeT>::pruneGrid(float tolerance)
1070 {
1071  this->prune(ValueType(zeroVal<ValueType>() + tolerance));
1072 }
1073 
1074 
1075 template<typename TreeT>
1076 inline void
1078 {
1079  tree().evalMinMax(minVal, maxVal);
1080 }
1081 
1082 
1083 template<typename TreeT>
1084 inline CoordBBox
1086 {
1087  CoordBBox bbox;
1088  tree().evalActiveVoxelBoundingBox(bbox);
1089  return bbox;
1090 }
1091 
1092 
1093 template<typename TreeT>
1094 inline Coord
1096 {
1097  Coord dim;
1098  const bool nonempty = tree().evalActiveVoxelDim(dim);
1099  return (nonempty ? dim : Coord());
1100 }
1101 
1102 
1104 
1105 
1108 
1109 template<typename TreeT>
1110 inline void
1111 Grid<TreeT>::readTopology(std::istream& is)
1112 {
1113  tree().readTopology(is, saveFloatAsHalf());
1114 }
1115 
1116 
1117 template<typename TreeT>
1118 inline void
1119 Grid<TreeT>::writeTopology(std::ostream& os) const
1120 {
1121  tree().writeTopology(os, saveFloatAsHalf());
1122 }
1123 
1124 
1125 template<typename TreeT>
1126 inline void
1127 Grid<TreeT>::readBuffers(std::istream& is)
1128 {
1129  tree().readBuffers(is, saveFloatAsHalf());
1130 }
1131 
1132 
1133 template<typename TreeT>
1134 inline void
1135 Grid<TreeT>::writeBuffers(std::ostream& os) const
1136 {
1137  tree().writeBuffers(os, saveFloatAsHalf());
1138 }
1139 
1140 
1141 template<typename TreeT>
1142 inline void
1143 Grid<TreeT>::print(std::ostream& os, int verboseLevel) const
1144 {
1145  tree().print(os, verboseLevel);
1146 
1147  if (metaCount() > 0) {
1148  os << "Additional metadata:" << std::endl;
1149  for (ConstMetaIterator it = beginMeta(), end = endMeta(); it != end; ++it) {
1150  os << " " << it->first;
1151  if (it->second) {
1152  const std::string value = it->second->str();
1153  if (!value.empty()) os << ": " << value;
1154  }
1155  os << "\n";
1156  }
1157  }
1158 
1159  os << "Transform:" << std::endl;
1160  transform().print(os, /*indent=*/" ");
1161  os << std::endl;
1162 }
1163 
1164 
1166 
1167 
1168 template<typename GridType>
1169 inline typename GridType::Ptr
1170 createGrid(const typename GridType::ValueType& background)
1171 {
1172  return GridType::create(background);
1173 }
1174 
1175 
1176 template<typename GridType>
1177 inline typename GridType::Ptr
1179 {
1180  return GridType::create();
1181 }
1182 
1183 
1184 template<typename TreePtrType>
1186 createGrid(TreePtrType tree)
1187 {
1188  typedef typename TreePtrType::element_type TreeType;
1189  return Grid<TreeType>::create(tree);
1190 }
1191 
1192 
1193 template<typename GridType>
1194 typename GridType::Ptr
1195 createLevelSet(double voxelSize, double halfWidth)
1196 {
1197  typedef typename GridType::ValueType ValueType;
1198 
1199  // GridType::ValueType is required to be a floating-point scalar.
1200  BOOST_STATIC_ASSERT(boost::is_floating_point<ValueType>::value);
1201 
1202  typename GridType::Ptr grid = GridType::create(
1203  /*background=*/static_cast<ValueType>(voxelSize * halfWidth));
1204  grid->setTransform(math::Transform::createLinearTransform(voxelSize));
1205  grid->setGridClass(GRID_LEVEL_SET);
1206  return grid;
1207 }
1208 
1209 } // namespace OPENVDB_VERSION_NAME
1210 } // namespace openvdb
1211 
1212 #endif // OPENVDB_GRID_HAS_BEEN_INCLUDED
1213 
1214 // Copyright (c) 2012-2013 DreamWorks Animation LLC
1215 // All rights reserved. This software is distributed under the
1216 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )