3#include <CesiumGltf/ClassProperty.h>
4#include <CesiumGltf/Enum.h>
5#include <CesiumGltf/PropertyArrayView.h>
6#include <CesiumGltf/PropertyAttributeProperty.h>
7#include <CesiumGltf/PropertyTableProperty.h>
8#include <CesiumGltf/PropertyTextureProperty.h>
9#include <CesiumGltf/PropertyType.h>
10#include <CesiumGltf/PropertyTypeTraits.h>
147 const bool hasEnumDefinition = pEnumDefinition !=
nullptr;
148 if (isEnum != hasEnumDefinition) {
155 if (expectedComponentType !=
172 if (classProperty.
array) {
204 const bool hasEnumDefinition = pEnumDefinition !=
nullptr;
205 if (isEnum != hasEnumDefinition) {
212 if (expectedComponentType !=
229 if (!classProperty.
array) {
257template <
typename VecType>
258static std::optional<VecType>
259getVecN(
const CesiumUtility::JsonValue& jsonValue) {
265 constexpr glm::length_t N = VecType::length();
266 if (array.size() != N) {
270 using T =
typename VecType::value_type;
273 for (glm::length_t i = 0; i < N; i++) {
274 std::optional<T> value = getScalar<T>(array[
static_cast<size_t>(i)]);
295template <
typename MatType>
296static std::optional<MatType>
297getMatN(
const CesiumUtility::JsonValue& jsonValue) {
303 constexpr glm::length_t N = MatType::length();
304 if (array.size() !=
static_cast<size_t>(N * N)) {
308 using T =
typename MatType::value_type;
311 for (glm::length_t i = 0; i < N; i++) {
313 for (glm::length_t j = 0; j < N; j++) {
314 std::optional<T> value =
315 getScalar<T>(array[
static_cast<size_t>(i * N + j)]);
320 result[i][j] = *value;
336template <
typename ElementType>
337int64_t
getCount(std::optional<std::vector<std::byte>>& buffer) {
342 return static_cast<int64_t
>(buffer->size() /
sizeof(ElementType));
348template <
typename ElementType,
bool Normalized = false>
class PropertyView;
362template <
typename ElementType>
class PropertyView<ElementType, false> {
370 _semantic(
std::nullopt),
371 _description(
std::nullopt),
372 _offset(
std::nullopt),
373 _scale(
std::nullopt),
377 _noData(
std::nullopt),
378 _defaultValue(
std::nullopt),
396 _name(classProperty.
name),
399 _offset(
std::nullopt),
400 _scale(
std::nullopt),
404 _noData(
std::nullopt),
405 _defaultValue(
std::nullopt),
412 _status = PropertyViewStatus::ErrorNormalizationMismatch;
417 getNumericPropertyValues(classProperty);
424 if (classProperty.
noData) {
425 if (!_required && _propertyType == PropertyType::Enum) {
426 CESIUM_ASSERT(pEnumDefinition != nullptr);
427 if constexpr (IsMetadataInteger<ElementType>::value) {
429 _noData = getEnumValue(*classProperty.noData, *pEnumDefinition);
432 _noData = getValue(*classProperty.
noData);
442 if (classProperty.defaultProperty) {
443 if (!_required && _propertyType == PropertyType::Enum) {
444 CESIUM_ASSERT(pEnumDefinition != nullptr);
445 if constexpr (IsMetadataInteger<ElementType>::value) {
448 getEnumValue(*classProperty.defaultProperty, *pEnumDefinition);
451 _defaultValue = getValue(*classProperty.defaultProperty);
454 if (!_defaultValue) {
472 _semantic(
std::nullopt),
473 _description(
std::nullopt),
474 _offset(
std::nullopt),
475 _scale(
std::nullopt),
479 _noData(
std::nullopt),
480 _defaultValue(
std::nullopt),
498 getNumericPropertyValues(property);
516 getNumericPropertyValues(property);
535 getNumericPropertyValues(property);
552 const std::optional<std::string>&
name() const noexcept {
return _name; }
560 const std::optional<std::string>&
semantic() const noexcept {
592 std::optional<ElementType>
offset() const noexcept {
return _offset; }
601 std::optional<ElementType>
scale() const noexcept {
return _scale; }
612 std::optional<ElementType>
max() const noexcept {
return _max; }
623 std::optional<ElementType>
min() const noexcept {
return _min; }
630 bool required() const noexcept {
return _required; }
641 std::optional<ElementType>
noData() const noexcept {
return _noData; }
652 return _defaultValue;
666 std::optional<std::string> _name;
667 std::optional<std::string> _semantic;
668 std::optional<std::string> _description;
670 std::optional<ElementType> _offset;
671 std::optional<ElementType> _scale;
672 std::optional<ElementType> _max;
673 std::optional<ElementType> _min;
676 std::optional<ElementType> _noData;
677 std::optional<ElementType> _defaultValue;
690 static std::optional<ElementType>
693 return getScalar<ElementType>(jsonValue);
697 return getVecN<ElementType>(jsonValue);
701 return getMatN<ElementType>(jsonValue);
705 static std::optional<ElementType> getEnumValue(
713 const auto foundValue = std::find_if(
714 enumDefinition.
values.begin(),
715 enumDefinition.
values.end(),
717 return enumValue.name == valueStr;
720 if (foundValue == enumDefinition.
values.end()) {
724 return static_cast<ElementType
>(foundValue->value);
727 using PropertyDefinitionType = std::variant<
729 PropertyTableProperty,
730 PropertyTextureProperty,
731 PropertyAttributeProperty>;
737 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
739 [
this](
auto property) {
740 if (property.offset) {
742 switch (TypeToPropertyType<ElementType>::component) {
743 case PropertyComponentType::Float32:
744 case PropertyComponentType::Float64:
745 this->_offset = getValue(*property.offset);
752 this->_status = PropertyViewStatus::ErrorInvalidOffset;
757 if (property.scale) {
759 switch (TypeToPropertyType<ElementType>::component) {
760 case PropertyComponentType::Float32:
761 case PropertyComponentType::Float64:
762 this->_scale = getValue(*property.scale);
769 this->_status = PropertyViewStatus::ErrorInvalidScale;
775 this->_max = getValue(*property.max);
778 this->_status = PropertyViewStatus::ErrorInvalidMax;
784 this->_min = getValue(*property.min);
787 this->_status = PropertyViewStatus::ErrorInvalidMin;
820 _semantic(
std::nullopt),
821 _description(
std::nullopt),
822 _offset(
std::nullopt),
823 _scale(
std::nullopt),
827 _noData(
std::nullopt),
828 _defaultValue(
std::nullopt),
836 _name(classProperty.
name),
839 _offset(
std::nullopt),
840 _scale(
std::nullopt),
844 _noData(
std::nullopt),
845 _defaultValue(
std::nullopt),
852 _status = PropertyViewStatus::ErrorNormalizationMismatch;
855 getNumericPropertyValues(classProperty);
860 if (classProperty.
noData) {
863 _noData = getValue<ElementType>(*classProperty.noData);
872 if (classProperty.defaultProperty) {
876 getValue<NormalizedType>(*classProperty.defaultProperty);
878 if (!_defaultValue) {
895 _semantic(
std::nullopt),
896 _description(
std::nullopt),
897 _offset(
std::nullopt),
898 _scale(
std::nullopt),
902 _noData(
std::nullopt),
903 _defaultValue(
std::nullopt),
919 getNumericPropertyValues(property);
935 getNumericPropertyValues(property);
951 getNumericPropertyValues(property);
963 const std::optional<std::string>&
name() const noexcept {
return _name; }
968 const std::optional<std::string>&
semantic() const noexcept {
992 std::optional<NormalizedType>
offset() const noexcept {
return _offset; }
997 std::optional<NormalizedType>
scale() const noexcept {
return _scale; }
1002 std::optional<NormalizedType>
max() const noexcept {
return _max; }
1007 std::optional<NormalizedType>
min() const noexcept {
return _min; }
1017 std::optional<ElementType>
noData() const noexcept {
return _noData; }
1023 return _defaultValue;
1037 std::optional<std::string> _name;
1038 std::optional<std::string> _semantic;
1039 std::optional<std::string> _description;
1041 std::optional<NormalizedType> _offset;
1042 std::optional<NormalizedType> _scale;
1043 std::optional<NormalizedType> _max;
1044 std::optional<NormalizedType> _min;
1047 std::optional<ElementType> _noData;
1048 std::optional<NormalizedType> _defaultValue;
1060 template <
typename T>
1063 return getScalar<T>(jsonValue);
1067 return getVecN<T>(jsonValue);
1071 return getMatN<T>(jsonValue);
1075 using PropertyDefinitionType = std::variant<
1085 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
1087 [
this](
auto property) {
1088 if (property.offset) {
1089 _offset = getValue<NormalizedType>(*property.offset);
1097 if (property.scale) {
1098 _scale = getValue<NormalizedType>(*property.scale);
1101 _status = PropertyViewStatus::ErrorInvalidScale;
1107 _max = getValue<NormalizedType>(*property.max);
1110 _status = PropertyViewStatus::ErrorInvalidMax;
1116 _min = getValue<NormalizedType>(*property.min);
1119 _status = PropertyViewStatus::ErrorInvalidMin;
1139 _name(
std::nullopt),
1140 _semantic(
std::nullopt),
1141 _description(
std::nullopt),
1143 _defaultValue(
std::nullopt) {}
1150 _name(classProperty.
name),
1154 _defaultValue(
std::nullopt) {
1161 _defaultValue = getBooleanValue(*classProperty.defaultProperty);
1164 if (!_defaultValue) {
1180 _name(
std::nullopt),
1181 _semantic(
std::nullopt),
1182 _description(
std::nullopt),
1184 _defaultValue(
std::nullopt) {}
1205 const std::optional<std::string>&
name() const noexcept {
return _name; }
1210 const std::optional<std::string>&
semantic() const noexcept {
1218 return _description;
1234 std::optional<bool>
offset() const noexcept {
return std::nullopt; }
1239 std::optional<bool>
scale() const noexcept {
return std::nullopt; }
1244 std::optional<bool>
max() const noexcept {
return std::nullopt; }
1249 std::optional<bool>
min() const noexcept {
return std::nullopt; }
1259 std::optional<bool>
noData() const noexcept {
return std::nullopt; }
1264 std::optional<bool>
defaultValue() const noexcept {
return _defaultValue; }
1277 std::optional<std::string> _name;
1278 std::optional<std::string> _semantic;
1279 std::optional<std::string> _description;
1282 std::optional<bool> _defaultValue;
1284 static std::optional<bool>
1287 return std::nullopt;
1305 _name(
std::nullopt),
1306 _semantic(
std::nullopt),
1307 _description(
std::nullopt),
1309 _noData(
std::nullopt),
1310 _defaultValue(
std::nullopt) {}
1317 _name(classProperty.
name),
1321 _noData(
std::nullopt),
1322 _defaultValue(
std::nullopt) {
1327 if (classProperty.
noData) {
1329 _noData = getStringValue(*classProperty.noData);
1339 if (classProperty.defaultProperty) {
1341 _defaultValue = getStringValue(*classProperty.defaultProperty);
1344 if (!_defaultValue) {
1360 _name(
std::nullopt),
1361 _semantic(
std::nullopt),
1362 _description(
std::nullopt),
1364 _noData(
std::nullopt),
1365 _defaultValue(
std::nullopt) {}
1386 const std::optional<std::string>&
name() const noexcept {
return _name; }
1391 const std::optional<std::string>&
semantic() const noexcept {
1399 return _description;
1415 std::optional<std::string_view>
offset() const noexcept {
1416 return std::nullopt;
1422 std::optional<std::string_view>
scale() const noexcept {
1423 return std::nullopt;
1429 std::optional<std::string_view>
max() const noexcept {
return std::nullopt; }
1434 std::optional<std::string_view>
min() const noexcept {
return std::nullopt; }
1444 std::optional<std::string_view>
noData() const noexcept {
1446 return std::string_view(*_noData);
1448 return std::nullopt;
1456 return std::string_view(*_defaultValue);
1458 return std::nullopt;
1472 std::optional<std::string> _name;
1473 std::optional<std::string> _semantic;
1474 std::optional<std::string> _description;
1477 std::optional<std::string> _noData;
1478 std::optional<std::string> _defaultValue;
1480 static std::optional<std::string>
1483 return std::nullopt;
1486 return std::string(value.
getString().c_str());
1503template <
typename ElementType>
1511 _name(
std::nullopt),
1512 _semantic(
std::nullopt),
1513 _description(
std::nullopt),
1540 _name(classProperty.
name),
1543 _count(classProperty.count ? *classProperty.count : 0),
1557 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1562 getNumericPropertyValues(classProperty);
1569 if (classProperty.
noData) {
1570 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1571 CESIUM_ASSERT(pEnumDefinition != nullptr);
1572 if constexpr (IsMetadataInteger<ElementType>::value) {
1574 getEnumArrayValue(*classProperty.noData, *pEnumDefinition);
1576 }
else if (!this->_required) {
1577 this->_noData = getArrayValue(*classProperty.
noData);
1580 if (this->_noData.size() == 0) {
1582 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
1587 if (classProperty.defaultProperty) {
1588 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1589 CESIUM_ASSERT(pEnumDefinition != nullptr);
1590 if constexpr (IsMetadataInteger<ElementType>::value) {
1591 this->_defaultValue = getEnumArrayValue(
1592 *classProperty.defaultProperty,
1595 }
else if (!this->_required) {
1596 this->_defaultValue = getArrayValue(*classProperty.defaultProperty);
1599 if (this->_defaultValue.size() == 0) {
1601 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
1615 _name(
std::nullopt),
1616 _semantic(
std::nullopt),
1617 _description(
std::nullopt),
1643 getNumericPropertyValues(property);
1662 getNumericPropertyValues(property);
1675 const std::optional<std::string>&
name() const noexcept {
return _name; }
1680 const std::optional<std::string>&
semantic() const noexcept {
1688 return _description;
1704 std::optional<PropertyArrayView<ElementType>>
offset() const noexcept {
1705 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
1712 std::optional<PropertyArrayView<ElementType>>
scale() const noexcept {
1713 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
1720 std::optional<PropertyArrayView<ElementType>>
max() const noexcept {
1721 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
1728 std::optional<PropertyArrayView<ElementType>>
min() const noexcept {
1729 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
1741 std::optional<PropertyArrayView<ElementType>>
noData() const noexcept {
1742 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
1749 std::optional<PropertyArrayView<ElementType>>
defaultValue() const noexcept {
1750 return this->_defaultValue.size() > 0
1751 ? std::make_optional(this->_defaultValue.view())
1766 std::optional<std::string> _name;
1767 std::optional<std::string> _semantic;
1768 std::optional<std::string> _description;
1782 using PropertyDefinitionType = std::
1783 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
1784 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
1786 [
this](
auto property) {
1787 bool isFixedSizeArray = this->_count > 0;
1789 if (property.offset) {
1794 if (isFixedSizeArray) {
1795 this->_offset = getArrayValue(*property.offset);
1796 if (this->_offset.
size() == this->_count) {
1808 if (property.scale) {
1813 if (isFixedSizeArray) {
1814 this->_scale = getArrayValue(*property.scale);
1815 if (this->_scale.
size() == this->_count) {
1828 if (isFixedSizeArray) {
1829 this->_max = getArrayValue(*property.max);
1831 if (!isFixedSizeArray || this->_max.
size() != this->_count) {
1839 if (isFixedSizeArray) {
1840 this->_min = getArrayValue(*property.min);
1842 if (!isFixedSizeArray || this->_min.
size() != this->_count) {
1859 std::vector<ElementType> values(array.size());
1861 if constexpr (IsMetadataScalar<ElementType>::value) {
1862 for (
size_t i = 0; i < array.size(); i++) {
1863 std::optional<ElementType> maybeValue =
1864 getScalar<ElementType>(array[i]);
1865 if (!maybeValue.has_value()) {
1866 return PropertyArrayCopy<ElementType>();
1869 values[i] = *maybeValue;
1872 if constexpr (IsMetadataVecN<ElementType>::value) {
1873 for (
size_t i = 0; i < array.size(); i++) {
1874 std::optional<ElementType> maybeValue = getVecN<ElementType>(array[i]);
1875 if (!maybeValue.has_value()) {
1876 return PropertyArrayCopy<ElementType>();
1879 values[i] = *maybeValue;
1883 if constexpr (IsMetadataMatN<ElementType>::value) {
1884 for (
size_t i = 0; i < array.size(); i++) {
1885 std::optional<ElementType> maybeValue = getMatN<ElementType>(array[i]);
1886 if (!maybeValue.has_value()) {
1887 return PropertyArrayCopy<ElementType>();
1890 values[i] = *maybeValue;
1894 return PropertyArrayCopy<ElementType>(values);
1897 static PropertyArrayCopy<ElementType> getEnumArrayValue(
1901 return PropertyArrayCopy<ElementType>();
1905 std::vector<ElementType> values(array.size());
1907 for (
size_t i = 0; i < array.size(); i++) {
1908 if (!array[i].isString()) {
1909 return PropertyArrayCopy<ElementType>();
1915 auto foundValue = std::find_if(
1916 enumDefinition.
values.begin(),
1917 enumDefinition.
values.end(),
1919 return enumValue.name == str;
1922 if (foundValue == enumDefinition.
values.end()) {
1923 return PropertyArrayCopy<ElementType>();
1926 values[i] =
static_cast<ElementType
>(foundValue->value);
1929 return PropertyArrayCopy<ElementType>(values);
1946template <
typename ElementType>
1957 _name(
std::nullopt),
1958 _semantic(
std::nullopt),
1959 _description(
std::nullopt),
1976 _name(classProperty.
name),
1979 _count(classProperty.count ? *classProperty.count : 0),
1993 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1997 getNumericPropertyValues(classProperty);
2002 if (classProperty.
noData) {
2003 if (!this->_required) {
2004 this->_noData = getArrayValue<ElementType>(*classProperty.noData);
2007 if (this->_noData.
size() == 0) {
2009 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2014 if (classProperty.defaultProperty) {
2015 if (!this->_required) {
2016 this->_defaultValue =
2017 getArrayValue<NormalizedType>(*classProperty.defaultProperty);
2020 if (this->_defaultValue.
size() == 0) {
2022 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2036 _name(
std::nullopt),
2037 _semantic(
std::nullopt),
2038 _description(
std::nullopt),
2062 getNumericPropertyValues(property);
2078 getNumericPropertyValues(property);
2090 const std::optional<std::string>&
name() const noexcept {
return _name; }
2095 const std::optional<std::string>&
semantic() const noexcept {
2103 return _description;
2119 std::optional<PropertyArrayView<NormalizedType>>
offset() const noexcept {
2120 return this->_offset.
size() > 0 ? std::make_optional(this->_offset.
view())
2127 std::optional<PropertyArrayView<NormalizedType>>
scale() const noexcept {
2128 return this->_scale.
size() > 0 ? std::make_optional(this->_scale.
view())
2135 std::optional<PropertyArrayView<NormalizedType>>
max() const noexcept {
2136 return this->_max.
size() > 0 ? std::make_optional(this->_max.
view())
2143 std::optional<PropertyArrayView<NormalizedType>>
min() const noexcept {
2144 return this->_min.
size() > 0 ? std::make_optional(this->_min.
view())
2156 std::optional<PropertyArrayView<ElementType>>
noData() const noexcept {
2157 return this->_noData.
size() > 0 ? std::make_optional(this->_noData.
view())
2164 std::optional<PropertyArrayView<NormalizedType>>
2166 return this->_defaultValue.
size() > 0
2167 ? std::make_optional(this->_defaultValue.
view())
2182 std::optional<std::string> _name;
2183 std::optional<std::string> _semantic;
2184 std::optional<std::string> _description;
2198 using PropertyDefinitionType = std::
2199 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
2200 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
2202 [
this](
auto property) {
2203 bool isFixedSizeArray = this->_count > 0;
2204 if (property.offset) {
2205 if (isFixedSizeArray) {
2206 this->_offset = getArrayValue<NormalizedType>(*property.offset);
2208 if (!isFixedSizeArray || this->_offset.
size() != this->_count) {
2215 if (property.scale) {
2216 if (isFixedSizeArray) {
2217 this->_scale = getArrayValue<NormalizedType>(*property.scale);
2219 if (!isFixedSizeArray || this->_scale.
size() != this->_count) {
2227 if (isFixedSizeArray) {
2228 this->_max = getArrayValue<NormalizedType>(*property.max);
2230 if (!isFixedSizeArray || this->_max.
size() != this->_count) {
2238 if (isFixedSizeArray) {
2239 this->_min = getArrayValue<NormalizedType>(*property.min);
2241 if (!isFixedSizeArray || this->_min.
size() != this->_count) {
2251 template <
typename T>
2259 std::vector<T> values(array.size());
2261 if constexpr (IsMetadataScalar<T>::value) {
2262 for (
size_t i = 0; i < array.size(); i++) {
2263 std::optional<T> maybeElement = getScalar<T>(array[i]);
2264 if (!maybeElement.has_value()) {
2265 return PropertyArrayCopy<T>();
2267 values[i] = *maybeElement;
2271 if constexpr (IsMetadataVecN<T>::value) {
2272 for (
size_t i = 0; i < array.size(); i++) {
2273 std::optional<T> maybeElement = getVecN<T>(array[i]);
2274 if (!maybeElement.has_value()) {
2275 return PropertyArrayCopy<T>();
2277 values[i] = *maybeElement;
2281 if constexpr (IsMetadataMatN<T>::value) {
2282 for (
size_t i = 0; i < array.size(); i++) {
2283 std::optional<T> maybeElement = getMatN<T>(array[i]);
2284 if (!maybeElement.has_value()) {
2285 return PropertyArrayCopy<T>();
2287 values[i] = *maybeElement;
2291 return PropertyArrayCopy<T>(values);
2306 _name(
std::nullopt),
2307 _semantic(
std::nullopt),
2308 _description(
std::nullopt),
2319 _name(classProperty.
name),
2322 _count(classProperty.count ? *classProperty.count : 0),
2330 if (!this->_required) {
2331 this->_defaultValue =
2332 getBooleanArrayValue(*classProperty.defaultProperty);
2335 if (this->_defaultValue.
size() == 0 ||
2336 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2337 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2351 _name(
std::nullopt),
2352 _semantic(
std::nullopt),
2353 _description(
std::nullopt),
2377 const std::optional<std::string>&
name() const noexcept {
return _name; }
2382 const std::optional<std::string>&
semantic() const noexcept {
2390 return _description;
2406 std::optional<PropertyArrayView<bool>>
offset() const noexcept {
2407 return std::nullopt;
2413 std::optional<PropertyArrayView<bool>>
scale() const noexcept {
2414 return std::nullopt;
2420 std::optional<PropertyArrayView<bool>>
max() const noexcept {
2421 return std::nullopt;
2427 std::optional<PropertyArrayView<bool>>
min() const noexcept {
2428 return std::nullopt;
2439 std::optional<PropertyArrayView<bool>>
noData() const noexcept {
2440 return std::nullopt;
2447 return this->_defaultValue.
size() > 0
2448 ? std::make_optional(this->_defaultValue.
view())
2463 std::optional<std::string> _name;
2464 std::optional<std::string> _semantic;
2465 std::optional<std::string> _description;
2479 std::vector<bool> values(array.size());
2480 for (
size_t i = 0; i < array.size(); i++) {
2481 if (!array[i].isBool()) {
2485 values[i] = array[i].getBool();
2502 _name(
std::nullopt),
2503 _semantic(
std::nullopt),
2504 _description(
std::nullopt),
2516 _name(classProperty.
name),
2519 _count(classProperty.count ? *classProperty.count : 0),
2527 if (classProperty.
noData) {
2528 if (!this->_required) {
2529 this->_noData = getStringArrayValue(*classProperty.noData);
2532 if (this->_noData.
size() == 0 ||
2533 (this->_count > 0 && this->_noData.size() != this->_count)) {
2534 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2539 if (classProperty.defaultProperty) {
2540 if (!this->_required) {
2541 this->_defaultValue =
2542 getStringArrayValue(*classProperty.defaultProperty);
2545 if (this->_defaultValue.
size() == 0 ||
2546 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2548 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2562 _name(
std::nullopt),
2563 _semantic(
std::nullopt),
2564 _description(
std::nullopt),
2589 const std::optional<std::string>&
name() const noexcept {
return _name; }
2594 const std::optional<std::string>&
semantic() const noexcept {
2602 return _description;
2618 std::optional<PropertyArrayView<std::string_view>>
offset() const noexcept {
2619 return std::nullopt;
2625 std::optional<PropertyArrayView<std::string_view>>
scale() const noexcept {
2626 return std::nullopt;
2632 std::optional<PropertyArrayView<std::string_view>>
max() const noexcept {
2633 return std::nullopt;
2639 std::optional<PropertyArrayView<std::string_view>>
min() const noexcept {
2640 return std::nullopt;
2651 std::optional<PropertyArrayView<std::string_view>>
noData() const noexcept {
2652 return this->_noData.
size() > 0 ? std::make_optional(this->_noData.
view())
2659 std::optional<PropertyArrayView<std::string_view>>
2661 return this->_defaultValue.
size() > 0
2662 ? std::make_optional(this->_defaultValue.
view())
2677 std::optional<std::string> _name;
2678 std::optional<std::string> _semantic;
2679 std::optional<std::string> _description;
2694 std::vector<std::string> strings(array.size());
2696 for (
size_t i = 0; i < array.size(); i++) {
2697 if (!array[i].isString()) {
2701 strings[i] = array[i].getString();
A copy of an array element of a PropertyTableProperty or PropertyTextureProperty.
int64_t size() const noexcept
The number of elements in this array.
const PropertyArrayView< ElementType > & view() const
Obtains a PropertyArrayView over the contents of this copy.
A view on an array element of a PropertyTableProperty or PropertyTextureProperty.
Indicates the status of a property view.
static const PropertyViewStatusType ErrorTypeMismatch
This property view's type does not match what is specified in ClassProperty::type.
static const PropertyViewStatusType ErrorInvalidDefaultValue
The property provided an invalid default value.
static const PropertyViewStatusType ErrorInvalidMin
The property provided an invalid minimum value.
static const PropertyViewStatusType ErrorInvalidMax
The property provided an invalid maximum value.
static const PropertyViewStatusType ErrorInvalidOffset
The property provided an invalid offset value.
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 ErrorInvalidNoDataValue
The property provided an invalid "no data" value.
static const PropertyViewStatusType ErrorNormalizationMismatch
This property view's normalization differs from what is specified in ClassProperty::normalized.
static const PropertyViewStatusType ErrorInvalidEnum
The property provided an invalid enum value.
static const PropertyViewStatusType EmptyPropertyWithDefault
This property view does not contain any data, but specifies a default value. This happens when a clas...
static const PropertyViewStatusType ErrorInvalidScale
The property provided an invalid scale value.
static const PropertyViewStatusType ErrorComponentTypeMismatch
This property view's component type does not match what is specified in ClassProperty::componentType.
std::optional< ElementType > offset() const noexcept
Gets the offset to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the...
std::optional< ElementType > scale() const noexcept
Gets the scale to apply to property values. Only applicable to SCALAR, VECN, and MATN types when the ...
bool required() const noexcept
Whether the property must be present in every entity conforming to the class. If not required,...
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property table property and its class definition,...
std::optional< ElementType > defaultValue() const noexcept
Gets the default value to use when encountering a "no data" value or an omitted property....
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property texture property, class definition,...
PropertyView(const ClassProperty &classProperty, const PropertyAttributeProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property attribute property and its class definition,...
const std::optional< std::string > & name() const noexcept
Gets the name of the property being viewed. Returns std::nullopt if no name was specified.
PropertyViewStatusType _status
Indicates the status of a property view.
const std::optional< std::string > & semantic() const noexcept
Gets the semantic of the property being viewed. The semantic is an identifier that describes how this...
bool normalized() const noexcept
Whether this property has a normalized integer type.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
int64_t arrayCount() const noexcept
Get the element count of the fixed-length arrays in this property. Only applicable when the property ...
PropertyViewStatusType status() const noexcept
Gets the status of this property view, indicating whether an error occurred.
std::optional< ElementType > noData() const noexcept
Gets the "no data" value, i.e., the value representing missing data in the property wherever it appea...
std::optional< ElementType > min() const noexcept
Gets the minimum allowed value for the property. Only applicable to SCALAR, VECN, and MATN types....
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
std::optional< ElementType > max() const noexcept
Gets the maximum allowed value for the property. Only applicable to SCALAR, VECN, and MATN types....
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
PropertyView(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition)
Constructs a property instance from a class definition and enum definition.
const std::optional< std::string > & description() const noexcept
Gets the description of the property being viewed. Returns std::nullopt if no description was specifi...
PropertyView()
Constructs an empty property instance.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property)
Constructs a property instance from a property table property and its class definition.
std::optional< ElementType > noData() const noexcept
Constructs an empty property instance. false>noData
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< NormalizedType > max() const noexcept
Constructs an empty property instance. false>max
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property)
Constructs a property instance from a property texture property and its class definition.
PropertyView(const ClassProperty &classProperty, const PropertyAttributeProperty &property)
Constructs a property instance from a property attribute property and its class definition.
PropertyViewStatusType _status
Indicates the status of a property view.
std::optional< NormalizedType > scale() const noexcept
Constructs an empty property instance. false>scale
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView()
Constructs an empty property instance.
std::optional< NormalizedType > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< NormalizedType > offset() const noexcept
Constructs an empty property instance. false>offset
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< NormalizedType > min() const noexcept
Constructs an empty property instance. false>min
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property texture property, its class definition,...
std::optional< PropertyArrayView< ElementType > > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< PropertyArrayView< ElementType > > offset() const noexcept
Constructs an empty property instance. false>offset
std::optional< PropertyArrayView< ElementType > > max() const noexcept
Constructs an empty property instance. false>max
std::optional< PropertyArrayView< ElementType > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< PropertyArrayView< ElementType > > min() const noexcept
Constructs an empty property instance. false>min
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
PropertyView(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition)
Constructs a property instance from a class definition and enum definition.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView()
Constructs an empty property instance.
PropertyType propertyType() const noexcept
Returns the PropertyType of the property that this view is accessing.
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Constructs a property instance from a property table property, its class definition,...
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< PropertyArrayView< ElementType > > scale() const noexcept
Constructs an empty property instance. false>scale
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
std::optional< PropertyArrayView< NormalizedType > > max() const noexcept
Constructs an empty property instance. false>max
PropertyViewStatusType _status
Indicates the status of a property view.
std::optional< PropertyArrayView< NormalizedType > > scale() const noexcept
Constructs an empty property instance. false>scale
std::optional< PropertyArrayView< ElementType > > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyView()
Constructs an empty property instance.
std::optional< PropertyArrayView< NormalizedType > > min() const noexcept
Constructs an empty property instance. false>min
PropertyView(const ClassProperty &classProperty, const PropertyTextureProperty &property)
Constructs a property instance from a property texture property and its class definition.
std::optional< PropertyArrayView< NormalizedType > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &property)
Constructs a property instance from a property table property and its class definition.
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< PropertyArrayView< NormalizedType > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
std::optional< PropertyArrayView< bool > > min() const noexcept
Constructs an empty property instance. false>min
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
std::optional< PropertyArrayView< bool > > max() const noexcept
Constructs an empty property instance. false>max
std::optional< PropertyArrayView< bool > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyView()
Constructs an empty property instance.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool required() const noexcept
Constructs an empty property instance. false>required
std::optional< PropertyArrayView< bool > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< PropertyArrayView< bool > > scale() const noexcept
Constructs an empty property instance. false>scale
std::optional< PropertyArrayView< bool > > noData() const noexcept
Constructs an empty property instance. false>noData
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
std::optional< PropertyArrayView< std::string_view > > max() const noexcept
Constructs an empty property instance. false>max
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
PropertyView()
Constructs an empty property instance.
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
std::optional< PropertyArrayView< std::string_view > > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyViewStatusType _status
Indicates the status of a property view.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
std::optional< PropertyArrayView< std::string_view > > min() const noexcept
Constructs an empty property instance. false>min
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
std::optional< PropertyArrayView< std::string_view > > noData() const noexcept
Constructs an empty property instance. false>noData
bool required() const noexcept
Constructs an empty property instance. false>required
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< PropertyArrayView< std::string_view > > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< PropertyArrayView< std::string_view > > scale() const noexcept
Constructs an empty property instance. false>scale
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
std::optional< bool > min() const noexcept
Constructs an empty property instance. false>min
std::optional< bool > noData() const noexcept
Constructs an empty property instance. false>noData
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
bool required() const noexcept
Constructs an empty property instance. false>required
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
std::optional< bool > scale() const noexcept
Constructs an empty property instance. false>scale
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyView()
Constructs an empty property instance.
std::optional< bool > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
std::optional< bool > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< bool > max() const noexcept
Constructs an empty property instance. false>max
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
bool required() const noexcept
Constructs an empty property instance. false>required
const std::optional< std::string > & name() const noexcept
Constructs an empty property instance. false>name
PropertyView()
Constructs an empty property instance.
std::optional< std::string_view > min() const noexcept
Constructs an empty property instance. false>min
std::optional< std::string_view > offset() const noexcept
Constructs an empty property instance. false>offset
PropertyViewStatusType _status
Indicates the status of a property view.
PropertyView(const ClassProperty &classProperty)
Constructs a property instance from a class definition only.
std::optional< std::string_view > scale() const noexcept
Constructs an empty property instance. false>scale
const std::optional< std::string > & description() const noexcept
Constructs an empty property instance. false>description
PropertyView(const ClassProperty &classProperty, const PropertyTableProperty &, const CesiumGltf::Enum *)
Constructs a property instance from a property table property and its class definition.
std::optional< std::string_view > defaultValue() const noexcept
Constructs an empty property instance. false>defaultValue
PropertyType propertyType() const noexcept
Returns the PropertyType of the property this view is accessing.
int64_t arrayCount() const noexcept
Constructs an empty property instance. false>arrayCount
PropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
std::optional< std::string_view > noData() const noexcept
Constructs an empty property instance. false>noData
std::optional< std::string_view > max() const noexcept
Constructs an empty property instance. false>max
const std::optional< std::string > & semantic() const noexcept
Constructs an empty property instance. false>semantic
bool normalized() const noexcept
Constructs an empty property instance. false>normalized
PropertyViewStatusType status() const noexcept
Constructs an empty property instance. false>status
Represents a metadata property in EXT_structural_metadata.
A generic implementation of a value in a JSON structure.
bool getBool() const
Gets the bool from the value.
const JsonValue::String & getString() const
Gets the string from the value.
std::vector< JsonValue > Array
The type to represent an Array JSON value.
bool isBool() const noexcept
Returns whether this value is a Bool value.
std::string String
The type to represent a String JSON value.
bool isArray() const noexcept
Returns whether this value is an Array value.
bool isString() const noexcept
Returns whether this value is a String value.
std::optional< To > getSafeNumber() const
Gets the numerical quantity from the value casted to the To type. This function should be used over g...
const JsonValue::Array & getArray() const
Gets the array from the value.
Classes for working with glTF models.
PropertyComponentType
The possible types of a property component.
@ Float32
A property component equivalent to a float.
@ Float64
A property component equivalent to a double.
PropertyComponentType convertStringToPropertyComponentType(const std::string &str)
Converts a string into a PropertyComponentType.
PropertyViewStatusType validatePropertyType(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Validates a ClassProperty representing a property, checking for any type mismatches.
PropertyViewStatusType validateArrayPropertyType(const ClassProperty &classProperty, const CesiumGltf::Enum *pEnumDefinition=nullptr)
Validates a ClassProperty representing an array of values, checking for any type mismatches.
bool canRepresentPropertyType(PropertyType type)
Returns whether the type T can represent the given PropertyType.
int64_t getCount(std::optional< std::vector< std::byte > > &buffer)
Obtains the number of values of type ElementType that could fit in the buffer.
PropertyType convertStringToPropertyType(const std::string &str)
Converts a string into a PropertyType.
PropertyType
The possible types of a property in a PropertyTableView.
@ Invalid
An invalid property type.
int32_t PropertyViewStatusType
The type used for fields of PropertyViewStatus.
static const std::string ENUM
ENUM
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::optional< CesiumUtility::JsonValue > noData
A noData value represents missing data — also known as a sentinel value — wherever it appears....
std::string type
The element type.
std::optional< CesiumUtility::JsonValue > defaultProperty
A default value to use when encountering a noData value or an omitted property. The value is given in...
std::vector< CesiumGltf::EnumValue > values
An array of enum values. Duplicate names or duplicate integer values are not allowed.
This class is not meant to be instantiated directly. Use Enum instead.
An attribute containing property values.
An array of binary property values.
A texture containing property values.
Convert an integer numeric type to the corresponding representation as a double type....
Infer the best-fitting PropertyType and PropertyComponentType for a C++ type.