5#include <glm/gtc/type_ptr.hpp>
23 std::vector<DataDimension>& dimensions,
26 , m_dimensions(dimensions)
27 , m_modality(modality)
39 requires std::is_arithmetic_v<T>
42 bool replace_existing =
true)
44 validate_scalar_insertion(target_modality);
46 if (replace_existing) {
47 m_variant = std::move(data);
48 m_modality = target_modality;
51 m_dimensions.emplace_back(
52 modality_to_dimension_name(target_modality),
53 static_cast<uint64_t
>(data.size()),
55 modality_to_role(target_modality));
57 append_to_existing(std::move(data));
71 bool replace_existing =
true)
73 validate_structured_insertion<T>(target_modality);
75 if (replace_existing) {
76 m_variant = std::move(data);
77 m_modality = target_modality;
80 m_dimensions.push_back(create_structured_dimension<T>(
81 static_cast<uint64_t
>(data.size()),
84 append_structured_to_existing(std::move(data));
97 std::vector<T> data_copy(data_span.begin(), data_span.end());
99 if constexpr (GlmType<T>) {
100 insert_structured(std::move(data_copy), target_modality);
102 insert_scalar(std::move(data_copy), target_modality);
113 template <
typename From,
typename To>
116 std::vector<To> converted;
117 auto source_span = std::span<From>(
118 const_cast<From*
>(source.data()), source.size());
119 convert_data<From, To>(source_span, converted);
121 if constexpr (GlmType<To>) {
122 insert_structured(std::move(converted), target_modality);
124 insert_scalar(std::move(converted), target_modality);
136 switch (target_modality) {
137 case DataModality::VERTEX_POSITIONS_3D:
138 case DataModality::VERTEX_NORMALS_3D:
139 case DataModality::VERTEX_TANGENTS_3D:
140 case DataModality::VERTEX_COLORS_RGB:
141 m_variant = std::vector<glm::vec3>();
142 std::get<std::vector<glm::vec3>>(m_variant).reserve(element_count);
145 case DataModality::TEXTURE_COORDS_2D:
146 m_variant = std::vector<glm::vec2>();
147 std::get<std::vector<glm::vec2>>(m_variant).reserve(element_count);
150 case DataModality::VERTEX_COLORS_RGBA:
151 m_variant = std::vector<glm::vec4>();
152 std::get<std::vector<glm::vec4>>(m_variant).reserve(element_count);
155 case DataModality::TRANSFORMATION_MATRIX:
156 m_variant = std::vector<glm::mat4>();
157 std::get<std::vector<glm::mat4>>(m_variant).reserve(element_count);
161 error<std::invalid_argument>(
162 Journal::Component::Kakshya,
163 Journal::Context::Runtime,
164 std::source_location::current(),
165 "Modality {} does not represent structured GLM data",
169 m_variant = std::vector<double>();
170 std::get<std::vector<double>>(m_variant).reserve(element_count);
173 m_modality = target_modality;
181 std::visit([](
auto& vec) { vec.clear(); }, m_variant);
182 m_dimensions.clear();
189 return std::visit([](
const auto& vec) {
return vec.empty(); }, m_variant);
203 error<std::invalid_argument>(
204 Journal::Component::Kakshya,
205 Journal::Context::Runtime,
206 std::source_location::current(),
207 "Modality {} expects structured data (GLM types), not scalars. "
208 "Use insert_structured() or change modality.",
219 constexpr size_t components = glm_component_count<T>();
223 case DataModality::VERTEX_POSITIONS_3D:
224 case DataModality::VERTEX_NORMALS_3D:
225 case DataModality::VERTEX_TANGENTS_3D:
226 case DataModality::VERTEX_COLORS_RGB:
227 valid = (components == 3);
230 case DataModality::TEXTURE_COORDS_2D:
231 valid = (components == 2);
234 case DataModality::VERTEX_COLORS_RGBA:
235 valid = (components == 4);
238 case DataModality::TRANSFORMATION_MATRIX:
239 valid = (components == 16);
243 error<std::invalid_argument>(
244 Journal::Component::Kakshya,
245 Journal::Context::Runtime,
246 std::source_location::current(),
247 "Modality {} does not represent structured GLM data",
252 error<std::invalid_argument>(
253 Journal::Component::Kakshya,
254 Journal::Context::Runtime,
255 std::source_location::current(),
256 "GLM type component count ({}) doesn't match modality {}. "
257 "Suggested type: {}",
260 suggest_glm_type_for_modality(modality));
272 case DataModality::VERTEX_POSITIONS_3D:
273 return DataDimension::vertex_positions(element_count);
275 case DataModality::VERTEX_NORMALS_3D:
276 return DataDimension::vertex_normals(element_count);
278 case DataModality::TEXTURE_COORDS_2D:
279 return DataDimension::texture_coords(element_count);
281 case DataModality::VERTEX_COLORS_RGB:
282 return DataDimension::vertex_colors(element_count,
false);
284 case DataModality::VERTEX_COLORS_RGBA:
285 return DataDimension::vertex_colors(element_count,
true);
287 case DataModality::TRANSFORMATION_MATRIX:
288 case DataModality::VERTEX_TANGENTS_3D:
290 constexpr size_t components = glm_component_count<T>();
291 return DataDimension::grouped(
292 modality_to_dimension_name(modality),
294 static_cast<uint8_t
>(components),
295 modality_to_role(modality));
303 template <
typename T>
306 std::visit([&](
auto& existing_vec) {
307 using ExistingType =
typename std::decay_t<
decltype(existing_vec)>::value_type;
309 if constexpr (std::is_same_v<ExistingType, T>) {
310 existing_vec.insert(existing_vec.end(),
313 }
else if constexpr (std::is_arithmetic_v<ExistingType> && std::is_arithmetic_v<T>) {
314 for (
const auto& val : new_data) {
315 existing_vec.push_back(
static_cast<ExistingType
>(val));
318 error<std::invalid_argument>(
319 Journal::Component::Kakshya,
320 Journal::Context::Runtime,
321 std::source_location::current(),
322 "Cannot append: incompatible types in variant (existing: {}, new: {})",
323 typeid(ExistingType).name(),
329 if (!m_dimensions.empty()) {
330 m_dimensions[0].size = std::visit(
331 [](
const auto& vec) {
return static_cast<uint64_t
>(vec.size()); },
342 if (!std::holds_alternative<std::vector<T>>(m_variant)) {
343 error<std::invalid_argument>(
344 Journal::Component::Kakshya,
345 Journal::Context::Runtime,
346 std::source_location::current(),
347 "Cannot append: existing variant doesn't hold matching GLM type ({})",
351 auto&
existing = std::get<std::vector<T>>(m_variant);
354 if (!m_dimensions.empty()) {
355 m_dimensions[0].size =
existing.size();
365 case DataModality::VERTEX_POSITIONS_3D:
367 case DataModality::VERTEX_NORMALS_3D:
369 case DataModality::VERTEX_TANGENTS_3D:
371 case DataModality::VERTEX_COLORS_RGB:
372 case DataModality::VERTEX_COLORS_RGBA:
374 case DataModality::TEXTURE_COORDS_2D:
376 case DataModality::TRANSFORMATION_MATRIX:
378 case DataModality::AUDIO_1D:
380 case DataModality::AUDIO_MULTICHANNEL:
393 case DataModality::AUDIO_1D:
394 case DataModality::AUDIO_MULTICHANNEL:
395 return DataDimension::Role::TIME;
397 case DataModality::VERTEX_POSITIONS_3D:
398 case DataModality::VERTEX_NORMALS_3D:
399 case DataModality::VERTEX_TANGENTS_3D:
400 case DataModality::TEXTURE_COORDS_2D:
401 return DataDimension::Role::UV;
403 case DataModality::VERTEX_COLORS_RGB:
404 case DataModality::VERTEX_COLORS_RGBA:
405 return DataDimension::Role::CHANNEL;
408 return DataDimension::Role::CUSTOM;
418 case DataModality::VERTEX_POSITIONS_3D:
419 case DataModality::VERTEX_NORMALS_3D:
420 case DataModality::VERTEX_TANGENTS_3D:
421 case DataModality::VERTEX_COLORS_RGB:
424 case DataModality::TEXTURE_COORDS_2D:
427 case DataModality::VERTEX_COLORS_RGBA:
430 case DataModality::TRANSFORMATION_MATRIX:
Cycle Behavior: The for_cycles(N) configuration controls how many times the capture operation execute...
DataModality & m_modality
void append_structured_to_existing(std::vector< T > new_data)
Append structured data to existing storage.
void insert_scalar(std::vector< T > data, DataModality target_modality, bool replace_existing=true)
Insert scalar array data.
void validate_structured_insertion(DataModality modality) const
Validate structured insertion matches GLM component count.
static std::string modality_to_dimension_name(DataModality modality)
Convert modality to appropriate dimension name.
void reserve_space(size_t element_count, DataModality target_modality)
Reserve space without initialization.
std::vector< DataDimension > & m_dimensions
DataInsertion(DataVariant &variant, std::vector< DataDimension > &dimensions, DataModality &modality)
void insert_structured(std::vector< T > data, DataModality target_modality, bool replace_existing=true)
Insert structured GLM data with automatic dimension setup.
void validate_scalar_insertion(DataModality modality) const
Validate scalar insertion matches modality expectations.
void append_to_existing(std::vector< T > new_data)
Append scalar data to existing storage.
static std::string_view suggest_glm_type_for_modality(DataModality modality)
Suggest appropriate GLM type for a modality.
DataModality current_modality() const
DataDimension create_structured_dimension(uint64_t element_count, DataModality modality) const
Create dimension descriptor for structured data.
void insert_converted(const std::vector< From > &source, DataModality target_modality)
Convert and insert from different type.
static DataDimension::Role modality_to_role(DataModality modality)
Convert modality to dimension role.
void clear_data()
Clear all data while preserving modality.
void insert_from_span(std::span< const T > data_span, DataModality target_modality)
Insert data from span (copy operation)
Type-erased writer for NDData with semantic construction.
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.
bool is_structured_modality(DataModality modality)
Check if a modality represents structured data (vectors, matrices).
std::string_view modality_to_string(DataModality modality)
Convert DataModality enum to string representation.
Role
Semantic role of the dimension.
Minimal dimension descriptor focusing on structure only.