5#include <glm/gtc/type_ptr.hpp>
22 const std::vector<DataDimension>& dimensions,
25 , m_dimensions(dimensions)
26 , m_modality(modality)
48 return std::visit([&](
auto& vec) {
49 using T =
typename std::decay_t<
decltype(vec)>::value_type;
50 return std::make_tuple(
51 static_cast<const void*
>(vec.data()),
52 vec.size() *
sizeof(T),
53 get_format_hint<T>());
62 return !m_dimensions.empty() && m_dimensions[0].grouping.has_value();
67 if (is_structured()) {
68 return m_dimensions[0].size;
70 return std::visit([](
const auto& vec) {
return vec.size(); }, m_variant);
75 if (is_structured() && m_dimensions[0].grouping) {
76 return m_dimensions[0].grouping->count;
83 if (is_structured()) {
84 return Journal::format(
"{}Ă—{} ({})",
89 return Journal::format(
"scalarĂ—{} ({})",
100 switch (m_modality) {
101 case DataModality::VERTEX_POSITIONS_3D:
102 case DataModality::VERTEX_NORMALS_3D:
103 case DataModality::VERTEX_TANGENTS_3D:
104 case DataModality::VERTEX_COLORS_RGB:
107 case DataModality::TEXTURE_COORDS_2D:
110 case DataModality::VERTEX_COLORS_RGBA:
113 case DataModality::TRANSFORMATION_MATRIX:
116 case DataModality::AUDIO_1D:
117 case DataModality::AUDIO_MULTICHANNEL:
118 case DataModality::SPECTRAL_2D:
121 case DataModality::IMAGE_2D:
122 case DataModality::IMAGE_COLOR:
123 case DataModality::TEXTURE_2D:
138 template <
typename T>
146 template <
typename T>
147 requires std::is_arithmetic_v<T>
148 std::span<const T> create_scalar_view()
const;
150 template <
typename T>
151 void validate_structured_access()
const;
159 template <
typename T>
162 if (!m_conversion_cache || m_conversion_cache->size() < required_bytes) {
163 m_conversion_cache = std::vector<uint8_t>(required_bytes);
165 return m_conversion_cache->data();
179 static constexpr size_t components = glm_component_count<T>();
191 return construct_glm_type<T>(base);
236 std::vector<T> result;
239 result.push_back((*
this)[i]);
249 template <
typename GlmType>
252 if constexpr (GlmVec2Type<GlmType>) {
254 }
else if constexpr (GlmVec3Type<GlmType>) {
256 }
else if constexpr (GlmVec4Type<GlmType>) {
258 }
else if constexpr (GlmMatrixType<GlmType>) {
271 if constexpr (GlmType<T>) {
272 validate_structured_access<T>();
275 using StorageType =
typename std::decay_t<
decltype(vec)>::value_type;
276 using ComponentType = glm_component_type<T>;
277 constexpr size_t components = glm_component_count<T>();
279 size_t required_components =
m_dimensions[0].size * components;
280 if (vec.size() < required_components) {
281 error<std::runtime_error>(
284 std::source_location::current(),
285 "Insufficient data: need {} elements of type {} but have {} elements of type {}",
288 vec.size() / components,
289 typeid(StorageType).name());
292 if constexpr (std::is_same_v<StorageType, ComponentType>) {
294 }
else if constexpr (std::is_convertible_v<StorageType, ComponentType>) {
295 size_t required_bytes = vec.size() *
sizeof(ComponentType);
296 void* cache_ptr = ensure_conversion_cache<ComponentType>(required_bytes);
298 ComponentType* cache_data =
static_cast<ComponentType*
>(cache_ptr);
299 std::ranges::transform(vec, cache_data,
300 [](
auto val) {
return static_cast<ComponentType
>(val); });
304 error<std::invalid_argument>(
307 std::source_location::current(),
308 "Cannot convert storage type {} to component type {}",
309 typeid(StorageType).name(),
310 typeid(ComponentType).name());
315 }
else if constexpr (std::is_arithmetic_v<T>) {
316 return create_scalar_view<T>();
319 static_assert(always_false_v<T>,
320 "Unsupported view type. Use glm types or arithmetic types (double, float, int, etc.)");
325 requires std::is_arithmetic_v<T>
328 return std::visit([
this](
auto& vec) -> std::span<const T> {
329 using StorageType =
typename std::decay_t<
decltype(vec)>::value_type;
331 if constexpr (std::is_same_v<StorageType, T>) {
332 return std::span<const T>(vec.data(), vec.size());
333 }
else if constexpr (std::is_convertible_v<StorageType, T>) {
334 size_t required_bytes = vec.size() *
sizeof(T);
335 void* cache_ptr = ensure_conversion_cache<T>(required_bytes);
337 T* cache_data =
static_cast<T*
>(cache_ptr);
338 std::ranges::transform(vec, cache_data,
339 [](
auto val) {
return static_cast<T
>(val); });
341 return std::span<const T>(cache_data, vec.size());
343 error<std::invalid_argument>(
346 std::source_location::current(),
347 "Cannot convert storage type {} to requested type {}",
348 typeid(StorageType).name(),
358 constexpr size_t requested_components = glm_component_count<T>();
361 error<std::runtime_error>(
364 std::source_location::current(),
365 "Cannot create structured view: no dimensions defined");
369 error<std::runtime_error>(
372 std::source_location::current(),
373 "Cannot create structured view: dimension '{}' missing component grouping. "
374 "Use DataDimension::grouped() to create structured dimensions.",
378 size_t actual_components =
m_dimensions[0].grouping->count;
379 if (actual_components != requested_components) {
380 error<std::runtime_error>(
383 std::source_location::current(),
384 "Component count mismatch: requested {} components ({}), but data has {} components per element. "
385 "Suggested type: {}",
386 requested_components,
static uint32_t get_format_hint()
size_t component_count() const
const std::vector< DataDimension > & m_dimensions
void * ensure_conversion_cache(size_t required_bytes) const
Ensure conversion cache exists and is properly sized.
std::span< const T > create_scalar_view() const
auto gpu_buffer() const
Get raw buffer info for GPU upload.
DataAccess(DataVariant &variant, const std::vector< DataDimension > &dimensions, DataModality modality)
auto view() const
Get explicit typed view of data.
DataModality modality() const
bool is_structured() const
std::string_view suggested_view_type() const
Get suggested view type for this data's modality.
std::optional< std::vector< uint8_t > > m_conversion_cache
std::string type_description() const
void validate_structured_access() const
size_t element_count() const
Type-erased accessor for NDData with semantic view construction.
iterator(const component_type *ptr, size_t stride)
bool operator==(const iterator &other) const
const component_type * m_ptr
bool operator!=(const iterator &other) const
std::ptrdiff_t difference_type
T operator[](size_t idx) const
const void * data() const
static GlmType construct_glm_type(const component_type *components)
size_t size_bytes() const
std::vector< T > to_vector() const
static constexpr size_t components
StructuredView(const void *data, size_t element_count, size_t stride_bytes=0)
glm_component_type< T > component_type
const component_type * m_data
Span-like view that interprets flat data as structured types (glm::vec3, etc.)
@ Runtime
General runtime operations (default fallback)
@ Kakshya
Containers[Signalsource, Stream, File], Regions, DataProcessors.
std::variant< std::vector< double >, std::vector< float >, std::vector< uint8_t >, std::vector< uint16_t >, std::vector< uint32_t >, std::vector< std::complex< float > >, std::vector< std::complex< double > >, std::vector< glm::vec2 >, std::vector< glm::vec3 >, std::vector< glm::vec4 >, std::vector< glm::mat4 > > DataVariant
Multi-type data storage for different precision needs.
DataModality
Data modality types for cross-modal analysis.
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.