OpenVDB  1.2.0
Grid.h
Go to the documentation of this file.
1 //
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  Real voxelSize = 1.0, Real 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  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  TreeBase::Ptr baseTreePtr();
164  TreeBase::ConstPtr baseTreePtr() const { return this->constBaseTreePtr(); }
165  virtual TreeBase::ConstPtr constBaseTreePtr() const = 0;
167 
169  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  math::Transform::Ptr transformPtr() { return mTransform; }
313  math::Transform::ConstPtr transformPtr() const { return mTransform; }
314  math::Transform::ConstPtr constTransformPtr() const { return mTransform; }
316 
317  math::Transform& transform() { return *mTransform; }
322  const math::Transform& transform() const { return *mTransform; }
323  const math::Transform& constTransform() const { return *mTransform; }
325  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  Vec3d indexToWorld(const Vec3d& xyz) const { return transform().indexToWorld(xyz); }
342  Vec3d indexToWorld(const Coord& ijk) const { return transform().indexToWorld(ijk); }
344  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  Ptr copy(CopyPolicy treePolicy = CP_SHARE) const;
527  virtual GridBase::Ptr copyGrid(CopyPolicy treePolicy = CP_SHARE) const;
529 
530  Ptr deepCopy() const { return Ptr(new Grid(*this)); }
532  virtual GridBase::Ptr deepCopyGrid() const { return this->deepCopy(); }
534 
536  virtual Name type() const { return this->gridType(); }
538  static Name gridType() { return TreeType::treeType(); }
539 
540 
541  //
542  // Voxel access methods
543  //
545  virtual Name valueType() const { return tree().valueType(); }
546 
548  const ValueType& background() const { return mTree->background(); }
550  void setBackground(const ValueType& val) { tree().setBackground(val); }
551 
553  virtual bool empty() const { return tree().empty(); }
555  virtual void clear() { tree().clear(); }
556 
558  Accessor getAccessor() { return Accessor(tree()); }
560  ConstAccessor getAccessor() const { return ConstAccessor(tree()); }
562  ConstAccessor getConstAccessor() const { return ConstAccessor(tree()); }
564 
566  ValueOnIter beginValueOn() { return tree().beginValueOn(); }
568  ValueOnCIter beginValueOn() const { return tree().cbeginValueOn(); }
569  ValueOnCIter cbeginValueOn() const { return tree().cbeginValueOn(); }
571 
572  ValueOffIter beginValueOff() { return tree().beginValueOff(); }
574  ValueOffCIter beginValueOff() const { return tree().cbeginValueOff(); }
575  ValueOffCIter cbeginValueOff() const { return tree().cbeginValueOff(); }
577 
578  ValueAllIter beginValueAll() { return tree().beginValueAll(); }
580  ValueAllCIter beginValueAll() const { return tree().cbeginValueAll(); }
581  ValueAllCIter cbeginValueAll() const { return tree().cbeginValueAll(); }
583 
585  void evalMinMax(ValueType& minVal, ValueType& maxVal) const;
586 
595  void fill(const CoordBBox& bbox, const ValueType& value, bool active = true);
596 
602  void signedFloodFill() { tree().signedFloodFill(); }
603 
611  void signedFloodFill(const ValueType& outside, const ValueType& inside);
612 
617  void prune(const ValueType& tolerance = zeroVal<ValueType>()) { tree().prune(tolerance); }
619  virtual void pruneGrid(float tolerance = 0.0);
620 
624  void merge(Grid& other) { tree().merge(other.tree()); }
625 
639  template<typename OtherTreeType>
640  void topologyUnion(const Grid<OtherTreeType>& other) { tree().topologyUnion(other.tree()); }
643 
644  //
645  // Statistics
646  //
648  virtual Index64 activeVoxelCount() const { return tree().activeVoxelCount(); }
650  virtual CoordBBox evalActiveVoxelBoundingBox() const;
652  virtual Coord evalActiveVoxelDim() const;
653 
656  virtual Index64 memUsage() const { return tree().memUsage(); }
657 
658 
659  //
660  // Tree methods
661  //
663  TreePtrType treePtr() { return mTree; }
666  ConstTreePtrType treePtr() const { return mTree; }
667  ConstTreePtrType constTreePtr() const { return mTree; }
668  virtual TreeBase::ConstPtr constBaseTreePtr() const { return mTree; }
670 
671  TreeType& tree() { return *mTree; }
676  const TreeType& tree() const { return *mTree; }
677  const TreeType& constTree() const { return *mTree; }
679 
685  virtual void setTree(TreeBase::Ptr);
686 
689  virtual void newTree();
690 
691 
692  //
693  // I/O methods
694  //
697  virtual void readTopology(std::istream&);
700  virtual void writeTopology(std::ostream&) const;
701 
703  virtual void readBuffers(std::istream&);
705  virtual void writeBuffers(std::ostream&) const;
706 
708  virtual void print(std::ostream& = std::cout, int verboseLevel = 1) const;
709 
710 
711  //
712  // Registry methods
713  //
717  static void registerGrid() { GridBase::registerGrid(Grid::gridType(), Grid::factory); }
720 
721 
722 private:
724  Grid& operator=(const Grid& other);
725 
727  static GridBase::Ptr factory() { return Grid::create(); }
728 
729  TreePtrType mTree;
730 }; // class Grid
731 
732 
734 
735 
743 template<typename GridType>
744 inline typename GridType::Ptr
746 {
747  return GridBase::grid<GridType>(grid);
748 }
749 
750 
759 template<typename GridType>
760 inline typename GridType::ConstPtr
762 {
763  return GridBase::constGrid<GridType>(grid);
764 }
765 
766 
768 
769 
776 template<typename GridType>
777 inline typename GridType::Ptr
779 {
780  if (!grid || !grid->isType<GridType>()) return typename GridType::Ptr();
781  return gridPtrCast<GridType>(grid->deepCopyGrid());
782 }
783 
784 
785 template<typename GridType>
786 inline typename GridType::Ptr
788 {
789  if (!grid.isType<GridType>()) return typename GridType::Ptr();
790  return gridPtrCast<GridType>(grid.deepCopyGrid());
791 }
793 
794 
796 
797 
799 template<typename _TreeType>
803 {
804  typedef _TreeType TreeType;
805  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
806  typedef typename TreeType::Ptr TreePtrType;
807  typedef typename TreeType::ConstPtr ConstTreePtrType;
808  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
811  typedef typename GridType::Ptr GridPtrType;
814  typedef typename TreeType::ValueType ValueType;
818 
819  static TreeType& tree(TreeType& t) { return t; }
820  static TreeType& tree(GridType& g) { return g.tree(); }
821  static const TreeType& tree(const TreeType& t) { return t; }
822  static const TreeType& tree(const GridType& g) { return g.tree(); }
823  static const TreeType& constTree(TreeType& t) { return t; }
824  static const TreeType& constTree(GridType& g) { return g.constTree(); }
825  static const TreeType& constTree(const TreeType& t) { return t; }
826  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
827 };
828 
829 
831 template<typename _TreeType>
832 struct TreeAdapter<Grid<_TreeType> >
833 {
834  typedef _TreeType TreeType;
835  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
836  typedef typename TreeType::Ptr TreePtrType;
837  typedef typename TreeType::ConstPtr ConstTreePtrType;
838  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
841  typedef typename GridType::Ptr GridPtrType;
844  typedef typename TreeType::ValueType ValueType;
848 
849  static TreeType& tree(TreeType& t) { return t; }
850  static TreeType& tree(GridType& g) { return g.tree(); }
851  static const TreeType& tree(const TreeType& t) { return t; }
852  static const TreeType& tree(const GridType& g) { return g.tree(); }
853  static const TreeType& constTree(TreeType& t) { return t; }
854  static const TreeType& constTree(GridType& g) { return g.constTree(); }
855  static const TreeType& constTree(const TreeType& t) { return t; }
856  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
857 };
858 
860 template<typename _TreeType>
861 struct TreeAdapter<tree::ValueAccessor<_TreeType> >
862 {
863  typedef _TreeType TreeType;
864  typedef typename boost::remove_const<TreeType>::type NonConstTreeType;
865  typedef typename TreeType::Ptr TreePtrType;
866  typedef typename TreeType::ConstPtr ConstTreePtrType;
867  typedef typename NonConstTreeType::Ptr NonConstTreePtrType;
870  typedef typename GridType::Ptr GridPtrType;
873  typedef typename TreeType::ValueType ValueType;
877 
878  static TreeType& tree(TreeType& t) { return t; }
879  static TreeType& tree(GridType& g) { return g.tree(); }
880  static TreeType& tree(AccessorType& a) { return a.tree(); }
881  static const TreeType& tree(const TreeType& t) { return t; }
882  static const TreeType& tree(const GridType& g) { return g.tree(); }
883  static const TreeType& tree(const AccessorType& a) { return a.tree(); }
884  static const TreeType& constTree(TreeType& t) { return t; }
885  static const TreeType& constTree(GridType& g) { return g.constTree(); }
886  static const TreeType& constTree(const TreeType& t) { return t; }
887  static const TreeType& constTree(const GridType& g) { return g.constTree(); }
888 };
889 
891 
892 
894 
895 
896 template<typename GridType>
897 inline typename GridType::Ptr
899 {
900  // The string comparison on type names is slower than a dynamic_pointer_cast, but
901  // it is safer when pointers cross dso boundaries, as they do in many Houdini nodes.
902  if (grid && grid->type() == GridType::gridType()) {
903  return boost::static_pointer_cast<GridType>(grid);
904  }
905  return typename GridType::Ptr();
906 }
907 
908 
909 template<typename GridType>
910 inline typename GridType::ConstPtr
912 {
913  return boost::const_pointer_cast<const GridType>(
914  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
915 }
916 
917 
918 template<typename GridType>
919 inline typename GridType::ConstPtr
921 {
922  return boost::const_pointer_cast<const GridType>(GridBase::grid<GridType>(grid));
923 }
924 
925 
926 template<typename GridType>
927 inline typename GridType::ConstPtr
929 {
930  return boost::const_pointer_cast<const GridType>(
931  GridBase::grid<GridType>(boost::const_pointer_cast<GridBase>(grid)));
932 }
933 
934 
935 inline TreeBase::Ptr
937 {
938  return boost::const_pointer_cast<TreeBase>(this->constBaseTreePtr());
939 }
940 
941 
942 inline void
944 {
945  if (!xform) OPENVDB_THROW(ValueError, "Transform pointer is null");
946  mTransform = xform;
947 }
948 
949 
951 
952 
953 template<typename TreeT>
954 inline Grid<TreeT>::Grid(): mTree(new TreeType)
955 {
956 }
957 
958 
959 template<typename TreeT>
960 inline Grid<TreeT>::Grid(const ValueType &background): mTree(new TreeType(background))
961 {
962 }
963 
964 
965 template<typename TreeT>
966 inline Grid<TreeT>::Grid(TreePtrType tree): mTree(tree)
967 {
968  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
969 }
970 
971 
972 template<typename TreeT>
973 inline Grid<TreeT>::Grid(const Grid& other):
974  GridBase(other),
975  mTree(boost::static_pointer_cast<TreeType>(other.mTree->copy()))
976 {
977 }
978 
979 
980 template<typename TreeT>
981 inline Grid<TreeT>::Grid(const Grid& other, ShallowCopy):
982  GridBase(other, ShallowCopy()),
983  mTree(other.mTree)
984 {
985 }
986 
987 
988 template<typename TreeT>
989 inline Grid<TreeT>::Grid(const GridBase& other):
990  GridBase(other),
991  mTree(new TreeType)
992 {
993 }
994 
995 
996 //static
997 template<typename TreeT>
998 inline typename Grid<TreeT>::Ptr
1000 {
1001  return Grid::create(zeroVal<ValueType>());
1002 }
1003 
1004 
1005 //static
1006 template<typename TreeT>
1007 inline typename Grid<TreeT>::Ptr
1008 Grid<TreeT>::create(const ValueType& background)
1009 {
1010  return Ptr(new Grid(background));
1011 }
1012 
1013 
1014 //static
1015 template<typename TreeT>
1016 inline typename Grid<TreeT>::Ptr
1018 {
1019  return Ptr(new Grid(tree));
1020 }
1021 
1022 
1023 //static
1024 template<typename TreeT>
1025 inline typename Grid<TreeT>::Ptr
1027 {
1028  return Ptr(new Grid(other));
1029 }
1030 
1031 
1033 
1034 
1035 template<typename TreeT>
1036 inline typename Grid<TreeT>::Ptr
1038 {
1039  Ptr ret;
1040  switch (treePolicy) {
1041  case CP_NEW:
1042  ret.reset(new Grid(*this, ShallowCopy()));
1043  ret->newTree();
1044  break;
1045  case CP_COPY:
1046  ret.reset(new Grid(*this));
1047  break;
1048  case CP_SHARE:
1049  ret.reset(new Grid(*this, ShallowCopy()));
1050  break;
1051  }
1052  return ret;
1053 }
1054 
1055 
1056 template<typename TreeT>
1057 inline GridBase::Ptr
1059 {
1060  return this->copy(treePolicy);
1061 }
1062 
1063 
1065 
1066 
1067 template<typename TreeT>
1068 inline void
1070 {
1071  if (!tree) OPENVDB_THROW(ValueError, "Tree pointer is null");
1072  if (tree->type() != TreeType::treeType()) {
1073  OPENVDB_THROW(TypeError, "Cannot assign a tree of type "
1074  + tree->type() + " to a grid of type " + this->type());
1075  }
1076  mTree = boost::static_pointer_cast<TreeType>(tree);
1077 }
1078 
1079 
1080 template<typename TreeT>
1081 inline void
1083 {
1084  mTree.reset(new TreeType(this->background()));
1085 }
1086 
1087 
1088 template<typename TreeT>
1089 inline void
1090 Grid<TreeT>::fill(const CoordBBox& bbox, const ValueType& value, bool active)
1091 {
1092  tree().fill(bbox, value, active);
1093 }
1094 
1095 
1096 template<typename TreeT>
1097 inline void
1098 Grid<TreeT>::signedFloodFill(const ValueType& outside, const ValueType& inside)
1099 {
1100  tree().signedFloodFill(outside, inside);
1101 }
1102 
1103 
1104 template<typename TreeT>
1105 inline void
1107 {
1108  this->prune(ValueType(zeroVal<ValueType>() + tolerance));
1109 }
1110 
1111 
1112 template<typename TreeT>
1113 inline void
1115 {
1116  tree().evalMinMax(minVal, maxVal);
1117 }
1118 
1119 
1120 template<typename TreeT>
1121 inline CoordBBox
1123 {
1124  CoordBBox bbox;
1125  tree().evalActiveVoxelBoundingBox(bbox);
1126  return bbox;
1127 }
1128 
1129 
1130 template<typename TreeT>
1131 inline Coord
1133 {
1134  Coord dim;
1135  const bool nonempty = tree().evalActiveVoxelDim(dim);
1136  return (nonempty ? dim : Coord());
1137 }
1138 
1139 
1141 
1142 
1145 
1146 template<typename TreeT>
1147 inline void
1148 Grid<TreeT>::readTopology(std::istream& is)
1149 {
1150  tree().readTopology(is, saveFloatAsHalf());
1151 }
1152 
1153 
1154 template<typename TreeT>
1155 inline void
1156 Grid<TreeT>::writeTopology(std::ostream& os) const
1157 {
1158  tree().writeTopology(os, saveFloatAsHalf());
1159 }
1160 
1161 
1162 template<typename TreeT>
1163 inline void
1164 Grid<TreeT>::readBuffers(std::istream& is)
1165 {
1166  tree().readBuffers(is, saveFloatAsHalf());
1167 }
1168 
1169 
1170 template<typename TreeT>
1171 inline void
1172 Grid<TreeT>::writeBuffers(std::ostream& os) const
1173 {
1174  tree().writeBuffers(os, saveFloatAsHalf());
1175 }
1176 
1177 
1178 template<typename TreeT>
1179 inline void
1180 Grid<TreeT>::print(std::ostream& os, int verboseLevel) const
1181 {
1182  tree().print(os, verboseLevel);
1183 
1184  if (metaCount() > 0) {
1185  os << "Additional metadata:" << std::endl;
1186  for (ConstMetaIterator it = beginMeta(), end = endMeta(); it != end; ++it) {
1187  os << " " << it->first;
1188  if (it->second) {
1189  const std::string value = it->second->str();
1190  if (!value.empty()) os << ": " << value;
1191  }
1192  os << "\n";
1193  }
1194  }
1195 
1196  os << "Transform:" << std::endl;
1197  transform().print(os, /*indent=*/" ");
1198  os << std::endl;
1199 }
1200 
1201 
1203 
1204 
1205 template<typename GridType>
1206 inline typename GridType::Ptr
1207 createGrid(const typename GridType::ValueType& background)
1208 {
1209  return GridType::create(background);
1210 }
1211 
1212 
1213 template<typename GridType>
1214 inline typename GridType::Ptr
1216 {
1217  return GridType::create();
1218 }
1219 
1220 
1221 template<typename TreePtrType>
1223 createGrid(TreePtrType tree)
1224 {
1225  typedef typename TreePtrType::element_type TreeType;
1226  return Grid<TreeType>::create(tree);
1227 }
1228 
1229 
1230 template<typename GridType>
1231 typename GridType::Ptr
1232 createLevelSet(Real voxelSize, Real halfWidth)
1233 {
1234  typedef typename GridType::ValueType ValueType;
1235 
1236  // GridType::ValueType is required to be a floating-point scalar.
1237  BOOST_STATIC_ASSERT(boost::is_floating_point<ValueType>::value);
1238 
1239  typename GridType::Ptr grid = GridType::create(
1240  /*background=*/static_cast<ValueType>(voxelSize * halfWidth));
1241  grid->setTransform(math::Transform::createLinearTransform(voxelSize));
1242  grid->setGridClass(GRID_LEVEL_SET);
1243  return grid;
1244 }
1245 
1246 } // namespace OPENVDB_VERSION_NAME
1247 } // namespace openvdb
1248 
1249 #endif // OPENVDB_GRID_HAS_BEEN_INCLUDED
1250 
1251 // Copyright (c) 2012-2013 DreamWorks Animation LLC
1252 // All rights reserved. This software is distributed under the
1253 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )