1.3.49
 
Loading...
Searching...
No Matches
Context_data.cpp
Go to the documentation of this file.
1
16#include "Context.h"
17
18using namespace helios;
19
20void Context::incrementPrimitiveDataLabelCounter(const std::string &primitive_data_label) {
21 primitive_data_label_counts[primitive_data_label]++;
22}
23
24void Context::decrementPrimitiveDataLabelCounter(const std::string &primitive_data_label) {
25 auto it = primitive_data_label_counts.find(primitive_data_label);
26 if (it != primitive_data_label_counts.end() && it->second > 0) {
27 it->second--;
28 if (it->second == 0) {
29 primitive_data_label_counts.erase(it);
30 }
31 }
32}
33
34//----------- VALUE-LEVEL CACHING CONFIGURATION ----------//
35
36void Context::enablePrimitiveDataValueCaching(const std::string &label) {
37 cached_primitive_data_labels.insert(label);
38}
39
40void Context::disablePrimitiveDataValueCaching(const std::string &label) {
41 cached_primitive_data_labels.erase(label);
42 // Clear cached values for this label
43 primitive_string_value_registry.erase(label);
44 primitive_int_value_registry.erase(label);
45 primitive_uint_value_registry.erase(label);
46}
47
48bool Context::isPrimitiveDataValueCachingEnabled(const std::string &label) const {
49 return cached_primitive_data_labels.find(label) != cached_primitive_data_labels.end();
50}
51
52void Context::enableObjectDataValueCaching(const std::string &label) {
53 cached_object_data_labels.insert(label);
54}
55
56void Context::disableObjectDataValueCaching(const std::string &label) {
57 cached_object_data_labels.erase(label);
58 // Clear cached values for this label
59 object_string_value_registry.erase(label);
60 object_int_value_registry.erase(label);
61 object_uint_value_registry.erase(label);
62}
63
64bool Context::isObjectDataValueCachingEnabled(const std::string &label) const {
65 return cached_object_data_labels.find(label) != cached_object_data_labels.end();
66}
67
68
69void Context::incrementObjectDataLabelCounter(const std::string &object_data_label) {
70 object_data_label_counts[object_data_label]++;
71}
72
73void Context::decrementObjectDataLabelCounter(const std::string &object_data_label) {
74 auto it = object_data_label_counts.find(object_data_label);
75 if (it != object_data_label_counts.end() && it->second > 0) {
76 it->second--;
77 if (it->second == 0) {
78 object_data_label_counts.erase(it);
79 }
80 }
81}
82
83// ------ Primitive Data -------- //
84
85HeliosDataType Primitive::getPrimitiveDataType(const char *label) const {
86
87#ifdef HELIOS_DEBUG
88 if (!doesPrimitiveDataExist(label)) {
89 helios_runtime_error("ERROR (Primitive::getPrimitiveDataType): Primitive data " + std::string(label) + " does not exist for primitive " + std::to_string(UUID));
90 }
91#endif
92
93 return primitive_data_types.at(label);
94}
95
97 const auto it = primitive_data_type_registry.find(label);
98 if (it != primitive_data_type_registry.end()) {
99 return it->second;
100 }
101 helios_runtime_error("ERROR (Context::getPrimitiveDataType): Primitive data " + std::string(label) + " does not exist.");
102 return HELIOS_TYPE_UNKNOWN; // Should never reach here, but added to avoid compiler warning
103}
104
105uint Primitive::getPrimitiveDataSize(const char *label) const {
106
107#ifdef HELIOS_DEBUG
108 if (!doesPrimitiveDataExist(label)) {
109 helios_runtime_error("ERROR (Primitive::getPrimitiveDataSize): Primitive data " + std::string(label) + " does not exist for primitive " + std::to_string(UUID));
110 }
111#endif
112
113 const HeliosDataType &type = primitive_data_types.at(label);
114
115 if (type == HELIOS_TYPE_INT) {
116 return primitive_data_int.at(label).size();
117 } else if (type == HELIOS_TYPE_UINT) {
118 return primitive_data_uint.at(label).size();
119 } else if (type == HELIOS_TYPE_FLOAT) {
120 return primitive_data_float.at(label).size();
121 } else if (type == HELIOS_TYPE_DOUBLE) {
122 return primitive_data_double.at(label).size();
123 } else if (type == HELIOS_TYPE_VEC2) {
124 return primitive_data_vec2.at(label).size();
125 } else if (type == HELIOS_TYPE_VEC3) {
126 return primitive_data_vec3.at(label).size();
127 } else if (type == HELIOS_TYPE_VEC4) {
128 return primitive_data_vec4.at(label).size();
129 } else if (type == HELIOS_TYPE_INT2) {
130 return primitive_data_int2.at(label).size();
131 } else if (type == HELIOS_TYPE_INT3) {
132 return primitive_data_int3.at(label).size();
133 } else if (type == HELIOS_TYPE_INT4) {
134 return primitive_data_int4.at(label).size();
135 } else if (type == HELIOS_TYPE_STRING) {
136 return primitive_data_string.at(label).size();
137 } else {
138 assert(false);
139 }
140
141 return 0;
142}
143
144void Primitive::clearPrimitiveData(const char *label) {
145
146 if (!doesPrimitiveDataExist(label)) {
147 return;
148 }
149
150 HeliosDataType type = primitive_data_types.at(label);
151
152 if (type == HELIOS_TYPE_INT) {
153 primitive_data_int.erase(label);
154 primitive_data_types.erase(label);
155 } else if (type == HELIOS_TYPE_UINT) {
156 primitive_data_uint.erase(label);
157 primitive_data_types.erase(label);
158 } else if (type == HELIOS_TYPE_FLOAT) {
159 primitive_data_float.erase(label);
160 primitive_data_types.erase(label);
161 } else if (type == HELIOS_TYPE_DOUBLE) {
162 primitive_data_double.erase(label);
163 primitive_data_types.erase(label);
164 } else if (type == HELIOS_TYPE_VEC2) {
165 primitive_data_vec2.erase(label);
166 primitive_data_types.erase(label);
167 } else if (type == HELIOS_TYPE_VEC3) {
168 primitive_data_vec3.erase(label);
169 primitive_data_types.erase(label);
170 } else if (type == HELIOS_TYPE_VEC4) {
171 primitive_data_vec4.erase(label);
172 primitive_data_types.erase(label);
173 } else if (type == HELIOS_TYPE_INT2) {
174 primitive_data_int2.erase(label);
175 primitive_data_types.erase(label);
176 } else if (type == HELIOS_TYPE_INT3) {
177 primitive_data_int3.erase(label);
178 primitive_data_types.erase(label);
179 } else if (type == HELIOS_TYPE_INT4) {
180 primitive_data_int4.erase(label);
181 primitive_data_types.erase(label);
182 } else if (type == HELIOS_TYPE_STRING) {
183 primitive_data_string.erase(label);
184 primitive_data_types.erase(label);
185 } else {
186 assert(false);
187 }
188 dirty_flag = true;
189}
190
191bool Primitive::doesPrimitiveDataExist(const char *label) const {
192 if (primitive_data_types.find(std::string(label)) == primitive_data_types.end()) {
193 return false;
194 }
195 return true;
196}
197
198std::vector<std::string> Primitive::listPrimitiveData() const {
199
200 std::vector<std::string> labels;
201 labels.reserve(primitive_data_types.size());
202
203 for (const auto &[label, type]: primitive_data_types) {
204 labels.push_back(label);
205 }
206
207 return labels;
208}
209
210HeliosDataType Context::getPrimitiveDataType(uint UUID, const char *label) const {
211#ifdef HELIOS_DEBUG
212 if (primitives.find(UUID) == primitives.end()) {
213 helios_runtime_error("ERROR (Context::getPrimitiveDataType): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
214 }
215#endif
216 return primitives.at(UUID)->getPrimitiveDataType(label);
217}
218
219uint Context::getPrimitiveDataSize(uint UUID, const char *label) const {
220#ifdef HELIOS_DEBUG
221 if (primitives.find(UUID) == primitives.end()) {
222 helios_runtime_error("ERROR (Context::getPrimitiveDataSize): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
223 }
224#endif
225 return primitives.at(UUID)->getPrimitiveDataSize(label);
226}
227
228bool Context::doesPrimitiveDataExist(uint UUID, const char *label) const {
229#ifdef HELIOS_DEBUG
230 if (primitives.find(UUID) == primitives.end()) {
231 helios_runtime_error("ERROR (Context::doesPrimitiveDataExist): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
232 }
233#endif
234 return primitives.at(UUID)->doesPrimitiveDataExist(label);
235}
236
237void Context::clearPrimitiveData(uint UUID, const char *label) {
238#ifdef HELIOS_DEBUG
239 if (primitives.find(UUID) == primitives.end()) {
240 helios_runtime_error("ERROR (Context::getPrimitiveData): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
241 }
242#endif
243 // Handle value registry before clearing if caching is enabled
244 std::string label_str = std::string(label);
245 if (isPrimitiveDataValueCachingEnabled(label_str) && primitives.at(UUID)->doesPrimitiveDataExist(label)) {
246 HeliosDataType data_type = primitives.at(UUID)->getPrimitiveDataType(label);
247 if (data_type == HELIOS_TYPE_STRING) {
248 std::string cached_value;
249 primitives.at(UUID)->getPrimitiveData(label, cached_value);
250 decrementPrimitiveValueRegistry(label_str, cached_value);
251 } else if (data_type == HELIOS_TYPE_INT) {
252 int cached_value;
253 primitives.at(UUID)->getPrimitiveData(label, cached_value);
254 decrementPrimitiveValueRegistry(label_str, cached_value);
255 } else if (data_type == HELIOS_TYPE_UINT) {
256 uint cached_value;
257 primitives.at(UUID)->getPrimitiveData(label, cached_value);
258 decrementPrimitiveValueRegistry(label_str, cached_value);
259 }
260 }
261
262 if (primitives.at(UUID)->doesPrimitiveDataExist(label)) {
263 decrementPrimitiveDataLabelCounter(label);
264 }
265 primitives.at(UUID)->clearPrimitiveData(label);
266}
267
268void Context::clearPrimitiveData(const std::vector<uint> &UUIDs, const char *label) {
269 for (unsigned int UUID: UUIDs) {
270#ifdef HELIOS_DEBUG
271 if (primitives.find(UUID) == primitives.end()) {
272 helios_runtime_error("ERROR (Context::getPrimitiveData): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
273 }
274#endif
275 // Handle value registry before clearing if caching is enabled
276 std::string label_str = std::string(label);
277 if (isPrimitiveDataValueCachingEnabled(label_str) && primitives.at(UUID)->doesPrimitiveDataExist(label)) {
278 HeliosDataType data_type = primitives.at(UUID)->getPrimitiveDataType(label);
279 if (data_type == HELIOS_TYPE_STRING) {
280 std::string cached_value;
281 primitives.at(UUID)->getPrimitiveData(label, cached_value);
282 decrementPrimitiveValueRegistry(label_str, cached_value);
283 } else if (data_type == HELIOS_TYPE_INT) {
284 int cached_value;
285 primitives.at(UUID)->getPrimitiveData(label, cached_value);
286 decrementPrimitiveValueRegistry(label_str, cached_value);
287 } else if (data_type == HELIOS_TYPE_UINT) {
288 uint cached_value;
289 primitives.at(UUID)->getPrimitiveData(label, cached_value);
290 decrementPrimitiveValueRegistry(label_str, cached_value);
291 }
292 }
293
294 if (primitives.at(UUID)->doesPrimitiveDataExist(label)) {
295 decrementPrimitiveDataLabelCounter(label);
296 }
297 primitives.at(UUID)->clearPrimitiveData(label);
298 }
299}
300
301void Context::copyPrimitiveData(uint sourceUUID, uint destinationUUID) {
302
303#ifdef HELIOS_DEBUG
304 if (primitives.find(sourceUUID) == primitives.end()) {
305 helios_runtime_error("ERROR (Context::copyPrimitiveData): Source UUID of " + std::to_string(sourceUUID) + " does not exist in the Context.");
306 } else if (primitives.find(destinationUUID) == primitives.end()) {
307 helios_runtime_error("ERROR (Context::copyPrimitiveData): Destination UUID of " + std::to_string(destinationUUID) + " does not exist in the Context.");
308 }
309#endif
310
311 const auto &dest_labels = primitives.at(destinationUUID)->primitive_data_types;
312 for (const auto &[label, type]: dest_labels) {
313 decrementPrimitiveDataLabelCounter(label);
314 }
315
316 primitives.at(destinationUUID)->primitive_data_types = primitives.at(sourceUUID)->primitive_data_types;
317
318 primitives.at(destinationUUID)->primitive_data_int = primitives.at(sourceUUID)->primitive_data_int;
319 primitives.at(destinationUUID)->primitive_data_uint = primitives.at(sourceUUID)->primitive_data_uint;
320 primitives.at(destinationUUID)->primitive_data_float = primitives.at(sourceUUID)->primitive_data_float;
321 primitives.at(destinationUUID)->primitive_data_double = primitives.at(sourceUUID)->primitive_data_double;
322 primitives.at(destinationUUID)->primitive_data_vec2 = primitives.at(sourceUUID)->primitive_data_vec2;
323 primitives.at(destinationUUID)->primitive_data_vec3 = primitives.at(sourceUUID)->primitive_data_vec3;
324 primitives.at(destinationUUID)->primitive_data_vec4 = primitives.at(sourceUUID)->primitive_data_vec4;
325 primitives.at(destinationUUID)->primitive_data_int2 = primitives.at(sourceUUID)->primitive_data_int2;
326 primitives.at(destinationUUID)->primitive_data_int3 = primitives.at(sourceUUID)->primitive_data_int3;
327 primitives.at(destinationUUID)->primitive_data_int4 = primitives.at(sourceUUID)->primitive_data_int4;
328 primitives.at(destinationUUID)->primitive_data_string = primitives.at(sourceUUID)->primitive_data_string;
329
330 for (const auto &[label, type]: primitives.at(destinationUUID)->primitive_data_types) {
331 incrementPrimitiveDataLabelCounter(label);
332 }
333
334 primitives.at(destinationUUID)->dirty_flag = true;
335}
336
337void Context::renamePrimitiveData(uint UUID, const char *old_label, const char *new_label) {
338
339#ifdef HELIOS_DEBUG
340 if (primitives.find(UUID) == primitives.end()) {
341 helios_runtime_error("ERROR (Context::renamePrimitiveData): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
342 } else if (!primitives.at(UUID)->doesPrimitiveDataExist(old_label)) {
343 helios_runtime_error("ERROR (Context::renamePrimitiveData): Primitive data of " + std::string(old_label) + " does not exist for primitive " + std::to_string(UUID) + ".");
344 }
345#endif
346
347 duplicatePrimitiveData(UUID, old_label, new_label);
348 clearPrimitiveData(UUID, old_label);
349 primitives.at(UUID)->dirty_flag = true;
350}
351
352void Context::duplicatePrimitiveData(uint UUID, const char *old_label, const char *new_label) {
353
354#ifdef HELIOS_DEBUG
355 if (primitives.find(UUID) == primitives.end()) {
356 helios_runtime_error("ERROR (Context::duplicatePrimitiveData): UUID of " + std::to_string(UUID) + " does not exist in the Context.");
357 } else if (!primitives.at(UUID)->doesPrimitiveDataExist(old_label)) {
358 helios_runtime_error("ERROR (Context::duplicatePrimitiveData): Primitive data of " + std::string(old_label) + " does not exist for primitive " + std::to_string(UUID) + ".");
359 }
360#endif
361
362 HeliosDataType type = getPrimitiveDataType(old_label);
363
364 if (!primitives.at(UUID)->doesPrimitiveDataExist(new_label)) {
365 incrementPrimitiveDataLabelCounter(new_label);
366 }
367 primitives.at(UUID)->primitive_data_types[new_label] = type;
368 if (type == HELIOS_TYPE_INT) {
369 primitives.at(UUID)->primitive_data_int[new_label] = primitives.at(UUID)->primitive_data_int.at(old_label);
370 } else if (type == HELIOS_TYPE_UINT) {
371 primitives.at(UUID)->primitive_data_uint[new_label] = primitives.at(UUID)->primitive_data_uint.at(old_label);
372 } else if (type == HELIOS_TYPE_FLOAT) {
373 primitives.at(UUID)->primitive_data_float[new_label] = primitives.at(UUID)->primitive_data_float.at(old_label);
374 } else if (type == HELIOS_TYPE_DOUBLE) {
375 primitives.at(UUID)->primitive_data_double[new_label] = primitives.at(UUID)->primitive_data_double.at(old_label);
376 } else if (type == HELIOS_TYPE_VEC2) {
377 primitives.at(UUID)->primitive_data_vec2[new_label] = primitives.at(UUID)->primitive_data_vec2.at(old_label);
378 } else if (type == HELIOS_TYPE_VEC3) {
379 primitives.at(UUID)->primitive_data_vec3[new_label] = primitives.at(UUID)->primitive_data_vec3.at(old_label);
380 } else if (type == HELIOS_TYPE_VEC4) {
381 primitives.at(UUID)->primitive_data_vec4[new_label] = primitives.at(UUID)->primitive_data_vec4.at(old_label);
382 } else if (type == HELIOS_TYPE_INT2) {
383 primitives.at(UUID)->primitive_data_int2[new_label] = primitives.at(UUID)->primitive_data_int2.at(old_label);
384 } else if (type == HELIOS_TYPE_INT3) {
385 primitives.at(UUID)->primitive_data_int3[new_label] = primitives.at(UUID)->primitive_data_int3.at(old_label);
386 } else if (type == HELIOS_TYPE_INT4) {
387 primitives.at(UUID)->primitive_data_int4[new_label] = primitives.at(UUID)->primitive_data_int4.at(old_label);
388 } else if (type == HELIOS_TYPE_STRING) {
389 primitives.at(UUID)->primitive_data_string[new_label] = primitives.at(UUID)->primitive_data_string.at(old_label);
390 } else {
391 assert(false);
392 }
393
394 primitives.at(UUID)->dirty_flag = true;
395}
396
397std::vector<std::string> Context::listPrimitiveData(uint UUID) const {
398 return getPrimitivePointer_private(UUID)->listPrimitiveData();
399}
400
401void Context::duplicatePrimitiveData(const char *existing_data_label, const char *copy_data_label) {
402 for (auto &[UUID, primitive]: primitives) {
403 if (primitive->doesPrimitiveDataExist(existing_data_label)) {
404 const HeliosDataType type = primitive->getPrimitiveDataType(existing_data_label);
405 if (!primitive->doesPrimitiveDataExist(copy_data_label)) {
406 incrementPrimitiveDataLabelCounter(copy_data_label);
407 }
408 primitive->primitive_data_types[copy_data_label] = type;
409 if (type == HELIOS_TYPE_FLOAT) {
410 primitive->primitive_data_float[copy_data_label] = primitive->primitive_data_float.at(existing_data_label);
411 } else if (type == HELIOS_TYPE_DOUBLE) {
412 primitive->primitive_data_double[copy_data_label] = primitive->primitive_data_double.at(existing_data_label);
413 } else if (type == HELIOS_TYPE_INT) {
414 primitive->primitive_data_int[copy_data_label] = primitive->primitive_data_int.at(existing_data_label);
415 } else if (type == HELIOS_TYPE_UINT) {
416 primitive->primitive_data_uint[copy_data_label] = primitive->primitive_data_uint.at(existing_data_label);
417 } else if (type == HELIOS_TYPE_VEC2) {
418 primitive->primitive_data_vec2[copy_data_label] = primitive->primitive_data_vec2.at(existing_data_label);
419 } else if (type == HELIOS_TYPE_VEC3) {
420 primitive->primitive_data_vec3[copy_data_label] = primitive->primitive_data_vec3.at(existing_data_label);
421 } else if (type == HELIOS_TYPE_VEC4) {
422 primitive->primitive_data_vec4[copy_data_label] = primitive->primitive_data_vec4.at(existing_data_label);
423 } else if (type == HELIOS_TYPE_INT2) {
424 primitive->primitive_data_int2[copy_data_label] = primitive->primitive_data_int2.at(existing_data_label);
425 } else if (type == HELIOS_TYPE_INT3) {
426 primitive->primitive_data_int3[copy_data_label] = primitive->primitive_data_int3.at(existing_data_label);
427 } else if (type == HELIOS_TYPE_STRING) {
428 primitive->primitive_data_string[copy_data_label] = primitive->primitive_data_string.at(existing_data_label);
429 }
430 primitive->dirty_flag = true;
431 }
432 }
433}
434
435void Context::calculatePrimitiveDataMean(const std::vector<uint> &UUIDs, const std::string &label, float &mean) const {
436 float value;
437 float sum = 0.f;
438 size_t count = 0;
439 for (uint UUID: UUIDs) {
440
441 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_FLOAT) {
442 getPrimitiveData(UUID, label.c_str(), value);
443 sum += value;
444 count++;
445 }
446 }
447
448 if (count == 0) {
449 std::cerr << "WARNING (Context::calculatePrimitiveDataMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
450 mean = 0;
451 } else {
452 mean = sum / float(count);
453 }
454}
455
456void Context::calculatePrimitiveDataMean(const std::vector<uint> &UUIDs, const std::string &label, double &mean) const {
457 double value;
458 double sum = 0.f;
459 size_t count = 0;
460 for (uint UUID: UUIDs) {
461
462 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_DOUBLE) {
463 getPrimitiveData(UUID, label.c_str(), value);
464 sum += value;
465 count++;
466 }
467 }
468
469 if (count == 0) {
470 std::cerr << "WARNING (Context::calculatePrimitiveDataMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
471 mean = 0;
472 } else {
473 mean = sum / float(count);
474 }
475}
476
477void Context::calculatePrimitiveDataMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec2 &mean) const {
478 vec2 value;
479 vec2 sum(0.f, 0.f);
480 size_t count = 0;
481 for (uint UUID: UUIDs) {
482
483 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC2) {
484 getPrimitiveData(UUID, label.c_str(), value);
485 sum = sum + value;
486 count++;
487 }
488 }
489
490 if (count == 0) {
491 std::cerr << "WARNING (Context::calculatePrimitiveDataMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
492 mean = make_vec2(0, 0);
493 } else {
494 mean = sum / float(count);
495 }
496}
497
498void Context::calculatePrimitiveDataMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec3 &mean) const {
499 vec3 value;
500 vec3 sum(0.f, 0.f, 0.f);
501 size_t count = 0;
502 for (uint UUID: UUIDs) {
503
504 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC3) {
505 getPrimitiveData(UUID, label.c_str(), value);
506 sum = sum + value;
507 count++;
508 }
509 }
510
511 if (count == 0) {
512 std::cerr << "WARNING (Context::calculatePrimitiveDataMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
513 mean = make_vec3(0, 0, 0);
514 } else {
515 mean = sum / float(count);
516 }
517}
518
519void Context::calculatePrimitiveDataMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec4 &mean) const {
520 vec4 value;
521 vec4 sum(0.f, 0.f, 0.f, 0.f);
522 size_t count = 0;
523 for (uint UUID: UUIDs) {
524
525 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC4) {
526 getPrimitiveData(UUID, label.c_str(), value);
527 sum = sum + value;
528 count++;
529 }
530 }
531
532 if (count == 0) {
533 std::cerr << "WARNING (Context::calculatePrimitiveDataMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
534 mean = make_vec4(0, 0, 0, 0);
535 } else {
536 mean = sum / float(count);
537 }
538}
539
540void Context::calculatePrimitiveDataAreaWeightedMean(const std::vector<uint> &UUIDs, const std::string &label, float &awt_mean) const {
541 float value, A;
542 float sum = 0.f;
543 float area = 0;
544 bool nan_warning = false;
545 for (uint UUID: UUIDs) {
546
547 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_FLOAT) {
548 getPrimitiveData(UUID, label.c_str(), value);
549 A = getPrimitiveArea(UUID);
550 if (std::isnan(A)) {
551 nan_warning = true;
552 }
553 sum += value * A;
554 area += A;
555 }
556 }
557
558 if (area == 0) {
559 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
560 awt_mean = 0;
561 } else if (nan_warning) {
562 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
563 } else {
564 awt_mean = sum / area;
565 }
566}
567
568void Context::calculatePrimitiveDataAreaWeightedMean(const std::vector<uint> &UUIDs, const std::string &label, double &awt_mean) const {
569 double value;
570 float A;
571 double sum = 0.f;
572 double area = 0;
573 bool nan_warning = false;
574 for (uint UUID: UUIDs) {
575
576 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_DOUBLE) {
577 getPrimitiveData(UUID, label.c_str(), value);
578 A = getPrimitiveArea(UUID);
579 if (std::isnan(A)) {
580 nan_warning = true;
581 }
582 sum += value * double(A);
583 area += A;
584 }
585 }
586
587 if (area == 0) {
588 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
589 awt_mean = 0;
590 } else if (nan_warning) {
591 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
592 } else {
593 awt_mean = sum / area;
594 }
595}
596
597void Context::calculatePrimitiveDataAreaWeightedMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec2 &awt_mean) const {
598 vec2 value;
599 vec2 sum(0.f, 0.f);
600 float area = 0;
601 bool nan_warning = false;
602 for (uint UUID: UUIDs) {
603
604 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC2) {
605 getPrimitiveData(UUID, label.c_str(), value);
606 float A = getPrimitiveArea(UUID);
607 if (std::isnan(A)) {
608 nan_warning = true;
609 }
610 sum = sum + (value * A);
611 area += A;
612 }
613 }
614
615 if (area == 0) {
616 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
617 awt_mean = make_vec2(0, 0);
618 } else if (nan_warning) {
619 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
620 } else {
621 awt_mean = sum / area;
622 }
623}
624
625void Context::calculatePrimitiveDataAreaWeightedMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec3 &awt_mean) const {
626 vec3 value;
627 vec3 sum(0.f, 0.f, 0.f);
628 float area = 0;
629 bool nan_warning = false;
630 for (uint UUID: UUIDs) {
631
632 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC3) {
633 getPrimitiveData(UUID, label.c_str(), value);
634 float A = getPrimitiveArea(UUID);
635 if (std::isnan(A)) {
636 nan_warning = true;
637 }
638 sum = sum + (value * A);
639 area += A;
640 }
641 }
642
643 if (area == 0) {
644 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
645 awt_mean = make_vec3(0, 0, 0);
646 } else if (nan_warning) {
647 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
648 } else {
649 awt_mean = sum / area;
650 }
651}
652
653void Context::calculatePrimitiveDataAreaWeightedMean(const std::vector<uint> &UUIDs, const std::string &label, helios::vec4 &awt_mean) const {
654 vec4 value;
655 vec4 sum(0.f, 0.f, 0.f, 0.f);
656 float area = 0;
657 bool nan_warning = false;
658 for (uint UUID: UUIDs) {
659
660 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC4) {
661 getPrimitiveData(UUID, label.c_str(), value);
662 float A = getPrimitiveArea(UUID);
663 if (std::isnan(A)) {
664 nan_warning = true;
665 }
666 sum = sum + (value * A);
667 area += A;
668 }
669 }
670
671 if (area == 0) {
672 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
673 awt_mean = make_vec4(0, 0, 0, 0);
674 } else if (nan_warning) {
675 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedMean): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
676 } else {
677 awt_mean = sum / area;
678 }
679}
680
681void Context::calculatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::string &label, float &sum) const {
682
683 float value;
684 sum = 0.f;
685 bool added_to_sum = false;
686 for (uint UUID: UUIDs) {
687
688 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_FLOAT) {
689 getPrimitiveData(UUID, label.c_str(), value);
690 sum += value;
691 added_to_sum = true;
692 }
693 }
694
695 if (!added_to_sum) {
696 std::cerr << "WARNING (Context::calculatePrimitiveDataSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
697 }
698}
699
700void Context::calculatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::string &label, double &sum) const {
701
702 double value;
703 sum = 0.f;
704 bool added_to_sum = false;
705 for (uint UUID: UUIDs) {
706
707 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_DOUBLE) {
708 getPrimitiveData(UUID, label.c_str(), value);
709 sum += value;
710 added_to_sum = true;
711 }
712 }
713
714 if (!added_to_sum) {
715 std::cerr << "WARNING (Context::calculatePrimitiveDataSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
716 }
717}
718
719void Context::calculatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec2 &sum) const {
720
721 vec2 value;
722 sum = make_vec2(0.f, 0.f);
723 bool added_to_sum = false;
724 for (uint UUID: UUIDs) {
725
726 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC2) {
727 getPrimitiveData(UUID, label.c_str(), value);
728 sum = sum + value;
729 added_to_sum = true;
730 }
731 }
732
733 if (!added_to_sum) {
734 std::cerr << "WARNING (Context::calculatePrimitiveDataSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
735 }
736}
737
738void Context::calculatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec3 &sum) const {
739
740 vec3 value;
741 sum = make_vec3(0.f, 0.f, 0.f);
742 bool added_to_sum = false;
743 for (uint UUID: UUIDs) {
744
745 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC3) {
746 getPrimitiveData(UUID, label.c_str(), value);
747 sum = sum + value;
748 added_to_sum = true;
749 }
750 }
751
752 if (!added_to_sum) {
753 std::cerr << "WARNING (Context::calculatePrimitiveDataSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
754 }
755}
756
757void Context::calculatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec4 &sum) const {
758
759 vec4 value;
760 sum = make_vec4(0.f, 0.f, 0.f, 0.f);
761 bool added_to_sum = false;
762 for (uint UUID: UUIDs) {
763
764 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC4) {
765 getPrimitiveData(UUID, label.c_str(), value);
766 sum = sum + value;
767 added_to_sum = true;
768 }
769 }
770
771 if (!added_to_sum) {
772 std::cerr << "WARNING (Context::calculatePrimitiveDataSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
773 }
774}
775
776void Context::calculatePrimitiveDataAreaWeightedSum(const std::vector<uint> &UUIDs, const std::string &label, float &awt_sum) const {
777
778 float value;
779 awt_sum = 0.f;
780 bool added_to_sum = false;
781 bool nan_warning = false;
782 for (uint UUID: UUIDs) {
783
784 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_FLOAT) {
785 float area = getPrimitiveArea(UUID);
786 if (std::isnan(area)) {
787 nan_warning = true;
788 continue;
789 }
790 getPrimitiveData(UUID, label.c_str(), value);
791 awt_sum += value * area;
792 added_to_sum = true;
793 }
794 }
795
796 if (!added_to_sum) {
797 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
798 } else if (nan_warning) {
799 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
800 }
801}
802
803void Context::calculatePrimitiveDataAreaWeightedSum(const std::vector<uint> &UUIDs, const std::string &label, double &awt_sum) const {
804
805 double value;
806 awt_sum = 0.f;
807 bool added_to_sum = false;
808 bool nan_warning = false;
809 for (uint UUID: UUIDs) {
810
811 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_DOUBLE) {
812 float area = getPrimitiveArea(UUID);
813 if (std::isnan(area)) {
814 nan_warning = true;
815 continue;
816 }
817 getPrimitiveData(UUID, label.c_str(), value);
818 awt_sum += value * area;
819 added_to_sum = true;
820 }
821 }
822
823 if (!added_to_sum) {
824 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
825 } else if (nan_warning) {
826 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
827 }
828}
829
830void Context::calculatePrimitiveDataAreaWeightedSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec2 &awt_sum) const {
831
832 vec2 value;
833 awt_sum = make_vec2(0.f, 0.f);
834 bool added_to_sum = false;
835 bool nan_warning = false;
836 for (uint UUID: UUIDs) {
837
838 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC2) {
839 float area = getPrimitiveArea(UUID);
840 if (std::isnan(area)) {
841 nan_warning = true;
842 continue;
843 }
844 getPrimitiveData(UUID, label.c_str(), value);
845 awt_sum = awt_sum + value * area;
846 added_to_sum = true;
847 }
848 }
849
850 if (!added_to_sum) {
851 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
852 } else if (nan_warning) {
853 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
854 }
855}
856
857void Context::calculatePrimitiveDataAreaWeightedSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec3 &awt_sum) const {
858
859 vec3 value;
860 awt_sum = make_vec3(0.f, 0.f, 0.f);
861 bool added_to_sum = false;
862 bool nan_warning = false;
863 for (uint UUID: UUIDs) {
864
865 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC3) {
866 float area = getPrimitiveArea(UUID);
867 if (std::isnan(area)) {
868 nan_warning = true;
869 continue;
870 }
871 getPrimitiveData(UUID, label.c_str(), value);
872 awt_sum = awt_sum + value * area;
873 added_to_sum = true;
874 }
875 }
876
877 if (!added_to_sum) {
878 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
879 } else if (nan_warning) {
880 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
881 }
882}
883
884void Context::calculatePrimitiveDataAreaWeightedSum(const std::vector<uint> &UUIDs, const std::string &label, helios::vec4 &awt_sum) const {
885
886 vec4 value;
887 awt_sum = make_vec4(0.f, 0.f, 0.f, 0.F);
888 bool added_to_sum = false;
889 bool nan_warning = false;
890 for (uint UUID: UUIDs) {
891
892 if (doesPrimitiveExist(UUID) && doesPrimitiveDataExist(UUID, label.c_str()) && getPrimitiveDataType(label.c_str()) == HELIOS_TYPE_VEC4) {
893 float area = getPrimitiveArea(UUID);
894 if (std::isnan(area)) {
895 nan_warning = true;
896 continue;
897 }
898 getPrimitiveData(UUID, label.c_str(), value);
899 awt_sum = awt_sum + value * area;
900 added_to_sum = true;
901 }
902 }
903
904 if (!added_to_sum) {
905 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): No primitives found with primitive data of '" << label << "'. Returning a value of 0." << std::endl;
906 } else if (nan_warning) {
907 std::cerr << "WARNING (Context::calculatePrimitiveDataAreaWeightedSum): At least one primitive has an area of NaN and was excluded from calculations" << std::endl;
908 }
909}
910
911void Context::scalePrimitiveData(const std::vector<uint> &UUIDs, const std::string &label, float scaling_factor) {
912
913 uint primitives_not_exist = 0;
914 uint primitive_data_not_exist = 0;
915 for (uint UUID: UUIDs) {
916 if (!doesPrimitiveExist(UUID)) {
917 primitives_not_exist++;
918 continue;
919 }
920 if (!doesPrimitiveDataExist(UUID, label.c_str())) {
921 primitive_data_not_exist++;
922 continue;
923 }
924 HeliosDataType data_type = getPrimitiveDataType(label.c_str());
925 if (data_type == HELIOS_TYPE_FLOAT) {
926 for (float &data: primitives.at(UUID)->primitive_data_float[label]) {
927 data *= scaling_factor;
928 }
929 } else if (data_type == HELIOS_TYPE_DOUBLE) {
930 for (double &data: primitives.at(UUID)->primitive_data_double[label]) {
931 data *= scaling_factor;
932 }
933 } else if (data_type == HELIOS_TYPE_VEC2) {
934 for (auto &data: primitives.at(UUID)->primitive_data_vec2[label]) {
935 data.x *= scaling_factor;
936 data.y *= scaling_factor;
937 }
938 } else if (data_type == HELIOS_TYPE_VEC3) {
939 for (auto &data: primitives.at(UUID)->primitive_data_vec3[label]) {
940 data.x *= scaling_factor;
941 data.y *= scaling_factor;
942 data.z *= scaling_factor;
943 }
944 } else if (data_type == HELIOS_TYPE_VEC4) {
945 for (auto &data: primitives.at(UUID)->primitive_data_vec4[label]) {
946 data.x *= scaling_factor;
947 data.y *= scaling_factor;
948 data.z *= scaling_factor;
949 data.w *= scaling_factor;
950 }
951 } else {
952 helios_runtime_error("ERROR (Context::scalePrimitiveData): This operation only supports primitive data of type float, double, vec2, vec3, and vec4.");
953 }
954 primitives.at(UUID)->dirty_flag = true;
955 }
956
957 if (primitives_not_exist > 0) {
958 std::cerr << "WARNING (Context::scalePrimitiveData): " << primitives_not_exist << " of " << UUIDs.size() << " from the input UUID vector did not exist." << std::endl;
959 }
960 if (primitive_data_not_exist > 0) {
961 std::cerr << "WARNING (Context::scalePrimitiveData): Primitive data did not exist for " << primitive_data_not_exist << " primitives, and thus no scaling was applied." << std::endl;
962 }
963}
964
965void Context::scalePrimitiveData(const std::string &label, float scaling_factor) {
966 scalePrimitiveData(getAllUUIDs(), label, scaling_factor);
967}
968
969void Context::incrementPrimitiveData(const std::vector<uint> &UUIDs, const char *label, int increment) {
970
971 for (uint UUID: UUIDs) {
972
973 if (!doesPrimitiveDataExist(UUID, label)) {
974 helios_runtime_error("ERROR (Context::incrementPrimitiveData): Primitive data " + std::string(label) + " does not exist in the Context for primitive " + std::to_string(UUID) + ".");
975 }
976
977 uint size = getPrimitiveDataSize(UUID, label);
978
979 if (primitives.at(UUID)->primitive_data_types.at(label) == HELIOS_TYPE_INT) {
980 for (uint i = 0; i < size; i++) {
981 primitives.at(UUID)->primitive_data_int.at(label).at(i) += increment;
982 }
983 primitives.at(UUID)->dirty_flag = true;
984 } else {
985 std::cerr << "WARNING (Context::incrementPrimitiveData): Attempted to increment primitive data for type int, but data '" << label << "' does not have type int." << std::endl;
986 }
987 }
988}
989
990void Context::incrementPrimitiveData(const std::vector<uint> &UUIDs, const char *label, uint increment) {
991
992 for (uint UUID: UUIDs) {
993
994 if (!doesPrimitiveDataExist(UUID, label)) {
995 helios_runtime_error("ERROR (Context::incrementPrimitiveData): Primitive data " + std::string(label) + " does not exist in the Context for primitive " + std::to_string(UUID) + ".");
996 }
997
998 uint size = getPrimitiveDataSize(UUID, label);
999
1000 if (primitives.at(UUID)->primitive_data_types.at(label) == HELIOS_TYPE_UINT) {
1001 for (uint i = 0; i < size; i++) {
1002 primitives.at(UUID)->primitive_data_uint.at(label).at(i) += increment;
1003 }
1004 primitives.at(UUID)->dirty_flag = true;
1005 } else {
1006 std::cerr << "WARNING (Context::incrementPrimitiveData): Attempted to increment Primitive data for type uint, but data '" << label << "' does not have type uint." << std::endl;
1007 }
1008 }
1009}
1010
1011void Context::incrementPrimitiveData(const std::vector<uint> &UUIDs, const char *label, float increment) {
1012
1013 for (uint UUID: UUIDs) {
1014
1015 if (!doesPrimitiveDataExist(UUID, label)) {
1016 helios_runtime_error("ERROR (Context::incrementPrimitiveData): Primitive data " + std::string(label) + " does not exist in the Context for primitive " + std::to_string(UUID) + ".");
1017 }
1018
1019 uint size = getPrimitiveDataSize(UUID, label);
1020
1021 if (primitives.at(UUID)->primitive_data_types.at(label) == HELIOS_TYPE_FLOAT) {
1022 for (uint i = 0; i < size; i++) {
1023 primitives.at(UUID)->primitive_data_float.at(label).at(i) += increment;
1024 }
1025 primitives.at(UUID)->dirty_flag = true;
1026 } else {
1027 std::cerr << "WARNING (Context::incrementPrimitiveData): Attempted to increment Primitive data for type float, but data '" << label << "' does not have type float." << std::endl;
1028 }
1029 }
1030}
1031
1032void Context::incrementPrimitiveData(const std::vector<uint> &UUIDs, const char *label, double increment) {
1033
1034 for (uint UUID: UUIDs) {
1035
1036 if (!doesPrimitiveDataExist(UUID, label)) {
1037 helios_runtime_error("ERROR (Context::incrementPrimitiveData): Primitive data " + std::string(label) + " does not exist in the Context for primitive " + std::to_string(UUID) + ".");
1038 }
1039
1040 uint size = getPrimitiveDataSize(UUID, label);
1041
1042 if (primitives.at(UUID)->primitive_data_types.at(label) == HELIOS_TYPE_DOUBLE) {
1043 for (uint i = 0; i < size; i++) {
1044 primitives.at(UUID)->primitive_data_double.at(label).at(i) += increment;
1045 }
1046 primitives.at(UUID)->dirty_flag = true;
1047 } else {
1048 std::cerr << "WARNING (Context::incrementPrimitiveData): Attempted to increment Primitive data for type double, but data '" << label << "' does not have type double." << std::endl;
1049 }
1050 }
1051}
1052
1053void Context::aggregatePrimitiveDataSum(const std::vector<uint> &UUIDs, const std::vector<std::string> &primitive_data_labels, const std::string &result_primitive_data_label) {
1054
1055 uint primitives_not_exist = 0;
1056 uint primitive_data_not_exist = 0;
1057
1058 float data_float = 0;
1059 double data_double = 0;
1060 uint data_uint = 0;
1061 int data_int = 0;
1062 int2 data_int2;
1063 int3 data_int3;
1064 int4 data_int4;
1065 vec2 data_vec2;
1066 vec3 data_vec3;
1067 vec4 data_vec4;
1068
1069 for (uint UUID: UUIDs) {
1070 if (!doesPrimitiveExist(UUID)) {
1071 primitives_not_exist++;
1072 continue;
1073 }
1074
1075 HeliosDataType data_type;
1076
1077 bool init_type = false;
1078 for (const auto &label: primitive_data_labels) {
1079
1080 if (!doesPrimitiveDataExist(UUID, label.c_str())) {
1081 continue;
1082 }
1083
1084 HeliosDataType data_type_current = getPrimitiveDataType(label.c_str());
1085 if (!init_type) {
1086 data_type = data_type_current;
1087 init_type = true;
1088 } else {
1089 if (data_type != data_type_current) {
1090 helios_runtime_error("ERROR (Context::aggregatePrimitiveDataSum): Primitive data types are not consistent for UUID " + std::to_string(UUID));
1091 }
1092 }
1093
1094 if (data_type_current == HELIOS_TYPE_FLOAT) {
1095 float data;
1096 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1097 data_float += data;
1098 } else if (data_type_current == HELIOS_TYPE_DOUBLE) {
1099 double data;
1100 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1101 data_double += data;
1102 } else if (data_type_current == HELIOS_TYPE_VEC2) {
1103 vec2 data;
1104 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1105 data_vec2 = data_vec2 + data;
1106 } else if (data_type_current == HELIOS_TYPE_VEC3) {
1107 vec3 data;
1108 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1109 data_vec3 = data_vec3 + data;
1110 } else if (data_type_current == HELIOS_TYPE_VEC4) {
1111 vec4 data;
1112 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1113 data_vec4 = data_vec4 + data;
1114 } else if (data_type_current == HELIOS_TYPE_INT) {
1115 int data;
1116 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1117 data_int = data_int + data;
1118 } else if (data_type_current == HELIOS_TYPE_UINT) {
1119 uint data;
1120 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1121 data_uint = data_uint + data;
1122 } else if (data_type_current == HELIOS_TYPE_INT2) {
1123 int2 data;
1124 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1125 data_int2 = data_int2 + data;
1126 } else if (data_type_current == HELIOS_TYPE_INT3) {
1127 int3 data;
1128 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1129 data_int3 = data_int3 + data;
1130 } else if (data_type_current == HELIOS_TYPE_INT4) {
1131 int4 data;
1132 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1133 data_int4 = data_int4 + data;
1134 } else {
1135 helios_runtime_error("ERROR (Context::aggregatePrimitiveDataSum): This operation is not supported for string primitive data types.");
1136 }
1137 }
1138
1139 if (!init_type) {
1140 primitive_data_not_exist++;
1141 continue;
1142 } else if (data_type == HELIOS_TYPE_FLOAT) {
1143 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_float);
1144 data_float = 0;
1145 } else if (data_type == HELIOS_TYPE_DOUBLE) {
1146 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_double);
1147 data_double = 0;
1148 } else if (data_type == HELIOS_TYPE_VEC2) {
1149 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec2);
1150 data_vec2 = make_vec2(0, 0);
1151 } else if (data_type == HELIOS_TYPE_VEC3) {
1152 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec3);
1153 data_vec3 = make_vec3(0, 0, 0);
1154 } else if (data_type == HELIOS_TYPE_VEC4) {
1155 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec4);
1156 data_vec4 = make_vec4(0, 0, 0, 0);
1157 } else if (data_type == HELIOS_TYPE_INT) {
1158 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int);
1159 data_int = 0;
1160 } else if (data_type == HELIOS_TYPE_UINT) {
1161 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_uint);
1162 data_uint = 0;
1163 } else if (data_type == HELIOS_TYPE_INT2) {
1164 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int2);
1165 data_int2 = make_int2(0, 0);
1166 } else if (data_type == HELIOS_TYPE_INT3) {
1167 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int3);
1168 data_int3 = make_int3(0, 0, 0);
1169 } else if (data_type == HELIOS_TYPE_INT4) {
1170 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int4);
1171 data_int4 = make_int4(0, 0, 0, 0);
1172 }
1173 }
1174
1175 if (primitives_not_exist > 0) {
1176 std::cerr << "WARNING (Context::aggregatePrimitiveDataSum): " << primitives_not_exist << " of " << UUIDs.size() << " from the input UUID vector did not exist." << std::endl;
1177 }
1178 if (primitive_data_not_exist > 0) {
1179 std::cerr << "WARNING (Context::aggregatePrimitiveDataSum): Primitive data did not exist for " << primitive_data_not_exist
1180 << " primitives, and thus no scaling summation was performed and new primitive data was not created for this primitive." << std::endl;
1181 }
1182}
1183
1184void Context::aggregatePrimitiveDataProduct(const std::vector<uint> &UUIDs, const std::vector<std::string> &primitive_data_labels, const std::string &result_primitive_data_label) {
1185
1186 uint primitives_not_exist = 0;
1187 uint primitive_data_not_exist = 0;
1188
1189 float data_float = 0;
1190 double data_double = 0;
1191 uint data_uint = 0;
1192 int data_int = 0;
1193 int2 data_int2;
1194 int3 data_int3;
1195 int4 data_int4;
1196 vec2 data_vec2;
1197 vec3 data_vec3;
1198 vec4 data_vec4;
1199
1200 for (uint UUID: UUIDs) {
1201 if (!doesPrimitiveExist(UUID)) {
1202 primitives_not_exist++;
1203 continue;
1204 }
1205
1206 HeliosDataType data_type;
1207
1208 bool init_type = false;
1209 int i = 0;
1210 for (const auto &label: primitive_data_labels) {
1211
1212 if (!doesPrimitiveDataExist(UUID, label.c_str())) {
1213 continue;
1214 }
1215
1216 HeliosDataType data_type_current = getPrimitiveDataType(label.c_str());
1217 if (!init_type) {
1218 data_type = data_type_current;
1219 init_type = true;
1220 } else {
1221 if (data_type != data_type_current) {
1222 helios_runtime_error("ERROR (Context::aggregatePrimitiveDataProduct): Primitive data types are not consistent for UUID " + std::to_string(UUID));
1223 }
1224 }
1225
1226 if (data_type_current == HELIOS_TYPE_FLOAT) {
1227 float data;
1228 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1229 if (i == 0) {
1230 data_float = data;
1231 } else {
1232 data_float *= data;
1233 }
1234 } else if (data_type_current == HELIOS_TYPE_DOUBLE) {
1235 double data;
1236 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1237 if (i == 0) {
1238 data_double *= data;
1239 } else {
1240 data_double = data;
1241 }
1242 } else if (data_type_current == HELIOS_TYPE_VEC2) {
1243 vec2 data;
1244 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1245 if (i == 0) {
1246 data_vec2.x *= data.x;
1247 data_vec2.y *= data.y;
1248 } else {
1249 data_vec2 = data;
1250 }
1251 } else if (data_type_current == HELIOS_TYPE_VEC3) {
1252 vec3 data;
1253 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1254 if (i == 0) {
1255 data_vec3.x *= data.x;
1256 data_vec3.y *= data.y;
1257 data_vec3.z *= data.z;
1258 } else {
1259 data_vec3 = data;
1260 }
1261 } else if (data_type_current == HELIOS_TYPE_VEC4) {
1262 vec4 data;
1263 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1264 if (i == 0) {
1265 data_vec4.x *= data.x;
1266 data_vec4.y *= data.y;
1267 data_vec4.z *= data.z;
1268 data_vec4.w *= data.w;
1269 } else {
1270 data_vec4 = data;
1271 }
1272 } else if (data_type_current == HELIOS_TYPE_INT) {
1273 int data;
1274 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1275 if (i == 0) {
1276 data_int = data_int * data;
1277 } else {
1278 data_int = data;
1279 }
1280 } else if (data_type_current == HELIOS_TYPE_UINT) {
1281 uint data;
1282 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1283 if (i == 0) {
1284 data_uint = data_uint * data;
1285 } else {
1286 data_uint = data;
1287 }
1288 } else if (data_type_current == HELIOS_TYPE_INT2) {
1289 int2 data;
1290 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1291 if (i == 0) {
1292 data_int2.x *= data.x;
1293 data_int2.y *= data.y;
1294 } else {
1295 data_int2 = data;
1296 }
1297 } else if (data_type_current == HELIOS_TYPE_INT3) {
1298 int3 data;
1299 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1300 if (i == 0) {
1301 data_int3.x *= data.x;
1302 data_int3.y *= data.y;
1303 data_int3.z *= data.z;
1304 } else {
1305 data_int3 = data;
1306 }
1307 } else if (data_type_current == HELIOS_TYPE_INT4) {
1308 int4 data;
1309 primitives.at(UUID)->getPrimitiveData(label.c_str(), data);
1310 if (i == 0) {
1311 data_int4.x *= data.x;
1312 data_int4.y *= data.y;
1313 data_int4.z *= data.z;
1314 data_int4.w *= data.w;
1315 } else {
1316 data_int4 = data;
1317 }
1318 } else {
1319 helios_runtime_error("ERROR (Context::aggregatePrimitiveDataProduct): This operation is not supported for string primitive data types.");
1320 }
1321 i++;
1322 }
1323
1324 if (!init_type) {
1325 primitive_data_not_exist++;
1326 continue;
1327 } else if (data_type == HELIOS_TYPE_FLOAT) {
1328 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_float);
1329 } else if (data_type == HELIOS_TYPE_DOUBLE) {
1330 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_double);
1331 } else if (data_type == HELIOS_TYPE_VEC2) {
1332 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec2);
1333 } else if (data_type == HELIOS_TYPE_VEC3) {
1334 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec3);
1335 } else if (data_type == HELIOS_TYPE_VEC4) {
1336 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_vec4);
1337 } else if (data_type == HELIOS_TYPE_INT) {
1338 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int);
1339 } else if (data_type == HELIOS_TYPE_UINT) {
1340 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_uint);
1341 } else if (data_type == HELIOS_TYPE_INT2) {
1342 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int2);
1343 } else if (data_type == HELIOS_TYPE_INT3) {
1344 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int3);
1345 } else if (data_type == HELIOS_TYPE_INT4) {
1346 setPrimitiveData(UUID, result_primitive_data_label.c_str(), data_int4);
1347 }
1348 }
1349
1350 if (primitives_not_exist > 0) {
1351 std::cerr << "WARNING (Context::aggregatePrimitiveDataProduct): " << primitives_not_exist << " of " << UUIDs.size() << " from the input UUID vector did not exist." << std::endl;
1352 }
1353 if (primitive_data_not_exist > 0) {
1354 std::cerr << "WARNING (Context::aggregatePrimitiveDataProduct): Primitive data did not exist for " << primitive_data_not_exist
1355 << " primitives, and thus no multiplication was performed and new primitive data was not created for this primitive." << std::endl;
1356 }
1357}
1358
1359
1360float Context::sumPrimitiveSurfaceArea(const std::vector<uint> &UUIDs) const {
1361
1362 bool primitive_warning = false;
1363 bool nan_warning = false;
1364 float area = 0;
1365 for (uint UUID: UUIDs) {
1366
1367 float A = getPrimitiveArea(UUID);
1368
1369 if (std::isnan(A)) {
1370 nan_warning = true;
1371 continue;
1372 }
1373
1374 if (doesPrimitiveExist(UUID)) {
1375 area += A;
1376 } else {
1377 primitive_warning = true;
1378 }
1379 }
1380
1381 if (primitive_warning) {
1382 std::cerr << "WARNING (Context::sumPrimitiveSurfaceArea): One or more primitives reference in the UUID vector did not exist." << std::endl;
1383 } else if (nan_warning) {
1384 std::cerr << "WARNING (Context::sumPrimitiveSurfaceArea): One or more primitives had an area of NaN." << std::endl;
1385 }
1386
1387 return area;
1388}
1389
1390std::vector<uint> Context::filterPrimitivesByData(const std::vector<uint> &UUIDs, const std::string &primitive_data_label, float filter_value, const std::string &comparator) const {
1391
1392 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1393 helios_runtime_error("ERROR (Context::filterPrimitivesByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1394 }
1395
1396 std::vector<uint> UUIDs_out = UUIDs;
1397 for (std::size_t p = UUIDs.size(); p-- > 0;) {
1398 uint UUID = UUIDs_out.at(p);
1399 if (doesPrimitiveDataExist(UUID, primitive_data_label.c_str()) && getPrimitiveDataType(primitive_data_label.c_str()) == HELIOS_TYPE_FLOAT) {
1400 float data;
1401 getPrimitiveData(UUID, primitive_data_label.c_str(), data);
1402 if (comparator == "==" && data == filter_value) {
1403 continue;
1404 }
1405 if (comparator == ">" && data > filter_value) {
1406 continue;
1407 }
1408 if (comparator == "<" && data < filter_value) {
1409 continue;
1410 }
1411 if (comparator == ">=" && data >= filter_value) {
1412 continue;
1413 }
1414 if (comparator == "<=" && data <= filter_value) {
1415 continue;
1416 }
1417
1418 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1419 UUIDs_out.pop_back();
1420 } else {
1421 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1422 UUIDs_out.pop_back();
1423 }
1424 }
1425
1426 return UUIDs_out;
1427}
1428
1429std::vector<uint> Context::filterPrimitivesByData(const std::vector<uint> &UUIDs, const std::string &primitive_data_label, double filter_value, const std::string &comparator) const {
1430
1431 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1432 helios_runtime_error("ERROR (Context::filterPrimitivesByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1433 }
1434
1435 std::vector<uint> UUIDs_out = UUIDs;
1436 for (std::size_t p = UUIDs.size(); p-- > 0;) {
1437 uint UUID = UUIDs_out.at(p);
1438 if (doesPrimitiveDataExist(UUID, primitive_data_label.c_str()) && getPrimitiveDataType(primitive_data_label.c_str()) == HELIOS_TYPE_DOUBLE) {
1439 double data;
1440 getPrimitiveData(UUID, primitive_data_label.c_str(), data);
1441 if (comparator == "==" && data == filter_value) {
1442 continue;
1443 }
1444 if (comparator == ">" && data > filter_value) {
1445 continue;
1446 }
1447 if (comparator == "<" && data < filter_value) {
1448 continue;
1449 }
1450 if (comparator == ">=" && data >= filter_value) {
1451 continue;
1452 }
1453 if (comparator == "<=" && data <= filter_value) {
1454 continue;
1455 }
1456
1457 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1458 UUIDs_out.pop_back();
1459 } else {
1460 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1461 UUIDs_out.pop_back();
1462 }
1463 }
1464
1465 return UUIDs_out;
1466}
1467
1468std::vector<uint> Context::filterPrimitivesByData(const std::vector<uint> &UUIDs, const std::string &primitive_data_label, int filter_value, const std::string &comparator) const {
1469
1470 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1471 helios_runtime_error("ERROR (Context::filterPrimitivesByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1472 }
1473
1474 std::vector<uint> UUIDs_out = UUIDs;
1475 for (std::size_t p = UUIDs.size(); p-- > 0;) {
1476 uint UUID = UUIDs_out.at(p);
1477 if (doesPrimitiveDataExist(UUID, primitive_data_label.c_str()) && getPrimitiveDataType(primitive_data_label.c_str()) == HELIOS_TYPE_INT) {
1478 int data;
1479 getPrimitiveData(UUID, primitive_data_label.c_str(), data);
1480 if (comparator == "==" && data == filter_value) {
1481 continue;
1482 }
1483 if (comparator == ">" && data > filter_value) {
1484 continue;
1485 }
1486 if (comparator == "<" && data < filter_value) {
1487 continue;
1488 }
1489 if (comparator == ">=" && data >= filter_value) {
1490 continue;
1491 }
1492 if (comparator == "<=" && data <= filter_value) {
1493 continue;
1494 }
1495
1496 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1497 UUIDs_out.pop_back();
1498 } else {
1499 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1500 UUIDs_out.pop_back();
1501 }
1502 }
1503
1504 return UUIDs_out;
1505}
1506
1507std::vector<uint> Context::filterPrimitivesByData(const std::vector<uint> &UUIDs, const std::string &primitive_data_label, uint filter_value, const std::string &comparator) const {
1508
1509 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1510 helios_runtime_error("ERROR (Context::filterPrimitivesByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1511 }
1512
1513 std::vector<uint> UUIDs_out = UUIDs;
1514 for (std::size_t p = UUIDs.size(); p-- > 0;) {
1515 uint UUID = UUIDs_out.at(p);
1516 if (doesPrimitiveDataExist(UUID, primitive_data_label.c_str()) && getPrimitiveDataType(primitive_data_label.c_str()) == HELIOS_TYPE_UINT) {
1517 uint data;
1518 getPrimitiveData(UUID, primitive_data_label.c_str(), data);
1519 if (comparator == "==" && data == filter_value) {
1520 continue;
1521 }
1522 if (comparator == ">" && data > filter_value) {
1523 continue;
1524 }
1525 if (comparator == "<" && data < filter_value) {
1526 continue;
1527 }
1528 if (comparator == ">=" && data >= filter_value) {
1529 continue;
1530 }
1531 if (comparator == "<=" && data <= filter_value) {
1532 continue;
1533 }
1534
1535 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1536 UUIDs_out.pop_back();
1537 } else {
1538 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1539 UUIDs_out.pop_back();
1540 }
1541 }
1542
1543 return UUIDs_out;
1544}
1545
1546std::vector<uint> Context::filterPrimitivesByData(const std::vector<uint> &UUIDs, const std::string &primitive_data_label, const std::string &filter_value) const {
1547
1548 std::vector<uint> UUIDs_out = UUIDs;
1549 for (std::size_t p = UUIDs.size(); p-- > 0;) {
1550 uint UUID = UUIDs_out.at(p);
1551 if (doesPrimitiveDataExist(UUID, primitive_data_label.c_str()) && getPrimitiveDataType(primitive_data_label.c_str()) == HELIOS_TYPE_STRING) {
1552 std::string data;
1553 getPrimitiveData(UUID, primitive_data_label.c_str(), data);
1554 if (data != filter_value) {
1555 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1556 UUIDs_out.pop_back();
1557 }
1558 } else {
1559 std::swap(UUIDs_out.at(p), UUIDs_out.back());
1560 UUIDs_out.pop_back();
1561 }
1562 }
1563
1564 return UUIDs_out;
1565}
1566
1567//------ Object Data ------- //
1568
1569HeliosDataType Context::getObjectDataType(uint objID, const char *label) const {
1570#ifdef HELIOS_DEBUG
1571 if (objects.find(objID) == objects.end()) {
1572 helios_runtime_error("ERROR (Context::getObjectDataType): objID of " + std::to_string(objID) + " does not exist in the Context.");
1573 }
1574#endif
1575 return objects.at(objID)->getObjectDataType(label);
1576}
1577
1578HeliosDataType Context::getObjectDataType(const char *label) const {
1579 const auto it = object_data_type_registry.find(label);
1580 if (it != object_data_type_registry.end()) {
1581 return it->second;
1582 }
1583 helios_runtime_error("ERROR (Context::getObjectDataType): Object data " + std::string(label) + " does not exist.");
1584 return HELIOS_TYPE_UNKNOWN; // This line will never be reached, but is needed to avoid compiler warnings.
1585}
1586
1587uint Context::getObjectDataSize(uint objID, const char *label) const {
1588#ifdef HELIOS_DEBUG
1589 if (objects.find(objID) == objects.end()) {
1590 helios_runtime_error("ERROR (Context::getObjectDataSize): objID of " + std::to_string(objID) + " does not exist in the Context.");
1591 }
1592#endif
1593 return objects.at(objID)->getObjectDataSize(label);
1594}
1595
1596bool Context::doesObjectDataExist(uint objID, const char *label) const {
1597#ifdef HELIOS_DEBUG
1598 if (objects.find(objID) == objects.end()) {
1599 helios_runtime_error("ERROR (Context::doesObjectDataExist): objID of " + std::to_string(objID) + " does not exist in the Context.");
1600 }
1601#endif
1602 return objects.at(objID)->doesObjectDataExist(label);
1603}
1604
1605void Context::copyObjectData(uint source_objID, uint destination_objID) {
1606
1607#ifdef HELIOS_DEBUG
1608 if (objects.find(source_objID) == objects.end()) {
1609 helios_runtime_error("ERROR (Context::copyObjectData): Source object ID of " + std::to_string(source_objID) + " does not exist in the Context.");
1610 } else if (objects.find(destination_objID) == objects.end()) {
1611 helios_runtime_error("ERROR (Context::copyObjectData): Destination object ID of " + std::to_string(destination_objID) + " does not exist in the Context.");
1612 }
1613#endif
1614
1615 const auto &dest_labels = objects.at(destination_objID)->object_data_types;
1616 for (const auto &[label, type]: dest_labels) {
1617 decrementObjectDataLabelCounter(label);
1618 }
1619
1620 objects.at(destination_objID)->object_data_types = objects.at(source_objID)->object_data_types;
1621
1622 objects.at(destination_objID)->object_data_int = objects.at(source_objID)->object_data_int;
1623 objects.at(destination_objID)->object_data_uint = objects.at(source_objID)->object_data_uint;
1624 objects.at(destination_objID)->object_data_float = objects.at(source_objID)->object_data_float;
1625 objects.at(destination_objID)->object_data_double = objects.at(source_objID)->object_data_double;
1626 objects.at(destination_objID)->object_data_vec2 = objects.at(source_objID)->object_data_vec2;
1627 objects.at(destination_objID)->object_data_vec3 = objects.at(source_objID)->object_data_vec3;
1628 objects.at(destination_objID)->object_data_vec4 = objects.at(source_objID)->object_data_vec4;
1629 objects.at(destination_objID)->object_data_int2 = objects.at(source_objID)->object_data_int2;
1630 objects.at(destination_objID)->object_data_int3 = objects.at(source_objID)->object_data_int3;
1631 objects.at(destination_objID)->object_data_int4 = objects.at(source_objID)->object_data_int4;
1632 objects.at(destination_objID)->object_data_string = objects.at(source_objID)->object_data_string;
1633
1634 for (const auto &[lbl, type]: objects.at(destination_objID)->object_data_types) {
1635 incrementObjectDataLabelCounter(lbl);
1636 }
1637}
1638
1639void Context::duplicateObjectData(uint objID, const char *old_label, const char *new_label) {
1640
1641#ifdef HELIOS_DEBUG
1642 if (objects.find(objID) == objects.end()) {
1643 helios_runtime_error("ERROR (Context::duplicateObjectData): Object ID of " + std::to_string(objID) + " does not exist in the Context.");
1644 } else if (!doesObjectDataExist(objID, old_label)) {
1645 helios_runtime_error("ERROR (Context::duplicateObjectData): Object ID of " + std::to_string(objID) + " does not have data with label " + std::string(old_label) + ".");
1646 }
1647#endif
1648
1649 HeliosDataType type = getObjectDataType(old_label);
1650
1651 if (!objects.at(objID)->doesObjectDataExist(new_label)) {
1652 incrementObjectDataLabelCounter(new_label);
1653 }
1654 objects.at(objID)->object_data_types[new_label] = type;
1655 if (type == HELIOS_TYPE_INT) {
1656 objects.at(objID)->object_data_int[new_label] = objects.at(objID)->object_data_int.at(old_label);
1657 } else if (type == HELIOS_TYPE_UINT) {
1658 objects.at(objID)->object_data_uint[new_label] = objects.at(objID)->object_data_uint.at(old_label);
1659 } else if (type == HELIOS_TYPE_FLOAT) {
1660 objects.at(objID)->object_data_float[new_label] = objects.at(objID)->object_data_float.at(old_label);
1661 } else if (type == HELIOS_TYPE_DOUBLE) {
1662 objects.at(objID)->object_data_double[new_label] = objects.at(objID)->object_data_double.at(old_label);
1663 } else if (type == HELIOS_TYPE_VEC2) {
1664 objects.at(objID)->object_data_vec2[new_label] = objects.at(objID)->object_data_vec2.at(old_label);
1665 } else if (type == HELIOS_TYPE_VEC3) {
1666 objects.at(objID)->object_data_vec3[new_label] = objects.at(objID)->object_data_vec3.at(old_label);
1667 } else if (type == HELIOS_TYPE_VEC4) {
1668 objects.at(objID)->object_data_vec4[new_label] = objects.at(objID)->object_data_vec4.at(old_label);
1669 } else if (type == HELIOS_TYPE_INT2) {
1670 objects.at(objID)->object_data_int2[new_label] = objects.at(objID)->object_data_int2.at(old_label);
1671 } else if (type == HELIOS_TYPE_INT3) {
1672 objects.at(objID)->object_data_int3[new_label] = objects.at(objID)->object_data_int3.at(old_label);
1673 } else if (type == HELIOS_TYPE_INT4) {
1674 objects.at(objID)->object_data_int4[new_label] = objects.at(objID)->object_data_int4.at(old_label);
1675 } else if (type == HELIOS_TYPE_STRING) {
1676 objects.at(objID)->object_data_string[new_label] = objects.at(objID)->object_data_string.at(old_label);
1677 } else {
1678 assert(false);
1679 }
1680}
1681
1682
1683void Context::renameObjectData(uint objID, const char *old_label, const char *new_label) {
1684
1685#ifdef HELIOS_DEBUG
1686 if (objects.find(objID) == objects.end()) {
1687 helios_runtime_error("ERROR (Context::renameObjectData): Object ID of " + std::to_string(objID) + " does not exist in the Context.");
1688 } else if (!doesObjectDataExist(objID, old_label)) {
1689 helios_runtime_error("ERROR (Context::renameObjectData): Object ID of " + std::to_string(objID) + " does not have data with label " + std::string(old_label) + ".");
1690 }
1691#endif
1692
1693 duplicateObjectData(objID, old_label, new_label);
1694 clearObjectData(objID, old_label);
1695}
1696
1697void Context::clearObjectData(uint objID, const char *label) {
1698#ifdef HELIOS_DEBUG
1699 if (objects.find(objID) == objects.end()) {
1700 helios_runtime_error("ERROR (Context::clearObjectData): objID of " + std::to_string(objID) + " does not exist in the Context.");
1701 }
1702#endif
1703 // Handle value registry before clearing if caching is enabled
1704 std::string label_str = std::string(label);
1705 if (isObjectDataValueCachingEnabled(label_str) && objects.at(objID)->doesObjectDataExist(label)) {
1706 HeliosDataType data_type = objects.at(objID)->getObjectDataType(label);
1707 if (data_type == HELIOS_TYPE_STRING) {
1708 std::string cached_value;
1709 objects.at(objID)->getObjectData(label, cached_value);
1710 decrementObjectValueRegistry(label_str, cached_value);
1711 } else if (data_type == HELIOS_TYPE_INT) {
1712 int cached_value;
1713 objects.at(objID)->getObjectData(label, cached_value);
1714 decrementObjectValueRegistry(label_str, cached_value);
1715 } else if (data_type == HELIOS_TYPE_UINT) {
1716 uint cached_value;
1717 objects.at(objID)->getObjectData(label, cached_value);
1718 decrementObjectValueRegistry(label_str, cached_value);
1719 }
1720 }
1721
1722 if (objects.at(objID)->doesObjectDataExist(label)) {
1723 decrementObjectDataLabelCounter(label);
1724 }
1725 objects.at(objID)->clearObjectData(label);
1726}
1727
1728void Context::clearObjectData(const std::vector<uint> &objIDs, const char *label) {
1729 std::string label_str = std::string(label);
1730 for (uint objID: objIDs) {
1731#ifdef HELIOS_DEBUG
1732 if (objects.find(objID) == objects.end()) {
1733 helios_runtime_error("ERROR (Context::clearObjectData): objID of " + std::to_string(objID) + " does not exist in the Context.");
1734 }
1735#endif
1736 // Handle value registry before clearing if caching is enabled
1737 if (isObjectDataValueCachingEnabled(label_str) && objects.at(objID)->doesObjectDataExist(label)) {
1738 HeliosDataType data_type = objects.at(objID)->getObjectDataType(label);
1739 if (data_type == HELIOS_TYPE_STRING) {
1740 std::string cached_value;
1741 objects.at(objID)->getObjectData(label, cached_value);
1742 decrementObjectValueRegistry(label_str, cached_value);
1743 } else if (data_type == HELIOS_TYPE_INT) {
1744 int cached_value;
1745 objects.at(objID)->getObjectData(label, cached_value);
1746 decrementObjectValueRegistry(label_str, cached_value);
1747 } else if (data_type == HELIOS_TYPE_UINT) {
1748 uint cached_value;
1749 objects.at(objID)->getObjectData(label, cached_value);
1750 decrementObjectValueRegistry(label_str, cached_value);
1751 }
1752 }
1753
1754 if (objects.at(objID)->doesObjectDataExist(label)) {
1755 decrementObjectDataLabelCounter(label);
1756 }
1757 objects.at(objID)->clearObjectData(label);
1758 }
1759}
1760
1761std::vector<std::string> Context::listObjectData(uint ObjID) const {
1762 return getObjectPointer_private(ObjID)->listObjectData();
1763}
1764
1766
1767#ifdef HELIOS_DEBUG
1768 if (!doesObjectDataExist(label)) {
1769 helios_runtime_error("ERROR (CompoundObject::getObjectDataType): Object data " + std::string(label) + " does not exist for object " + std::to_string(OID));
1770 }
1771#endif
1772
1773 return object_data_types.at(label);
1774}
1775
1776uint CompoundObject::getObjectDataSize(const char *label) const {
1777
1778#ifdef HELIOS_DEBUG
1779 if (!doesObjectDataExist(label)) {
1780 helios_runtime_error("ERROR (CompoundObject::getObjectDataSize): Object data " + std::string(label) + " does not exist for object " + std::to_string(OID));
1781 }
1782#endif
1783
1784 HeliosDataType qtype = object_data_types.at(label);
1785
1786 if (qtype == HELIOS_TYPE_INT) {
1787 return object_data_int.at(label).size();
1788 } else if (qtype == HELIOS_TYPE_UINT) {
1789 return object_data_uint.at(label).size();
1790 } else if (qtype == HELIOS_TYPE_FLOAT) {
1791 return object_data_float.at(label).size();
1792 } else if (qtype == HELIOS_TYPE_DOUBLE) {
1793 return object_data_double.at(label).size();
1794 } else if (qtype == HELIOS_TYPE_VEC2) {
1795 return object_data_vec2.at(label).size();
1796 } else if (qtype == HELIOS_TYPE_VEC3) {
1797 return object_data_vec3.at(label).size();
1798 } else if (qtype == HELIOS_TYPE_VEC4) {
1799 return object_data_vec4.at(label).size();
1800 } else if (qtype == HELIOS_TYPE_INT2) {
1801 return object_data_int2.at(label).size();
1802 } else if (qtype == HELIOS_TYPE_INT3) {
1803 return object_data_int3.at(label).size();
1804 } else if (qtype == HELIOS_TYPE_INT4) {
1805 return object_data_int4.at(label).size();
1806 } else if (qtype == HELIOS_TYPE_STRING) {
1807 return object_data_string.at(label).size();
1808 } else {
1809 assert(false);
1810 }
1811
1812 return 0;
1813}
1814
1815void CompoundObject::clearObjectData(const char *label) {
1816
1817 if (!doesObjectDataExist(label)) {
1818 return;
1819 }
1820
1821 const HeliosDataType &qtype = object_data_types.at(label);
1822
1823 if (qtype == HELIOS_TYPE_INT) {
1824 object_data_int.erase(label);
1825 object_data_types.erase(label);
1826 } else if (qtype == HELIOS_TYPE_UINT) {
1827 object_data_uint.erase(label);
1828 object_data_types.erase(label);
1829 } else if (qtype == HELIOS_TYPE_FLOAT) {
1830 object_data_float.erase(label);
1831 object_data_types.erase(label);
1832 } else if (qtype == HELIOS_TYPE_DOUBLE) {
1833 object_data_double.erase(label);
1834 object_data_types.erase(label);
1835 } else if (qtype == HELIOS_TYPE_VEC2) {
1836 object_data_vec2.erase(label);
1837 object_data_types.erase(label);
1838 } else if (qtype == HELIOS_TYPE_VEC3) {
1839 object_data_vec3.erase(label);
1840 object_data_types.erase(label);
1841 } else if (qtype == HELIOS_TYPE_VEC4) {
1842 object_data_vec4.erase(label);
1843 object_data_types.erase(label);
1844 } else if (qtype == HELIOS_TYPE_INT2) {
1845 object_data_int2.erase(label);
1846 object_data_types.erase(label);
1847 } else if (qtype == HELIOS_TYPE_INT3) {
1848 object_data_int3.erase(label);
1849 object_data_types.erase(label);
1850 } else if (qtype == HELIOS_TYPE_INT4) {
1851 object_data_int4.erase(label);
1852 object_data_types.erase(label);
1853 } else if (qtype == HELIOS_TYPE_STRING) {
1854 object_data_string.erase(label);
1855 object_data_types.erase(label);
1856 } else {
1857 assert(false);
1858 }
1859}
1860
1861bool CompoundObject::doesObjectDataExist(const char *label) const {
1862
1863 if (object_data_types.find(std::string(label)) == object_data_types.end()) {
1864 return false;
1865 } else {
1866 return true;
1867 }
1868}
1869
1870std::vector<std::string> CompoundObject::listObjectData() const {
1871
1872 std::vector<std::string> labels;
1873 labels.reserve(object_data_types.size());
1874
1875 for (const auto &[label, type]: object_data_types) {
1876 labels.push_back(label);
1877 }
1878
1879 return labels;
1880}
1881
1882std::vector<uint> Context::filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, float filter_value, const std::string &comparator) const {
1883
1884 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1885 helios_runtime_error("ERROR (Context::filterObjectsByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1886 }
1887
1888 std::vector<uint> objIDs_out = objIDs;
1889 for (std::size_t p = objIDs.size(); p-- > 0;) {
1890 uint objID = objIDs_out.at(p);
1891 if (doesObjectDataExist(objID, object_data_label.c_str()) && getObjectDataType(object_data_label.c_str()) == HELIOS_TYPE_FLOAT) {
1892 float data;
1893 getObjectData(objID, object_data_label.c_str(), data);
1894 if (comparator == "==" && data == filter_value) {
1895 continue;
1896 } else if (comparator == ">" && data > filter_value) {
1897 continue;
1898 } else if (comparator == "<" && data < filter_value) {
1899 continue;
1900 } else if (comparator == ">=" && data >= filter_value) {
1901 continue;
1902 } else if (comparator == "<=" && data <= filter_value) {
1903 continue;
1904 }
1905
1906 std::swap(objIDs_out.at(p), objIDs_out.back());
1907 objIDs_out.pop_back();
1908 } else {
1909 std::swap(objIDs_out.at(p), objIDs_out.back());
1910 objIDs_out.pop_back();
1911 }
1912 }
1913
1914 return objIDs_out;
1915}
1916
1917std::vector<uint> Context::filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, double filter_value, const std::string &comparator) const {
1918
1919 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1920 helios_runtime_error("ERROR (Context::filterObjectsByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1921 }
1922
1923 std::vector<uint> objIDs_out = objIDs;
1924 for (std::size_t p = objIDs.size(); p-- > 0;) {
1925 uint objID = objIDs_out.at(p);
1926 if (doesObjectDataExist(objID, object_data_label.c_str()) && getObjectDataType(object_data_label.c_str()) == HELIOS_TYPE_DOUBLE) {
1927 double data;
1928 getObjectData(objID, object_data_label.c_str(), data);
1929 if (comparator == "==" && data == filter_value) {
1930 continue;
1931 } else if (comparator == ">" && data > filter_value) {
1932 continue;
1933 } else if (comparator == "<" && data < filter_value) {
1934 continue;
1935 } else if (comparator == ">=" && data >= filter_value) {
1936 continue;
1937 } else if (comparator == "<=" && data <= filter_value) {
1938 continue;
1939 }
1940
1941 std::swap(objIDs_out.at(p), objIDs_out.back());
1942 objIDs_out.pop_back();
1943 } else {
1944 std::swap(objIDs_out.at(p), objIDs_out.back());
1945 objIDs_out.pop_back();
1946 }
1947 }
1948
1949 return objIDs_out;
1950}
1951
1952std::vector<uint> Context::filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, int filter_value, const std::string &comparator) const {
1953
1954 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1955 helios_runtime_error("ERROR (Context::filterObjectsByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1956 }
1957
1958 std::vector<uint> objIDs_out = objIDs;
1959 for (std::size_t p = objIDs.size(); p-- > 0;) {
1960 uint objID = objIDs_out.at(p);
1961 if (doesObjectDataExist(objID, object_data_label.c_str()) && getObjectDataType(object_data_label.c_str()) == HELIOS_TYPE_INT) {
1962 int data;
1963 getObjectData(objID, object_data_label.c_str(), data);
1964 if (comparator == "==" && data == filter_value) {
1965 continue;
1966 } else if (comparator == ">" && data > filter_value) {
1967 continue;
1968 } else if (comparator == "<" && data < filter_value) {
1969 continue;
1970 } else if (comparator == ">=" && data >= filter_value) {
1971 continue;
1972 } else if (comparator == "<=" && data <= filter_value) {
1973 continue;
1974 }
1975
1976 std::swap(objIDs_out.at(p), objIDs_out.back());
1977 objIDs_out.pop_back();
1978 } else {
1979 std::swap(objIDs_out.at(p), objIDs_out.back());
1980 objIDs_out.pop_back();
1981 }
1982 }
1983
1984 return objIDs_out;
1985}
1986
1987std::vector<uint> Context::filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, uint filter_value, const std::string &comparator) const {
1988
1989 if (comparator != "==" && comparator != ">" && comparator != "<" && comparator != ">=" && comparator != "<=") {
1990 helios_runtime_error("ERROR (Context::filterObjectsByData): Invalid comparator. Must be one of '==', '>', '<', '>=', or '<='.");
1991 }
1992
1993 std::vector<uint> objIDs_out = objIDs;
1994 for (std::size_t p = objIDs.size(); p-- > 0;) {
1995 uint objID = objIDs_out.at(p);
1996 if (doesObjectDataExist(objID, object_data_label.c_str()) && getObjectDataType(object_data_label.c_str()) == HELIOS_TYPE_UINT) {
1997 uint data;
1998 getObjectData(objID, object_data_label.c_str(), data);
1999 if (comparator == "==" && data == filter_value) {
2000 continue;
2001 } else if (comparator == ">" && data > filter_value) {
2002 continue;
2003 } else if (comparator == "<" && data < filter_value) {
2004 continue;
2005 } else if (comparator == ">=" && data >= filter_value) {
2006 continue;
2007 } else if (comparator == "<=" && data <= filter_value) {
2008 continue;
2009 }
2010
2011 std::swap(objIDs_out.at(p), objIDs_out.back());
2012 objIDs_out.pop_back();
2013 } else {
2014 std::swap(objIDs_out.at(p), objIDs_out.back());
2015 objIDs_out.pop_back();
2016 }
2017 }
2018
2019 return objIDs_out;
2020}
2021
2022std::vector<uint> Context::filterObjectsByData(const std::vector<uint> &objIDs, const std::string &object_data_label, const std::string &filter_value) const {
2023
2024 std::vector<uint> objIDs_out = objIDs;
2025 for (std::size_t p = objIDs.size(); p-- > 0;) {
2026 uint objID = objIDs_out.at(p);
2027 if (doesObjectDataExist(objID, object_data_label.c_str()) && getObjectDataType(object_data_label.c_str()) == HELIOS_TYPE_STRING) {
2028 std::string data;
2029 getObjectData(objID, object_data_label.c_str(), data);
2030 if (data != filter_value) {
2031 std::swap(objIDs_out.at(p), objIDs_out.back());
2032 objIDs_out.pop_back();
2033 }
2034 } else {
2035 std::swap(objIDs_out.at(p), objIDs_out.back());
2036 objIDs_out.pop_back();
2037 }
2038 }
2039
2040 return objIDs_out;
2041}
2042
2043// -------- Global Data ---------- //
2044
2045void Context::renameGlobalData(const char *old_label, const char *new_label) {
2046
2047 if (!doesGlobalDataExist(old_label)) {
2048 helios_runtime_error("ERROR (Context::duplicateGlobalData): Global data " + std::string(old_label) + " does not exist in the Context.");
2049 }
2050
2051 duplicateGlobalData(old_label, new_label);
2052 clearGlobalData(old_label);
2053}
2054
2055void Context::duplicateGlobalData(const char *old_label, const char *new_label) {
2056
2057 if (!doesGlobalDataExist(old_label)) {
2058 helios_runtime_error("ERROR (Context::duplicateGlobalData): Global data " + std::string(old_label) + " does not exist in the Context.");
2059 }
2060
2061 HeliosDataType type = getGlobalDataType(old_label);
2062
2063 if (type == HELIOS_TYPE_INT) {
2064 std::vector<int> gdata;
2065 getGlobalData(old_label, gdata);
2066 setGlobalData(new_label, gdata);
2067 } else if (type == HELIOS_TYPE_UINT) {
2068 std::vector<uint> gdata;
2069 getGlobalData(old_label, gdata);
2070 setGlobalData(new_label, gdata);
2071 } else if (type == HELIOS_TYPE_FLOAT) {
2072 std::vector<float> gdata;
2073 getGlobalData(old_label, gdata);
2074 setGlobalData(new_label, gdata);
2075 } else if (type == HELIOS_TYPE_DOUBLE) {
2076 std::vector<double> gdata;
2077 getGlobalData(old_label, gdata);
2078 setGlobalData(new_label, gdata);
2079 } else if (type == HELIOS_TYPE_VEC2) {
2080 std::vector<vec2> gdata;
2081 getGlobalData(old_label, gdata);
2082 setGlobalData(new_label, gdata);
2083 } else if (type == HELIOS_TYPE_VEC3) {
2084 std::vector<vec3> gdata;
2085 getGlobalData(old_label, gdata);
2086 setGlobalData(new_label, gdata);
2087 } else if (type == HELIOS_TYPE_VEC4) {
2088 std::vector<vec4> gdata;
2089 getGlobalData(old_label, gdata);
2090 setGlobalData(new_label, gdata);
2091 } else if (type == HELIOS_TYPE_INT2) {
2092 std::vector<int2> gdata;
2093 getGlobalData(old_label, gdata);
2094 setGlobalData(new_label, gdata);
2095 } else if (type == HELIOS_TYPE_INT3) {
2096 std::vector<int3> gdata;
2097 getGlobalData(old_label, gdata);
2098 setGlobalData(new_label, gdata);
2099 } else if (type == HELIOS_TYPE_INT4) {
2100 std::vector<int4> gdata;
2101 getGlobalData(old_label, gdata);
2102 setGlobalData(new_label, gdata);
2103 } else if (type == HELIOS_TYPE_STRING) {
2104 std::vector<std::string> gdata;
2105 getGlobalData(old_label, gdata);
2106 setGlobalData(new_label, gdata);
2107 } else {
2108 assert(false);
2109 }
2110}
2111
2112void Context::clearGlobalData(const char *label) {
2113
2114 if (doesGlobalDataExist(label)) {
2115 globaldata.erase(label);
2116 }
2117}
2118
2120
2121 if (!doesGlobalDataExist(label)) {
2122 helios_runtime_error("ERROR (Context::getGlobalDataType): Global data " + std::string(label) + " does not exist in the Context.");
2123 }
2124
2125 return globaldata.at(label).type;
2126}
2127
2128size_t Context::getGlobalDataSize(const char *label) const {
2129
2130 if (!doesGlobalDataExist(label)) {
2131 helios_runtime_error("ERROR (Context::getGlobalDataSize): Global data " + std::string(label) + " does not exist in the Context.");
2132 }
2133
2134 return globaldata.at(label).size;
2135}
2136
2137std::vector<std::string> Context::listGlobalData() const {
2138
2139 std::vector<std::string> labels;
2140 labels.reserve(globaldata.size());
2141 for (const auto &[label, data]: globaldata) {
2142 labels.push_back(label);
2143 }
2144
2145 return labels;
2146}
2147
2148std::vector<std::string> Context::listAllPrimitiveDataLabels() const {
2149 std::vector<std::string> labels;
2150 labels.reserve(primitive_data_label_counts.size());
2151 for (const auto &[label, count]: primitive_data_label_counts) {
2152 if (count > 0) {
2153 labels.push_back(label);
2154 }
2155 }
2156 return labels;
2157}
2158
2159
2160std::vector<std::string> Context::listAllObjectDataLabels() const {
2161 std::vector<std::string> labels;
2162 labels.reserve(object_data_label_counts.size());
2163 for (const auto &[label, count]: object_data_label_counts) {
2164 if (count > 0) {
2165 labels.push_back(label);
2166 }
2167 }
2168 return labels;
2169}
2170
2171bool Context::doesGlobalDataExist(const char *label) const {
2172 return globaldata.find(std::string(label)) != globaldata.end();
2173}
2174
2175void Context::incrementGlobalData(const char *label, int increment) {
2176
2177 if (!doesGlobalDataExist(label)) {
2178 helios_runtime_error("ERROR (Context::incrementGlobalData): Global data " + std::string(label) + " does not exist in the Context.");
2179 }
2180
2181 uint size = getGlobalDataSize(label);
2182
2183 if (globaldata.at(label).type == HELIOS_TYPE_INT) {
2184 for (uint i = 0; i < size; i++) {
2185 globaldata.at(label).global_data_int.at(i) += increment;
2186 }
2187 } else {
2188 std::cerr << "WARNING (Context::incrementGlobalData): Attempted to increment global data for type int, but data '" << label << "' does not have type int." << std::endl;
2189 }
2190}
2191
2192void Context::incrementGlobalData(const char *label, uint increment) {
2193
2194 if (!doesGlobalDataExist(label)) {
2195 helios_runtime_error("ERROR (Context::incrementGlobalData): Global data " + std::string(label) + " does not exist in the Context.");
2196 }
2197
2198 uint size = getGlobalDataSize(label);
2199
2200 if (globaldata.at(label).type == HELIOS_TYPE_UINT) {
2201 for (uint i = 0; i < size; i++) {
2202 globaldata.at(label).global_data_uint.at(i) += increment;
2203 }
2204 } else {
2205 std::cerr << "WARNING (Context::incrementGlobalData): Attempted to increment global data for type uint, but data '" << label << "' does not have type uint." << std::endl;
2206 }
2207}
2208
2209void Context::incrementGlobalData(const char *label, float increment) {
2210
2211 if (!doesGlobalDataExist(label)) {
2212 helios_runtime_error("ERROR (Context::incrementGlobalData): Global data " + std::string(label) + " does not exist in the Context.");
2213 }
2214
2215 uint size = getGlobalDataSize(label);
2216
2217 if (globaldata.at(label).type == HELIOS_TYPE_FLOAT) {
2218 for (uint i = 0; i < size; i++) {
2219 globaldata.at(label).global_data_float.at(i) += increment;
2220 }
2221 } else {
2222 std::cerr << "WARNING (Context::incrementGlobalData): Attempted to increment global data for type float, but data '" << label << "' does not have type float." << std::endl;
2223 }
2224}
2225
2226void Context::incrementGlobalData(const char *label, double increment) {
2227
2228 if (!doesGlobalDataExist(label)) {
2229 helios_runtime_error("ERROR (Context::incrementGlobalData): Global data " + std::string(label) + " does not exist in the Context.");
2230 }
2231
2232 uint size = getGlobalDataSize(label);
2233
2234 if (globaldata.at(label).type == HELIOS_TYPE_DOUBLE) {
2235 for (uint i = 0; i < size; i++) {
2236 globaldata.at(label).global_data_double.at(i) += increment;
2237 }
2238 } else {
2239 std::cerr << "WARNING (Context::incrementGlobalData): Attempted to increment global data for type double, but data '" << label << "' does not have type double." << std::endl;
2240 }
2241}
2242
2243std::string Context::dataTypeToString(HeliosDataType type) const {
2244 switch (type) {
2245 case HELIOS_TYPE_INT:
2246 return "int";
2247 case HELIOS_TYPE_UINT:
2248 return "uint";
2249 case HELIOS_TYPE_FLOAT:
2250 return "float";
2251 case HELIOS_TYPE_DOUBLE:
2252 return "double";
2253 case HELIOS_TYPE_VEC2:
2254 return "vec2";
2255 case HELIOS_TYPE_VEC3:
2256 return "vec3";
2257 case HELIOS_TYPE_VEC4:
2258 return "vec4";
2259 case HELIOS_TYPE_INT2:
2260 return "int2";
2261 case HELIOS_TYPE_INT3:
2262 return "int3";
2263 case HELIOS_TYPE_INT4:
2264 return "int4";
2265 case HELIOS_TYPE_STRING:
2266 return "string";
2267 case HELIOS_TYPE_BOOL:
2268 return "bool";
2270 return "unknown";
2271 default:
2272 return "undefined";
2273 }
2274}
2275
2276bool Context::isTypeCastingSupported(HeliosDataType from_type, HeliosDataType to_type) const {
2277 // Support casting between numeric types only
2278 const std::set<HeliosDataType> numeric_types = {HELIOS_TYPE_INT, HELIOS_TYPE_UINT, HELIOS_TYPE_FLOAT, HELIOS_TYPE_DOUBLE};
2279
2280 return (numeric_types.count(from_type) > 0 && numeric_types.count(to_type) > 0);
2281}