Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ENUM metadata support, treating them as scalars rather than using a container type #1112

Open
wants to merge 14 commits into
base: main
Choose a base branch
from
Open
Original file line number Diff line number Diff line change
Expand Up @@ -914,7 +914,7 @@ void updateScalarArrayProperty(
classProperty.type = ClassProperty::Type::SCALAR;
classProperty.componentType =
convertPropertyComponentTypeToString(static_cast<PropertyComponentType>(
TypeToPropertyType<ValueType>::component));
TypeToPropertyComponentType<ValueType>::component));
classProperty.array = true;

// Handle fixed-length arrays.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace CesiumGltf {
/**
* @brief An object defining the values of an enum.
*/
struct CESIUMGLTF_API Enum final : public CesiumUtility::ExtensibleObject {
struct CESIUMGLTF_API EnumSpec : public CesiumUtility::ExtensibleObject {
/**
* @brief The original name of this type.
*/
Expand Down Expand Up @@ -81,7 +81,7 @@ struct CESIUMGLTF_API Enum final : public CesiumUtility::ExtensibleObject {
*/
int64_t getSizeBytes() const {
int64_t accum = 0;
accum += int64_t(sizeof(Enum));
accum += int64_t(sizeof(EnumSpec));
accum += CesiumUtility::ExtensibleObject::getSizeBytes() -
int64_t(sizeof(CesiumUtility::ExtensibleObject));
if (this->name) {
Expand All @@ -96,5 +96,12 @@ struct CESIUMGLTF_API Enum final : public CesiumUtility::ExtensibleObject {
}
return accum;
}

protected:
/**
* @brief This class is not meant to be instantiated directly. Use {@link Enum} instead.
*/
EnumSpec() = default;
friend struct Enum;
};
} // namespace CesiumGltf
40 changes: 40 additions & 0 deletions CesiumGltf/include/CesiumGltf/Enum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#pragma once

#include <CesiumGltf/EnumSpec.h>
#include <CesiumGltf/Library.h>

#include <algorithm>
#include <optional>
#include <string_view>

namespace CesiumGltf {
/** @copydoc EnumSpec */
struct CESIUMGLTF_API Enum final : public EnumSpec {
Enum() = default;

/**
* @brief Obtains the name corresponding to the given enum integer value from
* this enum definition.
*
* @param enumValue The enum value to resolve into a name.
* @returns The name in the enum definition corresponding to this value, or an
* empty string if the value cannot be found in the definition.
*/
template <typename T>
std::optional<std::string_view> getName(T enumValue) const {
const auto found = std::find_if(
this->values.begin(),
this->values.end(),
[value = static_cast<int64_t>(enumValue)](
const CesiumGltf::EnumValue& enumValue) {
return enumValue.value == value;
});

if (found == this->values.end()) {
return std::nullopt;
}

return found->name;
}
};
} // namespace CesiumGltf
22 changes: 11 additions & 11 deletions CesiumGltf/include/CesiumGltf/PropertyAttributePropertyView.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,66 +25,66 @@ class PropertyAttributePropertyViewStatus : public PropertyViewStatus {
* @brief This property view was initialized from an invalid
* {@link PropertyAttribute}.
*/
static const int ErrorInvalidPropertyAttribute = 14;
static const int ErrorInvalidPropertyAttribute = 15;

/**
* @brief This property view is associated with a {@link ClassProperty} of an
* unsupported type.
*/
static const int ErrorUnsupportedProperty = 15;
static const int ErrorUnsupportedProperty = 16;

/**
* @brief This property view was initialized with a primitive that does not
* contain the specified attribute.
*/
static const int ErrorMissingAttribute = 16;
static const int ErrorMissingAttribute = 17;

/**
* @brief This property view's attribute does not have a valid accessor index.
*/
static const int ErrorInvalidAccessor = 17;
static const int ErrorInvalidAccessor = 18;

/**
* @brief This property view's type does not match the type of the accessor it
* uses.
*/
static const int ErrorAccessorTypeMismatch = 18;
static const int ErrorAccessorTypeMismatch = 19;

/**
* @brief This property view's component type does not match the type of the
* accessor it uses.
*/
static const int ErrorAccessorComponentTypeMismatch = 19;
static const int ErrorAccessorComponentTypeMismatch = 20;

/**
* @brief This property view's normalization does not match the normalization
* of the accessor it uses.
*/
static const int ErrorAccessorNormalizationMismatch = 20;
static const int ErrorAccessorNormalizationMismatch = 21;

/**
* @brief This property view uses an accessor that does not have a valid
* buffer view index.
*/
static const int ErrorInvalidBufferView = 21;
static const int ErrorInvalidBufferView = 22;

/**
* @brief This property view uses a buffer view that does not have a valid
* buffer index.
*/
static const int ErrorInvalidBuffer = 22;
static const int ErrorInvalidBuffer = 23;

/**
* @brief This property view uses an accessor that points outside the bounds
* of its target buffer view.
*/
static const PropertyViewStatusType ErrorAccessorOutOfBounds = 23;
static const PropertyViewStatusType ErrorAccessorOutOfBounds = 24;

/**
* @brief This property view uses a buffer view that points outside the bounds
* of its target buffer.
*/
static const PropertyViewStatusType ErrorBufferViewOutOfBounds = 24;
static const PropertyViewStatusType ErrorBufferViewOutOfBounds = 25;
};

/**
Expand Down
4 changes: 2 additions & 2 deletions CesiumGltf/include/CesiumGltf/PropertyAttributeView.h
Original file line number Diff line number Diff line change
Expand Up @@ -655,15 +655,15 @@ class PropertyAttributeView {
const ClassProperty& classProperty,
const PropertyAttributeProperty& propertyAttributeProperty) const {
const PropertyType type = convertStringToPropertyType(classProperty.type);
if (TypeToPropertyType<T>::value != type) {
if (!canRepresentPropertyType<T>(type)) {
return PropertyAttributePropertyView<T, Normalized>(
PropertyAttributePropertyViewStatus::ErrorTypeMismatch);
}

const PropertyComponentType componentType =
convertStringToPropertyComponentType(
classProperty.componentType.value_or(""));
if (TypeToPropertyType<T>::component != componentType) {
if (TypeToPropertyComponentType<T>::component != componentType) {
return PropertyAttributePropertyView<T, Normalized>(
PropertyAttributePropertyViewStatus::ErrorComponentTypeMismatch);
}
Expand Down
64 changes: 64 additions & 0 deletions CesiumGltf/include/CesiumGltf/PropertyTablePropertyView.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <CesiumGltf/Enum.h>
#include <CesiumGltf/PropertyArrayView.h>
#include <CesiumGltf/PropertyTransformations.h>
#include <CesiumGltf/PropertyTypeTraits.h>
Expand Down Expand Up @@ -258,6 +259,34 @@ class PropertyTablePropertyView<ElementType, false>
_stringOffsetType{PropertyComponentType::None},
_stringOffsetTypeSize{0} {}

/**
* @brief Construct an instance pointing to data specified by a {@link PropertyTableProperty}, with an enum definition attached.
* Used for non-array or fixed-length array data.
*
* @param property The {@link PropertyTableProperty}
* @param classProperty The {@link ClassProperty} this property conforms to.
* @param size The number of elements in the property table specified by {@link PropertyTable::count}
* @param values The raw buffer specified by {@link PropertyTableProperty::values}
* @param pEnumDefinition A pointer to the enum definition used for this
* value.
*/
PropertyTablePropertyView(
const PropertyTableProperty& property,
const ClassProperty& classProperty,
int64_t size,
std::span<const std::byte> values,
const CesiumGltf::Enum* pEnumDefinition) noexcept
: PropertyView<ElementType>(classProperty, property, pEnumDefinition),
_values{values},
_size{
this->_status == PropertyTablePropertyViewStatus::Valid ? size : 0},
_arrayOffsets{},
_arrayOffsetType{PropertyComponentType::None},
_arrayOffsetTypeSize{0},
_stringOffsets{},
_stringOffsetType{PropertyComponentType::None},
_stringOffsetTypeSize{0} {}

/**
* @brief Construct an instance pointing to the data specified by a {@link PropertyTableProperty}.
*
Expand Down Expand Up @@ -290,6 +319,41 @@ class PropertyTablePropertyView<ElementType, false>
_stringOffsetType{stringOffsetType},
_stringOffsetTypeSize{getOffsetTypeSize(stringOffsetType)} {}

/**
* @brief Construct an instance pointing to the data specified by a {@link PropertyTableProperty}, with an enum definition attached.
*
* @param property The {@link PropertyTableProperty}
* @param classProperty The {@link ClassProperty} this property conforms to.
* @param size The number of elements in the property table specified by {@link PropertyTable::count}
* @param values The raw buffer specified by {@link PropertyTableProperty::values}
* @param arrayOffsets The raw buffer specified by {@link PropertyTableProperty::arrayOffsets}
* @param stringOffsets The raw buffer specified by {@link PropertyTableProperty::stringOffsets}
* @param arrayOffsetType The offset type of arrayOffsets specified by {@link PropertyTableProperty::arrayOffsetType}
* @param stringOffsetType The offset type of stringOffsets specified by {@link PropertyTableProperty::stringOffsetType}
* @param pEnumDefinition A pointer to the enum definition used for this
* value.
*/
PropertyTablePropertyView(
const PropertyTableProperty& property,
const ClassProperty& classProperty,
int64_t size,
std::span<const std::byte> values,
std::span<const std::byte> arrayOffsets,
std::span<const std::byte> stringOffsets,
PropertyComponentType arrayOffsetType,
PropertyComponentType stringOffsetType,
const CesiumGltf::Enum* pEnumDefinition) noexcept
: PropertyView<ElementType>(classProperty, property, pEnumDefinition),
_values{values},
_size{
this->_status == PropertyTablePropertyViewStatus::Valid ? size : 0},
_arrayOffsets{arrayOffsets},
_arrayOffsetType{arrayOffsetType},
_arrayOffsetTypeSize{getOffsetTypeSize(arrayOffsetType)},
_stringOffsets{stringOffsets},
_stringOffsetType{stringOffsetType},
_stringOffsetTypeSize{getOffsetTypeSize(stringOffsetType)} {}

/**
* @brief Get the value of an element in the {@link PropertyTable},
* with all value transforms applied. That is, if the property specifies an
Expand Down
Loading
Loading