OpenVDB  9.0.0
File.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file File.h
5 
6 #ifndef OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
7 #define OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
8 
9 #include <openvdb/version.h>
10 #include "io.h" // for MappedFile::Notifier
11 #include "Archive.h"
12 #include "GridDescriptor.h"
13 #include <algorithm> // for std::copy()
14 #include <iosfwd>
15 #include <iterator> // for std::back_inserter()
16 #include <map>
17 #include <memory>
18 #include <string>
19 
20 
21 class TestFile;
22 class TestStream;
23 
24 namespace openvdb {
26 namespace OPENVDB_VERSION_NAME {
27 namespace io {
28 
29 /// Grid archive associated with a file on disk
30 class OPENVDB_API File: public Archive
31 {
32 public:
33  using NameMap = std::multimap<Name, GridDescriptor>;
34  using NameMapCIter = NameMap::const_iterator;
35 
36  explicit File(const std::string& filename);
37  ~File() override;
38 
39  /// @brief Copy constructor
40  /// @details The copy will be closed and will not reference the same
41  /// file descriptor as the original.
42  File(const File& other);
43  /// @brief Assignment
44  /// @details After assignment, this File will be closed and will not
45  /// reference the same file descriptor as the source File.
46  File& operator=(const File& other);
47 
48  /// @brief Return a copy of this archive.
49  /// @details The copy will be closed and will not reference the same
50  /// file descriptor as the original.
51  SharedPtr<Archive> copy() const override;
52 
53  /// @brief Return the name of the file with which this archive is associated.
54  /// @details The file does not necessarily exist on disk yet.
55  const std::string& filename() const;
56 
57  /// @brief Open the file, read the file header and the file-level metadata,
58  /// and populate the grid descriptors, but do not load any grids into memory.
59  /// @details If @a delayLoad is true, map the file into memory and enable delayed loading
60  /// of grids, and if a notifier is provided, call it when the file gets unmapped.
61  /// @note Define the environment variable @c OPENVDB_DISABLE_DELAYED_LOAD to disable
62  /// delayed loading unconditionally.
63  /// @throw IoError if the file is not a valid VDB file.
64  /// @return @c true if the file's UUID has changed since it was last read.
65  /// @see setCopyMaxBytes
66  bool open(bool delayLoad = true, const MappedFile::Notifier& = MappedFile::Notifier());
67 
68  /// Return @c true if the file has been opened for reading.
69  bool isOpen() const;
70 
71  /// Close the file once we are done reading from it.
72  void close();
73 
74  /// @brief Return this file's current size on disk in bytes.
75  /// @throw IoError if the file size cannot be determined.
76  Index64 getSize() const;
77 
78  /// @brief Return the size in bytes above which this file will not be
79  /// automatically copied during delayed loading.
81  /// @brief If this file is opened with delayed loading enabled, make a private copy
82  /// of the file if its size in bytes is less than the specified value.
83  /// @details Making a private copy ensures that the file can't change on disk
84  /// before it has been fully read.
85  /// @warning If the file is larger than this size, it is the user's responsibility
86  /// to ensure that it does not change on disk before it has been fully read.
87  /// Undefined behavior and/or a crash might result otherwise.
88  /// @note Copying is enabled by default, but it can be disabled for individual files
89  /// by setting the maximum size to zero bytes. A default size limit can be specified
90  /// by setting the environment variable @c OPENVDB_DELAYED_LOAD_COPY_MAX_BYTES
91  /// to the desired number of bytes.
92  void setCopyMaxBytes(Index64 bytes);
93 
94  /// Return @c true if a grid of the given name exists in this file.
95  bool hasGrid(const Name&) const;
96 
97  /// Return (in a newly created MetaMap) the file-level metadata.
99 
100  /// Read the entire contents of the file and return a list of grid pointers.
102 
103  /// @brief Read just the grid metadata and transforms from the file and return a list
104  /// of pointers to grids that are empty except for their metadata and transforms.
105  /// @throw IoError if this file is not open for reading.
107 
108  /// @brief Read a grid's metadata and transform only.
109  /// @return A pointer to a grid that is empty except for its metadata and transform.
110  /// @throw IoError if this file is not open for reading.
111  /// @throw KeyError if no grid with the given name exists in this file.
113 
114  /// Read an entire grid, including all of its data blocks.
116  /// @brief Read a grid, including its data blocks, but only where it
117  /// intersects the given world-space bounding box.
118  GridBase::Ptr readGrid(const Name&, const BBoxd&);
119 
120  /// @todo GridPtrVec readAllGrids(const Name&)
121 
122  /// @brief Write the grids in the given container to the file whose name
123  /// was given in the constructor.
124  void write(const GridCPtrVec&, const MetaMap& = MetaMap()) const override;
125 
126  /// @brief Write the grids in the given container to the file whose name
127  /// was given in the constructor.
128  template<typename GridPtrContainerT>
129  void write(const GridPtrContainerT&, const MetaMap& = MetaMap()) const;
130 
131  /// A const iterator that iterates over all names in the file. This is only
132  /// valid once the file has been opened.
134  {
135  public:
136  NameIterator(const NameMapCIter& iter): mIter(iter) {}
137  NameIterator(const NameIterator&) = default;
139 
140  NameIterator& operator++() { mIter++; return *this; }
141 
142  bool operator==(const NameIterator& iter) const { return mIter == iter.mIter; }
143  bool operator!=(const NameIterator& iter) const { return mIter != iter.mIter; }
144 
145  Name operator*() const { return this->gridName(); }
146 
147  Name gridName() const { return GridDescriptor::nameAsString(mIter->second.uniqueName()); }
148 
149  private:
150  NameMapCIter mIter;
151  };
152 
153  /// @return a NameIterator to iterate over all grid names in the file.
155 
156  /// @return the ending iterator for all grid names in the file.
158 
159 private:
160  /// Read in all grid descriptors that are stored in the given stream.
161  void readGridDescriptors(std::istream&);
162 
163  /// @brief Return an iterator to the descriptor for the grid with the given name.
164  /// If the name is non-unique, return an iterator to the first matching descriptor.
165  NameMapCIter findDescriptor(const Name&) const;
166 
167  /// Return a newly created, empty grid of the type specified by the given grid descriptor.
169 
170  /// @brief Read a grid, including its data blocks, but only where it
171  /// intersects the given world-space bounding box.
172  GridBase::Ptr readGridByName(const Name&, const BBoxd&);
173 
174  /// Read in and return the partially-populated grid specified by the given grid descriptor.
175  GridBase::ConstPtr readGridPartial(const GridDescriptor&, bool readTopology) const;
176 
177  /// Read in and return the grid specified by the given grid descriptor.
178  GridBase::Ptr readGrid(const GridDescriptor&) const;
179  /// Read in and return the region of the grid specified by the given grid descriptor
180  /// that intersects the given world-space bounding box.
181  GridBase::Ptr readGrid(const GridDescriptor&, const BBoxd&) const;
182  /// Read in and return the region of the grid specified by the given grid descriptor
183  /// that intersects the given index-space bounding box.
184  GridBase::Ptr readGrid(const GridDescriptor&, const CoordBBox&) const;
185 
186  /// @brief Partially populate the given grid by reading its metadata and transform and,
187  /// if the grid is not an instance, its tree structure, but not the tree's leaf nodes.
188  void readGridPartial(GridBase::Ptr, std::istream&, bool isInstance, bool readTopology) const;
189 
190  /// @brief Retrieve a grid from @c mNamedGrids. Return a null pointer
191  /// if @c mNamedGrids was not populated (because this file is random-access).
192  /// @throw KeyError if no grid with the given name exists in this file.
193  GridBase::Ptr retrieveCachedGrid(const Name&) const;
194 
195  void writeGrids(const GridCPtrVec&, const MetaMap&) const;
196 
197  MetaMap::Ptr fileMetadata();
198  MetaMap::ConstPtr fileMetadata() const;
199 
200  const NameMap& gridDescriptors() const;
201  NameMap& gridDescriptors();
202 
203  std::istream& inputStream() const;
204 
205  friend class ::TestFile;
206  friend class ::TestStream;
207 
208  struct Impl;
209  std::unique_ptr<Impl> mImpl;
210 };
211 
212 
213 ////////////////////////////////////////
214 
215 
216 inline void
217 File::write(const GridCPtrVec& grids, const MetaMap& meta) const
218 {
219  this->writeGrids(grids, meta);
220 }
221 
222 
223 template<typename GridPtrContainerT>
224 inline void
225 File::write(const GridPtrContainerT& container, const MetaMap& meta) const
226 {
227  GridCPtrVec grids;
228  std::copy(container.begin(), container.end(), std::back_inserter(grids));
229  this->writeGrids(grids, meta);
230 }
231 
232 } // namespace io
233 } // namespace OPENVDB_VERSION_NAME
234 } // namespace openvdb
235 
236 #endif // OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
#define OPENVDB_API
Definition: Platform.h:254
SharedPtr< const GridBase > ConstPtr
Definition: Grid.h:81
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
Container that maps names (strings) to values of arbitrary types.
Definition: MetaMap.h:20
SharedPtr< const MetaMap > ConstPtr
Definition: MetaMap.h:23
SharedPtr< MetaMap > Ptr
Definition: MetaMap.h:22
Grid serializer/unserializer.
Definition: Archive.h:33
NameIterator(const NameIterator &)=default
~NameIterator()
Definition: File.h:138
Name operator*() const
Definition: File.h:145
Name gridName() const
Definition: File.h:147
NameIterator & operator++()
Definition: File.h:140
bool operator!=(const NameIterator &iter) const
Definition: File.h:143
NameIterator(const NameMapCIter &iter)
Definition: File.h:136
bool operator==(const NameIterator &iter) const
Definition: File.h:142
Grid archive associated with a file on disk.
Definition: File.h:31
bool isOpen() const
Return true if the file has been opened for reading.
void setCopyMaxBytes(Index64 bytes)
If this file is opened with delayed loading enabled, make a private copy of the file if its size in b...
NameIterator endName() const
GridPtrVecPtr getGrids() const
Read the entire contents of the file and return a list of grid pointers.
bool hasGrid(const Name &) const
Return true if a grid of the given name exists in this file.
File(const std::string &filename)
GridBase::Ptr readGrid(const Name &, const BBoxd &)
Read a grid, including its data blocks, but only where it intersects the given world-space bounding b...
void close()
Close the file once we are done reading from it.
const std::string & filename() const
Return the name of the file with which this archive is associated.
NameMap::const_iterator NameMapCIter
Definition: File.h:34
SharedPtr< Archive > copy() const override
Return a copy of this archive.
NameIterator beginName() const
GridBase::Ptr readGrid(const Name &)
Read an entire grid, including all of its data blocks.
File & operator=(const File &other)
Assignment.
File(const File &other)
Copy constructor.
MetaMap::Ptr getMetadata() const
Return (in a newly created MetaMap) the file-level metadata.
GridBase::Ptr readGridMetadata(const Name &)
Read a grid's metadata and transform only.
bool open(bool delayLoad=true, const MappedFile::Notifier &=MappedFile::Notifier())
Open the file, read the file header and the file-level metadata, and populate the grid descriptors,...
GridPtrVecPtr readAllGridMetadata()
Read just the grid metadata and transforms from the file and return a list of pointers to grids that ...
Index64 getSize() const
Return this file's current size on disk in bytes.
Index64 copyMaxBytes() const
Return the size in bytes above which this file will not be automatically copied during delayed loadin...
std::multimap< Name, GridDescriptor > NameMap
Definition: File.h:33
Definition: GridDescriptor.h:20
std::function< void(std::string)> Notifier
Definition: io.h:156
Axis-aligned bounding box of signed integer coordinates.
Definition: Coord.h:248
static fileSize_t write(std::ostream &os, const GridHandle< BufferT > &handle, Codec codec)
void writeGrids(const std::string &fileName, const VecT< GridHandle< BufferT >> &handles, Codec codec=Codec::NONE, int verbose=0)
Write multiple grids to file (over-writing existing content of the file)
Definition: IO.h:543
GridHandle< BufferT > readGrid(const std::string &fileName, uint64_t n=0, int verbose=0, const BufferT &buffer=BufferT())
Read the n'th grid from file (defaults to first grid)
Definition: IO.h:576
std::string Name
Definition: Name.h:17
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:517
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1739
uint64_t Index64
Definition: Types.h:53
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:519
Definition: Exceptions.h:13
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:116
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:202