1.3.49
 
Loading...
Searching...
No Matches
GeometryHandler.cpp
Go to the documentation of this file.
1
16#include "GeometryHandler.h"
17
18void GeometryHandler::allocateBufferSize(size_t primitive_count, VisualizerGeometryType geometry_type) {
19
20 char vertex_count = getVertexCount(geometry_type);
21
22 face_index_data[geometry_type].reserve(face_index_data[geometry_type].size() + primitive_count);
23 vertex_data[geometry_type].reserve(vertex_data[geometry_type].size() + primitive_count * vertex_count * 3);
24 normal_data[geometry_type].reserve(normal_data[geometry_type].size() + primitive_count * vertex_count * 3);
25 color_data[geometry_type].reserve(color_data[geometry_type].size() + primitive_count * 4);
26 uv_data[geometry_type].reserve(uv_data[geometry_type].size() + primitive_count * vertex_count * 2);
27 texture_flag_data[geometry_type].reserve(texture_flag_data[geometry_type].size() + primitive_count);
28 texture_ID_data[geometry_type].reserve(texture_ID_data[geometry_type].size() + primitive_count);
29 coordinate_flag_data[geometry_type].reserve(coordinate_flag_data[geometry_type].size() + primitive_count);
30 delete_flag_data[geometry_type].reserve(delete_flag_data[geometry_type].size() + primitive_count);
31 context_geometry_flag_data[geometry_type].reserve(context_geometry_flag_data[geometry_type].size() + primitive_count);
32 size_data[geometry_type].reserve(size_data[geometry_type].size() + primitive_count);
33}
34
35void GeometryHandler::addGeometry(size_t UUID, const VisualizerGeometryType &geometry_type, const std::vector<helios::vec3> &vertices, const helios::RGBAcolor &color, const std::vector<helios::vec2> &uvs, int textureID, bool override_texture_color,
36 bool has_glyph_texture, uint coordinate_system, bool visible_flag, bool iscontextgeometry, int size) {
37
38 char vertex_count = getVertexCount(geometry_type);
39
40#ifdef HELIOS_DEBUG
41 assert(vertices.size() == vertex_count);
42 assert(uvs.empty() || uvs.size() == vertex_count);
43#endif
44
45 std::vector<helios::vec3> vertices_copy = vertices; // make a copy so it can be modified
46
47 bool geometry_is_new = false;
48 if (!doesGeometryExist(UUID)) {
49 registerUUID(UUID, geometry_type);
50 geometry_is_new = true;
51 }
52
53 if (coordinate_system == 0) { // No vertex transformation (i.e., identity matrix)
54
55 // NOTE for vertex positions: OpenGL window coordinates range from -1 to 1, but our rectangle coordinates are from 0 to 1 ---- need to convert
56 for (auto &vertex: vertices_copy) {
57 vertex.x = 2.f * vertex.x - 1.f;
58 vertex.y = 2.f * vertex.y - 1.f;
59 }
60 }
61
62 size_t vertex_index = UUID_map.at(UUID).vertex_index;
63 size_t normal_index = UUID_map.at(UUID).normal_index;
64 size_t uv_index = UUID_map.at(UUID).uv_index;
65 size_t color_index = UUID_map.at(UUID).color_index;
66 size_t texture_flag_index = UUID_map.at(UUID).texture_flag_index;
67 size_t texture_ID_index = UUID_map.at(UUID).texture_ID_index;
68
69 for (char i = 0; i < vertex_count; i++) {
70
71 if (geometry_is_new) {
72 face_index_data[geometry_type].push_back(static_cast<int>(visible_flag_data[geometry_type].size()));
73
74 vertex_data[geometry_type].push_back(vertices_copy.at(i).x);
75 vertex_data[geometry_type].push_back(vertices_copy.at(i).y);
76 vertex_data[geometry_type].push_back(vertices_copy.at(i).z);
77 } else {
78 // face index doesn't need to be updated
79
80 vertex_data[geometry_type].at(vertex_index) = vertices_copy.at(i).x;
81 vertex_data[geometry_type].at(vertex_index + 1) = vertices_copy.at(i).y;
82 vertex_data[geometry_type].at(vertex_index + 2) = vertices_copy.at(i).z;
83 vertex_index += 3;
84 }
85
86 if ((geometry_type == GEOMETRY_TYPE_TRIANGLE || geometry_type == GEOMETRY_TYPE_RECTANGLE) && !uvs.empty()) { // if (u, v)'s are provided, color triangle based on texture map image
87
88 if (geometry_is_new) {
89 uv_data[geometry_type].push_back(uvs.at(i).x);
90 uv_data[geometry_type].push_back(1.f - uvs.at(i).y);
91
92 if (i == 0) { // only need to do this one time
93 if (has_glyph_texture) {
94 texture_flag_data[geometry_type].push_back(3); // 3 means use RGB for color and red channel of texture for alpha
95 } else if (override_texture_color) { // if texture color is overridden, color primitive based on RGB color but use texture transparence for alpha mask
96 texture_flag_data[geometry_type].push_back(2); // 2 means use RGB for color and texture transparency for alpha
97 } else {
98 texture_flag_data[geometry_type].push_back(1); // 1 means use texture for color and transparency for alpha
99 }
100 texture_ID_data[geometry_type].push_back(textureID);
101 }
102 } else {
103 uv_data[geometry_type].at(uv_index) = uvs.at(i).x;
104 uv_data[geometry_type].at(uv_index + 1) = 1.f - uvs.at(i).y;
105 uv_index += 2;
106
107 if (i == 0) { // only need to do this one time
108 if (has_glyph_texture) {
109 texture_flag_data[geometry_type].at(texture_flag_index) = 3; // 3 means use RGB for color and red channel of texture for alpha
110 } else if (override_texture_color) { // if texture color is overridden, color primitive based on RGB color but use texture transparence for alpha mask
111 texture_flag_data[geometry_type].at(texture_flag_index) = 2; // 2 means use RGB for color and texture transparency for alpha
112 } else {
113 texture_flag_data[geometry_type].at(texture_flag_index) = 1; // 1 means use texture for color and transparency for alpha
114 }
115 texture_flag_index++;
116 texture_ID_data[geometry_type].at(texture_ID_index) = textureID;
117 texture_ID_index++;
118 }
119 }
120 } else { // if (u,v)'s are not provided, color primitive based on RGB color
121
122 if (geometry_is_new) {
123 uv_data[geometry_type].push_back(0.f);
124 uv_data[geometry_type].push_back(0.f);
125
126 if (i == 0) { // only need to do this one time
127 if (has_glyph_texture) {
128 texture_flag_data[geometry_type].push_back(3); // 3 means use RGB for color and red channel of texture for alpha
129 texture_ID_data[geometry_type].push_back(textureID);
130 } else {
131 texture_flag_data[geometry_type].push_back(0); // 0 means use RGB color
132 texture_ID_data[geometry_type].push_back(0);
133 }
134 }
135 } else {
136 uv_data[geometry_type].at(uv_index) = 0.f;
137 uv_data[geometry_type].at(uv_index + 1) = 0.f;
138 uv_index += 2;
139
140 if (i == 0) { // only need to do this one time
141 if (has_glyph_texture) {
142 texture_flag_data[geometry_type].at(texture_flag_index) = 3; // 3 means use RGB for color and red channel of texture for alpha
143 texture_ID_data[geometry_type].at(texture_ID_index) = textureID;
144 } else {
145 texture_flag_data[geometry_type].at(texture_flag_index) = 0; // 0 means use RGB color
146 texture_ID_data[geometry_type].at(texture_ID_index) = 0;
147 }
148 texture_flag_index++;
149 texture_ID_index++;
150 }
151 }
152 }
153 }
154
155 helios::vec3 normal;
156 if (geometry_type == GEOMETRY_TYPE_TRIANGLE || geometry_type == GEOMETRY_TYPE_RECTANGLE) {
157 normal = normalize(cross(vertices_copy.at(1) - vertices_copy.at(0), vertices_copy.at(2) - vertices_copy.at(0)));
158 }
159 if (geometry_is_new) {
160 normal_data[geometry_type].push_back(normal.x);
161 normal_data[geometry_type].push_back(normal.y);
162 normal_data[geometry_type].push_back(normal.z);
163
164 color_data[geometry_type].push_back(color.r);
165 color_data[geometry_type].push_back(color.g);
166 color_data[geometry_type].push_back(color.b);
167 color_data[geometry_type].push_back(color.a);
168
169 coordinate_flag_data[geometry_type].push_back(coordinate_system);
170
171 visible_flag_data[geometry_type].push_back(visible_flag);
172
173 delete_flag_data[geometry_type].push_back(false);
174
175 context_geometry_flag_data[geometry_type].push_back(iscontextgeometry);
176
177 size_data[geometry_type].push_back(static_cast<float>(size));
178 } else {
179 normal_data[geometry_type].at(normal_index) = normal.x;
180 normal_data[geometry_type].at(normal_index + 1) = normal.y;
181 normal_data[geometry_type].at(normal_index + 2) = normal.z;
182
183 color_data[geometry_type].at(color_index) = color.r;
184 color_data[geometry_type].at(color_index + 1) = color.g;
185 color_data[geometry_type].at(color_index + 2) = color.b;
186 color_data[geometry_type].at(color_index + 3) = color.a;
187 }
188
189 markDirty(UUID);
190}
191
192bool GeometryHandler::doesGeometryExist(size_t UUID) const {
193 return (UUID_map.find(UUID) != UUID_map.end());
194}
195
196std::vector<size_t> GeometryHandler::getAllGeometryIDs() const {
197 std::vector<size_t> result;
198 result.reserve(UUID_map.size());
199 for (const auto &[UUID, primitivemap]: UUID_map) {
200 if (getDeleteFlag(UUID)) {
201 // Only include non-deleted geometries
202 continue;
203 }
204 result.push_back(UUID);
205 }
206 return result;
207}
208
209size_t GeometryHandler::getPrimitiveCount(bool include_deleted) const {
210 size_t count = 0;
211 if (include_deleted) {
212 for (auto &type: all_geometry_types) {
213 count += delete_flag_data.at(type).size();
214 }
215 return count;
216 }
217
218 for (auto &type: all_geometry_types) {
219 count += std::count(delete_flag_data.at(type).begin(), delete_flag_data.at(type).end(), false);
220 }
221 return count;
222}
223
224[[nodiscard]] size_t GeometryHandler::getRectangleCount(bool include_deleted) const {
225 VisualizerGeometryType type = GEOMETRY_TYPE_RECTANGLE;
226 if (include_deleted) {
227 return delete_flag_data.at(type).size();
228 }
229
230 size_t count = std::count(delete_flag_data.at(type).begin(), delete_flag_data.at(type).end(), false);
231 return count;
232}
233
234[[nodiscard]] size_t GeometryHandler::getTriangleCount(bool include_deleted) const {
235 VisualizerGeometryType type = GEOMETRY_TYPE_TRIANGLE;
236 if (include_deleted) {
237 return delete_flag_data.at(type).size();
238 }
239
240 size_t count = std::count(delete_flag_data.at(type).begin(), delete_flag_data.at(type).end(), false);
241 return count;
242}
243
244[[nodiscard]] size_t GeometryHandler::getPointCount(bool include_deleted) const {
245 VisualizerGeometryType type = GEOMETRY_TYPE_POINT;
246 if (include_deleted) {
247 return delete_flag_data.at(type).size();
248 }
249
250 size_t count = std::count(delete_flag_data.at(type).begin(), delete_flag_data.at(type).end(), false);
251 return count;
252}
253
254[[nodiscard]] size_t GeometryHandler::getLineCount(bool include_deleted) const {
255 VisualizerGeometryType type = GEOMETRY_TYPE_LINE;
256 if (include_deleted) {
257 return delete_flag_data.at(type).size();
258 }
259
260 size_t count = std::count(delete_flag_data.at(type).begin(), delete_flag_data.at(type).end(), false);
261 return count;
262}
263
264const std::vector<int> *GeometryHandler::getFaceIndexData_ptr(VisualizerGeometryType geometry_type) const {
265#ifdef HELIOS_DEBUG
266 assert(face_index_data.find(geometry_type) != face_index_data.end());
267#endif
268 return &face_index_data.at(geometry_type);
269}
270
271void GeometryHandler::setVertices(size_t UUID, const std::vector<helios::vec3> &vertices) {
272
273#ifdef HELIOS_DEBUG
274 assert(UUID_map.find(UUID) != UUID_map.end());
275#endif
276
277 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
278
279 const char vertex_count = getVertexCount(index_map.geometry_type);
280
281#ifdef HELIOS_DEBUG
282 assert(vertices.size() == vertex_count);
283#endif
284
285 const size_t vertex_ind = index_map.vertex_index;
286
287 int ii = 0;
288 for (int i = 0; i < vertex_count; i++) {
289 vertex_data[index_map.geometry_type].at(vertex_ind + ii + 0) = vertices.at(i).x;
290 vertex_data[index_map.geometry_type].at(vertex_ind + ii + 1) = vertices.at(i).y;
291 vertex_data[index_map.geometry_type].at(vertex_ind + ii + 2) = vertices.at(i).z;
292 ii += 3;
293 }
294
295 const size_t normal_ind = index_map.normal_index;
296
297 const helios::vec3 normal = normalize(cross(vertices.at(1) - vertices.at(0), vertices.at(2) - vertices.at(0)));
298 normal_data[index_map.geometry_type].at(normal_ind + ii + 0) = normal.x;
299 normal_data[index_map.geometry_type].at(normal_ind + ii + 1) = normal.y;
300 normal_data[index_map.geometry_type].at(normal_ind + ii + 2) = normal.z;
301
302 markDirty(UUID);
303}
304
305std::vector<helios::vec3> GeometryHandler::getVertices(size_t UUID) const {
306
307#ifdef HELIOS_DEBUG
308 assert(UUID_map.find(UUID) != UUID_map.end());
309#endif
310
311 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
312
313 const size_t vertex_ind = index_map.vertex_index;
314
315 const char vertex_count = getVertexCount(index_map.geometry_type);
316
317 std::vector<helios::vec3> vertices(vertex_count);
318
319 for (int i = 0; i < vertex_count; i++) {
320 vertices.at(i).x = vertex_data.at(index_map.geometry_type).at(vertex_ind + i * 3 + 0);
321 vertices.at(i).y = vertex_data.at(index_map.geometry_type).at(vertex_ind + i * 3 + 1);
322 vertices.at(i).z = vertex_data.at(index_map.geometry_type).at(vertex_ind + i * 3 + 2);
323 }
324
325 return vertices;
326}
327
328const std::vector<float> *GeometryHandler::getVertexData_ptr(VisualizerGeometryType geometry_type) const {
329#ifdef HELIOS_DEBUG
330 assert(vertex_data.find(geometry_type) != vertex_data.end());
331#endif
332 return &vertex_data.at(geometry_type);
333}
334
336
337#ifdef HELIOS_DEBUG
338 assert(UUID_map.find(UUID) != UUID_map.end());
339#endif
340
341 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
342
343 const size_t normal_ind = index_map.normal_index;
344
345 helios::vec3 normal;
346
347 normal.x = normal_data.at(index_map.geometry_type).at(normal_ind + 0);
348 normal.y = normal_data.at(index_map.geometry_type).at(normal_ind + 1);
349 normal.z = normal_data.at(index_map.geometry_type).at(normal_ind + 2);
350
351 return normal;
352}
353
354const std::vector<float> *GeometryHandler::getNormalData_ptr(VisualizerGeometryType geometry_type) const {
355#ifdef HELIOS_DEBUG
356 assert(normal_data.find(geometry_type) != normal_data.end());
357#endif
358 return &normal_data.at(geometry_type);
359}
360
361void GeometryHandler::setColor(size_t UUID, const helios::RGBAcolor &color) {
362
363#ifdef HELIOS_DEBUG
364 assert(UUID_map.find(UUID) != UUID_map.end());
365#endif
366
367 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
368
369 const size_t color_ind = index_map.color_index;
370
371 color_data[index_map.geometry_type].at(color_ind + 0) = color.r;
372 color_data[index_map.geometry_type].at(color_ind + 1) = color.g;
373 color_data[index_map.geometry_type].at(color_ind + 2) = color.b;
374 color_data[index_map.geometry_type].at(color_ind + 3) = color.a;
375
376 markDirty(UUID);
377}
378
380
381#ifdef HELIOS_DEBUG
382 assert(UUID_map.find(UUID) != UUID_map.end());
383#endif
384
385 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
386
387 const size_t color_ind = index_map.color_index;
388
389 const helios::RGBAcolor color{color_data.at(index_map.geometry_type).at(color_ind), color_data.at(index_map.geometry_type).at(color_ind + 1), color_data.at(index_map.geometry_type).at(color_ind + 2),
390 color_data.at(index_map.geometry_type).at(color_ind + 3)};
391
392 return color;
393}
394
395const std::vector<float> *GeometryHandler::getColorData_ptr(VisualizerGeometryType geometry_type) const {
396#ifdef HELIOS_DEBUG
397 assert(color_data.find(geometry_type) != color_data.end());
398#endif
399 return &color_data.at(geometry_type);
400}
401
402void GeometryHandler::setUVs(size_t UUID, const std::vector<helios::vec2> &uvs) {
403
404#ifdef HELIOS_DEBUG
405 assert(UUID_map.find(UUID) != UUID_map.end());
406#endif
407
408 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
409
410 if (index_map.geometry_type == GEOMETRY_TYPE_LINE || index_map.geometry_type == GEOMETRY_TYPE_POINT) {
411 // These types do not have texture mapping
412 return;
413 }
414
415 const char vertex_count = getVertexCount(index_map.geometry_type);
416
417#ifdef HELIOS_DEBUG
418 assert(uvs.size() == vertex_count);
419#endif
420
421 const size_t uv_ind = index_map.uv_index;
422
423 int ii = 0;
424 for (int i = 0; i < vertex_count; i++) {
425 uv_data.at(index_map.geometry_type).at(uv_ind + ii) = uvs.at(i).x;
426 uv_data.at(index_map.geometry_type).at(uv_ind + ii + 1) = uvs.at(i).y;
427 ii += 2;
428 }
429
430 markDirty(UUID);
431}
432
433std::vector<helios::vec2> GeometryHandler::getUVs(size_t UUID) const {
434
435#ifdef HELIOS_DEBUG
436 assert(UUID_map.find(UUID) != UUID_map.end());
437#endif
438
439 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
440
441 const size_t uv_ind = index_map.uv_index;
442
443 const char vertex_count = getVertexCount(index_map.geometry_type);
444
445 std::vector<helios::vec2> uvs(vertex_count);
446
447 for (int i = 0; i < vertex_count; i++) {
448 uvs.at(i).x = uv_data.at(index_map.geometry_type).at(uv_ind + i * 2);
449 uvs.at(i).x = uv_data.at(index_map.geometry_type).at(uv_ind + i * 2 + 1);
450 }
451
452 return uvs;
453}
454
455const std::vector<float> *GeometryHandler::getUVData_ptr(VisualizerGeometryType geometry_type) const {
456#ifdef HELIOS_DEBUG
457 assert(uv_data.find(geometry_type) != uv_data.end());
458#endif
459 return &uv_data.at(geometry_type);
460}
461
462void GeometryHandler::setTextureID(size_t UUID, int textureID) {
463
464#ifdef HELIOS_DEBUG
465 assert(UUID_map.find(UUID) != UUID_map.end());
466#endif
467
468 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
469
470 if (index_map.geometry_type == GEOMETRY_TYPE_LINE || index_map.geometry_type == GEOMETRY_TYPE_POINT) {
471 // These types do not have texture mapping
472 return;
473 }
474
475 const size_t texture_ind = index_map.texture_ID_index;
476
477 texture_ID_data.at(index_map.geometry_type).at(texture_ind) = textureID;
478
479 markDirty(UUID);
480}
481
482int GeometryHandler::getTextureID(size_t UUID) const {
483
484#ifdef HELIOS_DEBUG
485 assert(UUID_map.find(UUID) != UUID_map.end());
486#endif
487
488 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
489
490 const size_t texture_ID_ind = index_map.texture_ID_index;
491
492 return texture_ID_data.at(index_map.geometry_type).at(texture_ID_ind);
493}
494
495const std::vector<int> *GeometryHandler::getTextureIDData_ptr(VisualizerGeometryType geometry_type) const {
496#ifdef HELIOS_DEBUG
497 assert(texture_ID_data.find(geometry_type) != texture_ID_data.end());
498#endif
499 return &texture_ID_data.at(geometry_type);
500}
501
503
504#ifdef HELIOS_DEBUG
505 assert(UUID_map.find(UUID) != UUID_map.end());
506#endif
507
508 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
509
510 if (index_map.geometry_type == GEOMETRY_TYPE_LINE || index_map.geometry_type == GEOMETRY_TYPE_POINT) {
511 // These types do not have texture mapping
512 return;
513 }
514
515 const size_t texture_flag_ind = index_map.texture_flag_index;
516
517 const int current_flag = texture_flag_data.at(index_map.geometry_type).at(texture_flag_ind);
518 if (current_flag == 1) {
519 // \todo This might be a problem in the case that the primitive does not have a texture with a transparency. In that case we would want to set to 0
520 texture_flag_data.at(index_map.geometry_type).at(texture_flag_ind) = 2;
521 }
522
523 markDirty(UUID);
524}
525
527
528#ifdef HELIOS_DEBUG
529 assert(UUID_map.find(UUID) != UUID_map.end());
530#endif
531
532 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
533
534 if (index_map.geometry_type == GEOMETRY_TYPE_LINE || index_map.geometry_type == GEOMETRY_TYPE_POINT) {
535 // These types do not have texture mapping
536 return;
537 }
538
539 const size_t texture_flag_ind = index_map.texture_flag_index;
540
541 // \todo This might be a problem in the case that the primitive does not have a texture image. In this case, we would want to set to 0.
542 texture_flag_data.at(index_map.geometry_type).at(texture_flag_ind) = 1;
543
544 markDirty(UUID);
545}
546
547const std::vector<int> *GeometryHandler::getTextureFlagData_ptr(VisualizerGeometryType geometry_type) const {
548#ifdef HELIOS_DEBUG
549 assert(texture_flag_data.find(geometry_type) != texture_flag_data.end());
550#endif
551 return &texture_flag_data.at(geometry_type);
552}
553
554void GeometryHandler::setVisibility(size_t UUID, bool isvisible) {
555
556#ifdef HELIOS_DEBUG
557 assert(UUID_map.find(UUID) != UUID_map.end());
558#endif
559
560 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
561
562 const size_t visibile_ind = index_map.visible_index;
563
564 visible_flag_data.at(index_map.geometry_type).at(visibile_ind) = static_cast<char>(isvisible);
565
566 markDirty(UUID);
567}
568
569bool GeometryHandler::isPrimitiveVisible(size_t UUID) const {
570
571#ifdef HELIOS_DEBUG
572 assert(UUID_map.find(UUID) != UUID_map.end());
573#endif
574
575 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
576
577 const size_t visible_ind = index_map.visible_index;
578
579 return static_cast<bool>(visible_flag_data.at(index_map.geometry_type).at(visible_ind));
580}
581
582const std::vector<char> *GeometryHandler::getVisibilityFlagData_ptr(VisualizerGeometryType geometry_type) const {
583#ifdef HELIOS_DEBUG
584 assert(visible_flag_data.find(geometry_type) != visible_flag_data.end());
585#endif
586 return &visible_flag_data.at(geometry_type);
587}
588
589const std::vector<int> *GeometryHandler::getCoordinateFlagData_ptr(VisualizerGeometryType geometry_type) const {
590#ifdef HELIOS_DEBUG
591 assert(coordinate_flag_data.find(geometry_type) != coordinate_flag_data.end());
592#endif
593 return &coordinate_flag_data.at(geometry_type);
594}
595
596void GeometryHandler::setSize(size_t UUID, float size) {
597
598#ifdef HELIOS_DEBUG
599 assert(UUID_map.find(UUID) != UUID_map.end());
600#endif
601
602 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
603
604 const size_t size_ind = index_map.size_index;
605
606 size_data[index_map.geometry_type].at(size_ind) = size;
607
608 markDirty(UUID);
609}
610
611float GeometryHandler::getSize(size_t UUID) const {
612
613#ifdef HELIOS_DEBUG
614 assert(UUID_map.find(UUID) != UUID_map.end());
615#endif
616
617 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
618
619 const size_t size_ind = index_map.size_index;
620
621 return size_data.at(index_map.geometry_type).at(size_ind);
622}
623
624const std::vector<float> *GeometryHandler::getSizeData_ptr(VisualizerGeometryType geometry_type) const {
625#ifdef HELIOS_DEBUG
626 assert(size_data.find(geometry_type) != size_data.end());
627#endif
628 return &size_data.at(geometry_type);
629}
630
631bool GeometryHandler::getDeleteFlag(size_t UUID) const {
632#ifdef HELIOS_DEBUG
633 assert(UUID_map.find(UUID) != UUID_map.end());
634#endif
635
636 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
637
638 const size_t delete_flag_ind = index_map.delete_flag_index;
639
640 return delete_flag_data.at(index_map.geometry_type).at(delete_flag_ind);
641}
642
644
645#ifdef HELIOS_DEBUG
646 assert(UUID_map.find(UUID) != UUID_map.end());
647#endif
648
649 const PrimitiveIndexMap &index_map = UUID_map.at(UUID);
650
651 delete_flag_data.at(index_map.geometry_type).at(index_map.delete_flag_index) = true;
652 visible_flag_data.at(index_map.geometry_type).at(index_map.visible_index) = false;
653
654 markDirty(UUID);
655
656 deleted_primitive_count++;
657
658 if (deleted_primitive_count > 250000) {
659 defragmentBuffers();
660 }
661}
662
663void GeometryHandler::deleteGeometry(const std::vector<size_t> &UUIDs) {
664 for (const auto &UUID: UUIDs) {
665 deleteGeometry(UUID);
666 }
667}
668
670
671 for (const auto &geometry_type: all_geometry_types) {
672 if (vertex_data.find(geometry_type) == vertex_data.end()) {
673 continue;
674 }
675
676 face_index_data.at(geometry_type).clear();
677 vertex_data.at(geometry_type).clear();
678 normal_data.at(geometry_type).clear();
679 uv_data.at(geometry_type).clear();
680 color_data.at(geometry_type).clear();
681 texture_flag_data.at(geometry_type).clear();
682 texture_ID_data.at(geometry_type).clear();
683 coordinate_flag_data.at(geometry_type).clear();
684 visible_flag_data.at(geometry_type).clear();
685 context_geometry_flag_data.at(geometry_type).clear();
686 delete_flag_data.at(geometry_type).clear();
687 size_data.at(geometry_type).clear();
688 }
689
690 UUID_map.clear();
691
692 deleted_primitive_count = 0;
693}
694
696
697 for (const auto &geometry_type: all_geometry_types) {
698 if (vertex_data.find(geometry_type) == vertex_data.end()) {
699 continue;
700 }
701
702 for (size_t i = 0; i < context_geometry_flag_data.at(geometry_type).size(); i++) {
703 assert(context_geometry_flag_data.at(geometry_type).size() == delete_flag_data.at(geometry_type).size());
704 if (context_geometry_flag_data.at(geometry_type).at(i)) {
705 delete_flag_data.at(geometry_type).at(i) = true;
706 // visible_flag_data.at(geometry_type).at(i) = false;
707 deleted_primitive_count++;
708 }
709 }
710 }
711
712 defragmentBuffers();
713}
714
716
717 xbounds.x = 1e8;
718 xbounds.y = -1e8;
719 ybounds.x = 1e8;
720 ybounds.y = -1e8;
721 zbounds.x = 1e8;
722 zbounds.y = -1e8;
723
724 for (const auto &[UUID, index_map]: UUID_map) {
725 // Only primitives with Cartesian coordinates should be included in bounding box
726 if (coordinate_flag_data.at(index_map.geometry_type).at(index_map.coordinate_flag_index) == 0) {
727 continue;
728 }
729
730 const auto &vertices = getVertices(UUID);
731
732 for (const auto &vertex: vertices) {
733 if (vertex.x < xbounds.x) {
734 xbounds.x = vertex.x;
735 }
736 if (vertex.x > xbounds.y) {
737 xbounds.y = vertex.x;
738 }
739 if (vertex.y < ybounds.x) {
740 ybounds.x = vertex.y;
741 }
742 if (vertex.y > ybounds.y) {
743 ybounds.y = vertex.y;
744 }
745 if (vertex.z < zbounds.x) {
746 zbounds.x = vertex.z;
747 }
748 if (vertex.z > zbounds.y) {
749 zbounds.y = vertex.z;
750 }
751 }
752 }
753}
754
756
757 helios::vec2 xbounds, ybounds, zbounds;
758 getDomainBoundingBox(xbounds, ybounds, zbounds);
759
760 radius = {0.5f * (xbounds.y - xbounds.x), 0.5f * (ybounds.y - ybounds.x), 0.5f * (zbounds.y - zbounds.x)};
761
762 center = {xbounds.x + radius.x, ybounds.x + radius.y, zbounds.x + radius.z};
763}
764
766 std::uniform_int_distribution<size_t> dist(1, (std::numeric_limits<size_t>::max)());
767 size_t UUID = 0;
768 while (UUID == 0 || UUID_map.find(UUID) != UUID_map.end()) {
769 UUID = dist(random_generator);
770 }
771 return UUID;
772}
773
774const GeometryHandler::PrimitiveIndexMap &GeometryHandler::getIndexMap(size_t UUID) const {
775#ifdef HELIOS_DEBUG
776 assert(UUID_map.find(UUID) != UUID_map.end());
777#endif
778 return UUID_map.at(UUID);
779}
780
781void GeometryHandler::defragmentBuffers() {
782
783 // If no primitives were deleted, nothing to do
784 if (deleted_primitive_count == 0) {
785 return;
786 }
787
788 // Iterate each geometry type
789
790 for (const auto &geometry_type: all_geometry_types) {
791 if (vertex_data.find(geometry_type) == vertex_data.end()) {
792 continue;
793 }
794
795 auto &oldFace = face_index_data.at(geometry_type);
796 auto &oldVertex = vertex_data.at(geometry_type);
797 auto &oldNormal = normal_data.at(geometry_type);
798 auto &oldUV = uv_data.at(geometry_type);
799 auto &oldColor = color_data.at(geometry_type);
800 auto &oldTexFlag = texture_flag_data.at(geometry_type);
801 auto &oldTexID = texture_ID_data.at(geometry_type);
802 auto &oldCoordFlag = coordinate_flag_data.at(geometry_type);
803 auto &oldVisible = visible_flag_data.at(geometry_type);
804 auto &oldContextFlag = context_geometry_flag_data.at(geometry_type);
805 auto &oldDeleteFlag = delete_flag_data.at(geometry_type);
806 auto &oldSize = size_data.at(geometry_type);
807
808 // New buffers
809 std::vector<VisualizerGeometryType> newType;
810 std::vector<float> newVertex, newNormal, newUV, newColor, newSize;
811 std::vector<int> newFace, newTexFlag, newTexID, newCoordFlag;
812 std::vector<bool> newDeleteFlag, newContextFlag;
813 std::vector<char> newVisible;
814
815 // Collect UUIDs to drop
816 std::vector<size_t> toErase;
817
818 // Walk the UUID_map and rebuild entries
819 for (auto &[UUID, prim]: UUID_map) {
820 if (prim.geometry_type != geometry_type) {
821 continue; // this UUID is another geometry type
822 }
823
824 // If marked deleted => drop
825 if (oldDeleteFlag[prim.delete_flag_index]) {
826 toErase.push_back(UUID);
827 continue;
828 }
829
830 // Otherwise copy its slices into the new buffers
831 const char vcount = getVertexCount(prim.geometry_type);
832 const size_t v3 = static_cast<size_t>(vcount) * 3;
833 const size_t v2 = static_cast<size_t>(vcount) * 2;
834
835 // Record new base indices
836 const size_t fi = newFace.size();
837 const size_t vi = newVertex.size();
838 const size_t ni = newNormal.size();
839 const size_t ui = newUV.size();
840 const size_t ci = newColor.size();
841 const size_t tfi = newTexFlag.size();
842 const size_t tidi = newTexID.size();
843 const size_t cfi = newCoordFlag.size();
844 const size_t vi2 = newVisible.size();
845 const size_t cfi2 = newContextFlag.size();
846 const size_t dfi = newDeleteFlag.size();
847 const size_t si = newSize.size();
848
849 // Copy raw data
850 newFace.insert(newFace.end(), vcount, scast<int>(newVisible.size())); // the new face index should be the new index not just copying the previous value. Note that we take the size of newVisible, but could be any per-face array size.
851
852 newVertex.insert(newVertex.end(), oldVertex.begin() + prim.vertex_index, oldVertex.begin() + prim.vertex_index + v3);
853
854 newNormal.insert(newNormal.end(), oldNormal.begin() + prim.normal_index, oldNormal.begin() + prim.normal_index + 3);
855
856 newUV.insert(newUV.end(), oldUV.begin() + prim.uv_index, oldUV.begin() + prim.uv_index + v2);
857
858 newColor.insert(newColor.end(), oldColor.begin() + prim.color_index, oldColor.begin() + prim.color_index + 4);
859
860 newTexFlag.push_back(oldTexFlag[prim.texture_flag_index]);
861 newTexID.push_back(oldTexID[prim.texture_ID_index]);
862 newCoordFlag.push_back(oldCoordFlag[prim.coordinate_flag_index]);
863 newVisible.push_back(oldVisible[prim.visible_index]);
864 newContextFlag.push_back(oldContextFlag[prim.context_geometry_flag_index]);
865 newDeleteFlag.push_back(oldDeleteFlag[prim.delete_flag_index]);
866 newSize.push_back(oldSize[prim.size_index]);
867
868 // Update the map entry to point at the new positions
869 prim.face_index_index = fi;
870 prim.vertex_index = vi;
871 prim.normal_index = ni;
872 prim.uv_index = ui;
873 prim.color_index = ci;
874 prim.texture_flag_index = tfi;
875 prim.texture_ID_index = tidi;
876 prim.coordinate_flag_index = cfi;
877 prim.visible_index = vi2;
878 prim.context_geometry_flag_index = cfi2;
879 prim.delete_flag_index = dfi;
880 prim.size_index = si;
881 }
882
883 // Erase deleted UUIDs
884 for (auto UUID: toErase) {
885 UUID_map.erase(UUID);
886 }
887
888 // Swap into place
889 oldFace.swap(newFace);
890 oldVertex.swap(newVertex);
891 oldNormal.swap(newNormal);
892 oldUV.swap(newUV);
893 oldColor.swap(newColor);
894 oldTexFlag.swap(newTexFlag);
895 oldTexID.swap(newTexID);
896 oldCoordFlag.swap(newCoordFlag);
897 oldVisible.swap(newVisible);
898 oldContextFlag.swap(newContextFlag);
899 oldDeleteFlag.swap(newDeleteFlag);
900 oldSize.swap(newSize);
901 }
902
903 // Reset deleted count
904 deleted_primitive_count = 0;
905}
906
907void GeometryHandler::registerUUID(size_t UUID, const VisualizerGeometryType &geometry_type) {
908
909 UUID_map[UUID] = {geometry_type,
910 face_index_data.at(geometry_type).size(),
911 vertex_data.at(geometry_type).size(),
912 normal_data.at(geometry_type).size(),
913 uv_data.at(geometry_type).size(),
914 color_data.at(geometry_type).size(),
915 texture_flag_data.at(geometry_type).size(),
916 texture_ID_data.at(geometry_type).size(),
917 coordinate_flag_data.at(geometry_type).size(),
918 visible_flag_data.at(geometry_type).size(),
919 context_geometry_flag_data.at(geometry_type).size(),
920 delete_flag_data.at(geometry_type).size(),
921 size_data.at(geometry_type).size()};
922}
923
925
926 switch (geometry_type) {
927 case GEOMETRY_TYPE_RECTANGLE:
928 return 4;
929 case GEOMETRY_TYPE_TRIANGLE:
930 return 3;
931 case GEOMETRY_TYPE_POINT:
932 return 1;
933 case GEOMETRY_TYPE_LINE:
934 return 2;
935 default:
936 assert(true);
937 return 0;
938 }
939}
940
941void GeometryHandler::markDirty(size_t UUID) {
942 dirty_UUIDs.insert(UUID);
943}
944
945const std::unordered_set<size_t> &GeometryHandler::getDirtyUUIDs() const {
946 return dirty_UUIDs;
947}
948
950 dirty_UUIDs.clear();
951}