OpenVDB 13.2.0
Loading...
Searching...
No Matches
File.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-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
21class TestFile;
22class TestStream;
23
24namespace openvdb {
26namespace OPENVDB_VERSION_NAME {
27namespace io {
28
29/// Grid archive associated with a file on disk
31{
32public:
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 /// @throw IoError if the file is not a valid VDB file.
60 /// @return @c true if the file's UUID has changed since it was last read.
61 bool open();
62
63 OPENVDB_DEPRECATED_MESSAGE("Use File::open() instead.This method is deprecated and will be removed. Delayed loading is no longer supported.")
64 bool open(bool /*delayLoad*/) { return open(); }
65 OPENVDB_DEPRECATED_MESSAGE("Use File::open() instead. This method is deprecated and will be removed. Delayed loading is no longer supported.")
66 bool open(bool /*delayLoad*/, const MappedFile::Notifier& /*notifier*/) { return open(); }
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.
77
78 OPENVDB_DEPRECATED_MESSAGE("Always returns 0. This method is deprecated and will be removed. Delayed loading is no longer supported.")
79 Index64 copyMaxBytes() const { return 0; }
80 OPENVDB_DEPRECATED_MESSAGE("This method is deprecated and will be removed. Delayed loading is no longer supported.")
81 void setCopyMaxBytes(Index64 /*bytes*/) { }
82
83 /// Return @c true if a grid of the given name exists in this file.
84 bool hasGrid(const Name&) const;
85
86 /// Return (in a newly created MetaMap) the file-level metadata.
88
89 /// @brief Read the entire contents of the file and return a list of grid pointers.
90 /// @details Instances share trees, except when clipping a file that has grid offsets,
91 /// where each grid is clipped independently.
93
94 /// @brief Read just the grid metadata and transforms from the file and return a list
95 /// of pointers to grids that are empty except for their metadata and transforms.
96 /// @throw IoError if this file is not open for reading.
98
99 /// @brief Read a grid's metadata and transform only.
100 /// @return A pointer to a grid that is empty except for its metadata and transform.
101 /// @throw IoError if this file is not open for reading.
102 /// @throw KeyError if no grid with the given name exists in this file.
104
105 /// Read an entire grid, including all of its data blocks, using the provided options if given.
107 /// @brief Read a grid, including its data blocks, but only where it
108 /// intersects the given world-space bounding box.
110
111 /// @brief Read all grids whose grid name is exactly @a name, in file order.
112 /// @details Grids have a name, such as "density", which may not be unique in a file.
113 /// When more than one grid share the same name, these names are made unique by adding
114 /// a [N] suffix. For example, the first "density" grid becomes "density[0]", the second
115 /// becomes "density[1]", etc. This method ignores the unique name and returns all grids
116 /// whose grid name exactly matches the given name.
117 /// Instances share trees as they do with getGrids(), except that a clip on a file
118 /// with grid offsets does a clip on each grid independently.
119 /// @return An empty list if no grid has this name.
120 /// @throw IoError if this file is not open for reading.
121 GridPtrVecPtr readGrids(const Name& name, const io::ReadOptions& readOptions = io::ReadOptions{});
122
123 /// @brief Write the grids in the given container to the file whose name
124 /// was given in the constructor.
125 void write(const GridCPtrVec&, const MetaMap& = MetaMap(),
126 const io::WriteOptions& = io::WriteOptions{}) const override;
127
128 /// @brief Write the grids in the given container to the file whose name
129 /// was given in the constructor.
130 template<typename GridPtrContainerT>
131 void write(const GridPtrContainerT&, const MetaMap& = MetaMap(),
132 const io::WriteOptions& = io::WriteOptions{}) const;
133
134 /// A const iterator that iterates over all names in the file. This is only
135 /// valid once the file has been opened.
137 {
138 public:
139 NameIterator(const NameMapCIter& iter): mIter(iter) {}
140 NameIterator(const NameIterator&) = default;
142
143 NameIterator& operator++() { mIter++; return *this; }
144
145 bool operator==(const NameIterator& iter) const { return mIter == iter.mIter; }
146 bool operator!=(const NameIterator& iter) const { return mIter != iter.mIter; }
147
148 Name operator*() const { return this->gridName(); }
149
150 Name gridName() const { return GridDescriptor::nameAsString(mIter->second.uniqueName()); }
151
152 private:
153 NameMapCIter mIter;
154 };
155
156 /// @return a NameIterator to iterate over all grid names in the file.
158
159 /// @return the ending iterator for all grid names in the file.
161
162private:
163 /// @brief Return an iterator to the descriptor for the grid with the given name.
164 /// @details If "density" is searched and there is more than one "density" grid,
165 /// returns an iterator to the first matching grid. If "density[1]" is searched,
166 /// it is tested against the unique name, so it matches the second "density" grid.
167 NameMapCIter findDescriptor(const Name&) const;
168
169 /// @brief Return an iterator to the descriptor whose unique name is exactly the given name,
170 /// or the end iterator if there is none.
171 /// @details Only the unique name is searched. "density" does not match a grid that was
172 /// made unique as "density[1]", "density[1]" must be used instead.
173 NameMapCIter findDescriptorByUniqueName(const Name&) const;
174
175 /// @brief Read the grid for the given descriptor, including its instance parent's tree.
176 /// @note This method should not be called for files that don't contain grid offsets.
177 /// @throw KeyError if the grid is an instance and its parent is missing.
178 GridBase::Ptr readGridFromDescriptor(const GridDescriptor&, const io::ReadOptions&) const;
179
180 /// @brief Retrieve a grid from @c mNamedGrids. Return a null pointer
181 /// if @c mNamedGrids was not populated (because this file is random-access).
182 /// @throw KeyError if no grid with the given name exists in this file.
183 GridBase::Ptr retrieveCachedGrid(const Name&) const;
184
185 /// @brief Return the grid that @a readOptions asks for, given the already
186 /// cached @a cachedGrid. Doesn't mutate @a cachedGrid, and returns it
187 /// unchanged when no option applies.
188 GridBase::Ptr resolveCachedGrid(const GridBase::Ptr& cachedGrid,
189 const io::ReadOptions& readOptions, ReadDiagnostics& diagnostics) const;
190
191 /// @brief Resolve each of @a cachedGrids as resolveCachedGrid() does. Grids that
192 /// share a source tree share the resolved tree when instancing is enabled.
193 GridPtrVecPtr resolveCachedGrids(const GridPtrVec& cachedGrids,
194 const io::ReadOptions& readOptions) const;
195
196 void writeGrids(const GridCPtrVec&, const MetaMap&, const io::WriteOptions&) const;
197
198 MetaMap::Ptr fileMetadata();
199 MetaMap::ConstPtr fileMetadata() const;
200
201 const NameMap& gridDescriptors() const;
202 NameMap& gridDescriptors();
203
204 std::istream& inputStream() const;
205
206 friend class ::TestFile;
207 friend class ::TestStream;
208
209 std::string mFilename;
210 // The file-level metadata
211 MetaMap::Ptr mMeta;
212 // The file stream that is open for reading
213 std::unique_ptr<std::istream> mInStream;
214 // File-level stream metadata (file format, compression, etc.)
215 StreamMetadata::Ptr mStreamMetadata;
216 // Flag indicating if we have read in the global information (header,
217 // metadata, and grid descriptors) for this VDB file
218 bool mIsOpen = false;
219 // Grid descriptors for all grids stored in the file, indexed by grid name
220 NameMap mGridDescriptors;
221 // All grids, indexed by unique name (used only when mHasGridOffsets is false)
222 Archive::NamedGridMap mNamedGrids;
223 // All grids stored in the file (used only when mHasGridOffsets is false)
224 GridPtrVecPtr mGrids;
225};
226
227
228////////////////////////////////////////
229
230
231inline void
232File::write(const GridCPtrVec& grids, const MetaMap& meta,
233 const io::WriteOptions& writeOptions) const
234{
235 this->writeGrids(grids, meta, writeOptions);
236}
237
238
239template<typename GridPtrContainerT>
240inline void
241File::write(const GridPtrContainerT& container, const MetaMap& meta,
242 const io::WriteOptions& writeOptions) const
243{
244 GridCPtrVec grids;
245 std::copy(container.begin(), container.end(), std::back_inserter(grids));
246 this->writeGrids(grids, meta, writeOptions);
247}
248
249} // namespace io
250} // namespace OPENVDB_VERSION_NAME
251} // namespace openvdb
252
253#endif // OPENVDB_IO_FILE_HAS_BEEN_INCLUDED
#define OPENVDB_API
Definition Platform.h:286
#define OPENVDB_DEPRECATED_MESSAGE(msg)
Definition Platform.h:158
SharedPtr< GridBase > Ptr
Definition Grid.h:81
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
std::map< Name, GridBase::Ptr > NamedGridMap
Definition Archive.h:157
NameIterator(const NameIterator &)=default
~NameIterator()
Definition File.h:141
Name operator*() const
Definition File.h:148
Name gridName() const
Definition File.h:150
bool operator!=(const NameIterator &iter) const
Definition File.h:146
NameIterator(const NameMapCIter &iter)
Definition File.h:139
NameIterator & operator++()
Definition File.h:143
bool operator==(const NameIterator &iter) const
Definition File.h:145
bool isOpen() const
Return true if the file has been opened for reading.
bool open(bool, const MappedFile::Notifier &)
Definition File.h:66
GridBase::Ptr readGrid(const Name &, const io::ReadOptions &readOptions=io::ReadOptions{})
Read an entire grid, including all of its data blocks, using the provided options if given.
NameIterator endName() const
bool hasGrid(const Name &) const
Return true if a grid of the given name exists in this file.
File(const std::string &filename)
const std::string & filename() const
Return the name of the file with which this archive is associated.
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...
GridPtrVecPtr readGrids(const Name &name, const io::ReadOptions &readOptions=io::ReadOptions{})
Read all grids whose grid name is exactly name, in file order.
void close()
Close the file once we are done reading from it.
NameMap::const_iterator NameMapCIter
Definition File.h:34
~File() override
Definition File.h:37
NameIterator beginName() const
File(const File &other)
Copy constructor.
File & operator=(const File &other)
Assignment.
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.
void write(const GridCPtrVec &, const MetaMap &=MetaMap(), const io::WriteOptions &=io::WriteOptions{}) const override
Write the grids in the given container to the file whose name was given in the constructor.
Definition File.h:232
SharedPtr< Archive > copy() const override
Return a copy of this archive.
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.
bool open()
Open the file, read the file header and the file-level metadata, and populate the grid descriptors,...
bool open(bool)
Definition File.h:64
Index64 copyMaxBytes() const
Definition File.h:79
std::multimap< Name, GridDescriptor > NameMap
Definition File.h:33
GridPtrVecPtr getGrids(const io::ReadOptions &readOptions=io::ReadOptions{}) const
Read the entire contents of the file and return a list of grid pointers.
void setCopyMaxBytes(Index64)
Definition File.h:81
Definition GridDescriptor.h:20
static std::string nameAsString(const Name &)
Given a name with suffix N, return "name[N]", otherwise just return "name". Use this to produce a hum...
SharedPtr< StreamMetadata > Ptr
Definition io.h:33
std::string Name
Definition Name.h:19
std::vector< GridBase::Ptr > GridPtrVec
Definition Grid.h:508
SharedPtr< GridPtrVec > GridPtrVecPtr
Definition Grid.h:511
math::BBox< Vec3d > BBoxd
Definition Types.h:65
uint64_t Index64
Definition Types.h:33
std::shared_ptr< T > SharedPtr
Definition Types.h:95
std::vector< GridBase::ConstPtr > GridCPtrVec
Definition Grid.h:513
Definition Exceptions.h:13
Thread-safe collection of read diagnostics accumulated during a codec read.
Definition Codec.h:211
Global read configuration passed to every codec during deserialization.
Definition Codec.h:167
Global write configuration passed to every codec during serialization.
Definition Codec.h:188
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition version.h.in:121
#define OPENVDB_USE_VERSION_NAMESPACE
Definition version.h.in:286