1#ifndef TATOOINE_AMIRA_READ_H
2#define TATOOINE_AMIRA_READ_H
15static constexpr auto lattice = std::string_view{
"define Lattice"};
16static constexpr auto boundingbox = std::string_view{
"BoundingBox"};
17static constexpr auto lattice_size = std::string_view{
"Lattice { float["};
18static constexpr auto data_follows = std::string_view{
"# Data section follows"};
22 auto const cur_cursor_pos = file.tellg();
24 auto buf = std::string(
32 file.seekg(0, std::ios_base::beg);
33 auto buffer = std::istringstream{std::move(buf)};
36 auto dims = std::array<std::size_t, 3>{};
37 auto const lattice_pos =
38 static_cast<std::streamoff
>(buffer.str().find(
lattice));
39 buffer.seekg(lattice_pos, std::ios_base::beg);
40 buffer.seekg(
static_cast<std::istringstream::off_type
>(
lattice.size()),
42 buffer >> dims[0] >> dims[1] >> dims[2];
46 auto const boundingbox_pos =
47 static_cast<std::istringstream::off_type
>(buffer.str().find(
boundingbox));
48 buffer.seekg(boundingbox_pos,
50 buffer.seekg(
static_cast<std::istringstream::off_type
>(
boundingbox.size()),
56 auto const is_uniform =
57 buffer.str().find(
"CoordType \"uniform\"") != std::string::npos;
60 auto num_components = std::size_t{};
61 if (buffer.str().find(
"Lattice { float Data }") != std::string::npos) {
67 buffer.seekg(
static_cast<std::istringstream::off_type
>(pos), std::ios_base::beg);
68 buffer.seekg(
static_cast<std::istringstream::off_type
>(
lattice_size.size()), std::ios_base::cur);
69 buffer >> num_components;
73 if (dims[0] <= 0 || dims[1] <= 0 || dims[2] <= 0 ||
76 throw std::runtime_error(
"something went wrong");
80 auto const data_follows_pos = buffer.str().find(
data_follows);
81 auto break_pos =
static_cast<std::string::size_type
>(buffer.str().find(
82 '\n',
static_cast<std::string::size_type
>(data_follows_pos)));
83 break_pos =
static_cast<std::string::size_type
>(
84 buffer.str().find(
'\n', break_pos + 1));
85 auto data_begin_pos = std::streamoff{};
86 if (data_follows_pos != std::string::npos) {
87 data_begin_pos =
static_cast<std::streamoff
>(break_pos + 1);
89 file.seekg(cur_cursor_pos);
90 return std::tuple{dims, std::move(
aabb), num_components, data_begin_pos};
94 auto file = std::ifstream{path};
95 if (!file.is_open()) {
96 throw std::runtime_error(
"could not open file " + path.string());
103template <
floating_po
int T =
float>
104auto read(std::ifstream& file) {
106 auto const num_to_read = dims[0] * dims[1] * dims[2] * num_components;
107 auto data = std::vector<float>(num_to_read);
109 file.seekg(data_begin_pos, std::ios_base::beg);
110 file.read(
reinterpret_cast<char*
>(data.data()),
111 static_cast<std::streamsize
>(
sizeof(
float) * num_to_read));
113 if constexpr (is_float<T>) {
114 return std::tuple{std::move(data), dims, std::move(
aabb), num_components};
116 return std::tuple{std::vector<T>(
begin(data),
end(data)), dims,
117 std::move(
aabb), num_components};
121template <
floating_po
int T =
float>
122auto read(filesystem::path
const& path) {
123 auto file = std::ifstream{path};
124 if (!file.is_open()) {
125 throw std::runtime_error(
"could not open file " + path.string());
127 return read<T>(file);
static constexpr auto num_bytes_header
Definition: read.h:19
static constexpr auto boundingbox
Definition: read.h:16
static constexpr auto lattice_size
Definition: read.h:17
static constexpr auto lattice
Definition: read.h:15
auto read_header(std::ifstream &file)
Definition: read.h:21
static constexpr auto data_follows
Definition: read.h:18
auto read(std::ifstream &file)
Definition: read.h:104
auto begin(Range &&range)
Definition: iterator_facade.h:318
auto end(Range &&range)
Definition: iterator_facade.h:322
axis_aligned_bounding_box< Real, NumDimensions > aabb
Definition: axis_aligned_bounding_box.h:553
Definition: axis_aligned_bounding_box.h:103
auto constexpr max() const -> auto const &
Definition: axis_aligned_bounding_box.h:156
auto constexpr min() const -> auto const &
Definition: axis_aligned_bounding_box.h:151