-
-
Notifications
You must be signed in to change notification settings - Fork 443
Expand file tree
/
Copy pathmesh_view.h
More file actions
197 lines (181 loc) · 6.27 KB
/
Copy pathmesh_view.h
File metadata and controls
197 lines (181 loc) · 6.27 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
#ifndef f3d_mesh_view_h
#define f3d_mesh_view_h
#include "exception.h"
#include "export.h"
/// @cond
#include <array>
#include <cstdint>
#include <string>
#include <vector>
/// @endcond
namespace f3d
{
/**
* @class mesh_view
* @brief Abstract class to represent a 3D surfacic mesh view in memory
*
* The mesh_view class represents a 3D surfacic mesh with points, faces, normals and texture
* coordinates. It is used to add meshes directly to the scene without having to write them to a
* file. The interface allows to provide a view of the mesh in memory, making it possible to
* visualize data without having to convert and copy to F3D internal structures. It also
* allows to provide an animated mesh by providing different views of the mesh at different times.
*/
class F3D_EXPORT mesh_view
{
public:
/**
* Get the temporal range
*/
[[nodiscard]] virtual std::array<double, 2> getTimeRange() const
{
return { 0.0, 0.0 };
}
/**
* Get the name of the mesh
*/
[[nodiscard]] virtual std::string getName() const
{
return "";
}
/**
* Enumeration of supported scalar types for point and face scalars
*/
enum class data_type : uint8_t
{
U8,
I8,
U16,
I16,
U32,
I32,
U64,
I64,
F32,
F64
};
/**
* Dispatch a functor based on the data type, used to avoid code duplication when handling
* data of different types.
*/
template<typename Functor>
static decltype(auto) dataTypeDispatch(f3d::mesh_view::data_type t, Functor&& f)
{
switch (t)
{
case f3d::mesh_view::data_type::U8:
return f.template operator()<uint8_t>();
case f3d::mesh_view::data_type::I8:
return f.template operator()<int8_t>();
case f3d::mesh_view::data_type::U16:
return f.template operator()<uint16_t>();
case f3d::mesh_view::data_type::I16:
return f.template operator()<int16_t>();
case f3d::mesh_view::data_type::U32:
return f.template operator()<uint32_t>();
case f3d::mesh_view::data_type::I32:
return f.template operator()<int32_t>();
case f3d::mesh_view::data_type::U64:
return f.template operator()<uint64_t>();
case f3d::mesh_view::data_type::I64:
return f.template operator()<int64_t>();
case f3d::mesh_view::data_type::F32:
return f.template operator()<float>();
case f3d::mesh_view::data_type::F64:
default:
return f.template operator()<double>();
}
}
/**
* Structure representing a view of an existing data array.
* `name` is optional but recommended for pointScalars and faceScalars.
* `data` pointer must remain valid while the mesh is used in the scene.
* `stride` is the number of elements (not bytes) to skip to get to the next tuple.
* If `timeDependent` is true, it means that the data in the array can change over time.
* Set it to false if the data in the array is constant over time, it can help improving
* performance.
*/
struct data_array_t
{
std::string name;
data_type type = data_type::F32;
const void* data = nullptr;
size_t components = 1;
size_t stride = 1;
bool timeDependent = true;
};
/**
* Structure representing a cell array.
* For vertices and lines, `offsets` encodes the size of the polyvertex and polylines group
* respectively. For polygons, `offsets` encodes the size of each polygons (number of vertices per
* face). `offsetCount` must be equal to the number of cells + 1, and the last value in `offsets`
* must be equal to `indexCount`. If `offsetCount` is 1, it means that there is no cell. Will
* throw a load_failure_exception if any of this assumptions is not respected:
* - offsetCount is less than 1
* - offsets can be empty or must have 1 component and a data type of I32, U32, I64, or U64
* - indices can be empty or must have 1 component and a data type of I32, U32, I64, or U64
* - offsets and indices must have the same data type
*/
struct cell_array_t
{
size_t offsetCount = 1;
data_array_t offsets;
size_t indexCount = 0;
data_array_t indices;
};
/**
* Structure representing an in-memory base-color (albedo) texture, sampled through the
* mesh `textureCoordinates`. Avoids writing a temporary image file to disk. `data` is a
* row-major uint8 buffer of `width * height * components` bytes, with `components` equal
* to 3 (RGB) or 4 (RGBA). Leave `data` null (the default) for no texture. The pointer
* must remain valid until the mesh is removed from the scene. When `emissive` is true the
* same image is additionally installed as the emissive texture (for unlit/flat display).
*/
struct texture_t
{
size_t width = 0;
size_t height = 0;
size_t components = 3;
const void* data = nullptr;
bool emissive = false;
};
/**
* Structure representing a view of the mesh in memory at a given time.
* The pointers provided in this structure must remain valid once the mesh is added to the scene.
* Will throw a load_failure_exception if any of this assumptions is not respected:
* - points must have a 3 components and a data type of F32 or F64
* - normals can be empty or must have a 3 components and a data type of F32 or F64
* - texture_coordinates can be empty or must have a 2 components and a data type of F32 or F64
*/
struct memory_view_t
{
// points
size_t pointCount = 0;
data_array_t points;
data_array_t normals;
data_array_t textureCoordinates;
// cells
cell_array_t vertices;
cell_array_t lines;
cell_array_t polygons;
// scalars
std::vector<data_array_t> pointScalars;
std::vector<data_array_t> cellScalars;
// optional in-memory base-color texture (sampled via textureCoordinates)
texture_t baseColorTexture;
};
/**
* Specify the mesh data by providing a view of the mesh in memory at a given time.
* Make sure to add a thread synchronization mechanism if the mesh data is updated asynchronously.
*/
[[nodiscard]] virtual memory_view_t getMemoryView(double time) const = 0;
//! @cond
mesh_view() = default;
virtual ~mesh_view() = default;
mesh_view(const mesh_view&) = delete;
mesh_view(mesh_view&&) = delete;
mesh_view& operator=(const mesh_view&) = delete;
mesh_view& operator=(mesh_view&&) = delete;
//! @endcond
};
}
#endif