MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
SpatialReader.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "SpatialCache.hpp"
4
5namespace MayaFlux::IO {
6
7/**
8 * @class SpatialReader
9 * @brief Reads back the time-sampled streams a SpatialCache wrote, in the
10 * same SpatialSample format it writes.
11 *
12 * Samples are read one at a time, on demand: nothing is loaded at open()
13 * beyond stream headers, so an archive of any length can be walked frame by
14 * frame.
15 *
16 * A sample returned by read_sample() borrows the reader's own storage for
17 * that stream. It stays valid until the next read_sample() call for the same
18 * stream or close(); copy what must outlive that. Samples of different
19 * streams do not invalidate each other.
20 *
21 * Only top level points and curves streams are read, which is everything
22 * SpatialCache writes. Any other object in the file is skipped with a
23 * warning. Attributes of types SpatialCache does not write are skipped with a
24 * warning. A curves stream is reported as LINE_STRIP: a file does not tell a
25 * list of pairs from curves of two vertices. Not safe to call from several
26 * threads at once.
27 *
28 * Usage:
29 * @code
30 * IO::SpatialReader reader;
31 * reader.open("swarm.abc");
32 * for (const auto& name : reader.get_stream_names()) {
33 * for (size_t i = 0; i < reader.get_sample_count(name); ++i) {
34 * auto sample = reader.read_sample(name, i);
35 * }
36 * }
37 * @endcode
38 */
39class MAYAFLUX_API SpatialReader {
40public:
43
44 SpatialReader(const SpatialReader&) = delete;
47 SpatialReader& operator=(SpatialReader&&) noexcept;
48
49 /**
50 * @brief Open an Ogawa or HDF5 archive and index its streams.
51 *
52 * The file is checked first: a missing path or a file that is not an
53 * archive fails with one logged line, without Alembic being involved.
54 *
55 * @param filepath Path to the file. Resolved the same way other readers do.
56 * @return True on success. On failure the error is logged and available
57 * from get_last_error().
58 */
59 bool open(const std::string& filepath);
60
61 /**
62 * @brief Release the archive. Safe on an unopened reader.
63 */
64 void close();
65
66 [[nodiscard]] bool is_open() const;
67
68 /**
69 * @brief Names of the streams found at open(), in file order.
70 */
71 [[nodiscard]] const std::vector<std::string>& get_stream_names() const;
72
73 /**
74 * @brief Topology a stream is read as: POINT_LIST or LINE_STRIP.
75 * @return nullopt for an unknown stream.
76 */
77 [[nodiscard]] std::optional<Portal::Graphics::PrimitiveTopology> get_topology(
78 const std::string& stream_name) const;
79
80 /**
81 * @brief Number of samples in a stream, 0 for an unknown stream.
82 */
83 [[nodiscard]] size_t get_sample_count(const std::string& stream_name) const;
84
85 /**
86 * @brief Object level tags a stream was written with, the same form
87 * SpatialCache::write_metadata takes. Empty for an unknown stream.
88 */
89 [[nodiscard]] std::unordered_map<std::string, std::string> get_metadata(
90 const std::string& stream_name) const;
91
92 /**
93 * @brief Read one sample of a stream.
94 *
95 * Fields the format does not carry for the stream's topology are empty:
96 * ids and velocities for a curves stream, vertex_counts_per_curve for
97 * points, and ids or velocities a points stream was written without.
98 *
99 * @param stream_name Name from get_stream_names().
100 * @param index Sample index, below get_sample_count().
101 * @return The sample, valid as described in the class doc, or nullopt for
102 * an unknown stream, an index out of range or a read failure; the
103 * reason is in get_last_error(). An unknown stream or index is
104 * not logged.
105 */
106 [[nodiscard]] std::optional<SpatialSample> read_sample(
107 const std::string& stream_name, size_t index) const;
108
109 /**
110 * @brief Time in seconds the archive assigns to a sample.
111 * @return The time, or nullopt if the stream or index is invalid.
112 */
113 [[nodiscard]] std::optional<double> sample_time(
114 const std::string& stream_name, size_t index) const;
115
116 [[nodiscard]] std::string get_last_error() const { return m_last_error; }
117
118private:
119 struct Impl;
120 std::unique_ptr<Impl> m_impl;
121
122 mutable std::string m_last_error;
123
124 void set_error(std::string msg) const { m_last_error = std::move(msg); }
125};
126
127} // namespace MayaFlux::IO
uint32_t index
Definition VKDevice.cpp:122
SpatialReader & operator=(const SpatialReader &)=delete
void set_error(std::string msg) const
std::unique_ptr< Impl > m_impl
SpatialReader(const SpatialReader &)=delete
SpatialReader(SpatialReader &&) noexcept
Reads back the time-sampled streams a SpatialCache wrote, in the same SpatialSample format it writes.
One sample's worth of data for one named stream.