7TEST_CASE(
"Global Data") {
10 SUBCASE(
"Set, Get, Exists, List, Clear") {
11 ctx.setGlobalData(
"test_int", 123);
12 ctx.setGlobalData(
"test_float", 456.789f);
13 ctx.setGlobalData(
"test_string",
"hello");
14 std::vector<double> double_vec = {1.1, 2.2, 3.3};
15 ctx.setGlobalData(
"test_double_vec", double_vec);
17 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"test_int"));
18 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"test_float"));
19 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"test_string"));
20 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"test_double_vec"));
21 DOCTEST_CHECK(!ctx.doesGlobalDataExist(
"non_existent"));
24 ctx.getGlobalData(
"test_int", i);
25 DOCTEST_CHECK(i == 123);
28 ctx.getGlobalData(
"test_float", f);
29 DOCTEST_CHECK(f == doctest::Approx(456.789f));
32 ctx.getGlobalData(
"test_string", s);
33 DOCTEST_CHECK(s ==
"hello");
35 std::vector<double> dv;
36 ctx.getGlobalData(
"test_double_vec", dv);
37 DOCTEST_CHECK(dv.size() == 3);
38 DOCTEST_CHECK(dv[1] == doctest::Approx(2.2));
40 std::vector<std::string> labels = ctx.listGlobalData();
41 DOCTEST_CHECK(labels.size() == 4);
43 ctx.clearGlobalData(
"test_int");
44 DOCTEST_CHECK(!ctx.doesGlobalDataExist(
"test_int"));
47 SUBCASE(
"Management") {
48 ctx.setGlobalData(
"g_int", 5);
49 DOCTEST_CHECK(ctx.getGlobalDataType(
"g_int") == HELIOS_TYPE_INT);
50 DOCTEST_CHECK(ctx.getGlobalDataSize(
"g_int") == 1);
52 ctx.duplicateGlobalData(
"g_int",
"g_int_copy");
53 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int_copy"));
55 ctx.renameGlobalData(
"g_int",
"g_int_new");
56 DOCTEST_CHECK(!ctx.doesGlobalDataExist(
"g_int"));
57 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int_new"));
60 SUBCASE(
"Increment") {
61 ctx.setGlobalData(
"inc_me_int", 10);
62 ctx.incrementGlobalData(
"inc_me_int", 5);
64 ctx.getGlobalData(
"inc_me_int", val_i);
65 DOCTEST_CHECK(val_i == 15);
67 ctx.setGlobalData(
"inc_me_uint", std::vector<uint>{1});
68 ctx.incrementGlobalData(
"inc_me_uint", (
uint) 1);
69 std::vector<uint> val_u;
70 ctx.getGlobalData(
"inc_me_uint", val_u);
71 DOCTEST_CHECK(val_u[0] == 2);
73 ctx.setGlobalData(
"inc_me_float", std::vector<float>{1.f});
74 ctx.incrementGlobalData(
"inc_me_float", 1.f);
75 std::vector<float> val_f;
76 ctx.getGlobalData(
"inc_me_float", val_f);
77 DOCTEST_CHECK(val_f[0] == doctest::Approx(2.f));
79 ctx.setGlobalData(
"inc_me_double", std::vector<double>{1.0});
80 ctx.incrementGlobalData(
"inc_me_double", 1.0);
81 std::vector<double> val_d;
82 ctx.getGlobalData(
"inc_me_double", val_d);
83 DOCTEST_CHECK(val_d[0] == doctest::Approx(2.0));
86 SUBCASE(
"All Vector Types") {
87 ctx.setGlobalData(
"g_uint_vec", std::vector<uint>{1});
88 ctx.setGlobalData(
"g_vec2_vec", std::vector<vec2>{
make_vec2(1, 1)});
89 ctx.setGlobalData(
"g_vec3_vec", std::vector<vec3>{
make_vec3(1, 1, 1)});
90 ctx.setGlobalData(
"g_vec4_vec", std::vector<vec4>{
make_vec4(1, 1, 1, 1)});
91 ctx.setGlobalData(
"g_int2_vec", std::vector<int2>{
make_int2(1, 1)});
92 ctx.setGlobalData(
"g_int3_vec", std::vector<int3>{
make_int3(1, 1, 1)});
93 ctx.setGlobalData(
"g_int4_vec", std::vector<int4>{
make_int4(1, 1, 1, 1)});
94 ctx.setGlobalData(
"g_string_vec", std::vector<std::string>{
"hello"});
96 ctx.duplicateGlobalData(
"g_uint_vec",
"g_uint_vec_copy");
97 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_uint_vec_copy"));
98 ctx.duplicateGlobalData(
"g_vec2_vec",
"g_vec2_vec_copy");
99 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec2_vec_copy"));
100 ctx.duplicateGlobalData(
"g_vec3_vec",
"g_vec3_vec_copy");
101 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec3_vec_copy"));
102 ctx.duplicateGlobalData(
"g_vec4_vec",
"g_vec4_vec_copy");
103 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec4_vec_copy"));
104 ctx.duplicateGlobalData(
"g_int2_vec",
"g_int2_vec_copy");
105 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int2_vec_copy"));
106 ctx.duplicateGlobalData(
"g_int3_vec",
"g_int3_vec_copy");
107 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int3_vec_copy"));
108 ctx.duplicateGlobalData(
"g_int4_vec",
"g_int4_vec_copy");
109 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int4_vec_copy"));
110 ctx.duplicateGlobalData(
"g_string_vec",
"g_string_vec_copy");
111 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_string_vec_copy"));
114 SUBCASE(
"Global data error handling and all types") {
116 capture_cerr cerr_buffer;
117 DOCTEST_CHECK_THROWS(ctx.getGlobalDataType(
"non_existent"));
118 DOCTEST_CHECK_THROWS(ctx.getGlobalDataSize(
"non_existent"));
119 DOCTEST_CHECK_THROWS(ctx.renameGlobalData(
"non_existent",
"new"));
120 DOCTEST_CHECK_THROWS(ctx.duplicateGlobalData(
"non_existent",
"new"));
121 DOCTEST_CHECK_THROWS(ctx.incrementGlobalData(
"non_existent", 1));
123 ctx.setGlobalData(
"g_uint", std::vector<uint>{1});
124 ctx.setGlobalData(
"g_float", std::vector<float>{1.f});
125 ctx.setGlobalData(
"g_double", std::vector<double>{1.0});
126 ctx.setGlobalData(
"g_vec2", std::vector<vec2>{
make_vec2(1, 1)});
127 ctx.setGlobalData(
"g_vec3", std::vector<vec3>{
make_vec3(1, 1, 1)});
128 ctx.setGlobalData(
"g_vec4", std::vector<vec4>{
make_vec4(1, 1, 1, 1)});
129 ctx.setGlobalData(
"g_int2", std::vector<int2>{
make_int2(1, 1)});
130 ctx.setGlobalData(
"g_int3", std::vector<int3>{
make_int3(1, 1, 1)});
131 ctx.setGlobalData(
"g_int4", std::vector<int4>{
make_int4(1, 1, 1, 1)});
132 ctx.setGlobalData(
"g_string", std::vector<std::string>{
"hello"});
134 ctx.duplicateGlobalData(
"g_uint",
"g_uint_copy");
135 ctx.duplicateGlobalData(
"g_float",
"g_float_copy");
136 ctx.duplicateGlobalData(
"g_double",
"g_double_copy");
137 ctx.duplicateGlobalData(
"g_vec2",
"g_vec2_copy");
138 ctx.duplicateGlobalData(
"g_vec3",
"g_vec3_copy");
139 ctx.duplicateGlobalData(
"g_vec4",
"g_vec4_copy");
140 ctx.duplicateGlobalData(
"g_int2",
"g_int2_copy");
141 ctx.duplicateGlobalData(
"g_int3",
"g_int3_copy");
142 ctx.duplicateGlobalData(
"g_int4",
"g_int4_copy");
143 ctx.duplicateGlobalData(
"g_string",
"g_string_copy");
145 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_uint_copy"));
146 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_float_copy"));
147 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_double_copy"));
148 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec2_copy"));
149 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec3_copy"));
150 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_vec4_copy"));
151 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int2_copy"));
152 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int3_copy"));
153 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_int4_copy"));
154 DOCTEST_CHECK(ctx.doesGlobalDataExist(
"g_string_copy"));
156 ctx.incrementGlobalData(
"g_uint", (
uint) 1);
157 ctx.incrementGlobalData(
"g_float", 1.f);
158 ctx.incrementGlobalData(
"g_double", 1.0);
160 std::vector<uint> g_uint;
161 ctx.getGlobalData(
"g_uint", g_uint);
162 DOCTEST_CHECK(g_uint[0] == 2);
166TEST_CASE(
"Object Data") {
171 SUBCASE(
"Set, Get, Exists, List, Clear") {
172 ctx.setObjectData(o1,
"test_uint", (
uint) 42);
174 ctx.setObjectData(o1,
"test_vec3_vec", vec_data);
176 DOCTEST_CHECK(ctx.doesObjectDataExist(o1,
"test_uint"));
177 DOCTEST_CHECK(ctx.doesObjectDataExist(o1,
"test_vec3_vec"));
178 DOCTEST_CHECK(!ctx.doesObjectDataExist(o1,
"non_existent"));
181 ctx.getObjectData(o1,
"test_uint", ui);
182 DOCTEST_CHECK(ui == 42);
184 std::vector<vec3> v_r;
185 ctx.getObjectData(o1,
"test_vec3_vec", v_r);
186 DOCTEST_CHECK(v_r.size() == 2);
187 DOCTEST_CHECK(v_r[1].y == doctest::Approx(5.0));
189 DOCTEST_CHECK(ctx.getObjectDataType(
"test_uint") == HELIOS_TYPE_UINT);
190 DOCTEST_CHECK(ctx.getObjectDataSize(o1,
"test_vec3_vec") == 2);
192 std::vector<std::string> labels = ctx.listObjectData(o1);
193 DOCTEST_CHECK(labels.size() == 2);
195 ctx.clearObjectData(o1,
"test_uint");
196 DOCTEST_CHECK(!ctx.doesObjectDataExist(o1,
"test_uint"));
199 SUBCASE(
"Management") {
200 ctx.setObjectData(o1,
"my_data", 10);
202 ctx.copyObjectData(o1, o2);
203 DOCTEST_CHECK(ctx.doesObjectDataExist(o2,
"my_data"));
205 ctx.renameObjectData(o1,
"my_data",
"new_name");
206 DOCTEST_CHECK(!ctx.doesObjectDataExist(o1,
"my_data"));
207 DOCTEST_CHECK(ctx.doesObjectDataExist(o1,
"new_name"));
209 ctx.duplicateObjectData(o2,
"my_data",
"my_data_copy");
210 DOCTEST_CHECK(ctx.doesObjectDataExist(o2,
"my_data_copy"));
212 std::vector<std::string> all_obj_labels = ctx.listAllObjectDataLabels();
213 DOCTEST_CHECK(std::find(all_obj_labels.begin(), all_obj_labels.end(),
"my_data") != all_obj_labels.end());
214 DOCTEST_CHECK(std::find(all_obj_labels.begin(), all_obj_labels.end(),
"new_name") != all_obj_labels.end());
215 DOCTEST_CHECK(std::find(all_obj_labels.begin(), all_obj_labels.end(),
"my_data_copy") != all_obj_labels.end());
218 SUBCASE(
"Object data error handling") {
220 capture_cerr cerr_buffer;
222 DOCTEST_CHECK_THROWS(ctx.getObjectDataType(
"test"));
223 DOCTEST_CHECK_THROWS(ctx.getObjectDataSize(bad_oid,
"test"));
224 DOCTEST_CHECK_THROWS(ctx.doesObjectDataExist(bad_oid,
"test"));
225 DOCTEST_CHECK_THROWS(ctx.clearObjectData(bad_oid,
"test"));
226 DOCTEST_CHECK_THROWS(ctx.copyObjectData(0, bad_oid));
227 DOCTEST_CHECK_THROWS(ctx.copyObjectData(bad_oid, 0));
228 DOCTEST_CHECK_THROWS(ctx.renameObjectData(bad_oid,
"old",
"new"));
229 DOCTEST_CHECK_THROWS(ctx.duplicateObjectData(bad_oid,
"old",
"new"));
232 SUBCASE(
"setObjectDataFromPrimitiveDataMean") {
237 std::vector<uint> prims = ctx.getObjectPrimitiveUUIDs(tile_obj);
238 DOCTEST_CHECK(prims.size() == 4);
240 ctx.setPrimitiveData(prims[0],
"temperature", 10.0f);
241 ctx.setPrimitiveData(prims[1],
"temperature", 20.0f);
242 ctx.setPrimitiveData(prims[2],
"temperature", 30.0f);
243 ctx.setPrimitiveData(prims[3],
"temperature", 40.0f);
245 ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"temperature");
247 DOCTEST_CHECK(ctx.doesObjectDataExist(tile_obj,
"temperature"));
249 ctx.getObjectData(tile_obj,
"temperature", temp_mean);
250 DOCTEST_CHECK(temp_mean == doctest::Approx(25.0f));
254 std::vector<uint> box_prims = ctx.getObjectPrimitiveUUIDs(box_obj);
256 ctx.setPrimitiveData(box_prims[0],
"value", 1.5);
257 ctx.setPrimitiveData(box_prims[1],
"value", 2.5);
258 ctx.setPrimitiveData(box_prims[2],
"value", 3.5);
259 ctx.setPrimitiveData(box_prims[3],
"value", 4.5);
260 ctx.setPrimitiveData(box_prims[4],
"value", 5.5);
261 ctx.setPrimitiveData(box_prims[5],
"value", 6.5);
263 ctx.setObjectDataFromPrimitiveDataMean(box_obj,
"value");
266 ctx.getObjectData(box_obj,
"value", value_mean);
267 DOCTEST_CHECK(value_mean == doctest::Approx(4.0));
271 std::vector<uint> cone_prims = ctx.getObjectPrimitiveUUIDs(cone_obj);
273 for (
size_t i = 0; i < cone_prims.size(); ++i) {
274 ctx.setPrimitiveData(cone_prims[i],
"vec2_data",
make_vec2(
float(i),
float(i) * 2.0f));
277 ctx.setObjectDataFromPrimitiveDataMean(cone_obj,
"vec2_data");
280 ctx.getObjectData(cone_obj,
"vec2_data", vec2_mean);
281 float expected_x = float(cone_prims.size() - 1) / 2.0f;
282 DOCTEST_CHECK(vec2_mean.x == doctest::Approx(expected_x));
283 DOCTEST_CHECK(vec2_mean.y == doctest::Approx(expected_x * 2.0f));
286 ctx.setPrimitiveData(prims[0],
"color",
make_vec3(1.0f, 0.0f, 0.0f));
287 ctx.setPrimitiveData(prims[1],
"color",
make_vec3(0.0f, 1.0f, 0.0f));
288 ctx.setPrimitiveData(prims[2],
"color",
make_vec3(0.0f, 0.0f, 1.0f));
289 ctx.setPrimitiveData(prims[3],
"color",
make_vec3(1.0f, 1.0f, 1.0f));
291 ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"color");
294 ctx.getObjectData(tile_obj,
"color", color_mean);
295 DOCTEST_CHECK(color_mean.x == doctest::Approx(0.5f));
296 DOCTEST_CHECK(color_mean.y == doctest::Approx(0.5f));
297 DOCTEST_CHECK(color_mean.z == doctest::Approx(0.5f));
300 ctx.setPrimitiveData(prims[0],
"rgba",
make_vec4(1.0f, 0.0f, 0.0f, 1.0f));
301 ctx.setPrimitiveData(prims[1],
"rgba",
make_vec4(0.0f, 1.0f, 0.0f, 0.8f));
303 ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"rgba");
306 ctx.getObjectData(tile_obj,
"rgba", rgba_mean);
307 DOCTEST_CHECK(rgba_mean.x == doctest::Approx(0.5f));
308 DOCTEST_CHECK(rgba_mean.y == doctest::Approx(0.5f));
309 DOCTEST_CHECK(rgba_mean.z == doctest::Approx(0.0f));
310 DOCTEST_CHECK(rgba_mean.w == doctest::Approx(0.9f));
313 ctx.setPrimitiveData(prims[0],
"partial", 100.0f);
314 ctx.setPrimitiveData(prims[2],
"partial", 200.0f);
316 ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"partial");
319 ctx.getObjectData(tile_obj,
"partial", partial_mean);
320 DOCTEST_CHECK(partial_mean == doctest::Approx(150.0f));
323 DOCTEST_CHECK_THROWS(ctx.setObjectDataFromPrimitiveDataMean(999,
"temperature"));
326 DOCTEST_CHECK_THROWS(ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"nonexistent_data"));
329 ctx.setPrimitiveData(prims[0],
"int_data", 42);
330 DOCTEST_CHECK_THROWS(ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"int_data"));
333 ctx.setPrimitiveData(prims[0],
"string_data",
"hello");
334 DOCTEST_CHECK_THROWS(ctx.setObjectDataFromPrimitiveDataMean(tile_obj,
"string_data"));
338TEST_CASE(
"Primitive Data") {
340 uint p1 = ctx.addPatch();
341 uint p2 = ctx.addPatch();
342 std::vector<uint> uuids;
343 for (
int i = 0; i < 5; ++i) {
348 SUBCASE(
"Set and Get All Data Types") {
350 ctx.setPrimitiveData(p1,
"test_int", 1);
351 ctx.setPrimitiveData(p1,
"test_uint", 1u);
352 ctx.setPrimitiveData(p1,
"test_float", 2.f);
353 ctx.setPrimitiveData(p1,
"test_double", 2.0);
354 ctx.setPrimitiveData(p1,
"test_vec2",
make_vec2(1, 2));
355 ctx.setPrimitiveData(p1,
"test_vec3",
make_vec3(1, 2, 3));
356 ctx.setPrimitiveData(p1,
"test_vec4",
make_vec4(1, 2, 3, 4));
357 ctx.setPrimitiveData(p1,
"test_int2",
make_int2(1, 2));
358 ctx.setPrimitiveData(p1,
"test_int3",
make_int3(1, 2, 3));
359 ctx.setPrimitiveData(p1,
"test_int4",
make_int4(1, 2, 3, 4));
360 ctx.setPrimitiveData(p1,
"test_string",
"world");
363 ctx.getPrimitiveData(p1,
"test_int", r_i);
364 DOCTEST_CHECK(r_i == 1);
366 ctx.getPrimitiveData(p1,
"test_uint", r_ui);
367 DOCTEST_CHECK(r_ui == 1);
369 ctx.getPrimitiveData(p1,
"test_float", r_f);
370 DOCTEST_CHECK(r_f == doctest::Approx(2.0));
372 ctx.getPrimitiveData(p1,
"test_double", r_d);
373 DOCTEST_CHECK(r_d == doctest::Approx(2.0));
375 ctx.getPrimitiveData(p1,
"test_vec2", r_v2);
378 ctx.getPrimitiveData(p1,
"test_vec3", r_v3);
379 DOCTEST_CHECK(r_v3 ==
make_vec3(1, 2, 3));
381 ctx.getPrimitiveData(p1,
"test_vec4", r_v4);
382 DOCTEST_CHECK(r_v4 ==
make_vec4(1, 2, 3, 4));
384 ctx.getPrimitiveData(p1,
"test_int2", r_i2);
387 ctx.getPrimitiveData(p1,
"test_int3", r_i3);
388 DOCTEST_CHECK(r_i3 ==
make_int3(1, 2, 3));
390 ctx.getPrimitiveData(p1,
"test_int4", r_i4);
391 DOCTEST_CHECK(r_i4 ==
make_int4(1, 2, 3, 4));
393 ctx.getPrimitiveData(p1,
"test_string", r_s);
394 DOCTEST_CHECK(r_s ==
"world");
397 std::vector<int> v_i = {1, 2, 3};
398 ctx.setPrimitiveData(p1,
"test_v_int", v_i);
399 std::vector<int> r_v_i;
400 ctx.getPrimitiveData(p1,
"test_v_int", r_v_i);
401 DOCTEST_CHECK(r_v_i == v_i);
402 std::vector<uint> v_ui = {4, 5, 6};
403 ctx.setPrimitiveData(p1,
"test_v_uint", v_ui);
404 std::vector<uint> r_v_ui;
405 ctx.getPrimitiveData(p1,
"test_v_uint", r_v_ui);
406 DOCTEST_CHECK(r_v_ui == v_ui);
407 std::vector<float> v_f = {1.1, 2.2};
408 ctx.setPrimitiveData(p1,
"test_v_float", v_f);
409 std::vector<float> r_v_f;
410 ctx.getPrimitiveData(p1,
"test_v_float", r_v_f);
411 DOCTEST_CHECK(r_v_f == v_f);
412 std::vector<double> v_d = {1.1, 2.2};
413 ctx.setPrimitiveData(p1,
"test_v_double", v_d);
414 std::vector<double> r_v_d;
415 ctx.getPrimitiveData(p1,
"test_v_double", r_v_d);
416 DOCTEST_CHECK(r_v_d == v_d);
418 ctx.setPrimitiveData(p1,
"test_v_vec2", v_v2);
419 std::vector<vec2> r_v_v2;
420 ctx.getPrimitiveData(p1,
"test_v_vec2", r_v_v2);
421 DOCTEST_CHECK(r_v_v2 == v_v2);
423 ctx.setPrimitiveData(p1,
"test_v_vec3", v_v3);
424 std::vector<vec3> r_v_v3;
425 ctx.getPrimitiveData(p1,
"test_v_vec3", r_v_v3);
426 DOCTEST_CHECK(r_v_v3 == v_v3);
428 ctx.setPrimitiveData(p1,
"test_v_vec4", v_v4);
429 std::vector<vec4> r_v_v4;
430 ctx.getPrimitiveData(p1,
"test_v_vec4", r_v_v4);
431 DOCTEST_CHECK(r_v_v4 == v_v4);
433 ctx.setPrimitiveData(p1,
"test_v_int2", v_i2);
434 std::vector<int2> r_v_i2;
435 ctx.getPrimitiveData(p1,
"test_v_int2", r_v_i2);
436 DOCTEST_CHECK(r_v_i2 == v_i2);
438 ctx.setPrimitiveData(p1,
"test_v_int3", v_i3);
439 std::vector<int3> r_v_i3;
440 ctx.getPrimitiveData(p1,
"test_v_int3", r_v_i3);
441 DOCTEST_CHECK(r_v_i3 == v_i3);
443 ctx.setPrimitiveData(p1,
"test_v_int4", v_i4);
444 std::vector<int4> r_v_i4;
445 ctx.getPrimitiveData(p1,
"test_v_int4", r_v_i4);
446 DOCTEST_CHECK(r_v_i4 == v_i4);
447 std::vector<std::string> v_s = {
"hello",
"world"};
448 ctx.setPrimitiveData(p1,
"test_v_string", v_s);
449 std::vector<std::string> r_v_s;
450 ctx.getPrimitiveData(p1,
"test_v_string", r_v_s);
451 DOCTEST_CHECK(r_v_s == v_s);
454 SUBCASE(
"Management") {
455 ctx.setPrimitiveData(p1,
"my_data", 10);
456 ctx.copyPrimitiveData(p1, p2);
457 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p2,
"my_data"));
459 ctx.getPrimitiveData(p2,
"my_data", val);
460 DOCTEST_CHECK(val == 10);
462 ctx.renamePrimitiveData(p1,
"my_data",
"new_data_name");
463 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p1,
"my_data"));
464 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p1,
"new_data_name"));
466 ctx.duplicatePrimitiveData(p2,
"my_data",
"my_data_copy");
467 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p2,
"my_data_copy"));
468 ctx.getPrimitiveData(p2,
"my_data_copy", val);
469 DOCTEST_CHECK(val == 10);
471 ctx.setPrimitiveData(p1,
"global_copy_test", 5.5f);
472 ctx.duplicatePrimitiveData(
"global_copy_test",
"global_copy_test_new");
473 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p1,
"global_copy_test_new"));
474 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p2,
"global_copy_test_new"));
476 std::vector<std::string> all_labels = ctx.listAllPrimitiveDataLabels();
477 DOCTEST_CHECK(std::find(all_labels.begin(), all_labels.end(),
"my_data") != all_labels.end());
478 DOCTEST_CHECK(std::find(all_labels.begin(), all_labels.end(),
"my_data_copy") != all_labels.end());
479 DOCTEST_CHECK(std::find(all_labels.begin(), all_labels.end(),
"new_data_name") != all_labels.end());
481 ctx.clearPrimitiveData(p1,
"new_data_name");
482 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p1,
"new_data_name"));
483 ctx.clearPrimitiveData(uuids,
"global_copy_test");
486 SUBCASE(
"Calculations") {
487 for (
int i = 0; i < 5; ++i) {
488 ctx.setPrimitiveData(uuids[i],
"float_val", (
float) i);
489 ctx.setPrimitiveData(uuids[i],
"double_val", (
double) i);
490 ctx.setPrimitiveData(uuids[i],
"vec2_val",
make_vec2((
float) i, (
float) i));
494 ctx.calculatePrimitiveDataMean(uuids,
"float_val", float_mean);
495 DOCTEST_CHECK(float_mean == doctest::Approx(2.0f));
497 ctx.calculatePrimitiveDataMean(uuids,
"double_val", double_mean);
498 DOCTEST_CHECK(double_mean == doctest::Approx(2.0));
500 ctx.calculatePrimitiveDataMean(uuids,
"vec2_val", vec2_mean);
501 DOCTEST_CHECK(vec2_mean.x == doctest::Approx(2.0f));
504 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"float_val", awt_mean_f);
505 DOCTEST_CHECK(awt_mean_f == doctest::Approx(2.0f));
508 ctx.calculatePrimitiveDataSum(uuids,
"float_val", float_sum);
509 DOCTEST_CHECK(float_sum == doctest::Approx(10.0f));
512 ctx.calculatePrimitiveDataAreaWeightedSum(uuids,
"float_val", awt_sum_f);
513 DOCTEST_CHECK(awt_sum_f == doctest::Approx(10.0f));
515 ctx.scalePrimitiveData(uuids,
"float_val", 2.0f);
516 ctx.getPrimitiveData(uuids[2],
"float_val", float_mean);
517 DOCTEST_CHECK(float_mean == doctest::Approx(4.0f));
518 capture_cerr cerr_buffer;
519 ctx.scalePrimitiveData(
"double_val", 0.5f);
520 ctx.getPrimitiveData(uuids[4],
"double_val", double_mean);
521 DOCTEST_CHECK(double_mean == doctest::Approx(2.0));
522 DOCTEST_CHECK(cerr_buffer.has_output());
524 ctx.setPrimitiveData(uuids,
"int_val", 10);
525 ctx.incrementPrimitiveData(uuids,
"int_val", 5);
527 ctx.getPrimitiveData(uuids[0],
"int_val", int_val);
528 DOCTEST_CHECK(int_val == 15);
531 SUBCASE(
"Context::calculatePrimitiveDataMean empty list") {
533 std::vector<uint> uuids;
535 capture_cerr cerr_buffer;
536 ctx.calculatePrimitiveDataMean(uuids,
"non_existent", float_mean);
537 DOCTEST_CHECK(float_mean == 0.f);
538 DOCTEST_CHECK(cerr_buffer.has_output());
541 SUBCASE(
"Context::calculatePrimitiveDataMean vec3/vec4") {
543 uint p1 = ctx.addPatch();
544 ctx.setPrimitiveData(p1,
"v3",
make_vec3(1, 2, 3));
545 ctx.setPrimitiveData(p1,
"v4",
make_vec4(1, 2, 3, 4));
546 std::vector<uint> uuids = {p1};
549 ctx.calculatePrimitiveDataMean(uuids,
"v3", v3_mean);
550 ctx.calculatePrimitiveDataMean(uuids,
"v4", v4_mean);
551 DOCTEST_CHECK(v3_mean ==
make_vec3(1, 2, 3));
552 DOCTEST_CHECK(v4_mean ==
make_vec4(1, 2, 3, 4));
555 SUBCASE(
"Context::calculatePrimitiveDataAreaWeightedMean all types") {
558 ctx.setPrimitiveData(p,
"double", 2.5);
559 ctx.setPrimitiveData(p,
"vec2",
make_vec2(1, 2));
560 ctx.setPrimitiveData(p,
"vec3",
make_vec3(1, 2, 3));
561 ctx.setPrimitiveData(p,
"vec4",
make_vec4(1, 2, 3, 4));
562 std::vector<uint> uuids = {p};
565 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"double", d_mean);
566 DOCTEST_CHECK(d_mean == doctest::Approx(2.5));
569 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec2", v2_mean);
570 DOCTEST_CHECK(v2_mean ==
make_vec2(1, 2));
573 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec3", v3_mean);
574 DOCTEST_CHECK(v3_mean ==
make_vec3(1, 2, 3));
577 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec4", v4_mean);
578 DOCTEST_CHECK(v4_mean ==
make_vec4(1, 2, 3, 4));
581 SUBCASE(
"Context::calculatePrimitiveDataSum all types") {
583 uint p = ctx.addPatch();
584 ctx.setPrimitiveData(p,
"double", 2.5);
585 ctx.setPrimitiveData(p,
"vec2",
make_vec2(1, 2));
586 ctx.setPrimitiveData(p,
"vec3",
make_vec3(1, 2, 3));
587 ctx.setPrimitiveData(p,
"vec4",
make_vec4(1, 2, 3, 4));
588 std::vector<uint> uuids = {p};
591 ctx.calculatePrimitiveDataSum(uuids,
"double", d_sum);
592 DOCTEST_CHECK(d_sum == doctest::Approx(2.5));
595 ctx.calculatePrimitiveDataSum(uuids,
"vec2", v2_sum);
596 DOCTEST_CHECK(v2_sum ==
make_vec2(1, 2));
599 ctx.calculatePrimitiveDataSum(uuids,
"vec3", v3_sum);
600 DOCTEST_CHECK(v3_sum ==
make_vec3(1, 2, 3));
603 ctx.calculatePrimitiveDataSum(uuids,
"vec4", v4_sum);
604 DOCTEST_CHECK(v4_sum ==
make_vec4(1, 2, 3, 4));
607 SUBCASE(
"Context::incrementPrimitiveData all types") {
609 uint p = ctx.addPatch();
610 ctx.setPrimitiveData(p,
"uint", (
uint) 1);
611 ctx.setPrimitiveData(p,
"float", 1.f);
612 ctx.setPrimitiveData(p,
"double", 1.0);
613 std::vector<uint> uuids = {p};
615 ctx.incrementPrimitiveData(uuids,
"uint", (
uint) 2);
617 ctx.getPrimitiveData(p,
"uint", u_val);
618 DOCTEST_CHECK(u_val == 3);
620 ctx.incrementPrimitiveData(uuids,
"float", 2.f);
622 ctx.getPrimitiveData(p,
"float", f_val);
623 DOCTEST_CHECK(f_val == doctest::Approx(3.f));
625 ctx.incrementPrimitiveData(uuids,
"double", 2.0);
627 ctx.getPrimitiveData(p,
"double", d_val);
628 DOCTEST_CHECK(d_val == doctest::Approx(3.0));
631 SUBCASE(
"Aggregation and Filtering") {
632 std::vector<uint> agg_uuids;
633 for (
int i = 0; i < 3; ++i) {
634 uint p = ctx.addPatch();
635 ctx.setPrimitiveData(p,
"d1", (
float) i);
636 ctx.setPrimitiveData(p,
"d2", (
float) i * 2.0f);
637 ctx.setPrimitiveData(p,
"d3", (
float) i * 3.0f);
638 ctx.setPrimitiveData(p,
"filter_me", i);
639 agg_uuids.push_back(p);
642 std::vector<std::string> labels = {
"d1",
"d2",
"d3"};
643 ctx.aggregatePrimitiveDataSum(agg_uuids, labels,
"sum_data");
645 ctx.getPrimitiveData(agg_uuids[1],
"sum_data", sum_val);
646 DOCTEST_CHECK(sum_val == doctest::Approx(1.f + 2.f + 3.f));
648 ctx.aggregatePrimitiveDataProduct(agg_uuids, labels,
"prod_data");
650 ctx.getPrimitiveData(agg_uuids[2],
"prod_data", prod_val);
651 DOCTEST_CHECK(prod_val == doctest::Approx(2.f * 4.f * 6.f));
653 std::vector<uint> filtered = ctx.filterPrimitivesByData(agg_uuids,
"filter_me", 1,
">=");
654 DOCTEST_CHECK(filtered.size() == 2);
655 filtered = ctx.filterPrimitivesByData(agg_uuids,
"filter_me", 1,
"==");
656 DOCTEST_CHECK(filtered.size() == 1);
657 DOCTEST_CHECK(filtered[0] == agg_uuids[1]);
660 SUBCASE(
"Context::filterPrimitivesByData all types") {
662 uint p = ctx.addPatch();
663 ctx.setPrimitiveData(p,
"double", 1.0);
664 ctx.setPrimitiveData(p,
"uint", (
uint) 10);
665 std::vector<uint> uuids = {p};
667 auto filtered_d = ctx.filterPrimitivesByData(uuids,
"double", 0.5,
">");
668 DOCTEST_CHECK(filtered_d.size() == 1);
670 auto filtered_u = ctx.filterPrimitivesByData(uuids,
"uint", (
uint) 5,
">");
671 DOCTEST_CHECK(filtered_u.size() == 1);
674 SUBCASE(
"Error Handling") {
675 capture_cerr cerr_buffer;
677 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataType(
"test"));
678 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataSize(bad_uuid,
"test"));
679 DOCTEST_CHECK_THROWS(ctx.doesPrimitiveDataExist(bad_uuid,
"test"));
680 DOCTEST_CHECK_THROWS(ctx.clearPrimitiveData(bad_uuid,
"test"));
681 DOCTEST_CHECK_THROWS(ctx.copyPrimitiveData(p1, bad_uuid));
682 DOCTEST_CHECK_THROWS(ctx.copyPrimitiveData(bad_uuid, p1));
683 DOCTEST_CHECK_THROWS(ctx.renamePrimitiveData(bad_uuid,
"old",
"new"));
684 DOCTEST_CHECK_THROWS(ctx.duplicatePrimitiveData(bad_uuid,
"old",
"new"));
686 std::vector<uint> empty_uuids;
688 ctx.calculatePrimitiveDataMean(empty_uuids,
"non_existent", float_mean);
689 DOCTEST_CHECK(float_mean == 0.f);
690 DOCTEST_CHECK(cerr_buffer.has_output());
692 ctx.setPrimitiveData(p1,
"float_val_err", 1.f);
693 ctx.incrementPrimitiveData(std::vector<uint>{p1},
"float_val_err", 1);
694 DOCTEST_CHECK(cerr_buffer.has_output());
696 std::vector<uint> filtered_UUIDs;
697 DOCTEST_CHECK_THROWS_AS(filtered_UUIDs = ctx.filterPrimitivesByData(uuids,
"filter_me", 1,
"!!"), std::runtime_error);
700 SUBCASE(
"Primitive::getPrimitiveDataSize all types") {
702 uint p = ctx.addPatch();
703 ctx.setPrimitiveData(p,
"uint", (
uint) 1);
704 ctx.setPrimitiveData(p,
"double", 1.0);
705 ctx.setPrimitiveData(p,
"vec2",
make_vec2(1, 1));
706 ctx.setPrimitiveData(p,
"vec3",
make_vec3(1, 1, 1));
707 ctx.setPrimitiveData(p,
"vec4",
make_vec4(1, 1, 1, 1));
708 ctx.setPrimitiveData(p,
"int2",
make_int2(1, 1));
709 ctx.setPrimitiveData(p,
"int3",
make_int3(1, 1, 1));
710 ctx.setPrimitiveData(p,
"int4",
make_int4(1, 1, 1, 1));
711 ctx.setPrimitiveData(p,
"string",
"hello");
713 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"uint") == 1);
714 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"double") == 1);
715 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec2") == 1);
716 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec3") == 1);
717 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec4") == 1);
718 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"int2") == 1);
719 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"int3") == 1);
720 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"int4") == 1);
721 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"string") == 1);
724 SUBCASE(
"Primitive::clearPrimitiveData all types") {
726 uint p = ctx.addPatch();
727 ctx.setPrimitiveData(p,
"uint", (
uint) 1);
728 ctx.setPrimitiveData(p,
"double", 1.0);
729 ctx.setPrimitiveData(p,
"vec2",
make_vec2(1, 1));
730 ctx.setPrimitiveData(p,
"vec3",
make_vec3(1, 1, 1));
731 ctx.setPrimitiveData(p,
"vec4",
make_vec4(1, 1, 1, 1));
732 ctx.setPrimitiveData(p,
"int2",
make_int2(1, 1));
733 ctx.setPrimitiveData(p,
"int3",
make_int3(1, 1, 1));
734 ctx.setPrimitiveData(p,
"int4",
make_int4(1, 1, 1, 1));
735 ctx.setPrimitiveData(p,
"string",
"hello");
737 ctx.clearPrimitiveData(p,
"uint");
738 ctx.clearPrimitiveData(p,
"double");
739 ctx.clearPrimitiveData(p,
"vec2");
740 ctx.clearPrimitiveData(p,
"vec3");
741 ctx.clearPrimitiveData(p,
"vec4");
742 ctx.clearPrimitiveData(p,
"int2");
743 ctx.clearPrimitiveData(p,
"int3");
744 ctx.clearPrimitiveData(p,
"int4");
745 ctx.clearPrimitiveData(p,
"string");
747 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"uint"));
748 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"double"));
749 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"vec2"));
750 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"vec3"));
751 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"vec4"));
752 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"int2"));
753 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"int3"));
754 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"int4"));
755 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p,
"string"));
758 SUBCASE(
"Context data functions with invalid UUID") {
760 capture_cerr cerr_buffer;
762 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataType(
"test"));
763 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataSize(bad_uuid,
"test"));
764 DOCTEST_CHECK_THROWS(ctx.doesPrimitiveDataExist(bad_uuid,
"test"));
765 DOCTEST_CHECK_THROWS(ctx.clearPrimitiveData(bad_uuid,
"test"));
766 DOCTEST_CHECK_THROWS(ctx.copyPrimitiveData(0, bad_uuid));
767 DOCTEST_CHECK_THROWS(ctx.copyPrimitiveData(bad_uuid, 0));
768 DOCTEST_CHECK_THROWS(ctx.renamePrimitiveData(bad_uuid,
"old",
"new"));
769 DOCTEST_CHECK_THROWS(ctx.duplicatePrimitiveData(bad_uuid,
"old",
"new"));
772 SUBCASE(
"Context::clearPrimitiveData for multiple UUIDs") {
774 uint p1 = ctx.addPatch();
775 uint p2 = ctx.addPatch();
776 ctx.setPrimitiveData(p1,
"data", 1);
777 ctx.setPrimitiveData(p2,
"data", 2);
778 std::vector<uint> uuids = {p1, p2};
779 ctx.clearPrimitiveData(uuids,
"data");
780 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p1,
"data"));
781 DOCTEST_CHECK(!ctx.doesPrimitiveDataExist(p2,
"data"));
784 SUBCASE(
"Context::duplicatePrimitiveData all types") {
786 uint p = ctx.addPatch();
787 ctx.setPrimitiveData(p,
"uint", (
uint) 1);
788 ctx.setPrimitiveData(p,
"double", 1.0);
789 ctx.setPrimitiveData(p,
"vec2",
make_vec2(1, 1));
790 ctx.setPrimitiveData(p,
"vec3",
make_vec3(1, 1, 1));
791 ctx.setPrimitiveData(p,
"vec4",
make_vec4(1, 1, 1, 1));
792 ctx.setPrimitiveData(p,
"int2",
make_int2(1, 1));
793 ctx.setPrimitiveData(p,
"int3",
make_int3(1, 1, 1));
794 ctx.setPrimitiveData(p,
"int4",
make_int4(1, 1, 1, 1));
795 ctx.setPrimitiveData(p,
"string",
"hello");
797 ctx.duplicatePrimitiveData(p,
"uint",
"uint_copy");
798 ctx.duplicatePrimitiveData(p,
"double",
"double_copy");
799 ctx.duplicatePrimitiveData(p,
"vec2",
"vec2_copy");
800 ctx.duplicatePrimitiveData(p,
"vec3",
"vec3_copy");
801 ctx.duplicatePrimitiveData(p,
"vec4",
"vec4_copy");
802 ctx.duplicatePrimitiveData(p,
"int2",
"int2_copy");
803 ctx.duplicatePrimitiveData(p,
"int3",
"int3_copy");
804 ctx.duplicatePrimitiveData(p,
"int4",
"int4_copy");
805 ctx.duplicatePrimitiveData(p,
"string",
"string_copy");
807 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"uint_copy"));
808 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"double_copy"));
809 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"vec2_copy"));
810 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"vec3_copy"));
811 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"vec4_copy"));
812 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"int2_copy"));
813 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"int3_copy"));
814 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"int4_copy"));
815 DOCTEST_CHECK(ctx.doesPrimitiveDataExist(p,
"string_copy"));
819 SUBCASE(
"Generic Value-Level Caching System") {
823 std::vector<std::string> test_values;
824 bool threw_error =
false;
826 ctx_test.getUniquePrimitiveDataValues(
"uncached_label", test_values);
827 }
catch (
const std::runtime_error &e) {
829 DOCTEST_CHECK(std::string(e.what()).find(
"Value-level caching is not enabled") != std::string::npos);
831 DOCTEST_CHECK(threw_error);
835 ctx_test.getUniqueObjectDataValues(
"uncached_label", test_values);
836 }
catch (
const std::runtime_error &e) {
838 DOCTEST_CHECK(std::string(e.what()).find(
"Value-level caching is not enabled") != std::string::npos);
840 DOCTEST_CHECK(threw_error);
843 DOCTEST_CHECK(!ctx_test.isPrimitiveDataValueCachingEnabled(
"test_string"));
844 DOCTEST_CHECK(!ctx_test.isObjectDataValueCachingEnabled(
"test_string"));
846 ctx_test.enablePrimitiveDataValueCaching(
"test_string");
847 ctx_test.enablePrimitiveDataValueCaching(
"test_int");
848 ctx_test.enablePrimitiveDataValueCaching(
"test_uint");
849 ctx_test.enableObjectDataValueCaching(
"obj_string");
850 ctx_test.enableObjectDataValueCaching(
"obj_int");
851 ctx_test.enableObjectDataValueCaching(
"obj_uint");
853 DOCTEST_CHECK(ctx_test.isPrimitiveDataValueCachingEnabled(
"test_string"));
854 DOCTEST_CHECK(ctx_test.isPrimitiveDataValueCachingEnabled(
"test_int"));
855 DOCTEST_CHECK(ctx_test.isPrimitiveDataValueCachingEnabled(
"test_uint"));
856 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"obj_string"));
857 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"obj_int"));
858 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"obj_uint"));
868 ctx_test.setPrimitiveData(patch1,
"test_string", std::string(
"apple"));
869 ctx_test.setPrimitiveData(patch2,
"test_string", std::string(
"banana"));
870 ctx_test.setPrimitiveData(patch3,
"test_string", std::string(
"apple"));
872 std::vector<std::string> string_values;
873 ctx_test.getUniquePrimitiveDataValues(
"test_string", string_values);
874 DOCTEST_CHECK(string_values.size() == 2);
875 std::sort(string_values.begin(), string_values.end());
876 DOCTEST_CHECK(string_values[0] ==
"apple");
877 DOCTEST_CHECK(string_values[1] ==
"banana");
880 ctx_test.setPrimitiveData(patch1,
"test_int", 10);
881 ctx_test.setPrimitiveData(patch2,
"test_int", 20);
882 ctx_test.setPrimitiveData(patch3,
"test_int", 10);
884 std::vector<int> int_values;
885 ctx_test.getUniquePrimitiveDataValues(
"test_int", int_values);
886 DOCTEST_CHECK(int_values.size() == 2);
887 std::sort(int_values.begin(), int_values.end());
888 DOCTEST_CHECK(int_values[0] == 10);
889 DOCTEST_CHECK(int_values[1] == 20);
892 ctx_test.setPrimitiveData(patch1,
"test_uint", 100u);
893 ctx_test.setPrimitiveData(patch2,
"test_uint", 200u);
894 ctx_test.setPrimitiveData(patch3,
"test_uint", 100u);
896 std::vector<uint> uint_values;
897 ctx_test.getUniquePrimitiveDataValues(
"test_uint", uint_values);
898 DOCTEST_CHECK(uint_values.size() == 2);
899 std::sort(uint_values.begin(), uint_values.end());
900 DOCTEST_CHECK(uint_values[0] == 100u);
901 DOCTEST_CHECK(uint_values[1] == 200u);
904 ctx_test.setObjectData(obj1,
"obj_string", std::string(
"circle"));
905 ctx_test.setObjectData(obj2,
"obj_string", std::string(
"square"));
907 std::vector<std::string> obj_string_values;
908 ctx_test.getUniqueObjectDataValues(
"obj_string", obj_string_values);
909 DOCTEST_CHECK(obj_string_values.size() == 2);
910 std::sort(obj_string_values.begin(), obj_string_values.end());
911 DOCTEST_CHECK(obj_string_values[0] ==
"circle");
912 DOCTEST_CHECK(obj_string_values[1] ==
"square");
915 ctx_test.setObjectData(obj1,
"obj_int", 5);
916 ctx_test.setObjectData(obj2,
"obj_int", 15);
918 std::vector<int> obj_int_values;
919 ctx_test.getUniqueObjectDataValues(
"obj_int", obj_int_values);
920 DOCTEST_CHECK(obj_int_values.size() == 2);
921 std::sort(obj_int_values.begin(), obj_int_values.end());
922 DOCTEST_CHECK(obj_int_values[0] == 5);
923 DOCTEST_CHECK(obj_int_values[1] == 15);
926 ctx_test.setObjectData(obj1,
"obj_uint", 50u);
927 ctx_test.setObjectData(obj2,
"obj_uint", 150u);
929 std::vector<uint> obj_uint_values;
930 ctx_test.getUniqueObjectDataValues(
"obj_uint", obj_uint_values);
931 DOCTEST_CHECK(obj_uint_values.size() == 2);
932 std::sort(obj_uint_values.begin(), obj_uint_values.end());
933 DOCTEST_CHECK(obj_uint_values[0] == 50u);
934 DOCTEST_CHECK(obj_uint_values[1] == 150u);
937 ctx_test.setPrimitiveData(patch1,
"test_string", std::string(
"cherry"));
938 ctx_test.getUniquePrimitiveDataValues(
"test_string", string_values);
939 DOCTEST_CHECK(string_values.size() == 3);
940 std::sort(string_values.begin(), string_values.end());
941 DOCTEST_CHECK(string_values[0] ==
"apple");
942 DOCTEST_CHECK(string_values[1] ==
"banana");
943 DOCTEST_CHECK(string_values[2] ==
"cherry");
946 ctx_test.clearPrimitiveData(patch2,
"test_string");
947 ctx_test.getUniquePrimitiveDataValues(
"test_string", string_values);
948 DOCTEST_CHECK(string_values.size() == 2);
949 std::sort(string_values.begin(), string_values.end());
950 DOCTEST_CHECK(string_values[0] ==
"apple");
951 DOCTEST_CHECK(string_values[1] ==
"cherry");
953 ctx_test.clearObjectData(obj1,
"obj_string");
954 ctx_test.getUniqueObjectDataValues(
"obj_string", obj_string_values);
955 DOCTEST_CHECK(obj_string_values.size() == 1);
956 DOCTEST_CHECK(obj_string_values[0] ==
"square");
959 ctx_test.disablePrimitiveDataValueCaching(
"test_string");
960 DOCTEST_CHECK(!ctx_test.isPrimitiveDataValueCachingEnabled(
"test_string"));
964 ctx_test.getUniquePrimitiveDataValues(
"test_string", string_values);
965 }
catch (
const std::runtime_error &e) {
968 DOCTEST_CHECK(threw_error);
970 ctx_test.disableObjectDataValueCaching(
"obj_string");
971 DOCTEST_CHECK(!ctx_test.isObjectDataValueCachingEnabled(
"obj_string"));
975 ctx_test.getUniqueObjectDataValues(
"obj_string", obj_string_values);
976 }
catch (
const std::runtime_error &e) {
979 DOCTEST_CHECK(threw_error);
982 ctx_test.enablePrimitiveDataValueCaching(
"empty_label");
983 std::vector<std::string> empty_values;
984 ctx_test.getUniquePrimitiveDataValues(
"empty_label", empty_values);
985 DOCTEST_CHECK(empty_values.empty());
989TEST_CASE(
"Vector setObjectData Value Caching") {
993 ctx_test.enableObjectDataValueCaching(
"vec_string");
994 ctx_test.enableObjectDataValueCaching(
"vec_int");
995 ctx_test.enableObjectDataValueCaching(
"vec_uint");
997 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"vec_string"));
998 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"vec_int"));
999 DOCTEST_CHECK(ctx_test.isObjectDataValueCachingEnabled(
"vec_uint"));
1004 uint obj3 = ctx_test.addSphereObject(1,
make_vec3(2, 0, 0), 1.0f);
1007 SUBCASE(
"Vector<uint> string caching") {
1009 std::vector<uint> obj_vec = {obj1, obj2};
1010 ctx_test.setObjectData(obj_vec,
"vec_string", std::string(
"apple"));
1013 ctx_test.setObjectData(obj3,
"vec_string", std::string(
"banana"));
1015 std::vector<std::string> string_values;
1016 ctx_test.getUniqueObjectDataValues(
"vec_string", string_values);
1017 DOCTEST_CHECK(string_values.size() == 2);
1018 std::sort(string_values.begin(), string_values.end());
1019 DOCTEST_CHECK(string_values[0] ==
"apple");
1020 DOCTEST_CHECK(string_values[1] ==
"banana");
1023 SUBCASE(
"Vector<uint> int caching") {
1025 std::vector<uint> obj_vec = {obj1, obj2, obj3};
1026 ctx_test.setObjectData(obj_vec,
"vec_int", 100);
1029 ctx_test.setObjectData(obj4,
"vec_int", 200);
1031 std::vector<int> int_values;
1032 ctx_test.getUniqueObjectDataValues(
"vec_int", int_values);
1033 DOCTEST_CHECK(int_values.size() == 2);
1034 std::sort(int_values.begin(), int_values.end());
1035 DOCTEST_CHECK(int_values[0] == 100);
1036 DOCTEST_CHECK(int_values[1] == 200);
1039 SUBCASE(
"Vector<uint> uint caching") {
1041 std::vector<uint> obj_vec = {obj1, obj2};
1042 ctx_test.setObjectData(obj_vec,
"vec_uint", 50u);
1045 std::vector<uint> obj_vec2 = {obj3};
1046 ctx_test.setObjectData(obj_vec2,
"vec_uint", 50u);
1049 ctx_test.setObjectData(obj4,
"vec_uint", 150u);
1051 std::vector<uint> uint_values;
1052 ctx_test.getUniqueObjectDataValues(
"vec_uint", uint_values);
1053 DOCTEST_CHECK(uint_values.size() == 2);
1054 std::sort(uint_values.begin(), uint_values.end());
1055 DOCTEST_CHECK(uint_values[0] == 50u);
1056 DOCTEST_CHECK(uint_values[1] == 150u);
1059 SUBCASE(
"Vector<vector<uint>> caching") {
1061 std::vector<std::vector<uint>> nested_vec = {{obj1, obj2}, {obj3}};
1062 ctx_test.setObjectData(nested_vec,
"vec_string", std::string(
"cherry"));
1065 ctx_test.setObjectData(obj4,
"vec_string", std::string(
"date"));
1067 std::vector<std::string> string_values;
1068 ctx_test.getUniqueObjectDataValues(
"vec_string", string_values);
1069 DOCTEST_CHECK(string_values.size() == 2);
1070 std::sort(string_values.begin(), string_values.end());
1071 DOCTEST_CHECK(string_values[0] ==
"cherry");
1072 DOCTEST_CHECK(string_values[1] ==
"date");
1075 SUBCASE(
"Vector<vector<vector<uint>>> caching") {
1077 std::vector<std::vector<std::vector<uint>>> triple_vec = {{{obj1}, {obj2}}, {{obj3}}};
1078 ctx_test.setObjectData(triple_vec,
"vec_int", 300);
1081 ctx_test.setObjectData(obj4,
"vec_int", 400);
1083 std::vector<int> int_values;
1084 ctx_test.getUniqueObjectDataValues(
"vec_int", int_values);
1085 DOCTEST_CHECK(int_values.size() == 2);
1086 std::sort(int_values.begin(), int_values.end());
1087 DOCTEST_CHECK(int_values[0] == 300);
1088 DOCTEST_CHECK(int_values[1] == 400);
1091 SUBCASE(
"Vector cache update behavior") {
1093 std::vector<uint> obj_vec = {obj1, obj2};
1096 ctx_test.setObjectData(obj_vec,
"vec_string", std::string(
"old_value"));
1097 ctx_test.setObjectData(obj3,
"vec_string", std::string(
"other_value"));
1100 std::vector<std::string> string_values;
1101 ctx_test.getUniqueObjectDataValues(
"vec_string", string_values);
1102 DOCTEST_CHECK(string_values.size() == 2);
1105 ctx_test.setObjectData(obj_vec,
"vec_string", std::string(
"new_value"));
1108 ctx_test.getUniqueObjectDataValues(
"vec_string", string_values);
1109 DOCTEST_CHECK(string_values.size() == 2);
1110 std::sort(string_values.begin(), string_values.end());
1111 DOCTEST_CHECK(string_values[0] ==
"new_value");
1112 DOCTEST_CHECK(string_values[1] ==
"other_value");
1115 SUBCASE(
"Mixed single and vector operations") {
1117 ctx_test.setObjectData(obj1,
"vec_int", 10);
1119 std::vector<uint> obj_vec = {obj2, obj3};
1120 ctx_test.setObjectData(obj_vec,
"vec_int", 10);
1122 ctx_test.setObjectData(obj4,
"vec_int", 20);
1124 std::vector<int> int_values;
1125 ctx_test.getUniqueObjectDataValues(
"vec_int", int_values);
1126 DOCTEST_CHECK(int_values.size() == 2);
1127 std::sort(int_values.begin(), int_values.end());
1128 DOCTEST_CHECK(int_values[0] == 10);
1129 DOCTEST_CHECK(int_values[1] == 20);
1133TEST_CASE(
"Object Data Filtering") {
1139 SUBCASE(
"filterObjectsByData for all types") {
1141 ctx.setObjectData(o1,
"float_val", 1.5f);
1142 ctx.setObjectData(o2,
"float_val", 2.5f);
1143 ctx.setObjectData(o3,
"float_val", 0.5f);
1145 ctx.setObjectData(o1,
"double_val", 1.5);
1146 ctx.setObjectData(o2,
"double_val", 2.5);
1147 ctx.setObjectData(o3,
"double_val", 0.5);
1149 ctx.setObjectData(o1,
"int_val", 1);
1150 ctx.setObjectData(o2,
"int_val", 2);
1151 ctx.setObjectData(o3,
"int_val", 0);
1153 ctx.setObjectData(o1,
"uint_val", (
uint) 1);
1154 ctx.setObjectData(o2,
"uint_val", (
uint) 2);
1155 ctx.setObjectData(o3,
"uint_val", (
uint) 0);
1157 ctx.setObjectData(o1,
"string_val", std::string(
"apple"));
1158 ctx.setObjectData(o2,
"string_val", std::string(
"banana"));
1159 ctx.setObjectData(o3,
"string_val", std::string(
"cherry"));
1161 std::vector<uint> all_objects = {o1, o2, o3};
1164 auto filtered_f = ctx.filterObjectsByData(all_objects, std::string(
"float_val"), 1.0f, std::string(
">"));
1165 DOCTEST_CHECK(filtered_f.size() == 2);
1166 DOCTEST_CHECK(std::find(filtered_f.begin(), filtered_f.end(), o1) != filtered_f.end());
1167 DOCTEST_CHECK(std::find(filtered_f.begin(), filtered_f.end(), o2) != filtered_f.end());
1169 filtered_f = ctx.filterObjectsByData(all_objects, std::string(
"float_val"), 2.5f, std::string(
"=="));
1170 DOCTEST_CHECK(filtered_f.size() == 1);
1171 DOCTEST_CHECK(filtered_f[0] == o2);
1174 auto filtered_d = ctx.filterObjectsByData(all_objects, std::string(
"double_val"), 1.0, std::string(
">="));
1175 DOCTEST_CHECK(filtered_d.size() == 2);
1178 auto filtered_i = ctx.filterObjectsByData(all_objects, std::string(
"int_val"), 1, std::string(
"<"));
1179 DOCTEST_CHECK(filtered_i.size() == 1);
1180 DOCTEST_CHECK(filtered_i[0] == o3);
1183 auto filtered_u = ctx.filterObjectsByData(all_objects, std::string(
"uint_val"), (
uint) 0, std::string(
">"));
1184 DOCTEST_CHECK(filtered_u.size() == 2);
1190 SUBCASE(
"filterObjectsByData error handling") {
1191 std::vector<uint> objects = {o1};
1192 capture_cerr cerr_buffer;
1195 std::vector<uint> filtered_f;
1196 DOCTEST_CHECK_THROWS_AS(filtered_f = ctx.filterObjectsByData(objects, std::string(
"non_existent"), 1.0f, std::string(
"!!")), std::runtime_error);
1199 auto empty_result = ctx.filterObjectsByData(objects, std::string(
"non_existent"), 1.0f, std::string(
">"));
1200 DOCTEST_CHECK(empty_result.empty());
1204TEST_CASE(
"Surface Area Calculations") {
1207 SUBCASE(
"sumPrimitiveSurfaceArea") {
1212 std::vector<uint> patches = {p1, p2};
1213 std::vector<uint> triangles = {t1};
1214 std::vector<uint> all_prims = {p1, p2, t1};
1216 float patch_area = ctx.sumPrimitiveSurfaceArea(patches);
1217 DOCTEST_CHECK(patch_area == doctest::Approx(10.0f));
1219 float triangle_area = ctx.sumPrimitiveSurfaceArea(triangles);
1220 DOCTEST_CHECK(triangle_area == doctest::Approx(2.0f));
1222 float total_area = ctx.sumPrimitiveSurfaceArea(all_prims);
1223 DOCTEST_CHECK(total_area == doctest::Approx(12.0f));
1226 std::vector<uint> empty_list;
1227 float zero_area = ctx.sumPrimitiveSurfaceArea(empty_list);
1228 DOCTEST_CHECK(zero_area == doctest::Approx(0.0f));
1232TEST_CASE(
"Advanced Area-Weighted Calculations") {
1235 SUBCASE(
"calculatePrimitiveDataAreaWeightedMean comprehensive") {
1242 ctx.setPrimitiveData(p1,
"double_val", 10.0);
1243 ctx.setPrimitiveData(p2,
"double_val", 20.0);
1244 ctx.setPrimitiveData(p3,
"double_val", 30.0);
1246 ctx.setPrimitiveData(p1,
"vec2_val",
make_vec2(1, 2));
1247 ctx.setPrimitiveData(p2,
"vec2_val",
make_vec2(3, 4));
1248 ctx.setPrimitiveData(p3,
"vec2_val",
make_vec2(5, 6));
1250 ctx.setPrimitiveData(p1,
"vec3_val",
make_vec3(1, 2, 3));
1251 ctx.setPrimitiveData(p2,
"vec3_val",
make_vec3(4, 5, 6));
1252 ctx.setPrimitiveData(p3,
"vec3_val",
make_vec3(7, 8, 9));
1254 ctx.setPrimitiveData(p1,
"vec4_val",
make_vec4(1, 2, 3, 4));
1255 ctx.setPrimitiveData(p2,
"vec4_val",
make_vec4(5, 6, 7, 8));
1256 ctx.setPrimitiveData(p3,
"vec4_val",
make_vec4(9, 10, 11, 12));
1258 std::vector<uint> uuids = {p1, p2, p3};
1263 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"double_val", d_mean);
1264 DOCTEST_CHECK(d_mean == doctest::Approx(22.5));
1270 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec2_val", v2_mean);
1271 DOCTEST_CHECK(v2_mean.x == doctest::Approx(3.5f));
1272 DOCTEST_CHECK(v2_mean.y == doctest::Approx(4.5f));
1276 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec3_val", v3_mean);
1277 DOCTEST_CHECK(v3_mean.x == doctest::Approx(4.75f));
1278 DOCTEST_CHECK(v3_mean.y == doctest::Approx(5.75f));
1279 DOCTEST_CHECK(v3_mean.z == doctest::Approx(6.75f));
1283 ctx.calculatePrimitiveDataAreaWeightedMean(uuids,
"vec4_val", v4_mean);
1284 DOCTEST_CHECK(v4_mean.x == doctest::Approx(6.0f));
1285 DOCTEST_CHECK(v4_mean.y == doctest::Approx(7.0f));
1286 DOCTEST_CHECK(v4_mean.z == doctest::Approx(8.0f));
1287 DOCTEST_CHECK(v4_mean.w == doctest::Approx(9.0f));
1290 SUBCASE(
"calculatePrimitiveDataAreaWeightedSum comprehensive") {
1294 ctx.setPrimitiveData(p1,
"double_val", 5.0);
1295 ctx.setPrimitiveData(p2,
"double_val", 10.0);
1297 ctx.setPrimitiveData(p1,
"vec2_val",
make_vec2(1, 2));
1298 ctx.setPrimitiveData(p2,
"vec2_val",
make_vec2(3, 4));
1300 ctx.setPrimitiveData(p1,
"vec3_val",
make_vec3(1, 2, 3));
1301 ctx.setPrimitiveData(p2,
"vec3_val",
make_vec3(4, 5, 6));
1303 ctx.setPrimitiveData(p1,
"vec4_val",
make_vec4(1, 2, 3, 4));
1304 ctx.setPrimitiveData(p2,
"vec4_val",
make_vec4(5, 6, 7, 8));
1306 std::vector<uint> uuids = {p1, p2};
1310 ctx.calculatePrimitiveDataAreaWeightedSum(uuids,
"double_val", d_sum);
1311 DOCTEST_CHECK(d_sum == doctest::Approx(40.0));
1315 ctx.calculatePrimitiveDataAreaWeightedSum(uuids,
"vec2_val", v2_sum);
1316 DOCTEST_CHECK(v2_sum.x == doctest::Approx(11.0f));
1317 DOCTEST_CHECK(v2_sum.y == doctest::Approx(16.0f));
1321 ctx.calculatePrimitiveDataAreaWeightedSum(uuids,
"vec3_val", v3_sum);
1322 DOCTEST_CHECK(v3_sum.x == doctest::Approx(14.0f));
1323 DOCTEST_CHECK(v3_sum.y == doctest::Approx(19.0f));
1324 DOCTEST_CHECK(v3_sum.z == doctest::Approx(24.0f));
1328 ctx.calculatePrimitiveDataAreaWeightedSum(uuids,
"vec4_val", v4_sum);
1329 DOCTEST_CHECK(v4_sum.x == doctest::Approx(17.0f));
1330 DOCTEST_CHECK(v4_sum.y == doctest::Approx(22.0f));
1331 DOCTEST_CHECK(v4_sum.z == doctest::Approx(27.0f));
1332 DOCTEST_CHECK(v4_sum.w == doctest::Approx(32.0f));
1336TEST_CASE(
"Global Data Scaling") {
1339 SUBCASE(
"scalePrimitiveData with label") {
1340 uint p1 = ctx.addPatch();
1341 uint p2 = ctx.addPatch();
1342 uint p3 = ctx.addPatch();
1345 ctx.setPrimitiveData(p1,
"scale_me", 10.0f);
1346 ctx.setPrimitiveData(p2,
"scale_me", 20.0f);
1347 ctx.setPrimitiveData(p3,
"other_data", 5.0f);
1350 capture_cerr cerr_buffer;
1351 ctx.scalePrimitiveData(
"scale_me", 2.0f);
1354 float val1, val2, val3;
1355 ctx.getPrimitiveData(p1,
"scale_me", val1);
1356 ctx.getPrimitiveData(p2,
"scale_me", val2);
1357 ctx.getPrimitiveData(p3,
"other_data", val3);
1359 DOCTEST_CHECK(val1 == doctest::Approx(20.0f));
1360 DOCTEST_CHECK(val2 == doctest::Approx(40.0f));
1361 DOCTEST_CHECK(val3 == doctest::Approx(5.0f));
1364 ctx.scalePrimitiveData(
"non_existent", 3.0f);
1365 DOCTEST_CHECK(cerr_buffer.has_output());
1369TEST_CASE(
"Aggregate Function Edge Cases") {
1372 SUBCASE(
"aggregatePrimitiveDataProduct edge cases") {
1373 uint p1 = ctx.addPatch();
1374 uint p2 = ctx.addPatch();
1375 uint p3 = ctx.addPatch();
1378 ctx.setPrimitiveData(p1,
"zero_test", 0.0f);
1379 ctx.setPrimitiveData(p1,
"normal", 5.0f);
1380 ctx.setPrimitiveData(p2,
"zero_test", 10.0f);
1381 ctx.setPrimitiveData(p2,
"normal", 2.0f);
1383 std::vector<uint> uuids = {p1, p2};
1384 std::vector<std::string> labels = {
"zero_test",
"normal"};
1386 ctx.aggregatePrimitiveDataProduct(uuids, labels,
"product_result");
1389 ctx.getPrimitiveData(p1,
"product_result", result);
1390 DOCTEST_CHECK(result == doctest::Approx(0.0f));
1392 ctx.getPrimitiveData(p2,
"product_result", result);
1393 DOCTEST_CHECK(result == doctest::Approx(20.0f));
1396 ctx.setPrimitiveData(p1,
"neg1", -2.0f);
1397 ctx.setPrimitiveData(p1,
"neg2", -3.0f);
1398 ctx.setPrimitiveData(p2,
"neg1", 4.0f);
1399 ctx.setPrimitiveData(p2,
"neg2", -1.0f);
1401 std::vector<std::string> neg_labels = {
"neg1",
"neg2"};
1402 ctx.aggregatePrimitiveDataProduct(uuids, neg_labels,
"neg_product");
1404 ctx.getPrimitiveData(p1,
"neg_product", result);
1405 DOCTEST_CHECK(result == doctest::Approx(6.0f));
1407 ctx.getPrimitiveData(p2,
"neg_product", result);
1408 DOCTEST_CHECK(result == doctest::Approx(-4.0f));
1412TEST_CASE(
"Data Type Coverage Extensions") {
1415 SUBCASE(
"Primitive data with int2, int3, int4 vectors") {
1416 uint p = ctx.addPatch();
1423 ctx.setPrimitiveData(p,
"vec_int2", v_i2);
1424 ctx.setPrimitiveData(p,
"vec_int3", v_i3);
1425 ctx.setPrimitiveData(p,
"vec_int4", v_i4);
1427 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"vec_int2") == HELIOS_TYPE_INT2);
1428 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"vec_int3") == HELIOS_TYPE_INT3);
1429 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"vec_int4") == HELIOS_TYPE_INT4);
1431 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec_int2") == 2);
1432 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec_int3") == 2);
1433 DOCTEST_CHECK(ctx.getPrimitiveDataSize(p,
"vec_int4") == 2);
1436 std::vector<int2> r_i2;
1437 std::vector<int3> r_i3;
1438 std::vector<int4> r_i4;
1440 ctx.getPrimitiveData(p,
"vec_int2", r_i2);
1441 ctx.getPrimitiveData(p,
"vec_int3", r_i3);
1442 ctx.getPrimitiveData(p,
"vec_int4", r_i4);
1444 DOCTEST_CHECK(r_i2 == v_i2);
1445 DOCTEST_CHECK(r_i3 == v_i3);
1446 DOCTEST_CHECK(r_i4 == v_i4);
1450TEST_CASE(
"Error Handling Edge Cases") {
1453 SUBCASE(
"Data operations with mixed primitive types") {
1454 uint patch = ctx.addPatch();
1459 ctx.setPrimitiveData(patch,
"mixed_data", 1.0f);
1460 ctx.setPrimitiveData(triangle,
"mixed_data", 2.0f);
1461 ctx.setPrimitiveData(voxel,
"mixed_data", 3.0f);
1463 std::vector<uint> mixed_prims = {patch, triangle, voxel};
1467 ctx.calculatePrimitiveDataMean(mixed_prims,
"mixed_data", mean_val);
1468 DOCTEST_CHECK(mean_val == doctest::Approx(2.0f));
1471 ctx.calculatePrimitiveDataSum(mixed_prims,
"mixed_data", sum_val);
1472 DOCTEST_CHECK(sum_val == doctest::Approx(6.0f));
1475 SUBCASE(
"Large dataset stress test") {
1476 std::vector<uint> large_dataset;
1479 for (
int i = 0; i < 1000; ++i) {
1480 uint p = ctx.addPatch();
1481 ctx.setPrimitiveData(p,
"stress_data", (
float) i);
1482 large_dataset.push_back(p);
1486 float mean_val, sum_val;
1487 ctx.calculatePrimitiveDataMean(large_dataset,
"stress_data", mean_val);
1488 ctx.calculatePrimitiveDataSum(large_dataset,
"stress_data", sum_val);
1490 DOCTEST_CHECK(mean_val == doctest::Approx(499.5f));
1491 DOCTEST_CHECK(sum_val == doctest::Approx(499500.0f));
1494 auto filtered = ctx.filterPrimitivesByData(large_dataset,
"stress_data", 500.0f,
">");
1495 DOCTEST_CHECK(filtered.size() == 499);
1499TEST_CASE(
"General Error Handling") {
1502 capture_cerr cerr_buffer;
1505 DOCTEST_CHECK_THROWS_AS(center = ctx.getPatchCenter(tri), std::runtime_error);
1509 std::vector<uint> vlist{vox};
1510 DOCTEST_CHECK_THROWS_AS(ctx.rotatePrimitive(vlist,
PI_F / 4.f,
"a"), std::runtime_error);
1513TEST_CASE(
"Data Type Consistency and Caching") {
1516 SUBCASE(
"Primitive data type caching") {
1518 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataType(
"test_label"));
1525 ctx.setPrimitiveData(patch1,
"temperature", 25.5f);
1526 ctx.setPrimitiveData(patch2,
"temperature", 30.2f);
1529 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"temperature") == HELIOS_TYPE_FLOAT);
1532 ctx.setPrimitiveData(patch1,
"leaf_id", 123);
1533 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"leaf_id") == HELIOS_TYPE_INT);
1536 DOCTEST_CHECK_THROWS(ctx.getPrimitiveDataType(
"nonexistent"));
1539 SUBCASE(
"Object data type caching") {
1541 DOCTEST_CHECK_THROWS(ctx.getObjectDataType(
"test_obj_label"));
1548 ctx.setObjectData(box1,
"volume", 1.0);
1549 ctx.setObjectData(box2,
"volume", 2.5);
1552 DOCTEST_CHECK(ctx.getObjectDataType(
"volume") == HELIOS_TYPE_DOUBLE);
1555 ctx.setObjectData(box1,
"material_id",
static_cast<uint>(42));
1556 DOCTEST_CHECK(ctx.getObjectDataType(
"material_id") == HELIOS_TYPE_UINT);
1559 DOCTEST_CHECK_THROWS(ctx.getObjectDataType(
"nonexistent"));
1562 SUBCASE(
"Type consistency enforcement - compatible numeric casting") {
1566 ctx.setPrimitiveData(patch,
"value", 10.5f);
1567 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"value") == HELIOS_TYPE_FLOAT);
1573 capture_cerr cerr_buffer;
1574 ctx.setPrimitiveData(patch2,
"value", 20);
1578 ctx.getPrimitiveData(patch,
"value", val1);
1579 ctx.getPrimitiveData(patch2,
"value", val2);
1580 DOCTEST_CHECK(val1 == doctest::Approx(10.5f));
1581 DOCTEST_CHECK(val2 == doctest::Approx(20.0f));
1584 DOCTEST_CHECK(cerr_buffer.get_captured_output().find(
"WARNING") != std::string::npos);
1585 DOCTEST_CHECK(cerr_buffer.get_captured_output().find(
"Type casting") != std::string::npos);
1588 SUBCASE(
"Type consistency enforcement - incompatible types") {
1592 ctx.setObjectData(box,
"material", std::string(
"wood"));
1593 DOCTEST_CHECK(ctx.getObjectDataType(
"material") == HELIOS_TYPE_STRING);
1599 DOCTEST_CHECK_THROWS_AS(ctx.setObjectData(box2,
"material", 3.14f), std::runtime_error);
1602 SUBCASE(
"Multiple data labels per primitive/object") {
1606 ctx.setPrimitiveData(tri,
"temperature", 25.0f);
1607 ctx.setPrimitiveData(tri,
"id", 100);
1608 ctx.setPrimitiveData(tri,
"name", std::string(
"leaf1"));
1609 ctx.setPrimitiveData(tri,
"position",
make_vec3(0.5f, 0.5f, 0.0f));
1612 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"temperature") == HELIOS_TYPE_FLOAT);
1613 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"id") == HELIOS_TYPE_INT);
1614 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"name") == HELIOS_TYPE_STRING);
1615 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"position") == HELIOS_TYPE_VEC3);
1619 ctx.setPrimitiveData(tri2,
"temperature", 30.0f);
1620 ctx.setPrimitiveData(tri2,
"id", 101);
1621 ctx.setPrimitiveData(tri2,
"name", std::string(
"leaf2"));
1622 ctx.setPrimitiveData(tri2,
"position",
make_vec3(1.5f, 0.5f, 0.0f));
1630 ctx.getPrimitiveData(tri2,
"temperature", temp);
1631 ctx.getPrimitiveData(tri2,
"id",
id);
1632 ctx.getPrimitiveData(tri2,
"name", name);
1633 ctx.getPrimitiveData(tri2,
"position", pos);
1635 DOCTEST_CHECK(temp == doctest::Approx(30.0f));
1636 DOCTEST_CHECK(
id == 101);
1637 DOCTEST_CHECK(name ==
"leaf2");
1638 DOCTEST_CHECK(pos.x == doctest::Approx(1.5f));
1641 SUBCASE(
"Cross-contamination prevention") {
1644 uint sphere = ctx.addSphereObject(10,
make_vec3(0, 0, 0), 1.0f);
1647 ctx.setPrimitiveData(patch,
"value", 42);
1648 ctx.setObjectData(sphere,
"value", 3.14f);
1651 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"value") == HELIOS_TYPE_INT);
1652 DOCTEST_CHECK(ctx.getObjectDataType(
"value") == HELIOS_TYPE_FLOAT);
1655 SUBCASE(
"Vector data type consistency") {
1660 std::vector<float> temps1 = {20.0f, 25.0f, 30.0f};
1661 std::vector<float> temps2 = {22.0f, 27.0f, 32.0f};
1663 ctx.setPrimitiveData(vox1,
"temperature_profile", temps1);
1664 ctx.setPrimitiveData(vox2,
"temperature_profile", temps2);
1667 DOCTEST_CHECK(ctx.getPrimitiveDataType(
"temperature_profile") == HELIOS_TYPE_FLOAT);