MayaFlux 1.0.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NDData.cpp
Go to the documentation of this file.
1#include "NDData.hpp"
2
4
6
7namespace MayaFlux::Kakshya {
8
9DataDimension::DataDimension(std::string n, uint64_t s, uint64_t st, Role r)
10 : name(std::move(n))
11 , size(s)
12 , stride(st)
13 , role(r)
14{
15}
16
17DataDimension DataDimension::time(uint64_t samples, std::string name)
18{
19 return { std::move(name), samples, 1, Role::TIME };
20}
21
22DataDimension DataDimension::channel(uint64_t count, uint64_t stride)
23{
24 return { "channel", count, stride, Role::CHANNEL };
25}
26
27DataDimension DataDimension::depth(uint64_t count, uint64_t stride)
28{
29 return { "depth", count, stride, Role::DEPTH };
30}
31
32DataDimension DataDimension::frequency(uint64_t bins, std::string name)
33{
34 return { std::move(name), bins, 1, Role::FREQUENCY };
35}
36
37DataDimension DataDimension::spatial(uint64_t size, char axis, uint64_t stride, std::string name)
38{
39 Role r = [axis]() {
40 switch (axis) {
41 case 'x':
42 return Role::SPATIAL_X;
43 case 'y':
44 return Role::SPATIAL_Y;
45 case 'z':
46 default:
47 return Role::SPATIAL_Z;
48 }
49 }();
50
51 if (name == "") {
52 name = std::string("spatial_") + axis;
53 }
54 return { name, size, stride, r };
55}
56
58{
59 return spatial(width, 'x');
60}
61
63{
64 return spatial(height, 'y', width);
65}
66
68{
69 return spatial(depth, 'z', width * height);
70}
71
73{
74 return { "mip_levels", levels, 1, Role::MIP_LEVEL };
75}
76
78 std::string name,
79 uint64_t element_count,
80 uint8_t components_per_element,
81 Role role)
82{
83 DataDimension dim { std::move(name), element_count, 1, role };
84 dim.grouping = ComponentGroup { components_per_element, 0 };
85 return dim;
86}
87
89 std::optional<double> invalid)
90{
91 if (max <= min) {
93 "DataDimension::with_range on '{}': max ({}) must exceed min ({}); range not applied",
94 name, max, min);
95 return *this;
96 }
97
98 value_range = ValueRange { .min = min, .max = max, .invalid = invalid };
99 return *this;
100}
101
102std::string_view modality_to_string(DataModality modality)
103{
104 return Reflect::enum_to_string(modality);
105}
106
108{
109 return grouped("positions", count, 3, Role::POSITION);
110}
111
113{
114 return grouped("normals", count, 3, Role::NORMAL);
115}
116
118{
119 return grouped("uvs", count, 2, Role::UV);
120}
121
123{
124 return grouped("colors", count, has_alpha ? 4 : 3, Role::COLOR);
125}
126
127std::vector<DataDimension> DataDimension::create_dimensions(
128 DataModality modality,
129 const std::vector<uint64_t>& shape,
130 MemoryLayout layout)
131{
132 std::vector<DataDimension> dims;
133 auto strides = calculate_strides(shape, layout);
134
135 switch (modality) {
137 if (shape.size() != 1) {
138 error<std::invalid_argument>(
141 std::source_location::current(),
142 "AUDIO_1D requires 1D shape");
143 }
144 dims.push_back(DataDimension::time(shape[0]));
145 break;
146
148 if (shape.size() != 2) {
149 error<std::invalid_argument>(
152 std::source_location::current(),
153 "AUDIO_MULTICHANNEL requires 2D shape [samples, channels]");
154 }
155 dims.push_back(DataDimension::time(shape[0]));
156 dims.push_back(DataDimension::channel(shape[1], strides[1]));
157 break;
158
160 if (shape.size() != 2) {
161 error<std::invalid_argument>(
164 std::source_location::current(),
165 "IMAGE_2D requires 2D shape [height, width]");
166 }
167 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
168 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
169 break;
170
172 if (shape.size() != 3) {
173 error<std::invalid_argument>(
176 std::source_location::current(),
177 "IMAGE_COLOR requires 3D shape [height, width, channels]");
178 }
179 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
180 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
181 dims.push_back(DataDimension::channel(shape[2], strides[2]));
182 break;
183
185 if (shape.size() != 4) {
186 error<std::invalid_argument>(
189 std::source_location::current(),
190 "IMAGE_COLOR_ARRAY requires 4D shape [frames, height, width, channels]");
191 }
192 dims.push_back(DataDimension::time(shape[0], "index"));
193 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
194 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
195 dims.push_back(DataDimension::channel(shape[3], strides[3]));
196 break;
197
199 if (shape.size() != 3) {
200 error<std::invalid_argument>(
203 std::source_location::current(),
204 "DEPTH_MAP requires 3D shape [height, width, components]");
205 }
206 dims.push_back(DataDimension::spatial(shape[0], 'y', strides[0]));
207 dims.push_back(DataDimension::spatial(shape[1], 'x', strides[1]));
208 dims.push_back(DataDimension::depth(shape[2], strides[2]));
209 break;
210
212 if (shape.size() != 2) {
213 error<std::invalid_argument>(
216 std::source_location::current(),
217 "SPECTRAL_2D requires 2D shape [time_windows, frequency_bins]");
218 }
219 dims.push_back(DataDimension::time(shape[0], "time_windows"));
220 dims.push_back(DataDimension::frequency(shape[1]));
221 dims[1].stride = strides[1];
222 break;
223
225 if (shape.size() != 3) {
226 error<std::invalid_argument>(
229 std::source_location::current(),
230 "VOLUMETRIC_3D requires 3D shape [x, y, z]");
231 }
232 dims.push_back(DataDimension::spatial(shape[0], 'x', strides[0]));
233 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
234 dims.push_back(DataDimension::spatial(shape[2], 'z', strides[2]));
235 break;
236
238 if (shape.size() != 3) {
239 error<std::invalid_argument>(
242 std::source_location::current(),
243 "VIDEO_GRAYSCALE requires 3D shape [frames, height, width]");
244 }
245 dims.push_back(DataDimension::time(shape[0], "frames"));
246 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
247 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
248 break;
249
251 if (shape.size() != 4) {
252 error<std::invalid_argument>(
255 std::source_location::current(),
256 "VIDEO_COLOR requires 4D shape [frames, height, width, channels]");
257 }
258 dims.push_back(DataDimension::time(shape[0], "frames"));
259 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
260 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
261 dims.push_back(DataDimension::channel(shape[3], strides[3]));
262 break;
263
265 if (shape.size() != 4) {
266 error<std::invalid_argument>(
269 std::source_location::current(),
270 "VIDEO_DEPTH requires 4D shape [frames, height, width, components]");
271 }
272 dims.push_back(DataDimension::time(shape[0], "frames"));
273 dims.push_back(DataDimension::spatial(shape[1], 'y', strides[1]));
274 dims.push_back(DataDimension::spatial(shape[2], 'x', strides[2]));
275 dims.push_back(DataDimension::depth(shape[3], strides[3]));
276 break;
277
278 default:
279 error<std::invalid_argument>(
282 std::source_location::current(),
283 "Unsupported modality for dimension creation: {}", modality_to_string(modality));
284 }
285
286 return dims;
287}
288
290 const std::vector<uint64_t>& shape,
291 MemoryLayout layout)
292{
293 if (shape.empty())
294 return {};
295
296 std::vector<uint64_t> strides(shape.size());
297
298 if (layout == MemoryLayout::ROW_MAJOR) {
299 auto reversed_shape = shape | std::views::reverse;
300 std::exclusive_scan(
301 reversed_shape.begin(),
302 reversed_shape.end(),
303 strides.rbegin(),
304 uint64_t(1),
305 std::multiplies<uint64_t> {});
306 } else {
307 std::exclusive_scan(
308 shape.begin(),
309 shape.end(),
310 strides.begin(),
311 uint64_t(1),
312 std::multiplies<uint64_t> {});
313 }
314
315 return strides;
316}
317
318}
#define MF_ERROR(comp, ctx,...)
bool size
glm::ivec3 min
glm::ivec3 max
std::string name
Definition VKDevice.cpp:123
size_t count
uint32_t width
uint32_t height
uint32_t depth
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:132
@ DEPTH_MAP
[height, width, components] - range/disparity image
@ AUDIO_MULTICHANNEL
Multi-channel audio.
@ SPECTRAL_2D
2D spectral data (time + frequency)
@ VIDEO_DEPTH
[frames, height, width, components] - streaming range data
@ IMAGE_COLOR_ARRAY
4D (idx + 2D + color)
@ VOLUMETRIC_3D
3D volumetric data
@ VIDEO_GRAYSCALE
3D video (time + 2D grayscale)
@ VIDEO_COLOR
4D video (time + 2D + color)
@ IMAGE_COLOR
2D RGB/RGBA image
@ IMAGE_2D
2D image (grayscale or single channel)
MemoryLayout
Memory layout for multi-dimensional data.
Definition NDData.hpp:33
@ ROW_MAJOR
C/C++ style (last dimension varies fastest)
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
Definition NDData.cpp:102
constexpr std::string_view enum_to_string(EnumType value) noexcept
Universal enum to string converter using magic_enum (original case)
Grouping information for sub-dimensions.
Definition NDData.hpp:229
Numeric interpretation of the values along this dimension.
Definition NDData.hpp:257
std::optional< ValueRange > value_range
Definition NDData.hpp:263
static DataDimension spatial_2d(uint64_t width, uint64_t height)
Convenience constructor for a 2D spatial dimension.
Definition NDData.cpp:62
Role
Semantic role of the dimension.
Definition NDData.hpp:204
@ FREQUENCY
Spectral/frequency axis.
@ TIME
Temporal progression (samples, frames, steps)
@ POSITION
Vertex positions (3D space)
@ DEPTH
Distance from the observation point (depth, disparity, range)
@ CHANNEL
Parallel streams (audio channels, color channels)
@ SPATIAL_X
Spatial X axis (images, tensors)
uint64_t stride
Memory stride (elements between consecutive indices)
Definition NDData.hpp:267
std::string name
Human-readable identifier for the dimension.
Definition NDData.hpp:265
static DataDimension vertex_positions(uint64_t count)
Create dimension for vertex positions (vec3)
Definition NDData.cpp:107
DataDimension & with_range(double min, double max, std::optional< double > invalid=std::nullopt)
Attach a value range.
Definition NDData.cpp:88
uint64_t size
Number of elements in this dimension.
Definition NDData.hpp:266
static DataDimension vertex_colors(uint64_t count, bool has_alpha=false)
Create dimension for colors (vec3 or vec4)
Definition NDData.cpp:122
Role role
Semantic hint for common operations.
Definition NDData.hpp:268
static DataDimension spatial(uint64_t size, char axis, uint64_t stride=1, std::string name="spatial")
Convenience constructor for a spatial dimension.
Definition NDData.cpp:37
static DataDimension grouped(std::string name, uint64_t element_count, uint8_t components_per_element, Role role=Role::CUSTOM)
Create dimension with component grouping.
Definition NDData.cpp:77
static DataDimension vertex_normals(uint64_t count)
Create dimension for vertex normals (vec3)
Definition NDData.cpp:112
static DataDimension frequency(uint64_t bins, std::string name="frequency")
Convenience constructor for a frequency dimension.
Definition NDData.cpp:32
static DataDimension spatial_1d(uint64_t width)
Convenience constructor for an array dimension.
Definition NDData.cpp:57
static DataDimension time(uint64_t samples, std::string name="time")
Convenience constructor for a temporal (time) dimension.
Definition NDData.cpp:17
static std::vector< uint64_t > calculate_strides(const std::vector< uint64_t > &shape, MemoryLayout layout)
Calculate memory strides based on shape and layout.
Definition NDData.cpp:289
static DataDimension depth(uint64_t count=1, uint64_t stride=1)
Convenience constructor for a depth dimension.
Definition NDData.cpp:27
static std::vector< DataDimension > create_dimensions(DataModality modality, const std::vector< uint64_t > &shape, MemoryLayout layout=MemoryLayout::ROW_MAJOR)
Create dimension descriptors for a data modality.
Definition NDData.cpp:127
static DataDimension mipmap_levels(uint64_t levels)
Create dimension for mipmap levels.
Definition NDData.cpp:72
static DataDimension texture_coords(uint64_t count)
Create dimension for texture coordinates (vec2)
Definition NDData.cpp:117
static DataDimension spatial_3d(uint64_t width, uint64_t height, uint64_t depth)
Convenience constructor for a 3D spatial dimension.
Definition NDData.cpp:67
std::optional< ComponentGroup > grouping
Definition NDData.hpp:245
static DataDimension channel(uint64_t count, uint64_t stride=1)
Convenience constructor for a channel dimension.
Definition NDData.cpp:22
Minimal dimension descriptor focusing on structure only.
Definition NDData.hpp:197