3#include <CesiumGltf/PropertyArrayView.h>
4#include <CesiumGltf/PropertyTransformations.h>
5#include <CesiumGltf/PropertyTypeTraits.h>
6#include <CesiumGltf/PropertyView.h>
7#include <CesiumUtility/Assert.h>
144template <
typename ElementType,
bool Normalized = false>
161template <
typename ElementType>
174 _arrayOffsetTypeSize{0},
177 _stringOffsetTypeSize{0} {}
190 _arrayOffsetTypeSize{0},
193 _stringOffsetTypeSize{0} {
196 "An empty property view should not be constructed with a valid status");
214 _arrayOffsetTypeSize{0},
217 _stringOffsetTypeSize{0} {
228 this->_status = PropertyTablePropertyViewStatus::ErrorNonexistentProperty;
249 std::span<const std::byte> values) noexcept
256 _arrayOffsetTypeSize{0},
259 _stringOffsetTypeSize{0} {}
277 std::span<const std::byte> values,
278 std::span<const std::byte> arrayOffsets,
279 std::span<const std::byte> stringOffsets,
286 _arrayOffsets{arrayOffsets},
287 _arrayOffsetType{arrayOffsetType},
289 _stringOffsets{stringOffsets},
290 _stringOffsetType{stringOffsetType},
308 std::optional<PropertyValueViewToCopy<ElementType>>
309 get(int64_t index)
const noexcept {
312 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
313 CESIUM_ASSERT(index < size() &&
"index must be less than size");
315 return propertyValueViewToCopy(this->defaultValue());
318 ElementType value = getRaw(index);
320 if (value == this->noData()) {
321 return propertyValueViewToCopy(this->defaultValue());
341 ElementType
getRaw(int64_t index)
const noexcept {
344 "Check the status() first to make sure view is valid");
347 "Check the size() of the view to make sure it's not empty");
348 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
349 CESIUM_ASSERT(index < size() &&
"index must be less than size");
352 return getNumericValue(index);
356 return getBooleanValue(index);
360 return getStringValue(index);
364 return getNumericArrayValues<
369 return getBooleanArrayValues(index);
373 return getStringArrayValues(index);
384 int64_t
size() const noexcept {
return _size; }
387 ElementType getNumericValue(int64_t index)
const noexcept {
388 return reinterpret_cast<const ElementType*
>(_values.data())[index];
391 bool getBooleanValue(int64_t index)
const noexcept {
392 const int64_t byteIndex = index / 8;
393 const int64_t bitIndex = index % 8;
394 const int bitValue =
static_cast<int>(_values[byteIndex] >> bitIndex) & 1;
395 return bitValue == 1;
398 std::string_view getStringValue(int64_t index)
const noexcept {
399 const size_t currentOffset =
400 getOffsetFromOffsetsBuffer(index, _stringOffsets, _stringOffsetType);
401 const size_t nextOffset = getOffsetFromOffsetsBuffer(
405 return std::string_view(
406 reinterpret_cast<const char*
>(_values.data() + currentOffset),
407 nextOffset - currentOffset);
410 template <
typename T>
411 PropertyArrayView<T> getNumericArrayValues(int64_t index)
const noexcept {
412 size_t count =
static_cast<size_t>(this->arrayCount());
415 size_t arraySize = count *
sizeof(T);
416 const std::span<const std::byte> values(
417 _values.data() + index * arraySize,
419 return PropertyArrayView<T>{values};
424 const size_t currentOffset =
425 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType) *
427 const size_t nextOffset =
428 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType) *
430 const std::span<const std::byte> values(
431 _values.data() + currentOffset,
432 nextOffset - currentOffset);
433 return PropertyArrayView<T>{values};
436 PropertyArrayView<std::string_view>
437 getStringArrayValues(int64_t index)
const noexcept {
438 size_t count =
static_cast<size_t>(this->arrayCount());
442 const size_t arraySize = count * _stringOffsetTypeSize;
443 const std::span<const std::byte> stringOffsetValues(
444 _stringOffsets.data() + index * arraySize,
445 arraySize + _stringOffsetTypeSize);
446 return PropertyArrayView<std::string_view>(
454 const size_t currentArrayOffset =
455 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType);
456 const size_t nextArrayOffset =
457 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType);
458 const size_t arraySize = nextArrayOffset - currentArrayOffset;
459 const std::span<const std::byte> stringOffsetValues(
460 _stringOffsets.data() + currentArrayOffset,
461 arraySize + _arrayOffsetTypeSize);
462 return PropertyArrayView<std::string_view>(
466 arraySize / _arrayOffsetTypeSize);
469 PropertyArrayView<bool> getBooleanArrayValues(int64_t index)
const noexcept {
470 size_t count =
static_cast<size_t>(this->arrayCount());
473 const size_t offsetBits = count * index;
474 const size_t nextOffsetBits = count * (index + 1);
475 const std::span<const std::byte> buffer(
476 _values.data() + offsetBits / 8,
477 (nextOffsetBits / 8 - offsetBits / 8 + 1));
478 return PropertyArrayView<bool>(buffer, offsetBits % 8, count);
482 const size_t currentOffset =
483 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType);
484 const size_t nextOffset =
485 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType);
486 const size_t totalBits = nextOffset - currentOffset;
487 const std::span<const std::byte> buffer(
488 _values.data() + currentOffset / 8,
489 (nextOffset / 8 - currentOffset / 8 + 1));
490 return PropertyArrayView<bool>(buffer, currentOffset % 8, totalBits);
493 std::span<const std::byte> _values;
496 std::span<const std::byte> _arrayOffsets;
498 int64_t _arrayOffsetTypeSize;
500 std::span<const std::byte> _stringOffsets;
502 int64_t _stringOffsetTypeSize;
519template <
typename ElementType>
535 _arrayOffsetTypeSize{0} {}
548 _arrayOffsetTypeSize{0} {
551 "An empty property view should not be constructed with a valid status");
569 _arrayOffsetTypeSize{0} {
580 this->_status = PropertyTablePropertyViewStatus::ErrorNonexistentProperty;
601 std::span<const std::byte> values) noexcept
608 _arrayOffsetTypeSize{0} {}
625 std::span<const std::byte> values,
626 std::span<const std::byte> arrayOffsets,
632 _arrayOffsets{arrayOffsets},
633 _arrayOffsetType{arrayOffsetType},
651 std::optional<PropertyValueViewToCopy<NormalizedType>>
652 get(int64_t index)
const noexcept {
655 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
656 CESIUM_ASSERT(index < size() &&
"index must be less than size");
658 return propertyValueViewToCopy(this->defaultValue());
661 ElementType value = getRaw(index);
662 if (this->noData() && value == *(this->noData())) {
663 return propertyValueViewToCopy(this->defaultValue());
670 constexpr glm::length_t N = ElementType::length();
671 using T =
typename ElementType::value_type;
672 using NormalizedT =
typename NormalizedType::value_type;
678 constexpr glm::length_t N = ElementType::length();
679 using T =
typename ElementType::value_type;
680 using NormalizedT =
typename NormalizedType::value_type;
693 constexpr glm::length_t N = ArrayElementType::length();
694 using T =
typename ArrayElementType::value_type;
700 constexpr glm::length_t N = ArrayElementType::length();
701 using T =
typename ArrayElementType::value_type;
720 ElementType
getRaw(int64_t index)
const noexcept {
723 "Check the status() first to make sure view is valid");
726 "Check the size() of the view to make sure it's not empty");
727 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
728 CESIUM_ASSERT(index < size() &&
"index must be less than size");
731 return getValue(index);
735 return getArrayValues<typename MetadataArrayType<ElementType>::type>(
747 int64_t
size() const noexcept {
752 ElementType getValue(int64_t index)
const noexcept {
753 return reinterpret_cast<const ElementType*
>(_values.data())[index];
756 template <
typename T>
757 PropertyArrayView<T> getArrayValues(int64_t index)
const noexcept {
758 size_t count =
static_cast<size_t>(this->arrayCount());
761 size_t arraySize = count *
sizeof(T);
762 const std::span<const std::byte> values(
763 _values.data() + index * arraySize,
765 return PropertyArrayView<T>{values};
770 const size_t currentOffset =
771 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType) *
773 const size_t nextOffset =
774 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType) *
776 const std::span<const std::byte> values(
777 _values.data() + currentOffset,
778 nextOffset - currentOffset);
779 return PropertyArrayView<T>{values};
782 std::span<const std::byte> _values;
785 std::span<const std::byte> _arrayOffsets;
787 int64_t _arrayOffsetTypeSize;
Indicates the status of a property table property view.
static const PropertyViewStatusType ErrorBufferViewSizeDoesNotMatchPropertyTableCount
This property view has an invalid buffer view; its length does not match the size of the property tab...
static const PropertyViewStatusType ErrorInvalidArrayOffsetBufferView
This array property view does not have a valid array offset buffer view index.
static const PropertyViewStatusType ErrorBufferViewOutOfBounds
This property view has a buffer view that points outside the bounds of its target buffer.
static const PropertyViewStatusType ErrorArrayCountAndOffsetBufferCoexist
This array property view has both a fixed length and an offset buffer view defined.
static const PropertyViewStatusType ErrorInvalidValueBufferView
This property view does not have a valid value buffer view index.
static const PropertyViewStatusType ErrorInvalidStringOffsetBuffer
This property view has a valid string offset buffer view, but the buffer view specifies an invalid bu...
static const PropertyViewStatusType ErrorInvalidStringOffsetType
This property view has an unknown string offset type.
static const PropertyViewStatusType ErrorArrayCountAndOffsetBufferDontExist
This array property view has neither a fixed length nor an offset buffer view defined.
static const PropertyViewStatusType ErrorArrayOffsetsNotSorted
This property view's array offset values are not sorted in ascending order.
static const PropertyViewStatusType ErrorInvalidArrayOffsetBuffer
This property view has a valid array string buffer view, but the buffer view specifies an invalid buf...
static const PropertyViewStatusType ErrorArrayOffsetOutOfBounds
This property view has an array offset that is out of bounds.
static const PropertyViewStatusType ErrorInvalidPropertyTable
This property view was initialized from an invalid PropertyTable.
static const PropertyViewStatusType ErrorInvalidValueBuffer
This property view has a valid value buffer view, but the buffer view specifies an invalid buffer ind...
static const PropertyViewStatusType ErrorInvalidStringOffsetBufferView
This string property view does not have a valid string offset buffer view index.
static const PropertyViewStatusType ErrorInvalidArrayOffsetType
This property view has an unknown array offset type.
static const PropertyViewStatusType ErrorStringOffsetsNotSorted
This property view's string offset values are not sorted in ascending order.
static const PropertyViewStatusType ErrorStringOffsetOutOfBounds
This property view has a string offset that is out of bounds.
static const PropertyViewStatusType ErrorBufferViewSizeNotDivisibleByTypeSize
This property view has an invalid buffer view; its length is not a multiple of the size of its type /...
PropertyTablePropertyView(const ClassProperty &classProperty, int64_t size)
Constructs an instance of an empty property that specifies a default value. Although this property ha...
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) noexcept
Construct an instance pointing to the data specified by a PropertyTableProperty.
PropertyTablePropertyView()
Constructs an invalid instance for a non-existent property.
std::optional< PropertyValueViewToCopy< ElementType > > get(int64_t index) const noexcept
Get the value of an element in the PropertyTable, with all value transforms applied....
ElementType getRaw(int64_t index) const noexcept
Get the raw value of an element of the PropertyTable, without offset or scale applied.
PropertyTablePropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
int64_t size() const noexcept
Get the number of elements in this PropertyTablePropertyView. If the view is valid,...
PropertyTablePropertyView(const PropertyTableProperty &property, const ClassProperty &classProperty, int64_t size, std::span< const std::byte > values) noexcept
Construct an instance pointing to data specified by a PropertyTableProperty. Used for non-array or fi...
PropertyTablePropertyView()
Constructs an invalid instance for a non-existent property.
std::optional< PropertyValueViewToCopy< NormalizedType > > get(int64_t index) const noexcept
Get the value of an element of the PropertyTable, with normalization and other value transforms appli...
ElementType getRaw(int64_t index) const noexcept
Get the raw value of an element of the PropertyTable, without offset, scale, or normalization applied...
PropertyTablePropertyView(const PropertyTableProperty &property, const ClassProperty &classProperty, int64_t size, std::span< const std::byte > values) noexcept
Construct an instance pointing to data specified by a PropertyTableProperty. Used for non-array or fi...
PropertyTablePropertyView(PropertyViewStatusType status)
Constructs an invalid instance for an erroneous property.
PropertyTablePropertyView(const PropertyTableProperty &property, const ClassProperty &classProperty, int64_t size, std::span< const std::byte > values, std::span< const std::byte > arrayOffsets, PropertyComponentType arrayOffsetType) noexcept
Construct an instance pointing to the data specified by a PropertyTableProperty.
int64_t size() const noexcept
Get the number of elements in this PropertyTablePropertyView. If the view is valid,...
PropertyTablePropertyView(const ClassProperty &classProperty, int64_t size)
Constructs an instance of an empty property that specifies a default value. Although this property ha...
A view on the data of the PropertyTableProperty that is created by a PropertyTableView.
Indicates the status of a property view.
static const PropertyViewStatusType Valid
This property view is valid and ready to use.
static const PropertyViewStatusType EmptyPropertyWithDefault
This property view does not contain any data, but specifies a default value. This happens when a clas...
Represents a metadata property in EXT_structural_metadata.
Classes for working with glTF models.
PropertyComponentType
The possible types of a property component.
PropertyArrayCopy< glm::mat< N, N, double > > transformNormalizedMatNArray(const PropertyArrayView< glm::mat< N, N, T > > &value, const std::optional< PropertyArrayView< glm::mat< N, N, double > > > &offset, const std::optional< PropertyArrayView< glm::mat< N, N, double > > > &scale)
Normalizes each element of an array of matrices and transforms them by optional offset and scale fact...
PropertyArrayCopy< glm::vec< N, double > > transformNormalizedVecNArray(const PropertyArrayView< glm::vec< N, T > > &value, const std::optional< PropertyArrayView< glm::vec< N, double > > > &offset, const std::optional< PropertyArrayView< glm::vec< N, double > > > &scale)
Normalizes each element of an array of vectors and transforms them by optional offset and scale facto...
PropertyArrayCopy< NormalizedType > transformNormalizedArray(const PropertyArrayView< T > &value, const std::optional< PropertyArrayView< NormalizedType > > &offset, const std::optional< PropertyArrayView< NormalizedType > > &scale)
Normalizes each element of an array of values and transforms them by optional offset and scale factor...
T transformValue(const T &value, const std::optional< T > &offset, const std::optional< T > &scale)
Transforms the value by optional offset and scale factors.
double normalize(T value)
Normalizes the given value between [0, 1] if unsigned or [-1, 1] if signed, based on the type's maxim...
int64_t getOffsetTypeSize(PropertyComponentType offsetType) noexcept
Returns the size in bytes of a PropertyComponentType used as the arrayOffsetType in the constructor o...
PropertyArrayCopy< T > transformArray(const PropertyArrayView< T > &value, const std::optional< PropertyArrayView< T > > &offset, const std::optional< PropertyArrayView< T > > &scale)
Transforms each element of an array of values by optional offset and scale factors....
int32_t PropertyViewStatusType
The type used for fields of PropertyViewStatus.
std::optional< CesiumUtility::JsonValue > defaultProperty
A default value to use when encountering a noData value or an omitted property. The value is given in...
An array of binary property values.
Convert an integer numeric type to the corresponding representation as a double type....