OpenVDB  11.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 #ifdef OPENVDB_USE_DELAYED_LOADING
58  /// @brief Open the file, read the file header and the file-level metadata,
59  /// and populate the grid descriptors, but do not load any grids into memory.
60  /// @details If @a delayLoad is true, map the file into memory and enable delayed loading
61  /// of grids, and if a notifier is provided, call it when the file gets unmapped.
62  /// @note Define the environment variable @c OPENVDB_DISABLE_DELAYED_LOAD to disable
63  /// delayed loading unconditionally.
64  /// @throw IoError if the file is not a valid VDB file.
65  /// @return @c true if the file's UUID has changed since it was last read.
66  /// @see setCopyMaxBytes
67  bool open(bool delayLoad = true, const MappedFile::Notifier& = MappedFile::Notifier());
68 #else
69  bool open(bool /*delayLoad*/ = false);
70 #endif
71 
72  /// Return @c true if the file has been opened for reading.
73  bool isOpen() const;
74 
75  /// Close the file once we are done reading from it.
76  void close();
77 
78  /// @brief Return this file's current size on disk in bytes.
79  /// @throw IoError if the file size cannot be determined.
80  Index64 getSize() const;
81 
82 #ifdef OPENVDB_USE_DELAYED_LOADING
83  /// @brief Return the size in bytes above which this file will not be
84  /// automatically copied during delayed loading.
85  Index64 copyMaxBytes() const;
86  /// @brief If this file is opened with delayed loading enabled, make a private copy
87  /// of the file if its size in bytes is less than the specified value.
88  /// @details Making a private copy ensures that the file can't change on disk
89  /// before it has been fully read.
90  /// @warning If the file is larger than this size, it is the user's responsibility
91  /// to ensure that it does not change on disk before it has been fully read.
92  /// Undefined behavior and/or a crash might result otherwise.
93  /// @note Copying is enabled by default, but it can be disabled for individual files
94  /// by setting the maximum size to zero bytes. A default size limit can be specified
95  /// by setting the environment variable @c OPENVDB_DELAYED_LOAD_COPY_MAX_BYTES
96  /// to the desired number of bytes.
97  void setCopyMaxBytes(Index64 bytes);
98 #endif
99 
100  /// Return @c true if a grid of the given name exists in this file.
101  bool hasGrid(const Name&) const;
102 
103  /// Return (in a newly created MetaMap) the file-level metadata.
104  MetaMap::Ptr getMetadata() const;
105 
106  /// Read the entire contents of the file and return a list of grid pointers.
107  GridPtrVecPtr getGrids() const;
108 
109  /// @brief Read just the grid metadata and transforms from the file and return a list
110  /// of pointers to grids that are empty except for their metadata and transforms.
111  /// @throw IoError if this file is not open for reading.
112  GridPtrVecPtr readAllGridMetadata();
113 
114  /// @brief Read a grid's metadata and transform only.
115  /// @return A pointer to a grid that is empty except for its metadata and transform.
116  /// @throw IoError if this file is not open for reading.
117  /// @throw KeyError if no grid with the given name exists in this file.
118  GridBase::Ptr readGridMetadata(const Name&);
119 
120  /// Read an entire grid, including all of its data blocks.
121  GridBase::Ptr readGrid(const Name&);
122  /// @brief Read a grid, including its data blocks, but only where it
123  /// intersects the given world-space bounding box.
124  GridBase::Ptr readGrid(const Name&, const BBoxd&);
125 
126  /// @todo GridPtrVec readAllGrids(const Name&)
127 
128  /// @brief Write the grids in the given container to the file whose name
129  /// was given in the constructor.
130  void write(const GridCPtrVec&, const MetaMap& = MetaMap()) const override;
131 
132  /// @brief Write the grids in the given container to the file whose name
133  /// was given in the constructor.
134  template<typename GridPtrContainerT>
135  void write(const GridPtrContainerT&, const MetaMap& = MetaMap()) const;
136 
137  /// A const iterator that iterates over all names in the file. This is only
138  /// valid once the file has been opened.
140  {
141  public:
142  NameIterator(const NameMapCIter& iter): mIter(iter) {}
143  NameIterator(const NameIterator&) = default;
145 
146  NameIterator& operator++() { mIter++; return *this; }
147 
148  bool operator==(const NameIterator& iter) const { return mIter == iter.mIter; }
149  bool operator!=(const NameIterator& iter) const { return mIter != iter.mIter; }
150 
151  Name operator*() const { return this->gridName(); }
152 
153  Name gridName() const { return GridDescriptor::nameAsString(mIter->second.uniqueName()); }
154 
155  private:
156  NameMapCIter mIter;
157  };
158 
159  /// @return a NameIterator to iterate over all grid names in the file.
160  NameIterator beginName() const;
161 
162  /// @return the ending iterator for all grid names in the file.
163  NameIterator endName() const;
164 
165 private:
166  /// Read in all grid descriptors that are stored in the given stream.
167  void readGridDescriptors(std::istream&);
168 
169  /// @brief Return an iterator to the descriptor for the grid with the given name.
170  /// If the name is non-unique, return an iterator to the first matching descriptor.
171  NameMapCIter findDescriptor(const Name&) const;
172 
173  /// Return a newly created, empty grid of the type specified by the given grid descriptor.
175 
176  /// @brief Read a grid, including its data blocks, but only where it
177  /// intersects the given world-space bounding box.
178  GridBase::Ptr readGridByName(const Name&, const BBoxd&);
179 
180  /// Read in and return the partially-populated grid specified by the given grid descriptor.
181  GridBase::ConstPtr readGridPartial(const GridDescriptor&, bool readTopology) const;
182 
183  /// Read in and return the grid specified by the given grid descriptor.
184  GridBase::Ptr readGrid(const GridDescriptor&) const;
185  /// Read in and return the region of the grid specified by the given grid descriptor
186  /// that intersects the given world-space bounding box.
187  GridBase::Ptr readGrid(const GridDescriptor&, const BBoxd&) const;
188  /// Read in and return the region of the grid specified by the given grid descriptor
189  /// that intersects the given index-space bounding box.
190  GridBase::Ptr readGrid(const GridDescriptor&, const CoordBBox&) const;
191 
192  /// @brief Partially populate the given grid by reading its metadata and transform and,
193  /// if the grid is not an instance, its tree structure, but not the tree's leaf nodes.
194  void readGridPartial(GridBase::Ptr, std::istream&, bool isInstance, bool readTopology) const;
195 
196  /// @brief Retrieve a grid from @c mNamedGrids. Return a null pointer
197  /// if @c mNamedGrids was not populated (because this file is random-access).
198  /// @throw KeyError if no grid with the given name exists in this file.
199  GridBase::Ptr retrieveCachedGrid(const Name&) const;
200 
201  void writeGrids(const GridCPtrVec&, const MetaMap&) const;
202 
203  MetaMap::Ptr fileMetadata();
204  MetaMap::ConstPtr fileMetadata() const;
205 
206  const NameMap& gridDescriptors() const;
207  NameMap& gridDescriptors();
208 
209  std::istream& inputStream() const;
210 
211  friend class ::TestFile;
212  friend class ::TestStream;
213 
214  struct Impl;
215  std::unique_ptr<Impl> mImpl;
216 };
217 
218 
219 ////////////////////////////////////////
220 
221 
222 inline void
223 File::write(const GridCPtrVec& grids, const MetaMap& meta) const
224 {
225  this->writeGrids(grids, meta);
226 }
227 
228 
229 template<typename GridPtrContainerT>
230 inline void
231 File::write(const GridPtrContainerT& container, const MetaMap& meta) const
232 {
233  GridCPtrVec grids;
234  std::copy(container.begin(), container.end(), std::back_inserter(grids));
235  this->writeGrids(grids, meta);
236 }
237 
238 } // namespace io
239 } // namespace OPENVDB_VERSION_NAME
240 } // namespace openvdb
241 
242 #endif // OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
#define OPENVDB_API
Definition: Platform.h:274
GridType::Ptr createGrid(const typename GridType::ValueType &background)
Create a new grid of type GridType with a given background value.
Definition: Grid.h:1722
SharedPtr< const GridBase > ConstPtr
Definition: Grid.h:81
bool hasGrid(const std::string &fileName, const std::string &gridName)
Return true if the file contains a grid with the specified name.
Definition: IO.h:715
static fileSize_t write(std::ostream &os, const GridHandle< BufferT > &handle, Codec codec, uint32_t n)
std::shared_ptr< T > SharedPtr
Definition: Types.h:114
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition: Grid.h:513
std::multimap< Name, GridDescriptor > NameMap
Definition: File.h:33
BBox< Coord > CoordBBox
Definition: NanoVDB.h:2535
bool operator!=(const NameIterator &iter) const
Definition: File.h:149
uint64_t Index64
Definition: Types.h:53
Grid serializer/unserializer.
Definition: Archive.h:31
Container that maps names (strings) to values of arbitrary types.
Definition: MetaMap.h:19
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition: Grid.h:511
NameMap::const_iterator NameMapCIter
Definition: File.h:34
Definition: Exceptions.h:13
Grid archive associated with a file on disk.
Definition: File.h:30
NameIterator(const NameMapCIter &iter)
Definition: File.h:142
NameIterator & operator++()
Definition: File.h:146
Name gridName() const
Definition: File.h:153
std::string Name
Definition: Name.h:19
GridHandle< BufferT > readGrid(const std::string &fileName, int n=0, int verbose=0, const BufferT &buffer=BufferT())
Read and return one or all grids from a file into a single GridHandle.
Definition: IO.h:580
SharedPtr< MetaMap > Ptr
Definition: MetaMap.h:22
Name operator*() const
Definition: File.h:151
SharedPtr< GridBase > Ptr
Definition: Grid.h:80
Definition: GridDescriptor.h:19
SharedPtr< const MetaMap > ConstPtr
Definition: MetaMap.h:23
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h.in:121
bool operator==(const NameIterator &iter) const
Definition: File.h:148
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:508
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h.in:212
~NameIterator()
Definition: File.h:144