3 #include "CesiumGltf/Class.h"
4 #include "CesiumGltf/ClassProperty.h"
5 #include "CesiumGltf/ExtensionModelExtStructuralMetadata.h"
6 #include "CesiumGltf/Model.h"
7 #include "CesiumGltf/PropertyTexture.h"
8 #include "CesiumGltf/PropertyTexturePropertyView.h"
9 #include "CesiumGltf/TextureView.h"
75 const std::optional<std::string>&
name() const noexcept {
76 return _pPropertyTexture->
name;
121 template <
typename T,
bool Normalized = false>
123 const std::string& propertyId,
131 if (!pClassProperty) {
136 return getPropertyViewImpl<T, Normalized>(
162 template <
typename Callback>
164 const std::string& propertyId,
176 if (!pClassProperty) {
184 PropertyType type = convertStringToPropertyType(pClassProperty->
type);
185 PropertyComponentType componentType = PropertyComponentType::None;
188 convertStringToPropertyComponentType(*pClassProperty->
componentType);
192 if (normalized && !isPropertyComponentTypeInteger(componentType)) {
201 if (pClassProperty->
array) {
203 getArrayPropertyViewImpl<Callback, true>(
208 std::forward<Callback>(callback),
211 getArrayPropertyViewImpl<Callback, false>(
216 std::forward<Callback>(callback),
222 if (type == PropertyType::Scalar) {
224 getScalarPropertyViewImpl<Callback, true>(
228 std::forward<Callback>(callback),
231 getScalarPropertyViewImpl<Callback, false>(
235 std::forward<Callback>(callback),
241 if (isPropertyTypeVecN(type)) {
243 getVecNPropertyViewImpl<Callback, true>(
248 std::forward<Callback>(callback),
251 getVecNPropertyViewImpl<Callback, false>(
256 std::forward<Callback>(callback),
290 template <
typename Callback>
294 for (
const auto& property : this->_pClass->
properties) {
297 std::forward<Callback>(callback),
303 template <
typename T,
bool Normalized>
305 const std::string& propertyId,
308 auto propertyTexturePropertyIter =
309 _pPropertyTexture->
properties.find(propertyId);
310 if (propertyTexturePropertyIter == _pPropertyTexture->
properties.end()) {
318 return PropertyTexturePropertyView<T, Normalized>(
322 const PropertyTextureProperty& propertyTextureProperty =
323 propertyTexturePropertyIter->second;
325 if constexpr (IsMetadataScalar<T>::value) {
326 return createScalarPropertyView<T, Normalized>(
328 propertyTextureProperty,
332 if constexpr (IsMetadataVecN<T>::value) {
333 return createVecNPropertyView<T, Normalized>(
335 propertyTextureProperty,
339 if constexpr (IsMetadataArray<T>::value) {
340 return createArrayPropertyView<
341 typename MetadataArrayType<T>::type,
342 Normalized>(classProperty, propertyTextureProperty, propertyOptions);
346 template <
typename Callback,
bool Normalized>
347 void getArrayPropertyViewImpl(
348 const std::string& propertyId,
349 const ClassProperty& classProperty,
351 PropertyComponentType componentType,
353 const TextureViewOptions& propertyOptions)
const {
355 if (type != PropertyType::Scalar) {
358 PropertyTexturePropertyView<uint8_t>(
363 int64_t count = classProperty.count.value_or(0);
364 if (count <= 0 || count > 4) {
367 PropertyTexturePropertyView<uint8_t>(
372 switch (componentType) {
373 case PropertyComponentType::Int8:
376 getPropertyViewImpl<PropertyArrayView<int8_t>, Normalized>(
381 case PropertyComponentType::Uint8:
384 getPropertyViewImpl<PropertyArrayView<uint8_t>, Normalized>(
389 case PropertyComponentType::Int16:
392 getPropertyViewImpl<PropertyArrayView<int16_t>, Normalized>(
397 case PropertyComponentType::Uint16:
400 getPropertyViewImpl<PropertyArrayView<uint16_t>, Normalized>(
408 PropertyTexturePropertyView<uint8_t>(
414 template <
typename Callback,
bool Normalized>
415 void getScalarPropertyViewImpl(
416 const std::string& propertyId,
417 const ClassProperty& classProperty,
418 PropertyComponentType componentType,
420 const TextureViewOptions& propertyOptions)
const {
421 switch (componentType) {
422 case PropertyComponentType::Int8:
425 getPropertyViewImpl<int8_t, Normalized>(
430 case PropertyComponentType::Uint8:
433 getPropertyViewImpl<uint8_t, Normalized>(
438 case PropertyComponentType::Int16:
441 getPropertyViewImpl<int16_t, Normalized>(
446 case PropertyComponentType::Uint16:
449 getPropertyViewImpl<uint16_t, Normalized>(
454 case PropertyComponentType::Int32:
457 getPropertyViewImpl<int32_t, Normalized>(
462 case PropertyComponentType::Uint32:
465 getPropertyViewImpl<uint32_t, Normalized>(
470 case PropertyComponentType::Float32:
473 getPropertyViewImpl<float, false>(
481 PropertyTexturePropertyView<uint8_t>(
487 template <
typename Callback, glm::length_t N,
bool Normalized>
488 void getVecNPropertyViewImpl(
489 const std::string& propertyId,
490 const ClassProperty& classProperty,
491 PropertyComponentType componentType,
493 const TextureViewOptions& propertyOptions)
const {
494 switch (componentType) {
495 case PropertyComponentType::Int8:
498 getPropertyViewImpl<glm::vec<N, int8_t>, Normalized>(
503 case PropertyComponentType::Uint8:
506 getPropertyViewImpl<glm::vec<N, uint8_t>, Normalized>(
511 case PropertyComponentType::Int16:
512 if constexpr (N == 2) {
515 getPropertyViewImpl<glm::vec<N, int16_t>, Normalized>(
522 case PropertyComponentType::Uint16:
523 if constexpr (N == 2) {
526 getPropertyViewImpl<glm::vec<N, uint16_t>, Normalized>(
536 PropertyTexturePropertyView<uint8_t>(
542 template <
typename Callback,
bool Normalized>
543 void getVecNPropertyViewImpl(
544 const std::string& propertyId,
545 const ClassProperty& classProperty,
547 PropertyComponentType componentType,
549 const TextureViewOptions& propertyOptions)
const {
550 const glm::length_t N = getDimensionsFromPropertyType(type);
553 getVecNPropertyViewImpl<Callback, 2, Normalized>(
557 std::forward<Callback>(callback),
561 getVecNPropertyViewImpl<Callback, 3, Normalized>(
565 std::forward<Callback>(callback),
569 getVecNPropertyViewImpl<Callback, 4, Normalized>(
573 std::forward<Callback>(callback),
579 PropertyTexturePropertyView<uint8_t>(
585 template <
typename T,
bool Normalized>
586 PropertyTexturePropertyView<T, Normalized> createScalarPropertyView(
587 const ClassProperty& classProperty,
588 [[maybe_unused]]
const PropertyTextureProperty& propertyTextureProperty,
589 const TextureViewOptions& propertyOptions)
const {
590 if (classProperty.array) {
591 return PropertyTexturePropertyView<T, Normalized>(
595 const PropertyType type = convertStringToPropertyType(classProperty.type);
596 if (TypeToPropertyType<T>::value != type) {
597 return PropertyTexturePropertyView<T, Normalized>(
601 const PropertyComponentType componentType =
602 convertStringToPropertyComponentType(
603 classProperty.componentType.value_or(
""));
604 if (TypeToPropertyType<T>::component != componentType) {
605 return PropertyTexturePropertyView<T, Normalized>(
609 if (classProperty.normalized != Normalized) {
610 return PropertyTexturePropertyView<T, Normalized>(
615 if constexpr (
sizeof(T) <= 4) {
616 return createPropertyViewImpl<T, Normalized>(
618 propertyTextureProperty,
622 return PropertyTexturePropertyView<T, Normalized>(
627 template <
typename T,
bool Normalized>
628 PropertyTexturePropertyView<T, Normalized> createVecNPropertyView(
629 const ClassProperty& classProperty,
630 [[maybe_unused]]
const PropertyTextureProperty& propertyTextureProperty,
631 [[maybe_unused]]
const TextureViewOptions& propertyOptions)
const {
632 if (classProperty.array) {
633 return PropertyTexturePropertyView<T, Normalized>(
637 const PropertyType type = convertStringToPropertyType(classProperty.type);
638 if (TypeToPropertyType<T>::value != type) {
639 return PropertyTexturePropertyView<T, Normalized>(
643 const PropertyComponentType componentType =
644 convertStringToPropertyComponentType(
645 classProperty.componentType.value_or(
""));
646 if (TypeToPropertyType<T>::component != componentType) {
647 return PropertyTexturePropertyView<T, Normalized>(
651 if (classProperty.normalized != Normalized) {
652 return PropertyTexturePropertyView<T, Normalized>(
657 if constexpr (
sizeof(T) <= 4) {
658 return createPropertyViewImpl<T, Normalized>(
660 propertyTextureProperty,
664 return PropertyTexturePropertyView<T, Normalized>(
669 template <
typename T,
bool Normalized>
670 PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>
671 createArrayPropertyView(
672 const ClassProperty& classProperty,
673 [[maybe_unused]]
const PropertyTextureProperty& propertyTextureProperty,
674 [[maybe_unused]]
const TextureViewOptions& propertyOptions)
const {
675 if (!classProperty.array) {
676 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
680 const PropertyType type = convertStringToPropertyType(classProperty.type);
681 if (TypeToPropertyType<T>::value != type) {
682 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
686 const PropertyComponentType componentType =
687 convertStringToPropertyComponentType(
688 classProperty.componentType.value_or(
""));
689 if (TypeToPropertyType<T>::component != componentType) {
690 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
694 if (classProperty.normalized != Normalized) {
695 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
701 if constexpr (IsMetadataScalar<T>::value &&
sizeof(T) <= 4) {
703 int64_t count = classProperty.count.value_or(0);
704 if (count <= 0 || count > 4) {
705 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
709 if (count *
sizeof(T) > 4) {
710 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
714 return createPropertyViewImpl<PropertyArrayView<T>, Normalized>(
716 propertyTextureProperty,
720 return PropertyTexturePropertyView<PropertyArrayView<T>, Normalized>(
725 template <
typename T,
bool Normalized>
726 PropertyTexturePropertyView<T, Normalized> createPropertyViewImpl(
727 const ClassProperty& classProperty,
728 const PropertyTextureProperty& propertyTextureProperty,
730 const TextureViewOptions& propertyOptions)
const {
731 int32_t samplerIndex;
735 getTextureSafe(propertyTextureProperty.index, samplerIndex, imageIndex);
738 return PropertyTexturePropertyView<T, Normalized>(
status);
741 status = checkSampler(samplerIndex);
743 return PropertyTexturePropertyView<T, Normalized>(
status);
746 status = checkImage(imageIndex);
748 return PropertyTexturePropertyView<T, Normalized>(
status);
752 _pModel->
images[imageIndex].pAsset;
753 const std::vector<int64_t>& channels = propertyTextureProperty.channels;
755 status = checkChannels(channels, *pImage);
757 return PropertyTexturePropertyView<T, Normalized>(
status);
760 if (channels.size() * pImage->bytesPerChannel != elementSize) {
764 return PropertyTexturePropertyView<T, Normalized>(
765 propertyTextureProperty,
772 PropertyViewStatusType getTextureSafe(
773 const int32_t textureIndex,
774 int32_t& samplerIndex,
775 int32_t& imageIndex)
const noexcept;
777 PropertyViewStatusType
778 checkSampler(
const int32_t samplerIndex)
const noexcept;
780 PropertyViewStatusType checkImage(
const int32_t imageIndex)
const noexcept;
782 PropertyViewStatusType checkChannels(
783 const std::vector<int64_t>& channels,
784 const ImageAsset& image)
const noexcept;
786 const Model* _pModel;
787 const PropertyTexture* _pPropertyTexture;
788 const Class* _pClass;
static const int ErrorUnsupportedProperty
This property view is associated with a ClassProperty of an unsupported type.
static const int ErrorChannelsAndTypeMismatch
The channels of this property texture property do not provide the exact number of bytes required by t...
static const int ErrorInvalidPropertyTexture
This property view was initialized from an invalid PropertyTexture.
A view of the data specified by a PropertyTextureProperty.
A view on a PropertyTexture.
PropertyTextureView(const Model &model, const PropertyTexture &propertyTexture) noexcept
Construct a PropertyTextureView.
PropertyTextureViewStatus status() const noexcept
Gets the status of this property texture view.
void forEachProperty(Callback &&callback, const TextureViewOptions &propertyOptions=TextureViewOptions()) const
Iterates over each property in the PropertyTexture with a callback that accepts a property id and a P...
void getPropertyView(const std::string &propertyId, Callback &&callback, const TextureViewOptions &propertyOptions=TextureViewOptions()) const
Gets a PropertyTexturePropertyView through a callback that accepts a property id and a PropertyTextur...
PropertyTexturePropertyView< T, Normalized > getPropertyView(const std::string &propertyId, const TextureViewOptions &propertyOptions=TextureViewOptions()) const
Gets a PropertyTexturePropertyView that views the data of a property stored in the PropertyTexture.
const ClassProperty * getClassProperty(const std::string &propertyId) const
Finds the ClassProperty that describes the type information of the property with the specified id.
const Class * getClass() const noexcept
Gets the Class that this property texture conforms to.
const std::optional< std::string > & name() const noexcept
Gets the name of the property texture being viewed. Returns std::nullopt if no name was specified.
static const PropertyViewStatusType ErrorTypeMismatch
This property view's type does not match what is specified in ClassProperty::type.
static const PropertyViewStatusType Valid
This property view is valid and ready to use.
static const PropertyViewStatusType ErrorNonexistentProperty
This property view is trying to view a property that does not exist.
static const PropertyViewStatusType ErrorInvalidNormalization
This property says it is normalized, but it does not have an integer component type.
static const PropertyViewStatusType ErrorArrayTypeMismatch
This property view differs from what is specified in ClassProperty::array.
static const PropertyViewStatusType ErrorNormalizationMismatch
This property view's normalization differs from what is specified in ClassProperty::normalized.
static const PropertyViewStatusType ErrorComponentTypeMismatch
This property view's component type does not match what is specified in ClassProperty::componentType.
A smart pointer that calls addReference and releaseReference on the controlled object.
Classes for working with glTF models.
PropertyTextureViewStatus
Indicates the status of a property texture view.
@ Valid
This property texture view is valid and ready to use.
@ ErrorClassNotFound
The property texture's specified class could not be found in the extension.
@ ErrorMissingMetadataExtension
The glTF is missing the EXT_structural_metadata extension.
@ ErrorMissingSchema
The glTF EXT_structural_metadata extension doesn't contain a schema.
bool normalized
Specifies whether integer values are normalized. Only applicable to SCALAR, VECN, and MATN types with...
std::optional< std::string > componentType
The datatype of the element's components. Only applicable to SCALAR, VECN, and MATN types.
bool array
Whether the property is an array. When count is defined the property is a fixed-length array....
std::string type
The element type.
bool required
If required, the property must be present in every entity conforming to the class....
std::optional< CesiumUtility::JsonValue > defaultProperty
A default value to use when encountering a noData value or an omitted property. The value is given in...
A class containing a set of properties.
std::unordered_map< std::string, CesiumGltf::ClassProperty > properties
A dictionary, where each key is a property ID and each value is an object defining the property....
std::vector< CesiumGltf::Sampler > samplers
An array of samplers.
std::vector< CesiumGltf::Image > images
An array of images.
The root object for a glTF asset.
Properties conforming to a class, organized as property values stored in textures.
std::optional< std::string > name
The name of the property texture, e.g. for display purposes.
std::unordered_map< std::string, CesiumGltf::PropertyTextureProperty > properties
A dictionary, where each key corresponds to a property ID in the class' properties dictionary and eac...
Describes options for constructing a view on a glTF texture.