cesium-native 0.43.0
Loading...
Searching...
No Matches
PropertyTableView.h
1#pragma once
2
3#include "CesiumGltf/ExtensionModelExtStructuralMetadata.h"
4#include "CesiumGltf/Model.h"
5#include "CesiumGltf/PropertyTablePropertyView.h"
6#include "CesiumGltf/PropertyType.h"
7
8#include <glm/common.hpp>
9
10#include <optional>
11
12namespace CesiumGltf {
13
46
55public:
62 PropertyTableView(const Model& model, const PropertyTable& propertyTable);
63
72 PropertyTableViewStatus status() const noexcept { return _status; }
73
78 const std::optional<std::string>& name() const noexcept {
79 return _pPropertyTable->name;
80 }
81
88 int64_t size() const noexcept {
89 return _status == PropertyTableViewStatus::Valid ? _pPropertyTable->count
90 : 0;
91 }
92
99 const Class* getClass() const noexcept { return _pClass; }
100
108 const ClassProperty* getClassProperty(const std::string& propertyId) const;
109
136 template <typename T, bool Normalized = false>
138 getPropertyView(const std::string& propertyId) const {
139 if (this->size() <= 0) {
142 }
143
144 const ClassProperty* pClassProperty = getClassProperty(propertyId);
145 if (!pClassProperty) {
148 }
149
150 return getPropertyViewImpl<T, Normalized>(propertyId, *pClassProperty);
151 }
152
175 template <typename Callback>
176 void
177 getPropertyView(const std::string& propertyId, Callback&& callback) const {
178 if (this->size() <= 0) {
179 callback(
180 propertyId,
183 return;
184 }
185
186 const ClassProperty* pClassProperty = getClassProperty(propertyId);
187 if (!pClassProperty) {
188 callback(
189 propertyId,
192 return;
193 }
194
195 PropertyType type = convertStringToPropertyType(pClassProperty->type);
197 if (pClassProperty->componentType) {
198 componentType =
200 }
201
202 bool normalized = pClassProperty->normalized;
203 if (normalized && !isPropertyComponentTypeInteger(componentType)) {
204 // Only integer components may be normalized.
205 callback(
206 propertyId,
209 return;
210 }
211
212 if (pClassProperty->array) {
213 if (normalized) {
214 getArrayPropertyViewImpl<Callback, true>(
215 propertyId,
216 *pClassProperty,
217 type,
218 componentType,
219 std::forward<Callback>(callback));
220 } else {
221 getArrayPropertyViewImpl<Callback, false>(
222 propertyId,
223 *pClassProperty,
224 type,
225 componentType,
226 std::forward<Callback>(callback));
227 }
228 return;
229 }
230
231 if (type == PropertyType::Scalar) {
232 if (normalized) {
233 getScalarPropertyViewImpl<Callback, true>(
234 propertyId,
235 *pClassProperty,
236 componentType,
237 std::forward<Callback>(callback));
238 } else {
239 getScalarPropertyViewImpl<Callback, false>(
240 propertyId,
241 *pClassProperty,
242 componentType,
243 std::forward<Callback>(callback));
244 }
245 return;
246 }
247
248 if (isPropertyTypeVecN(type)) {
249 if (normalized) {
250 getVecNPropertyViewImpl<Callback, true>(
251 propertyId,
252 *pClassProperty,
253 type,
254 componentType,
255 std::forward<Callback>(callback));
256 } else {
257 getVecNPropertyViewImpl<Callback, false>(
258 propertyId,
259 *pClassProperty,
260 type,
261 componentType,
262 std::forward<Callback>(callback));
263 }
264 return;
265 }
266
267 if (isPropertyTypeMatN(type)) {
268 if (normalized) {
269 getMatNPropertyViewImpl<Callback, true>(
270 propertyId,
271 *pClassProperty,
272 type,
273 componentType,
274 std::forward<Callback>(callback));
275 } else {
276 getMatNPropertyViewImpl<Callback, false>(
277 propertyId,
278 *pClassProperty,
279 type,
280 componentType,
281 std::forward<Callback>(callback));
282 }
283 return;
284 }
285
286 if (type == PropertyType::String) {
287 callback(
288 propertyId,
289 getPropertyViewImpl<std::string_view, false>(
290 propertyId,
291 *pClassProperty));
292 return;
293 }
294
295 if (type == PropertyType::Boolean) {
296 callback(
297 propertyId,
298 getPropertyViewImpl<bool, false>(propertyId, *pClassProperty));
299 return;
300 }
301
302 callback(
303 propertyId,
306 }
307
329 template <typename Callback> void forEachProperty(Callback&& callback) const {
330 for (const auto& property : this->_pClass->properties) {
331 getPropertyView(property.first, std::forward<Callback>(callback));
332 }
333 }
334
335private:
336 template <typename Callback, bool Normalized>
337 void getScalarArrayPropertyViewImpl(
338 const std::string& propertyId,
339 const ClassProperty& classProperty,
340 PropertyComponentType componentType,
341 Callback&& callback) const {
342 switch (componentType) {
344 callback(
345 propertyId,
346 getPropertyViewImpl<PropertyArrayView<int8_t>, Normalized>(
347 propertyId,
348 classProperty));
349 break;
351 callback(
352 propertyId,
353 getPropertyViewImpl<PropertyArrayView<uint8_t>, Normalized>(
354 propertyId,
355 classProperty));
356 break;
358 callback(
359 propertyId,
360 getPropertyViewImpl<PropertyArrayView<int16_t>, Normalized>(
361 propertyId,
362 classProperty));
363 break;
365 callback(
366 propertyId,
367 getPropertyViewImpl<PropertyArrayView<uint16_t>, Normalized>(
368 propertyId,
369 classProperty));
370 break;
372 callback(
373 propertyId,
374 getPropertyViewImpl<PropertyArrayView<int32_t>, Normalized>(
375 propertyId,
376 classProperty));
377 break;
379 callback(
380 propertyId,
381 getPropertyViewImpl<PropertyArrayView<uint32_t>, Normalized>(
382 propertyId,
383 classProperty));
384 break;
386 callback(
387 propertyId,
388 getPropertyViewImpl<PropertyArrayView<int64_t>, Normalized>(
389 propertyId,
390 classProperty));
391 break;
393 callback(
394 propertyId,
395 getPropertyViewImpl<PropertyArrayView<uint64_t>, Normalized>(
396 propertyId,
397 classProperty));
398 break;
400 callback(
401 propertyId,
402 getPropertyViewImpl<PropertyArrayView<float>, false>(
403 propertyId,
404 classProperty));
405 break;
407 callback(
408 propertyId,
409 getPropertyViewImpl<PropertyArrayView<double>, false>(
410 propertyId,
411 classProperty));
412 break;
413 default:
414 callback(
415 propertyId,
418 break;
419 }
420 }
421
422 template <typename Callback, glm::length_t N, bool Normalized>
423 void getVecNArrayPropertyViewImpl(
424 const std::string& propertyId,
425 const ClassProperty& classProperty,
426 PropertyComponentType componentType,
427 Callback&& callback) const {
428 switch (componentType) {
430 callback(
431 propertyId,
432 getPropertyViewImpl<
433 PropertyArrayView<glm::vec<N, int8_t>>,
434 Normalized>(propertyId, classProperty));
435 break;
437 callback(
438 propertyId,
439 getPropertyViewImpl<
440 PropertyArrayView<glm::vec<N, uint8_t>>,
441 Normalized>(propertyId, classProperty));
442 break;
444 callback(
445 propertyId,
446 getPropertyViewImpl<
447 PropertyArrayView<glm::vec<N, int16_t>>,
448 Normalized>(propertyId, classProperty));
449 break;
451 callback(
452 propertyId,
453 getPropertyViewImpl<
454 PropertyArrayView<glm::vec<N, uint16_t>>,
455 Normalized>(propertyId, classProperty));
456 break;
458 callback(
459 propertyId,
460 getPropertyViewImpl<
461 PropertyArrayView<glm::vec<N, int32_t>>,
462 Normalized>(propertyId, classProperty));
463 break;
465 callback(
466 propertyId,
467 getPropertyViewImpl<
468 PropertyArrayView<glm::vec<N, uint32_t>>,
469 Normalized>(propertyId, classProperty));
470 break;
472 callback(
473 propertyId,
474 getPropertyViewImpl<
475 PropertyArrayView<glm::vec<N, int64_t>>,
476 Normalized>(propertyId, classProperty));
477 break;
479 callback(
480 propertyId,
481 getPropertyViewImpl<
482 PropertyArrayView<glm::vec<N, uint64_t>>,
483 Normalized>(propertyId, classProperty));
484 break;
486 callback(
487 propertyId,
488 getPropertyViewImpl<PropertyArrayView<glm::vec<N, float>>, false>(
489 propertyId,
490 classProperty));
491 break;
493 callback(
494 propertyId,
495 getPropertyViewImpl<PropertyArrayView<glm::vec<N, double>>, false>(
496 propertyId,
497 classProperty));
498 break;
499 default:
500 callback(
501 propertyId,
502 PropertyTablePropertyView<uint8_t>(
504 break;
505 }
506 }
507
508 template <typename Callback, bool Normalized>
509 void getVecNArrayPropertyViewImpl(
510 const std::string& propertyId,
511 const ClassProperty& classProperty,
512 PropertyType type,
513 PropertyComponentType componentType,
514 Callback&& callback) const {
515 glm::length_t N = getDimensionsFromPropertyType(type);
516 switch (N) {
517 case 2:
518 getVecNArrayPropertyViewImpl<Callback, 2, Normalized>(
519 propertyId,
520 classProperty,
521 componentType,
522 std::forward<Callback>(callback));
523 break;
524 case 3:
525 getVecNArrayPropertyViewImpl<Callback, 3, Normalized>(
526 propertyId,
527 classProperty,
528 componentType,
529 std::forward<Callback>(callback));
530 break;
531 case 4:
532 getVecNArrayPropertyViewImpl<Callback, 4, Normalized>(
533 propertyId,
534 classProperty,
535 componentType,
536 std::forward<Callback>(callback));
537 break;
538 default:
539 callback(
540 propertyId,
541 PropertyTablePropertyView<uint8_t>(
543 break;
544 }
545 }
546
547 template <typename Callback, glm::length_t N, bool Normalized>
548 void getMatNArrayPropertyViewImpl(
549 const std::string& propertyId,
550 const ClassProperty& classProperty,
551 PropertyComponentType componentType,
552 Callback&& callback) const {
553 switch (componentType) {
555 callback(
556 propertyId,
557 getPropertyViewImpl<
558 PropertyArrayView<glm::mat<N, N, int8_t>>,
559 Normalized>(propertyId, classProperty));
560 break;
562 callback(
563 propertyId,
564 getPropertyViewImpl<
565 PropertyArrayView<glm::mat<N, N, uint8_t>>,
566 Normalized>(propertyId, classProperty));
567 break;
569 callback(
570 propertyId,
571 getPropertyViewImpl<
572 PropertyArrayView<glm::mat<N, N, int16_t>>,
573 Normalized>(propertyId, classProperty));
574 break;
576 callback(
577 propertyId,
578 getPropertyViewImpl<
579 PropertyArrayView<glm::mat<N, N, uint16_t>>,
580 Normalized>(propertyId, classProperty));
581 break;
583 callback(
584 propertyId,
585 getPropertyViewImpl<
586 PropertyArrayView<glm::mat<N, N, int32_t>>,
587 Normalized>(propertyId, classProperty));
588 break;
590 callback(
591 propertyId,
592 getPropertyViewImpl<
593 PropertyArrayView<glm::mat<N, N, uint32_t>>,
594 Normalized>(propertyId, classProperty));
595 break;
597 callback(
598 propertyId,
599 getPropertyViewImpl<
600 PropertyArrayView<glm::mat<N, N, int64_t>>,
601 Normalized>(propertyId, classProperty));
602 break;
604 callback(
605 propertyId,
606 getPropertyViewImpl<
607 PropertyArrayView<glm::mat<N, N, uint64_t>>,
608 Normalized>(propertyId, classProperty));
609 break;
611 callback(
612 propertyId,
613 getPropertyViewImpl<PropertyArrayView<glm::mat<N, N, float>>, false>(
614 propertyId,
615 classProperty));
616 break;
618 callback(
619 propertyId,
620 getPropertyViewImpl<PropertyArrayView<glm::mat<N, N, double>>, false>(
621 propertyId,
622 classProperty));
623 break;
624 default:
625 callback(
626 propertyId,
627 PropertyTablePropertyView<uint8_t>(
629 break;
630 }
631 }
632
633 template <typename Callback, bool Normalized>
634 void getMatNArrayPropertyViewImpl(
635 const std::string& propertyId,
636 const ClassProperty& classProperty,
637 PropertyType type,
638 PropertyComponentType componentType,
639 Callback&& callback) const {
640 const glm::length_t N = getDimensionsFromPropertyType(type);
641 switch (N) {
642 case 2:
643 getMatNArrayPropertyViewImpl<Callback, 2, Normalized>(
644 propertyId,
645 classProperty,
646 componentType,
647 std::forward<Callback>(callback));
648 break;
649 case 3:
650 getMatNArrayPropertyViewImpl<Callback, 3, Normalized>(
651 propertyId,
652 classProperty,
653 componentType,
654 std::forward<Callback>(callback));
655 break;
656 case 4:
657 getMatNArrayPropertyViewImpl<Callback, 4, Normalized>(
658 propertyId,
659 classProperty,
660 componentType,
661 std::forward<Callback>(callback));
662 break;
663 default:
664 callback(
665 propertyId,
666 PropertyTablePropertyView<uint8_t>(
668 break;
669 }
670 }
671
672 template <typename Callback, bool Normalized>
673 void getArrayPropertyViewImpl(
674 const std::string& propertyId,
675 const ClassProperty& classProperty,
676 PropertyType type,
677 PropertyComponentType componentType,
678 Callback&& callback) const {
679 if (type == PropertyType::Scalar) {
680 getScalarArrayPropertyViewImpl<Callback, Normalized>(
681 propertyId,
682 classProperty,
683 componentType,
684 std::forward<Callback>(callback));
685 } else if (isPropertyTypeVecN(type)) {
686 getVecNArrayPropertyViewImpl<Callback, Normalized>(
687 propertyId,
688 classProperty,
689 type,
690 componentType,
691 std::forward<Callback>(callback));
692 } else if (isPropertyTypeMatN(type)) {
693 getMatNArrayPropertyViewImpl<Callback, Normalized>(
694 propertyId,
695 classProperty,
696 type,
697 componentType,
698 std::forward<Callback>(callback));
699 } else if (type == PropertyType::Boolean) {
700 callback(
701 propertyId,
702 getPropertyViewImpl<PropertyArrayView<bool>, false>(
703 propertyId,
704 classProperty));
705
706 } else if (type == PropertyType::String) {
707 callback(
708 propertyId,
709 getPropertyViewImpl<PropertyArrayView<std::string_view>, false>(
710 propertyId,
711 classProperty));
712 } else {
713 callback(
714 propertyId,
715 PropertyTablePropertyView<uint8_t>(
717 }
718 }
719
720 template <typename Callback, glm::length_t N, bool Normalized>
721 void getVecNPropertyViewImpl(
722 const std::string& propertyId,
723 const ClassProperty& classProperty,
724 PropertyComponentType componentType,
725 Callback&& callback) const {
726
727 switch (componentType) {
729 callback(
730 propertyId,
731 getPropertyViewImpl<glm::vec<N, int8_t>, Normalized>(
732 propertyId,
733 classProperty));
734 break;
736 callback(
737 propertyId,
738 getPropertyViewImpl<glm::vec<N, uint8_t>, Normalized>(
739 propertyId,
740 classProperty));
741 break;
743 callback(
744 propertyId,
745 getPropertyViewImpl<glm::vec<N, int16_t>, Normalized>(
746 propertyId,
747 classProperty));
748 break;
750 callback(
751 propertyId,
752 getPropertyViewImpl<glm::vec<N, uint16_t>, Normalized>(
753 propertyId,
754 classProperty));
755 break;
757 callback(
758 propertyId,
759 getPropertyViewImpl<glm::vec<N, int32_t>, Normalized>(
760 propertyId,
761 classProperty));
762 break;
764 callback(
765 propertyId,
766 getPropertyViewImpl<glm::vec<N, uint32_t>, Normalized>(
767 propertyId,
768 classProperty));
769 break;
771 callback(
772 propertyId,
773 getPropertyViewImpl<glm::vec<N, int64_t>, Normalized>(
774 propertyId,
775 classProperty));
776 break;
778 callback(
779 propertyId,
780 getPropertyViewImpl<glm::vec<N, uint64_t>, Normalized>(
781 propertyId,
782 classProperty));
783 break;
785 callback(
786 propertyId,
787 getPropertyViewImpl<glm::vec<N, float>, false>(
788 propertyId,
789 classProperty));
790 break;
792 callback(
793 propertyId,
794 getPropertyViewImpl<glm::vec<N, double>, false>(
795 propertyId,
796 classProperty));
797 break;
798 default:
799 callback(
800 propertyId,
801 PropertyTablePropertyView<uint8_t>(
803 break;
804 }
805 }
806
807 template <typename Callback, bool Normalized>
808 void getVecNPropertyViewImpl(
809 const std::string& propertyId,
810 const ClassProperty& classProperty,
811 PropertyType type,
812 PropertyComponentType componentType,
813 Callback&& callback) const {
814 const glm::length_t N = getDimensionsFromPropertyType(type);
815 switch (N) {
816 case 2:
817 getVecNPropertyViewImpl<Callback, 2, Normalized>(
818 propertyId,
819 classProperty,
820 componentType,
821 std::forward<Callback>(callback));
822 break;
823 case 3:
824 getVecNPropertyViewImpl<Callback, 3, Normalized>(
825 propertyId,
826 classProperty,
827 componentType,
828 std::forward<Callback>(callback));
829 break;
830 case 4:
831 getVecNPropertyViewImpl<Callback, 4, Normalized>(
832 propertyId,
833 classProperty,
834 componentType,
835 std::forward<Callback>(callback));
836 break;
837 default:
838 callback(
839 propertyId,
840 PropertyTablePropertyView<uint8_t>(
842 break;
843 }
844 }
845
846 template <typename Callback, glm::length_t N, bool Normalized>
847 void getMatNPropertyViewImpl(
848 const std::string& propertyId,
849 const ClassProperty& classProperty,
850 PropertyComponentType componentType,
851 Callback&& callback) const {
852 switch (componentType) {
854 callback(
855 propertyId,
856 getPropertyViewImpl<glm::mat<N, N, int8_t>, Normalized>(
857 propertyId,
858 classProperty));
859 break;
861 callback(
862 propertyId,
863 getPropertyViewImpl<glm::mat<N, N, uint8_t>, Normalized>(
864 propertyId,
865 classProperty));
866 break;
868 callback(
869 propertyId,
870 getPropertyViewImpl<glm::mat<N, N, int16_t>, Normalized>(
871 propertyId,
872 classProperty));
873 break;
875 callback(
876 propertyId,
877 getPropertyViewImpl<glm::mat<N, N, uint16_t>, Normalized>(
878 propertyId,
879 classProperty));
880 break;
882 callback(
883 propertyId,
884 getPropertyViewImpl<glm::mat<N, N, int32_t>, Normalized>(
885 propertyId,
886 classProperty));
887 break;
889 callback(
890 propertyId,
891 getPropertyViewImpl<glm::mat<N, N, uint32_t>, Normalized>(
892 propertyId,
893 classProperty));
894 break;
896 callback(
897 propertyId,
898 getPropertyViewImpl<glm::mat<N, N, int64_t>, Normalized>(
899 propertyId,
900 classProperty));
901 break;
903 callback(
904 propertyId,
905 getPropertyViewImpl<glm::mat<N, N, uint64_t>, Normalized>(
906 propertyId,
907 classProperty));
908 break;
910 callback(
911 propertyId,
912 getPropertyViewImpl<glm::mat<N, N, float>, false>(
913 propertyId,
914 classProperty));
915 break;
917 callback(
918 propertyId,
919 getPropertyViewImpl<glm::mat<N, N, double>, false>(
920 propertyId,
921 classProperty));
922 break;
923 default:
924 callback(
925 propertyId,
926 PropertyTablePropertyView<uint8_t>(
928 break;
929 }
930 }
931
932 template <typename Callback, bool Normalized>
933 void getMatNPropertyViewImpl(
934 const std::string& propertyId,
935 const ClassProperty& classProperty,
936 PropertyType type,
937 PropertyComponentType componentType,
938 Callback&& callback) const {
939 glm::length_t N = getDimensionsFromPropertyType(type);
940 switch (N) {
941 case 2:
942 getMatNPropertyViewImpl<Callback, 2, Normalized>(
943 propertyId,
944 classProperty,
945 componentType,
946 std::forward<Callback>(callback));
947 break;
948 case 3:
949 getMatNPropertyViewImpl<Callback, 3, Normalized>(
950 propertyId,
951 classProperty,
952 componentType,
953 std::forward<Callback>(callback));
954 break;
955 case 4:
956 getMatNPropertyViewImpl<Callback, 4, Normalized>(
957 propertyId,
958 classProperty,
959 componentType,
960 std::forward<Callback>(callback));
961 break;
962 default:
963 callback(
964 propertyId,
965 PropertyTablePropertyView<uint8_t>(
967 break;
968 }
969 }
970
971 template <typename Callback, bool Normalized>
972 void getScalarPropertyViewImpl(
973 const std::string& propertyId,
974 const ClassProperty& classProperty,
975 PropertyComponentType componentType,
976 Callback&& callback) const {
977 switch (componentType) {
979 callback(
980 propertyId,
981 getPropertyViewImpl<int8_t, Normalized>(propertyId, classProperty));
982 return;
984 callback(
985 propertyId,
986 getPropertyViewImpl<uint8_t, Normalized>(propertyId, classProperty));
987 return;
989 callback(
990 propertyId,
991 getPropertyViewImpl<int16_t, Normalized>(propertyId, classProperty));
992 return;
994 callback(
995 propertyId,
996 getPropertyViewImpl<uint16_t, Normalized>(propertyId, classProperty));
997 break;
999 callback(
1000 propertyId,
1001 getPropertyViewImpl<int32_t, Normalized>(propertyId, classProperty));
1002 break;
1004 callback(
1005 propertyId,
1006 getPropertyViewImpl<uint32_t, Normalized>(propertyId, classProperty));
1007 break;
1009 callback(
1010 propertyId,
1011 getPropertyViewImpl<int64_t, Normalized>(propertyId, classProperty));
1012 break;
1014 callback(
1015 propertyId,
1016 getPropertyViewImpl<uint64_t, Normalized>(propertyId, classProperty));
1017 break;
1019 callback(
1020 propertyId,
1021 getPropertyViewImpl<float, false>(propertyId, classProperty));
1022 break;
1024 callback(
1025 propertyId,
1026 getPropertyViewImpl<double, false>(propertyId, classProperty));
1027 break;
1028 default:
1029 callback(
1030 propertyId,
1031 PropertyTablePropertyView<uint8_t>(
1033 break;
1034 }
1035 }
1036
1037 template <typename T, bool Normalized>
1038 PropertyTablePropertyView<T, Normalized> getPropertyViewImpl(
1039 const std::string& propertyId,
1040 const ClassProperty& classProperty) const {
1041 auto propertyTablePropertyIter =
1042 _pPropertyTable->properties.find(propertyId);
1043 if (propertyTablePropertyIter == _pPropertyTable->properties.end()) {
1044 if (!classProperty.required && classProperty.defaultProperty) {
1045 // If the property was omitted from the property table, it is still
1046 // technically valid if it specifies a default value. Create a view that
1047 // just returns the default value.
1048 return PropertyTablePropertyView<T, Normalized>(
1049 classProperty,
1050 _pPropertyTable->count);
1051 }
1052
1053 // Otherwise, the property is erroneously nonexistent.
1054 return PropertyTablePropertyView<T, Normalized>(
1056 }
1057
1058 const PropertyTableProperty& propertyTableProperty =
1059 propertyTablePropertyIter->second;
1060
1061 if constexpr (IsMetadataNumeric<T>::value || IsMetadataBoolean<T>::value) {
1062 return getNumericOrBooleanPropertyValues<T, Normalized>(
1063 classProperty,
1064 propertyTableProperty);
1065 }
1066
1067 if constexpr (IsMetadataString<T>::value) {
1068 return getStringPropertyValues(classProperty, propertyTableProperty);
1069 }
1070
1071 if constexpr (IsMetadataBooleanArray<T>::value) {
1072 return getBooleanArrayPropertyValues(
1073 classProperty,
1074 propertyTableProperty);
1075 }
1076
1077 if constexpr (IsMetadataNumericArray<T>::value) {
1078 return getNumericArrayPropertyValues<
1080 Normalized>(classProperty, propertyTableProperty);
1081 }
1082
1083 if constexpr (IsMetadataStringArray<T>::value) {
1084 return getStringArrayPropertyValues(classProperty, propertyTableProperty);
1085 }
1086 }
1087
1088 template <typename T, bool Normalized>
1089 PropertyTablePropertyView<T, Normalized> getNumericOrBooleanPropertyValues(
1090 const ClassProperty& classProperty,
1091 const PropertyTableProperty& propertyTableProperty) const {
1092 if (classProperty.array) {
1093 return PropertyTablePropertyView<T, Normalized>(
1095 }
1096
1097 const PropertyType type = convertStringToPropertyType(classProperty.type);
1098 if (TypeToPropertyType<T>::value != type) {
1099 return PropertyTablePropertyView<T, Normalized>(
1101 }
1102 const PropertyComponentType componentType =
1104 classProperty.componentType.value_or(""));
1105 if (TypeToPropertyType<T>::component != componentType) {
1106 return PropertyTablePropertyView<T, Normalized>(
1108 }
1109
1110 if (classProperty.normalized != Normalized) {
1111 return PropertyTablePropertyView<T, Normalized>(
1113 }
1114
1115 std::span<const std::byte> values;
1116 const auto status = getBufferSafe(propertyTableProperty.values, values);
1118 return PropertyTablePropertyView<T, Normalized>(status);
1119 }
1120
1121 if (values.size() % sizeof(T) != 0) {
1122 return PropertyTablePropertyView<T, Normalized>(
1123 PropertyTablePropertyViewStatus::
1124 ErrorBufferViewSizeNotDivisibleByTypeSize);
1125 }
1126
1127 size_t maxRequiredBytes = 0;
1128 if (IsMetadataBoolean<T>::value) {
1129 maxRequiredBytes = static_cast<size_t>(
1130 glm::ceil(static_cast<double>(_pPropertyTable->count) / 8.0));
1131 } else {
1132 maxRequiredBytes = _pPropertyTable->count * sizeof(T);
1133 }
1134
1135 if (values.size() < maxRequiredBytes) {
1136 return PropertyTablePropertyView<T, Normalized>(
1137 PropertyTablePropertyViewStatus::
1138 ErrorBufferViewSizeDoesNotMatchPropertyTableCount);
1139 }
1140
1141 return PropertyTablePropertyView<T, Normalized>(
1142 propertyTableProperty,
1143 classProperty,
1144 _pPropertyTable->count,
1145 values);
1146 }
1147
1148 PropertyTablePropertyView<std::string_view> getStringPropertyValues(
1149 const ClassProperty& classProperty,
1150 const PropertyTableProperty& propertyTableProperty) const;
1151
1152 PropertyTablePropertyView<PropertyArrayView<bool>>
1153 getBooleanArrayPropertyValues(
1154 const ClassProperty& classProperty,
1155 const PropertyTableProperty& propertyTableProperty) const;
1156
1157 template <typename T, bool Normalized>
1158 PropertyTablePropertyView<PropertyArrayView<T>, Normalized>
1159 getNumericArrayPropertyValues(
1160 const ClassProperty& classProperty,
1161 const PropertyTableProperty& propertyTableProperty) const {
1162 if (!classProperty.array) {
1163 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1165 }
1166
1167 const PropertyType type = convertStringToPropertyType(classProperty.type);
1168 if (TypeToPropertyType<T>::value != type) {
1169 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1171 }
1172
1173 const PropertyComponentType componentType =
1175 classProperty.componentType.value_or(""));
1176 if (TypeToPropertyType<T>::component != componentType) {
1177 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1179 }
1180
1181 if (classProperty.normalized != Normalized) {
1182 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1184 }
1185
1186 std::span<const std::byte> values;
1187 auto status = getBufferSafe(propertyTableProperty.values, values);
1189 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1190 status);
1191 }
1192
1193 if (values.size() % sizeof(T) != 0) {
1194 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1197 }
1198
1199 const int64_t fixedLengthArrayCount = classProperty.count.value_or(0);
1200 if (fixedLengthArrayCount > 0 && propertyTableProperty.arrayOffsets >= 0) {
1201 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1204 }
1205
1206 if (fixedLengthArrayCount <= 0 && propertyTableProperty.arrayOffsets < 0) {
1207 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1210 }
1211
1212 // Handle fixed-length arrays
1213 if (fixedLengthArrayCount > 0) {
1214 size_t maxRequiredBytes = maxRequiredBytes = static_cast<size_t>(
1215 _pPropertyTable->count * fixedLengthArrayCount * sizeof(T));
1216
1217 if (values.size() < maxRequiredBytes) {
1218 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1221 }
1222
1223 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1224 propertyTableProperty,
1225 classProperty,
1226 _pPropertyTable->count,
1227 values);
1228 }
1229
1230 // Handle variable-length arrays
1231 const PropertyComponentType arrayOffsetType =
1233 propertyTableProperty.arrayOffsetType);
1234 if (arrayOffsetType == PropertyComponentType::None) {
1235 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1237 }
1238
1239 constexpr bool checkBitsSize = false;
1240 std::span<const std::byte> arrayOffsets;
1241 status = getArrayOffsetsBufferSafe(
1242 propertyTableProperty.arrayOffsets,
1243 arrayOffsetType,
1244 values.size(),
1245 static_cast<size_t>(_pPropertyTable->count),
1246 checkBitsSize,
1247 arrayOffsets);
1249 return PropertyTablePropertyView<PropertyArrayView<T>, Normalized>(
1250 status);
1251 }
1252
1253 if constexpr (Normalized) {
1254 return PropertyTablePropertyView<PropertyArrayView<T>, true>(
1255 propertyTableProperty,
1256 classProperty,
1257 _pPropertyTable->count,
1258 values,
1259 arrayOffsets,
1260 arrayOffsetType);
1261 } else {
1262 return PropertyTablePropertyView<PropertyArrayView<T>, false>(
1263 propertyTableProperty,
1264 classProperty,
1265 _pPropertyTable->count,
1266 values,
1267 arrayOffsets,
1268 std::span<const std::byte>(),
1269 arrayOffsetType,
1271 }
1272 }
1273
1274 PropertyTablePropertyView<PropertyArrayView<std::string_view>>
1275 getStringArrayPropertyValues(
1276 const ClassProperty& classProperty,
1277 const PropertyTableProperty& propertyTableProperty) const;
1278
1279 PropertyViewStatusType getBufferSafe(
1280 int32_t bufferView,
1281 std::span<const std::byte>& buffer) const noexcept;
1282
1283 PropertyViewStatusType getArrayOffsetsBufferSafe(
1284 int32_t arrayOffsetsBufferView,
1285 PropertyComponentType arrayOffsetType,
1286 size_t valuesBufferSize,
1287 size_t propertyTableCount,
1288 bool checkBitsSize,
1289 std::span<const std::byte>& arrayOffsetsBuffer) const noexcept;
1290
1291 PropertyViewStatusType getStringOffsetsBufferSafe(
1292 int32_t stringOffsetsBufferView,
1293 PropertyComponentType stringOffsetType,
1294 size_t valuesBufferSize,
1295 size_t propertyTableCount,
1296 std::span<const std::byte>& stringOffsetsBuffer) const noexcept;
1297
1298 const Model* _pModel;
1299 const PropertyTable* _pPropertyTable;
1300 const Class* _pClass;
1302};
1303} // namespace CesiumGltf
A view on an array element of a PropertyTableProperty or PropertyTextureProperty.
static const PropertyViewStatusType ErrorBufferViewSizeDoesNotMatchPropertyTableCount
This property view has an invalid buffer view; its length does not match the size of the property tab...
static const PropertyViewStatusType ErrorArrayCountAndOffsetBufferCoexist
This array property view has both a fixed length and an offset buffer view defined.
static const PropertyViewStatusType ErrorArrayCountAndOffsetBufferDontExist
This array property view has neither a fixed length nor an offset buffer view defined.
static const PropertyViewStatusType ErrorInvalidPropertyTable
This property view was initialized from an invalid PropertyTable.
static const PropertyViewStatusType ErrorInvalidArrayOffsetType
This property view has an unknown array offset type.
static const PropertyViewStatusType ErrorBufferViewSizeNotDivisibleByTypeSize
This property view has an invalid buffer view; its length is not a multiple of the size of its type /...
A view on the data of the PropertyTableProperty that is created by a PropertyTableView.
Utility to retrieve the data of PropertyTable.
PropertyTableViewStatus status() const noexcept
Gets the status of this property table view.
void getPropertyView(const std::string &propertyId, Callback &&callback) const
Gets a PropertyTablePropertyView through a callback that accepts a property id and a PropertyTablePro...
const Class * getClass() const noexcept
Gets the Class that this property table conforms to.
PropertyTablePropertyView< T, Normalized > getPropertyView(const std::string &propertyId) const
Gets a PropertyTablePropertyView that views the data of a property stored in the PropertyTable.
int64_t size() const noexcept
Get the number of elements in this PropertyTableView. If the view is valid, this returns PropertyTabl...
const std::optional< std::string > & name() const noexcept
Gets the name of the property table being viewed. Returns std::nullopt if no name was specified.
void forEachProperty(Callback &&callback) const
Iterates over each property in the PropertyTable with a callback that accepts a property id and a Pro...
const ClassProperty * getClassProperty(const std::string &propertyId) const
Finds the ClassProperty that describes the type information of the property with the specified id.
PropertyTableView(const Model &model, const PropertyTable &propertyTable)
Creates an instance of PropertyTableView.
static const PropertyViewStatusType ErrorTypeMismatch
This property view's type does not match what is specified in ClassProperty::type.
static const PropertyViewStatusType Valid
This property view is valid and ready to use.
static const PropertyViewStatusType ErrorNonexistentProperty
This property view is trying to view a property that does not exist.
static const PropertyViewStatusType ErrorInvalidNormalization
This property says it is normalized, but it does not have an integer component type.
static const PropertyViewStatusType ErrorArrayTypeMismatch
This property view differs from what is specified in ClassProperty::array.
static const PropertyViewStatusType ErrorNormalizationMismatch
This property view's normalization differs from what is specified in ClassProperty::normalized.
static const PropertyViewStatusType ErrorComponentTypeMismatch
This property view's component type does not match what is specified in ClassProperty::componentType.
Classes for working with glTF models.
PropertyComponentType
The possible types of a property component.
@ Float32
A property component equivalent to a float.
@ Uint32
A property component equivalent to a uint32_t.
@ Uint16
A property component equivalent to a uint16_t.
@ Int16
A property component equivalent to an int16_t.
@ Uint8
A property component equivalent to a uint8_t.
@ Int8
A property component equivalent to an int8_t.
@ Int32
A property component equivalent to an int32_t.
@ Uint64
A property component equivalent to a uint32_t.
@ Float64
A property component equivalent to a double.
@ Int64
A property component equivalent to an int64_t.
PropertyComponentType convertArrayOffsetTypeStringToPropertyComponentType(const std::string &str)
Converts a string listed in PropertyTableProperty::ArrayOffsetType to its corresponding PropertyCompo...
bool isPropertyTypeVecN(PropertyType type)
Checks if the given PropertyType represents a vector with any number of components.
bool isPropertyComponentTypeInteger(PropertyComponentType componentType)
Checks if the given PropertyComponentType represents an integer value.
PropertyComponentType convertStringToPropertyComponentType(const std::string &str)
Converts a string into a PropertyComponentType.
@ ErrorClassNotFound
The property attribute's specified class could not be found in the extension.
@ ErrorMissingMetadataExtension
The glTF is missing the EXT_structural_metadata extension.
@ ErrorMissingSchema
The glTF EXT_structural_metadata extension doesn't contain a schema.
bool isPropertyTypeMatN(PropertyType type)
Checks if the given PropertyType represents a matrix with any number of components.
@ Valid
This accessor is valid and ready to use.
PropertyType convertStringToPropertyType(const std::string &str)
Converts a string into a PropertyType.
PropertyType
The possible types of a property in a PropertyTableView.
@ Scalar
A scalar property, i.e. an integer or floating point value.
glm::length_t getDimensionsFromPropertyType(PropertyType type)
Obtains the number of dimensions in the given PropertyType.
PropertyTableViewStatus
Indicates the status of a property table view.
@ Valid
This property table view is valid and ready to use.
int32_t PropertyViewStatusType
The type used for fields of PropertyViewStatus.
bool normalized
Specifies whether integer values are normalized. Only applicable to SCALAR, VECN, and MATN types with...
std::optional< std::string > componentType
The datatype of the element's components. Only applicable to SCALAR, VECN, and MATN types.
bool array
Whether the property is an array. When count is defined the property is a fixed-length array....
std::string type
The element type.
A class containing a set of properties.
Definition Class.h:17
std::unordered_map< std::string, CesiumGltf::ClassProperty > properties
A dictionary, where each key is a property ID and each value is an object defining the property....
Definition Class.h:38
void type
The component type of this metadata array.
This class is not meant to be instantiated directly. Use Model instead.
Definition Model.h:14
Properties conforming to a class, organized as property values stored in binary columnar arrays.
std::unordered_map< std::string, CesiumGltf::PropertyTableProperty > properties
A dictionary, where each key corresponds to a property ID in the class' properties dictionary and eac...
std::optional< std::string > name
The name of the property table, e.g. for display purposes.
int64_t count
The number of elements in each property array.