3 #include "CesiumGltf/Class.h"
4 #include "CesiumGltf/ClassProperty.h"
5 #include "CesiumGltf/ExtensionModelExtStructuralMetadata.h"
6 #include "CesiumGltf/PropertyAttribute.h"
7 #include "CesiumGltf/PropertyAttributePropertyView.h"
41 PropertyType getAccessorTypeAsPropertyType(
const Accessor& accessor);
44 getAccessorComponentTypeAsPropertyComponentType(
const Accessor& accessor);
79 const std::optional<std::string>&
name() const noexcept {
80 return _pPropertyAttribute->
name;
125 template <
typename T,
bool Normalized = false>
128 const std::string& propertyId)
const {
134 if (!pClassProperty) {
146 return getPropertyViewImpl<T, Normalized>(
172 template <
typename Callback>
175 const std::string& propertyId,
176 Callback&& callback)
const {
182 ErrorInvalidPropertyAttribute));
187 if (!pClassProperty) {
195 if (pClassProperty->
array) {
203 PropertyType type = convertStringToPropertyType(pClassProperty->
type);
204 PropertyComponentType componentType = PropertyComponentType::None;
207 convertStringToPropertyComponentType(*pClassProperty->
componentType);
211 if (normalized && !isPropertyComponentTypeInteger(componentType)) {
219 if (type == PropertyType::Scalar) {
221 getScalarPropertyViewImpl<Callback, true>(
226 std::forward<Callback>(callback));
228 getScalarPropertyViewImpl<Callback, false>(
233 std::forward<Callback>(callback));
238 if (isPropertyTypeVecN(type)) {
240 getVecNPropertyViewImpl<Callback, true>(
246 std::forward<Callback>(callback));
248 getVecNPropertyViewImpl<Callback, false>(
254 std::forward<Callback>(callback));
259 if (isPropertyTypeMatN(type)) {
261 getMatNPropertyViewImpl<Callback, true>(
267 std::forward<Callback>(callback));
269 getMatNPropertyViewImpl<Callback, false>(
275 std::forward<Callback>(callback));
306 template <
typename Callback>
309 for (
const auto& property : this->_pClass->
properties) {
313 std::forward<Callback>(callback));
318 template <
typename T,
bool Normalized>
330 const Accessor* pAccessor = _pModel->
getSafe<Accessor>(
334 return PropertyAttributePropertyView<T, Normalized>(
338 return PropertyAttributePropertyView<T, Normalized>(
343 template <
typename T,
bool Normalized>
344 PropertyAttributePropertyView<T, Normalized> getPropertyViewImpl(
345 const MeshPrimitive& primitive,
346 const std::string& propertyId,
347 const ClassProperty& classProperty)
const {
348 auto propertyAttributePropertyIter =
349 _pPropertyAttribute->
properties.find(propertyId);
350 if (propertyAttributePropertyIter ==
352 if (!classProperty.required && classProperty.defaultProperty) {
356 return getEmptyPropertyViewWithDefault<T, Normalized>(
362 return PropertyAttributePropertyView<T, Normalized>(
366 const PropertyAttributeProperty& propertyAttributeProperty =
367 propertyAttributePropertyIter->second;
369 return createPropertyView<T, Normalized>(
372 propertyAttributeProperty);
375 template <
typename Callback,
bool Normalized>
376 void getScalarPropertyViewImpl(
377 const MeshPrimitive& primitive,
378 const std::string& propertyId,
379 const ClassProperty& classProperty,
380 PropertyComponentType componentType,
381 Callback&& callback)
const {
382 switch (componentType) {
383 case PropertyComponentType::Int8:
386 getPropertyViewImpl<int8_t, Normalized>(
391 case PropertyComponentType::Uint8:
394 getPropertyViewImpl<uint8_t, Normalized>(
399 case PropertyComponentType::Int16:
402 getPropertyViewImpl<int16_t, Normalized>(
407 case PropertyComponentType::Uint16:
410 getPropertyViewImpl<uint16_t, Normalized>(
415 case PropertyComponentType::Float32:
418 getPropertyViewImpl<float, false>(
426 PropertyAttributePropertyView<uint8_t>(
432 template <
typename Callback, glm::length_t N,
bool Normalized>
433 void getVecNPropertyViewImpl(
434 const MeshPrimitive& primitive,
435 const std::string& propertyId,
436 const ClassProperty& classProperty,
437 PropertyComponentType componentType,
438 Callback&& callback)
const {
439 switch (componentType) {
440 case PropertyComponentType::Int8:
443 getPropertyViewImpl<glm::vec<N, int8_t>, Normalized>(
448 case PropertyComponentType::Uint8:
451 getPropertyViewImpl<glm::vec<N, uint8_t>, Normalized>(
456 case PropertyComponentType::Int16:
459 getPropertyViewImpl<glm::vec<N, int16_t>, Normalized>(
464 case PropertyComponentType::Uint16:
467 getPropertyViewImpl<glm::vec<N, uint16_t>, Normalized>(
472 case PropertyComponentType::Float32:
475 getPropertyViewImpl<glm::vec<N, float>,
false>(
483 PropertyAttributePropertyView<uint8_t>(
489 template <
typename Callback,
bool Normalized>
490 void getVecNPropertyViewImpl(
491 const MeshPrimitive& primitive,
492 const std::string& propertyId,
493 const ClassProperty& classProperty,
495 PropertyComponentType componentType,
496 Callback&& callback)
const {
497 const glm::length_t N = getDimensionsFromPropertyType(type);
500 getVecNPropertyViewImpl<Callback, 2, Normalized>(
505 std::forward<Callback>(callback));
508 getVecNPropertyViewImpl<Callback, 3, Normalized>(
513 std::forward<Callback>(callback));
516 getVecNPropertyViewImpl<Callback, 4, Normalized>(
521 std::forward<Callback>(callback));
526 PropertyAttributePropertyView<uint8_t>(
532 template <
typename Callback, glm::length_t N,
bool Normalized>
533 void getMatNPropertyViewImpl(
534 const MeshPrimitive& primitive,
535 const std::string& propertyId,
536 const ClassProperty& classProperty,
537 PropertyComponentType componentType,
538 Callback&& callback)
const {
539 switch (componentType) {
540 case PropertyComponentType::Int8:
543 getPropertyViewImpl<glm::mat<N, N, int8_t>, Normalized>(
548 case PropertyComponentType::Uint8:
551 getPropertyViewImpl<glm::mat<N, N, uint8_t>, Normalized>(
556 case PropertyComponentType::Int16:
559 getPropertyViewImpl<glm::mat<N, N, int16_t>, Normalized>(
564 case PropertyComponentType::Uint16:
567 getPropertyViewImpl<glm::mat<N, N, uint16_t>, Normalized>(
572 case PropertyComponentType::Float32:
575 getPropertyViewImpl<glm::mat<N, N, float>,
false>(
583 PropertyAttributePropertyView<uint8_t>(
589 template <
typename Callback,
bool Normalized>
590 void getMatNPropertyViewImpl(
591 const MeshPrimitive& primitive,
592 const std::string& propertyId,
593 const ClassProperty& classProperty,
595 PropertyComponentType componentType,
596 Callback&& callback)
const {
597 glm::length_t N = getDimensionsFromPropertyType(type);
600 getMatNPropertyViewImpl<Callback, 2, Normalized>(
605 std::forward<Callback>(callback));
608 getMatNPropertyViewImpl<Callback, 3, Normalized>(
613 std::forward<Callback>(callback));
616 getMatNPropertyViewImpl<Callback, 4, Normalized>(
621 std::forward<Callback>(callback));
626 PropertyAttributePropertyView<uint8_t>(
632 template <
typename T,
bool Normalized>
633 PropertyAttributePropertyView<T, Normalized> createPropertyView(
634 const MeshPrimitive& primitive,
635 const ClassProperty& classProperty,
636 const PropertyAttributeProperty& propertyAttributeProperty)
const {
637 const PropertyType type = convertStringToPropertyType(classProperty.type);
638 if (TypeToPropertyType<T>::value != type) {
639 return PropertyAttributePropertyView<T, Normalized>(
643 const PropertyComponentType componentType =
644 convertStringToPropertyComponentType(
645 classProperty.componentType.value_or(
""));
646 if (TypeToPropertyType<T>::component != componentType) {
647 return PropertyAttributePropertyView<T, Normalized>(
651 if (classProperty.normalized != Normalized) {
652 return PropertyAttributePropertyView<T, Normalized>(
656 if (primitive.attributes.find(propertyAttributeProperty.attribute) ==
657 primitive.attributes.end()) {
658 return PropertyAttributePropertyView<T, Normalized>(
662 const Accessor* pAccessor = _pModel->
getSafe<Accessor>(
664 primitive.attributes.at(propertyAttributeProperty.attribute));
666 return PropertyAttributePropertyView<T, Normalized>(
670 if (getAccessorTypeAsPropertyType(*pAccessor) != type) {
671 return PropertyAttributePropertyView<T, Normalized>(
675 if (getAccessorComponentTypeAsPropertyComponentType(*pAccessor) !=
677 return PropertyAttributePropertyView<T, Normalized>(
678 PropertyAttributePropertyViewStatus::
679 ErrorAccessorComponentTypeMismatch);
682 if (pAccessor->normalized != Normalized) {
683 return PropertyAttributePropertyView<T, Normalized>(
684 PropertyAttributePropertyViewStatus::
685 ErrorAccessorNormalizationMismatch);
688 AccessorView<T> accessorView = AccessorView<T>(*_pModel, *pAccessor);
690 switch (accessorView.status()) {
692 return PropertyAttributePropertyView<T, Normalized>(
695 return PropertyAttributePropertyView<T, Normalized>(
698 return PropertyAttributePropertyView<T, Normalized>(
701 return PropertyAttributePropertyView<T, Normalized>(
704 return PropertyAttributePropertyView<T, Normalized>(
709 return PropertyAttributePropertyView<T, Normalized>(
710 propertyAttributeProperty,
715 const Model* _pModel;
716 const PropertyAttribute* _pPropertyAttribute;
717 const Class* _pClass;
Indicates the status of a property attribute property view.
static const int ErrorInvalidBufferView
This property view uses an accessor that does not have a valid buffer view index.
static const int ErrorInvalidBuffer
This property view uses a buffer view that does not have a valid buffer index.
static const int ErrorInvalidAccessor
This property view's attribute does not have a valid accessor index.
static const int ErrorMissingAttribute
This property view was initialized with a primitive that does not contain the specified attribute.
static const int ErrorUnsupportedProperty
This property view is associated with a ClassProperty of an unsupported type.
static const int ErrorAccessorTypeMismatch
This property view's type does not match the type of the accessor it uses.
static const int ErrorInvalidPropertyAttribute
This property view was initialized from an invalid PropertyAttribute.
static const PropertyViewStatusType ErrorAccessorOutOfBounds
This property view uses an accessor that points outside the bounds of its target buffer view.
static const PropertyViewStatusType ErrorBufferViewOutOfBounds
This property view uses a buffer view that points outside the bounds of its target buffer.
A view of the data specified by a PropertyAttributeProperty.
A view on a PropertyAttribute.
const ClassProperty * getClassProperty(const std::string &propertyId) const
Finds the ClassProperty that describes the type information of the property with the specified id.
PropertyAttributeView(const Model &model, const PropertyAttribute &propertyAttribute) noexcept
Construct a PropertyAttributeView.
PropertyAttributeViewStatus status() const noexcept
Gets the status of this property attribute view.
const Class * getClass() const noexcept
Gets the Class that this property attribute conforms to.
const std::optional< std::string > & name() const noexcept
Gets the name of the property attribute being viewed. Returns std::nullopt if no name was specified.
PropertyAttributePropertyView< T, Normalized > getPropertyView(const MeshPrimitive &primitive, const std::string &propertyId) const
Gets a PropertyAttributePropertyView that views the data of a property stored in the PropertyAttribut...
void getPropertyView(const MeshPrimitive &primitive, const std::string &propertyId, Callback &&callback) const
Gets a PropertyAttributePropertyView through a callback that accepts a property id and a PropertyAttr...
void forEachProperty(const MeshPrimitive &primitive, Callback &&callback) const
Iterates over each property in the PropertyAttribute with a callback that accepts a property id and a...
static const PropertyViewStatusType ErrorTypeMismatch
This property view's type does not match what is specified in ClassProperty::type.
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 ErrorNormalizationMismatch
This property view's normalization differs from what is specified in ClassProperty::normalized.
static const PropertyViewStatusType ErrorComponentTypeMismatch
This property view's component type does not match what is specified in ClassProperty::componentType.
Classes for working with glTF models.
PropertyAttributeViewStatus
Indicates the status of a property attribute view.
@ Valid
This property attribute view is valid and ready to use.
@ ErrorClassNotFound
The property attribute's specified class could not be found in the extension.
@ ErrorMissingMetadataExtension
The glTF is missing the EXT_structural_metadata extension.
@ ErrorMissingSchema
The glTF EXT_structural_metadata extension doesn't contain a schema.
@ BufferViewTooSmall
The accessor is too large to fit in its bufferView.
@ Valid
This accessor is valid and ready to use.
@ InvalidBufferViewIndex
The accessor's bufferView index does not refer to a valid bufferView.
@ InvalidBufferIndex
The accessor's bufferView's buffer index does not refer to a valid buffer.
@ BufferTooSmall
The accessor's bufferView is too large to fit in its buffer.
bool normalized
Specifies whether integer values are normalized. Only applicable to SCALAR, VECN, and MATN types with...
std::optional< std::string > componentType
The datatype of the element's components. Only applicable to SCALAR, VECN, and MATN types.
bool array
Whether the property is an array. When count is defined the property is a fixed-length array....
std::string type
The element type.
A class containing a set of properties.
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....
Geometry to be rendered with the given material.
std::unordered_map< std::string, int32_t > attributes
A plain JSON object, where each key corresponds to a mesh attribute semantic and each value is the in...
std::vector< CesiumGltf::Accessor > accessors
An array of accessors.
The root object for a glTF asset.
static const T & getSafe(const std::vector< T > &items, int32_t index)
Safely gets the element with a given index, returning a default instance if the index is outside the ...
Properties conforming to a class, organized as property values stored in attributes.
std::optional< std::string > name
The name of the property attribute, e.g. for display purposes.
std::unordered_map< std::string, CesiumGltf::PropertyAttributeProperty > properties
A dictionary, where each key corresponds to a property ID in the class' properties dictionary and eac...