MayaFlux 0.5.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
NDimensionalContainer.hpp
Go to the documentation of this file.
1#pragma once
2
3#include "NDData/NDData.hpp"
4
5namespace MayaFlux::Kakshya {
6
7/**
8 * @brief Forward declarations for region structures used in N-dimensional data containers.
9 */
10struct Region;
11struct RegionGroup;
12struct RegionSegment;
13
14/**
15 * @brief Container structure for consistent dimension ordering.
16 *
17 * Provides standard indices and layout structures for common data types,
18 * supporting digital-first, data-driven workflows. These structures are
19 * not tied to analog metaphors, but instead facilitate generic, flexible
20 * processing of multi-dimensional data.
21 */
22struct MAYAFLUX_API ContainerDataStructure {
23
24 // Image/Video structures
25 // static constexpr size_t FRAME_DIM = 0;
26 // static constexpr size_t COLOR_DIM = 3;
27
28 // Spectral structures
29 // static constexpr size_t TIME_WINDOW_DIM = 0;
30
31 std::vector<DataDimension> dimensions;
32
33 std::optional<size_t> time_dims;
34 std::optional<size_t> channel_dims;
35 std::optional<size_t> height_dims;
36 std::optional<size_t> width_dims;
37 std::optional<size_t> frequency_dims;
38
39 DataModality modality {};
40 MemoryLayout memory_layout = MemoryLayout::ROW_MAJOR;
41 OrganizationStrategy organization = OrganizationStrategy::PLANAR;
42
43 /**
44 * @brief Construct a container structure with specified parameters.
45 * @param mod Data modality type
46 * @param org Organization strategy (default: PLANAR)
47 * @param layout Memory layout (default: ROW_MAJOR)
48 */
50 OrganizationStrategy org = OrganizationStrategy::PLANAR,
51 MemoryLayout layout = MemoryLayout::ROW_MAJOR);
52
54
55 /**
56 * @brief Get the expected dimension roles for this structure's modality.
57 * @return Vector of dimension roles in order
58 */
59 [[nodiscard]] std::vector<DataDimension::Role> get_expected_dimension_roles() const;
60
61 /**
62 * @brief Create structure for planar audio data.
63 * @return Containerstructure configured for planar audio
64 */
65 static ContainerDataStructure audio_planar();
66
67 /**
68 * @brief Create structure for interleaved audio data.
69 * @return Containerstructure configured for interleaved audio
70 */
71 static ContainerDataStructure audio_interleaved();
72
73 /**
74 * @brief Create structure for planar image data.
75 * @return Containerstructure configured for planar images
76 */
77 static ContainerDataStructure image_planar();
78
79 /**
80 * @brief Create structure for interleaved image data.
81 * @return Containerstructure configured for interleaved images
82 */
83 static ContainerDataStructure image_interleaved();
84
85 /**
86 * @brief Calculate expected number of data variants for given dimensions.
87 * @param dimensions Vector of dimension descriptors
88 * @return Expected number of DataVariant objects needed
89 */
90 [[nodiscard]] size_t get_expected_variant_count(const std::vector<DataDimension>& dimensions) const;
91
92 /**
93 * @brief Calculate size of a specific variant in the organization.
94 * @param dimensions Vector of dimension descriptors
95 * @param modality Data modality type
96 * @param organization Organization strategy
97 * @param variant_index Index of the variant (0-based)
98 * @return Number of elements in the specified variant
99 */
100 [[nodiscard]] static uint64_t get_variant_size(const std::vector<DataDimension>& dimensions,
101 DataModality modality, OrganizationStrategy organization, size_t variant_index = 0);
102 [[nodiscard]] uint64_t get_variant_size() const { return get_variant_size(dimensions, modality, organization); }
103
104 /**
105 * @brief Validate that dimensions match this structure's expectations.
106 * @param dimensions Vector of dimension descriptors to validate
107 * @return true if dimensions are valid for this structure
108 */
109 [[nodiscard]] bool validate_dimensions(const std::vector<DataDimension>& dimensions) const;
110
111 /**
112 * @brief Find the index of a dimension with the specified role.
113 * @param dimensions Vector of dimension descriptors to search
114 * @param role Dimension role to find
115 * @return Index of the dimension with the specified role
116 */
117 [[nodiscard]] size_t get_dimension_index_for_role(const std::vector<DataDimension>& dimensions,
118 DataDimension::Role role) const;
119
120 /**
121 * @brief Get total elements across all dimensions.
122 * @param dimensions Vector of dimension descriptors
123 * @return Total number of elements
124 */
125 [[nodiscard]] static uint64_t get_total_elements(const std::vector<DataDimension>& dimensions);
126 [[nodiscard]] uint64_t get_total_elements() const { return get_total_elements(dimensions); }
127
128 /**
129 * @brief Get total number of components (channels, spatial, frequency).
130 * @param dimensions Vector of dimension descriptors
131 * @return Total number of components
132 */
133 [[nodiscard]] static uint64_t get_component_count(const std::vector<DataDimension>& dimensions);
134 [[nodiscard]] uint64_t get_component_count() const { return get_component_count(dimensions); }
135
136 /**
137 * @brief Extract sample count from dimensions.
138 * @param dimensions Vector of dimension descriptors
139 * @return Number of samples in the temporal dimension
140 */
141 [[nodiscard]] static uint64_t get_samples_count(const std::vector<DataDimension>& dimensions);
142 [[nodiscard]] uint64_t get_samples_count() const { return get_samples_count(dimensions); }
143
144 /**
145 * @brief Get samples per channel (time dimension only).
146 * @param dimensions Vector of dimension descriptors
147 * @return Number of samples per channel
148 */
149 [[nodiscard]] static uint64_t get_samples_count_per_channel(const std::vector<DataDimension>& dimensions);
150 [[nodiscard]] uint64_t get_samples_count_per_channel() const { return get_samples_count_per_channel(dimensions); }
151
152 /**
153 * @brief Extract channel count from dimensions.
154 * @param dimensions Vector of dimension descriptors
155 * @return Number of channels
156 */
157 [[nodiscard]] static uint64_t get_channel_count(const std::vector<DataDimension>& dimensions);
158 [[nodiscard]] uint64_t get_channel_count() const { return get_channel_count(dimensions); }
159
160 /**
161 * @brief Get pixel count (spatial dimensions only).
162 * @param dimensions Vector of dimension descriptors
163 * @return Number of pixels
164 */
165 [[nodiscard]] static uint64_t get_pixels_count(const std::vector<DataDimension>& dimensions);
166 [[nodiscard]] uint64_t get_pixels_count() const { return get_pixels_count(dimensions); }
167
168 /**
169 * @brief Extract height from image/video dimensions.
170 * @param dimensions Vector of dimension descriptors
171 * @return Height in pixels
172 */
173 [[nodiscard]] static uint64_t get_height(const std::vector<DataDimension>& dimensions);
174 [[nodiscard]] uint64_t get_height() const { return get_height(dimensions); }
175
176 /**
177 * @brief Extract width from image/video dimensions.
178 * @param dimensions Vector of dimension descriptors
179 * @return Width in pixels
180 */
181 [[nodiscard]] static uint64_t get_width(const std::vector<DataDimension>& dimensions);
182 [[nodiscard]] uint64_t get_width() const { return get_width(dimensions); }
183
184 /**
185 * @brief Extract frame count from video dimensions.
186 * @param dimensions Vector of dimension descriptors
187 * @return Number of frames
188 */
189 [[nodiscard]] static size_t get_frame_count(const std::vector<DataDimension>& dimensions);
190 [[nodiscard]] size_t get_frame_count() const { return get_frame_count(dimensions); }
191
192 /**
193 * @brief Extract the size of non time dimensions (channel, spatial, frequency)
194 * @param dimensions Vector of dimension descriptors
195 * @return cumulative size of non time dimensions
196 */
197 [[nodiscard]] static size_t get_frame_size(const std::vector<DataDimension>& dimensions);
198 [[nodiscard]] size_t get_frame_size() const { return get_frame_size(dimensions); }
199};
200
201/**
202 * @class NDDataContainer
203 * @brief Abstract interface for N-dimensional data containers.
204 *
205 * NDDataContainer provides a dimension-agnostic API for accessing and manipulating
206 * multi-dimensional data (audio, video, tensors, etc). It is designed for digital-first,
207 * data-driven workflows, enabling flexible, efficient, and generic processing of
208 * structured data without imposing analog metaphors or legacy constraints.
209 *
210 * Key features:
211 * - Arbitrary dimension support (not limited to 2D or 3D)
212 * - Explicit memory layout control (row-major/column-major)
213 * - Region-based access for efficient subsetting and streaming
214 * - Thread-safe locking for concurrent processing
215 * - Support for multiple data types and precisions
216 * - Designed for composability with processors, buffers, and computational nodes
217 *
218 * This interface is the foundation for all high-level data containers in Maya Flux,
219 * enabling advanced workflows such as real-time streaming, offline analysis, and
220 * hybrid computational models.
221 */
222class MAYAFLUX_API NDDataContainer {
223public:
224 virtual ~NDDataContainer() = default;
225
226 /**
227 * @brief Get the dimensions describing the structure of the data.
228 * @return Vector of DataDimension objects (one per axis)
229 */
230 [[nodiscard]] virtual std::vector<DataDimension> get_dimensions() const = 0;
231
232 /**
233 * @brief Get the total number of elements in the container.
234 * @return Product of all dimension sizes
235 */
236 [[nodiscard]] virtual uint64_t get_total_elements() const = 0;
237
238 /**
239 * @brief Get the memory layout used by this container.
240 * @return Current memory layout (row-major or column-major)
241 */
242 [[nodiscard]] virtual MemoryLayout get_memory_layout() const = 0;
243
244 /**
245 * @brief Set the memory layout for this container.
246 * @param layout New memory layout to use
247 * @note May trigger data reorganization if implementation supports both layouts
248 */
249 virtual void set_memory_layout(MemoryLayout layout) = 0;
250
251 /**
252 * @brief Get the number of elements that constitute one "frame".
253 * For audio: channels per sample. For images: pixels per frame.
254 * @return Number of elements per frame
255 */
256 [[nodiscard]] virtual uint64_t get_frame_size() const = 0;
257
258 /**
259 * @brief Get the number of frames in the primary (temporal) dimension.
260 * @return Number of frames
261 */
262 [[nodiscard]] virtual uint64_t get_num_frames() const = 0;
263
264 /**
265 * @brief Get data for a specific region.
266 * @param region The region to extract data from
267 * @return std::vector<DataVariant> containing the region's data
268 */
269 [[nodiscard]] virtual std::vector<DataVariant> get_region_data(const Region& region) const = 0;
270
271 /**
272 * @brief Get data for multiple regions efficiently.
273 * @param regions Vector of regions to extract data from
274 * @return Vector of DataVariant vectors, one per region
275 */
276 [[nodiscard]] virtual std::vector<DataVariant> get_region_group_data(const RegionGroup& regions) const = 0;
277
278 /**
279 * @brief Get data for multiple region segments efficiently.
280 * @param segments Vector of region segments to extract data from
281 * @return Vector of DataVariant vectors, one per segment
282 */
283 [[nodiscard]] virtual std::vector<DataVariant> get_segments_data(const std::vector<RegionSegment>& segments) const = 0;
284
285 /**
286 * @brief Set data for a specific region.
287 * @param region The region to write data to
288 * @param data The data to write
289 */
290 virtual void set_region_data(const Region& region, const std::vector<DataVariant>& data) = 0;
291
292 /**
293 * @brief Get a single frame of data efficiently.
294 * @param frame_index Index of the frame (in the temporal dimension)
295 * @return Span of data representing one complete frame
296 */
297 [[nodiscard]] auto get_frame(uint64_t frame_index) const -> FrameView
298 {
299 return FrameView(get_frame_span_impl(frame_index));
300 }
301
302 /**
303 * @brief Get multiple frames efficiently.
304 * @param output Buffer to write frames into
305 * @param start_frame First frame index
306 * @param num_frames Number of frames to retrieve
307 */
308 template <DataVariantElement T>
309 void get_frames(std::span<T> output, uint64_t start_frame, uint64_t num_frames) const
310 {
311 get_frames_impl(output.data(), output.size(), start_frame, num_frames, typeid(T));
312 }
313
314 /**
315 * @brief Get a single frame of data as a typed span.
316 * @tparam T Element type to interpret the frame data as
317 * @param frame_index Index of the frame (in the temporal dimension)
318 * @return Span of data representing one complete frame, interpreted as type T
319 */
320 template <DataVariantElement T>
321 [[nodiscard]] auto get_frame_as(uint64_t frame_index) const -> std::span<const T>
322 {
323 return get_frame(frame_index).template as<T>();
324 }
325
326 /**
327 * @brief Get multiple frames efficiently as a typed span.
328 *
329 * Convenience wrapper over get_frames() for callers that know the element
330 * type statically but hold the output buffer as a plain vector rather than
331 * a typed span. Deduces T from the vector element type; no visitor, no
332 * type query needed at the call site.
333 *
334 * @tparam T Element type. Must satisfy DataVariantElement and match the
335 * container's native element type. The impl silently no-ops or
336 * errors on mismatch depending on the container.
337 * @param output Destination vector. Resized to num_frames * frame_size
338 * by the caller before passing; content is overwritten.
339 * @param start_frame First frame index.
340 * @param num_frames Number of frames to retrieve.
341 */
342 template <DataVariantElement T>
343 void get_frames_as(std::vector<T>& output, uint64_t start_frame, uint64_t num_frames) const
344 {
345 get_frames_impl(output.data(), output.size(), start_frame, num_frames, typeid(T));
346 }
347
348 /**
349 * @brief Runtime query for the native scalar element type of this container.
350 *
351 * Mirrors FrameView::element_type(). Typical return values:
352 * - typeid(uint8_t) -- 8-bit image / video / window
353 * - typeid(uint16_t) -- 16-bit image
354 * - typeid(float) -- HDR image
355 * - typeid(double) -- audio / plot
356 *
357 * Use this to branch once before calling get_value_at<T>() when the
358 * container's native type is not statically known at the call site.
359 */
360 [[nodiscard]] virtual std::type_index value_element_type() const = 0;
361
362 /**
363 * @brief Read a single element at the given N-dimensional coordinates.
364 *
365 * Returns a default-constructed T on coordinate out-of-range or type mismatch.
366 * No conversion is performed: T must match the container's native element type
367 * (query value_element_type() first when the type is not statically known).
368 *
369 * @tparam T Element type. Must satisfy DataVariantElement.
370 * @param coordinates N-dimensional coordinate vector.
371 * @return Native-typed value, zero-initialised on error.
372 */
373 template <DataVariantElement T>
374 [[nodiscard]] T get_value_at(const std::vector<uint64_t>& coordinates) const
375 {
376 T v {};
377 get_value_impl(coordinates, &v, typeid(T));
378 return v;
379 }
380
381 /**
382 * @brief Write a single element at the given N-dimensional coordinates.
383 *
384 * No-ops on coordinate out-of-range or type mismatch.
385 * T must match the container's native element type.
386 *
387 * @tparam T Element type. Must satisfy DataVariantElement.
388 * @param coordinates N-dimensional coordinate vector.
389 * @param value Value to write.
390 */
391 template <DataVariantElement T>
392 void set_value_at(const std::vector<uint64_t>& coordinates, T value)
393 {
394 set_value_impl(coordinates, &value, typeid(T));
395 }
396
397 /**
398 * @brief Add a named group of regions to the container.
399 * @param group RegionGroup to add
400 */
401 virtual void add_region_group(const RegionGroup& group) = 0;
402
403 /**
404 * @brief Get a region group by name.
405 * @param name Name of the region group
406 * @return Reference to the RegionGroup
407 */
408 [[nodiscard]] virtual RegionGroup get_region_group(const std::string& name) const = 0;
409
410 /**
411 * @brief Get all region groups in the container.
412 * @return Map of region group names to RegionGroup objects
413 */
414 [[nodiscard]] virtual std::unordered_map<std::string, RegionGroup> get_all_region_groups() const = 0;
415
416 /**
417 * @brief Remove a region group by name.
418 * @param name Name of the region group to remove
419 */
420 virtual void remove_region_group(const std::string& name) = 0;
421
422 /**
423 * @brief Check if a region is loaded in memory.
424 * @param region Region to check
425 * @return true if region is loaded, false otherwise
426 */
427 [[nodiscard]] virtual bool is_region_loaded(const Region& region) const = 0;
428
429 /**
430 * @brief Load a region into memory.
431 * @param region Region to load
432 */
433 virtual void load_region(const Region& region) = 0;
434
435 /**
436 * @brief Unload a region from memory.
437 * @param region Region to unload
438 */
439 virtual void unload_region(const Region& region) = 0;
440
441 /**
442 * @brief Convert coordinates to linear index based on current memory layout.
443 * @param coordinates N-dimensional coordinates
444 * @return Linear index into the underlying data storage
445 */
446 [[nodiscard]] virtual uint64_t coordinates_to_linear_index(const std::vector<uint64_t>& coordinates) const = 0;
447
448 /**
449 * @brief Convert linear index to coordinates based on current memory layout.
450 * @param linear_index Linear index into the underlying data storage
451 * @return N-dimensional coordinates
452 */
453 [[nodiscard]] virtual std::vector<uint64_t> linear_index_to_coordinates(uint64_t linear_index) const = 0;
454
455 /**
456 * @brief Clear all data in the container.
457 */
458 virtual void clear() = 0;
459
460 /**
461 * @brief Get a raw pointer to the underlying data storage.
462 * @return Pointer to raw data (type depends on DataVariant)
463 */
464 [[nodiscard]] virtual const void* get_raw_data() const = 0;
465
466 /**
467 * @brief Check if the container currently holds any data.
468 * @return true if data is present, false otherwise
469 */
470 [[nodiscard]] virtual bool has_data() const = 0;
471
472 /**
473 * @brief Get the data structure defining this container's layout.
474 * @return Reference to the ContainerDataStructure
475 */
476 [[nodiscard]] virtual ContainerDataStructure& get_structure() = 0;
477 [[nodiscard]] virtual const ContainerDataStructure& get_structure() const = 0;
478
479 /**
480 * @brief Set the data structure for this container.
481 * @param structure New ContainerDataStructure to apply
482 * @note This may trigger reorganization of existing data to match the new structure.
483 */
484 virtual void set_structure(ContainerDataStructure structure) = 0;
485
486protected:
487 /**
488 * @brief Implementation-specific method to retrieve a frame span.
489 * @param frame_index Index of the frame to retrieve
490 * @return DataSpanVariant representing the frame's data
491 */
492 [[nodiscard]] virtual auto get_frame_span_impl(uint64_t frame_index) const -> DataSpanVariant = 0;
493
494 /**
495 * @brief Implementation-specific method to retrieve multiple frames.
496 *
497 * Implementations write up to count * frame_size elements into output,
498 * starting from start_frame. The type parameter indicates the expected
499 * element type; implementations may choose to support or reject it based
500 * on their native data type, but must not write past the output buffer
501 * regardless.
502 *
503 * @param output Pointer to caller-owned buffer for frame data
504 * @param count Number of frames to retrieve (output buffer size in frames)
505 * @param start_frame First frame index to retrieve
506 * @param num_frames Number of frames to retrieve
507 * @param type Type information for the expected element type (e.g. float, uint8_t)
508 */
509 virtual void get_frames_impl(void* output, size_t count, uint64_t start_frame, uint64_t num_frames, const std::type_info& type) const = 0;
510
511 /**
512 * @brief Type-erased single-element read.
513 *
514 * Implementations copy the native element at @p coords into @p out
515 * if @p type matches their native type, otherwise no-op.
516 * @p out points to a caller-owned buffer of exactly sizeof(native type) bytes.
517 */
518 virtual void get_value_impl(const std::vector<uint64_t>& coords,
519 void* out,
520 const std::type_info& type) const = 0;
521
522 /**
523 * @brief Type-erased single-element write.
524 *
525 * Implementations copy from @p in into their storage at @p coords
526 * if @p type matches their native type, otherwise no-op.
527 * @p in points to a caller-owned buffer of exactly sizeof(native type) bytes.
528 */
529 virtual void set_value_impl(const std::vector<uint64_t>& coords,
530 const void* in,
531 const std::type_info& type) = 0;
532};
533
534} // namespace MayaFlux::Kakshya
vk::PhysicalDeviceType type
Definition VKDevice.cpp:146
std::string name
Definition VKDevice.cpp:143
size_t count
float value
std::shared_ptr< Core::VKImage > output
Zero-copy typed view over one frame of container storage.
Definition NDData.hpp:686
virtual std::vector< DataVariant > get_region_group_data(const RegionGroup &regions) const =0
Get data for multiple regions efficiently.
virtual void set_region_data(const Region &region, const std::vector< DataVariant > &data)=0
Set data for a specific region.
void get_frames_as(std::vector< T > &output, uint64_t start_frame, uint64_t num_frames) const
Get multiple frames efficiently as a typed span.
virtual void unload_region(const Region &region)=0
Unload a region from memory.
virtual void clear()=0
Clear all data in the container.
virtual void set_value_impl(const std::vector< uint64_t > &coords, const void *in, const std::type_info &type)=0
Type-erased single-element write.
virtual RegionGroup get_region_group(const std::string &name) const =0
Get a region group by name.
virtual void add_region_group(const RegionGroup &group)=0
Add a named group of regions to the container.
virtual void get_frames_impl(void *output, size_t count, uint64_t start_frame, uint64_t num_frames, const std::type_info &type) const =0
Implementation-specific method to retrieve multiple frames.
virtual const ContainerDataStructure & get_structure() const =0
virtual std::type_index value_element_type() const =0
Runtime query for the native scalar element type of this container.
virtual bool has_data() const =0
Check if the container currently holds any data.
void set_value_at(const std::vector< uint64_t > &coordinates, T value)
Write a single element at the given N-dimensional coordinates.
virtual std::vector< DataDimension > get_dimensions() const =0
Get the dimensions describing the structure of the data.
virtual void set_memory_layout(MemoryLayout layout)=0
Set the memory layout for this container.
virtual ContainerDataStructure & get_structure()=0
Get the data structure defining this container's layout.
void get_frames(std::span< T > output, uint64_t start_frame, uint64_t num_frames) const
Get multiple frames efficiently.
virtual void load_region(const Region &region)=0
Load a region into memory.
virtual void set_structure(ContainerDataStructure structure)=0
Set the data structure for this container.
T get_value_at(const std::vector< uint64_t > &coordinates) const
Read a single element at the given N-dimensional coordinates.
virtual std::unordered_map< std::string, RegionGroup > get_all_region_groups() const =0
Get all region groups in the container.
virtual bool is_region_loaded(const Region &region) const =0
Check if a region is loaded in memory.
virtual void remove_region_group(const std::string &name)=0
Remove a region group by name.
auto get_frame(uint64_t frame_index) const -> FrameView
Get a single frame of data efficiently.
virtual const void * get_raw_data() const =0
Get a raw pointer to the underlying data storage.
virtual std::vector< DataVariant > get_segments_data(const std::vector< RegionSegment > &segments) const =0
Get data for multiple region segments efficiently.
virtual auto get_frame_span_impl(uint64_t frame_index) const -> DataSpanVariant=0
Implementation-specific method to retrieve a frame span.
virtual std::vector< DataVariant > get_region_data(const Region &region) const =0
Get data for a specific region.
virtual MemoryLayout get_memory_layout() const =0
Get the memory layout used by this container.
virtual uint64_t coordinates_to_linear_index(const std::vector< uint64_t > &coordinates) const =0
Convert coordinates to linear index based on current memory layout.
virtual uint64_t get_frame_size() const =0
Get the number of elements that constitute one "frame".
auto get_frame_as(uint64_t frame_index) const -> std::span< const T >
Get a single frame of data as a typed span.
virtual void get_value_impl(const std::vector< uint64_t > &coords, void *out, const std::type_info &type) const =0
Type-erased single-element read.
virtual uint64_t get_total_elements() const =0
Get the total number of elements in the container.
virtual uint64_t get_num_frames() const =0
Get the number of frames in the primary (temporal) dimension.
virtual std::vector< uint64_t > linear_index_to_coordinates(uint64_t linear_index) const =0
Convert linear index to coordinates based on current memory layout.
Abstract interface for N-dimensional data containers.
typename detail::span_const_from_vector_variant< DataVariant >::type DataSpanVariant
Definition NDData.hpp:657
DataModality
Data modality types for cross-modal analysis.
Definition NDData.hpp:164
MemoryLayout
Memory layout for multi-dimensional data.
Definition NDData.hpp:65
OrganizationStrategy
Data organization strategy for multi-channel/multi-frame data.
Definition NDData.hpp:75
Container structure for consistent dimension ordering.
Role
Semantic role of the dimension.
Definition NDData.hpp:236
Organizes related signal regions into a categorized collection.
Represents a point or span in N-dimensional space.
Definition Region.hpp:73