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) {
896 _semantic(
std::nullopt),
897 _description(
std::nullopt),
898 _offset(
std::nullopt),
899 _scale(
std::nullopt),
903 _noData(
std::nullopt),
904 _defaultValue(
std::nullopt),
920 getNumericPropertyValues(property);
936 getNumericPropertyValues(property);
952 getNumericPropertyValues(property);
964 const std::optional<std::string>&
name() const noexcept {
return _name; }
969 const std::optional<std::string>&
semantic() const noexcept {
993 std::optional<NormalizedType>
offset() const noexcept {
return _offset; }
998 std::optional<NormalizedType>
scale() const noexcept {
return _scale; }
1003 std::optional<NormalizedType>
max() const noexcept {
return _max; }
1008 std::optional<NormalizedType>
min() const noexcept {
return _min; }
1018 std::optional<ElementType>
noData() const noexcept {
return _noData; }
1024 return _defaultValue;
1038 std::optional<std::string> _name;
1039 std::optional<std::string> _semantic;
1040 std::optional<std::string> _description;
1042 std::optional<NormalizedType> _offset;
1043 std::optional<NormalizedType> _scale;
1044 std::optional<NormalizedType> _max;
1045 std::optional<NormalizedType> _min;
1048 std::optional<ElementType> _noData;
1049 std::optional<NormalizedType> _defaultValue;
1061 template <
typename T>
1064 return getScalar<T>(jsonValue);
1068 return getVecN<T>(jsonValue);
1072 return getMatN<T>(jsonValue);
1076 using PropertyDefinitionType = std::variant<
1086 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
1088 [
this](
auto property) {
1089 if (property.offset) {
1090 _offset = getValue<NormalizedType>(*property.offset);
1098 if (property.scale) {
1099 _scale = getValue<NormalizedType>(*property.scale);
1102 _status = PropertyViewStatus::ErrorInvalidScale;
1108 _max = getValue<NormalizedType>(*property.max);
1111 _status = PropertyViewStatus::ErrorInvalidMax;
1117 _min = getValue<NormalizedType>(*property.min);
1120 _status = PropertyViewStatus::ErrorInvalidMin;
1140 _name(
std::nullopt),
1141 _semantic(
std::nullopt),
1142 _description(
std::nullopt),
1144 _defaultValue(
std::nullopt) {}
1151 _name(classProperty.
name),
1155 _defaultValue(
std::nullopt) {
1162 _defaultValue = getBooleanValue(*classProperty.defaultProperty);
1165 if (!_defaultValue) {
1182 _name(
std::nullopt),
1183 _semantic(
std::nullopt),
1184 _description(
std::nullopt),
1186 _defaultValue(
std::nullopt) {}
1207 const std::optional<std::string>&
name() const noexcept {
return _name; }
1212 const std::optional<std::string>&
semantic() const noexcept {
1220 return _description;
1236 std::optional<bool>
offset() const noexcept {
return std::nullopt; }
1241 std::optional<bool>
scale() const noexcept {
return std::nullopt; }
1246 std::optional<bool>
max() const noexcept {
return std::nullopt; }
1251 std::optional<bool>
min() const noexcept {
return std::nullopt; }
1261 std::optional<bool>
noData() const noexcept {
return std::nullopt; }
1266 std::optional<bool>
defaultValue() const noexcept {
return _defaultValue; }
1279 std::optional<std::string> _name;
1280 std::optional<std::string> _semantic;
1281 std::optional<std::string> _description;
1284 std::optional<bool> _defaultValue;
1286 static std::optional<bool>
1289 return std::nullopt;
1307 _name(
std::nullopt),
1308 _semantic(
std::nullopt),
1309 _description(
std::nullopt),
1311 _noData(
std::nullopt),
1312 _defaultValue(
std::nullopt) {}
1319 _name(classProperty.
name),
1323 _noData(
std::nullopt),
1324 _defaultValue(
std::nullopt) {
1329 if (classProperty.
noData) {
1331 _noData = getStringValue(*classProperty.noData);
1341 if (classProperty.defaultProperty) {
1343 _defaultValue = getStringValue(*classProperty.defaultProperty);
1346 if (!_defaultValue) {
1363 _name(
std::nullopt),
1364 _semantic(
std::nullopt),
1365 _description(
std::nullopt),
1367 _noData(
std::nullopt),
1368 _defaultValue(
std::nullopt) {}
1389 const std::optional<std::string>&
name() const noexcept {
return _name; }
1394 const std::optional<std::string>&
semantic() const noexcept {
1402 return _description;
1418 std::optional<std::string_view>
offset() const noexcept {
1419 return std::nullopt;
1425 std::optional<std::string_view>
scale() const noexcept {
1426 return std::nullopt;
1432 std::optional<std::string_view>
max() const noexcept {
return std::nullopt; }
1437 std::optional<std::string_view>
min() const noexcept {
return std::nullopt; }
1447 std::optional<std::string_view>
noData() const noexcept {
1449 return std::string_view(*_noData);
1451 return std::nullopt;
1459 return std::string_view(*_defaultValue);
1461 return std::nullopt;
1475 std::optional<std::string> _name;
1476 std::optional<std::string> _semantic;
1477 std::optional<std::string> _description;
1480 std::optional<std::string> _noData;
1481 std::optional<std::string> _defaultValue;
1483 static std::optional<std::string>
1486 return std::nullopt;
1489 return std::string(value.
getString().c_str());
1506template <
typename ElementType>
1514 _name(
std::nullopt),
1515 _semantic(
std::nullopt),
1516 _description(
std::nullopt),
1543 _name(classProperty.
name),
1546 _count(classProperty.count ? *classProperty.count : 0),
1560 _status = PropertyViewStatus::ErrorNormalizationMismatch;
1565 getNumericPropertyValues(classProperty);
1572 if (classProperty.
noData) {
1573 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1574 CESIUM_ASSERT(pEnumDefinition != nullptr);
1575 if constexpr (IsMetadataInteger<ElementType>::value) {
1577 getEnumArrayValue(*classProperty.noData, *pEnumDefinition);
1579 }
else if (!this->_required) {
1580 this->_noData = getArrayValue(*classProperty.
noData);
1583 if (this->_noData.size() == 0) {
1585 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
1590 if (classProperty.defaultProperty) {
1591 if (!this->_required && this->_propertyType == PropertyType::Enum) {
1592 CESIUM_ASSERT(pEnumDefinition != nullptr);
1593 if constexpr (IsMetadataInteger<ElementType>::value) {
1594 this->_defaultValue = getEnumArrayValue(
1595 *classProperty.defaultProperty,
1598 }
else if (!this->_required) {
1599 this->_defaultValue = getArrayValue(*classProperty.defaultProperty);
1602 if (this->_defaultValue.size() == 0) {
1604 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
1619 _name(
std::nullopt),
1620 _semantic(
std::nullopt),
1621 _description(
std::nullopt),
1647 getNumericPropertyValues(property);
1666 getNumericPropertyValues(property);
1679 const std::optional<std::string>&
name() const noexcept {
return _name; }
1684 const std::optional<std::string>&
semantic() const noexcept {
1692 return _description;
1708 std::optional<PropertyArrayView<ElementType>>
offset() const noexcept {
1709 return this->_offset.size() > 0 ? std::make_optional(this->_offset.view())
1716 std::optional<PropertyArrayView<ElementType>>
scale() const noexcept {
1717 return this->_scale.size() > 0 ? std::make_optional(this->_scale.view())
1724 std::optional<PropertyArrayView<ElementType>>
max() const noexcept {
1725 return this->_max.size() > 0 ? std::make_optional(this->_max.view())
1732 std::optional<PropertyArrayView<ElementType>>
min() const noexcept {
1733 return this->_min.size() > 0 ? std::make_optional(this->_min.view())
1745 std::optional<PropertyArrayView<ElementType>>
noData() const noexcept {
1746 return this->_noData.size() > 0 ? std::make_optional(this->_noData.view())
1753 std::optional<PropertyArrayView<ElementType>>
defaultValue() const noexcept {
1754 return this->_defaultValue.size() > 0
1755 ? std::make_optional(this->_defaultValue.view())
1770 std::optional<std::string> _name;
1771 std::optional<std::string> _semantic;
1772 std::optional<std::string> _description;
1786 using PropertyDefinitionType = std::
1787 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
1788 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
1790 [
this](
auto property) {
1791 bool isFixedSizeArray = this->_count > 0;
1793 if (property.offset) {
1798 if (isFixedSizeArray) {
1799 this->_offset = getArrayValue(*property.offset);
1800 if (this->_offset.
size() == this->_count) {
1812 if (property.scale) {
1817 if (isFixedSizeArray) {
1818 this->_scale = getArrayValue(*property.scale);
1819 if (this->_scale.
size() == this->_count) {
1832 if (isFixedSizeArray) {
1833 this->_max = getArrayValue(*property.max);
1835 if (!isFixedSizeArray || this->_max.
size() != this->_count) {
1843 if (isFixedSizeArray) {
1844 this->_min = getArrayValue(*property.min);
1846 if (!isFixedSizeArray || this->_min.
size() != this->_count) {
1863 std::vector<ElementType> values(array.size());
1865 if constexpr (IsMetadataScalar<ElementType>::value) {
1866 for (
size_t i = 0; i < array.size(); i++) {
1867 std::optional<ElementType> maybeValue =
1868 getScalar<ElementType>(array[i]);
1869 if (!maybeValue.has_value()) {
1870 return PropertyArrayCopy<ElementType>();
1873 values[i] = *maybeValue;
1876 if constexpr (IsMetadataVecN<ElementType>::value) {
1877 for (
size_t i = 0; i < array.size(); i++) {
1878 std::optional<ElementType> maybeValue = getVecN<ElementType>(array[i]);
1879 if (!maybeValue.has_value()) {
1880 return PropertyArrayCopy<ElementType>();
1883 values[i] = *maybeValue;
1887 if constexpr (IsMetadataMatN<ElementType>::value) {
1888 for (
size_t i = 0; i < array.size(); i++) {
1889 std::optional<ElementType> maybeValue = getMatN<ElementType>(array[i]);
1890 if (!maybeValue.has_value()) {
1891 return PropertyArrayCopy<ElementType>();
1894 values[i] = *maybeValue;
1898 return PropertyArrayCopy<ElementType>(values);
1901 static PropertyArrayCopy<ElementType> getEnumArrayValue(
1905 return PropertyArrayCopy<ElementType>();
1909 std::vector<ElementType> values(array.size());
1911 for (
size_t i = 0; i < array.size(); i++) {
1912 if (!array[i].isString()) {
1913 return PropertyArrayCopy<ElementType>();
1919 auto foundValue = std::find_if(
1920 enumDefinition.
values.begin(),
1921 enumDefinition.
values.end(),
1923 return enumValue.name == str;
1926 if (foundValue == enumDefinition.
values.end()) {
1927 return PropertyArrayCopy<ElementType>();
1930 values[i] =
static_cast<ElementType
>(foundValue->value);
1933 return PropertyArrayCopy<ElementType>(values);
1950template <
typename ElementType>
1961 _name(
std::nullopt),
1962 _semantic(
std::nullopt),
1963 _description(
std::nullopt),
1980 _name(classProperty.
name),
1983 _count(classProperty.count ? *classProperty.count : 0),
1997 _status = PropertyViewStatus::ErrorNormalizationMismatch;
2001 getNumericPropertyValues(classProperty);
2006 if (classProperty.
noData) {
2007 if (!this->_required) {
2008 this->_noData = getArrayValue<ElementType>(*classProperty.noData);
2011 if (this->_noData.
size() == 0) {
2013 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2018 if (classProperty.defaultProperty) {
2019 if (!this->_required) {
2020 this->_defaultValue =
2021 getArrayValue<NormalizedType>(*classProperty.defaultProperty);
2024 if (this->_defaultValue.
size() == 0) {
2026 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2041 _name(
std::nullopt),
2042 _semantic(
std::nullopt),
2043 _description(
std::nullopt),
2067 getNumericPropertyValues(property);
2083 getNumericPropertyValues(property);
2095 const std::optional<std::string>&
name() const noexcept {
return _name; }
2100 const std::optional<std::string>&
semantic() const noexcept {
2108 return _description;
2124 std::optional<PropertyArrayView<NormalizedType>>
offset() const noexcept {
2125 return this->_offset.
size() > 0 ? std::make_optional(this->_offset.
view())
2132 std::optional<PropertyArrayView<NormalizedType>>
scale() const noexcept {
2133 return this->_scale.
size() > 0 ? std::make_optional(this->_scale.
view())
2140 std::optional<PropertyArrayView<NormalizedType>>
max() const noexcept {
2141 return this->_max.
size() > 0 ? std::make_optional(this->_max.
view())
2148 std::optional<PropertyArrayView<NormalizedType>>
min() const noexcept {
2149 return this->_min.
size() > 0 ? std::make_optional(this->_min.
view())
2161 std::optional<PropertyArrayView<ElementType>>
noData() const noexcept {
2162 return this->_noData.
size() > 0 ? std::make_optional(this->_noData.
view())
2169 std::optional<PropertyArrayView<NormalizedType>>
2171 return this->_defaultValue.
size() > 0
2172 ? std::make_optional(this->_defaultValue.
view())
2187 std::optional<std::string> _name;
2188 std::optional<std::string> _semantic;
2189 std::optional<std::string> _description;
2203 using PropertyDefinitionType = std::
2204 variant<ClassProperty, PropertyTableProperty, PropertyTextureProperty>;
2205 void getNumericPropertyValues(
const PropertyDefinitionType& inProperty) {
2207 [
this](
auto property) {
2208 bool isFixedSizeArray = this->_count > 0;
2209 if (property.offset) {
2210 if (isFixedSizeArray) {
2211 this->_offset = getArrayValue<NormalizedType>(*property.offset);
2213 if (!isFixedSizeArray || this->_offset.
size() != this->_count) {
2220 if (property.scale) {
2221 if (isFixedSizeArray) {
2222 this->_scale = getArrayValue<NormalizedType>(*property.scale);
2224 if (!isFixedSizeArray || this->_scale.
size() != this->_count) {
2232 if (isFixedSizeArray) {
2233 this->_max = getArrayValue<NormalizedType>(*property.max);
2235 if (!isFixedSizeArray || this->_max.
size() != this->_count) {
2243 if (isFixedSizeArray) {
2244 this->_min = getArrayValue<NormalizedType>(*property.min);
2246 if (!isFixedSizeArray || this->_min.
size() != this->_count) {
2256 template <
typename T>
2264 std::vector<T> values(array.size());
2266 if constexpr (IsMetadataScalar<T>::value) {
2267 for (
size_t i = 0; i < array.size(); i++) {
2268 std::optional<T> maybeElement = getScalar<T>(array[i]);
2269 if (!maybeElement.has_value()) {
2270 return PropertyArrayCopy<T>();
2272 values[i] = *maybeElement;
2276 if constexpr (IsMetadataVecN<T>::value) {
2277 for (
size_t i = 0; i < array.size(); i++) {
2278 std::optional<T> maybeElement = getVecN<T>(array[i]);
2279 if (!maybeElement.has_value()) {
2280 return PropertyArrayCopy<T>();
2282 values[i] = *maybeElement;
2286 if constexpr (IsMetadataMatN<T>::value) {
2287 for (
size_t i = 0; i < array.size(); i++) {
2288 std::optional<T> maybeElement = getMatN<T>(array[i]);
2289 if (!maybeElement.has_value()) {
2290 return PropertyArrayCopy<T>();
2292 values[i] = *maybeElement;
2296 return PropertyArrayCopy<T>(values);
2311 _name(
std::nullopt),
2312 _semantic(
std::nullopt),
2313 _description(
std::nullopt),
2324 _name(classProperty.
name),
2327 _count(classProperty.count ? *classProperty.count : 0),
2335 if (!this->_required) {
2336 this->_defaultValue =
2337 getBooleanArrayValue(*classProperty.defaultProperty);
2340 if (this->_defaultValue.
size() == 0 ||
2341 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2342 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2357 _name(
std::nullopt),
2358 _semantic(
std::nullopt),
2359 _description(
std::nullopt),
2383 const std::optional<std::string>&
name() const noexcept {
return _name; }
2388 const std::optional<std::string>&
semantic() const noexcept {
2396 return _description;
2412 std::optional<PropertyArrayView<bool>>
offset() const noexcept {
2413 return std::nullopt;
2419 std::optional<PropertyArrayView<bool>>
scale() const noexcept {
2420 return std::nullopt;
2426 std::optional<PropertyArrayView<bool>>
max() const noexcept {
2427 return std::nullopt;
2433 std::optional<PropertyArrayView<bool>>
min() const noexcept {
2434 return std::nullopt;
2445 std::optional<PropertyArrayView<bool>>
noData() const noexcept {
2446 return std::nullopt;
2453 return this->_defaultValue.
size() > 0
2454 ? std::make_optional(this->_defaultValue.
view())
2469 std::optional<std::string> _name;
2470 std::optional<std::string> _semantic;
2471 std::optional<std::string> _description;
2485 std::vector<bool> values(array.size());
2486 for (
size_t i = 0; i < array.size(); i++) {
2487 if (!array[i].isBool()) {
2491 values[i] = array[i].getBool();
2508 _name(
std::nullopt),
2509 _semantic(
std::nullopt),
2510 _description(
std::nullopt),
2522 _name(classProperty.
name),
2525 _count(classProperty.count ? *classProperty.count : 0),
2533 if (classProperty.
noData) {
2534 if (!this->_required) {
2535 this->_noData = getStringArrayValue(*classProperty.noData);
2538 if (this->_noData.
size() == 0 ||
2539 (this->_count > 0 && this->_noData.size() != this->_count)) {
2540 this->_status = PropertyViewStatus::ErrorInvalidNoDataValue;
2545 if (classProperty.defaultProperty) {
2546 if (!this->_required) {
2547 this->_defaultValue =
2548 getStringArrayValue(*classProperty.defaultProperty);
2551 if (this->_defaultValue.
size() == 0 ||
2552 (this->_count > 0 && this->_defaultValue.size() != this->_count)) {
2554 this->_status = PropertyViewStatus::ErrorInvalidDefaultValue;
2569 _name(
std::nullopt),
2570 _semantic(
std::nullopt),
2571 _description(
std::nullopt),
2596 const std::optional<std::string>&
name() const noexcept {
return _name; }
2601 const std::optional<std::string>&
semantic() const noexcept {
2609 return _description;
2625 std::optional<PropertyArrayView<std::string_view>>
offset() const noexcept {
2626 return std::nullopt;
2632 std::optional<PropertyArrayView<std::string_view>>
scale() const noexcept {
2633 return std::nullopt;
2639 std::optional<PropertyArrayView<std::string_view>>
max() const noexcept {
2640 return std::nullopt;
2646 std::optional<PropertyArrayView<std::string_view>>
min() const noexcept {
2647 return std::nullopt;
2658 std::optional<PropertyArrayView<std::string_view>>
noData() const noexcept {
2659 return this->_noData.
size() > 0 ? std::make_optional(this->_noData.
view())
2666 std::optional<PropertyArrayView<std::string_view>>
2668 return this->_defaultValue.
size() > 0
2669 ? std::make_optional(this->_defaultValue.
view())
2684 std::optional<std::string> _name;
2685 std::optional<std::string> _semantic;
2686 std::optional<std::string> _description;
2701 std::vector<std::string> strings(array.size());
2703 for (
size_t i = 0; i < array.size(); i++) {
2704 if (!array[i].isString()) {
2708 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.