3#include "CesiumGltf/PropertyArrayView.h"
4#include "CesiumGltf/PropertyTransformations.h"
5#include "CesiumGltf/PropertyTypeTraits.h"
6#include "CesiumGltf/PropertyView.h"
8#include <CesiumUtility/Assert.h>
145template <
typename ElementType,
bool Normalized = false>
162template <
typename ElementType>
175 _arrayOffsetTypeSize{0},
178 _stringOffsetTypeSize{0} {}
191 _arrayOffsetTypeSize{0},
194 _stringOffsetTypeSize{0} {
197 "An empty property view should not be constructed with a valid status");
215 _arrayOffsetTypeSize{0},
218 _stringOffsetTypeSize{0} {
229 this->_status = PropertyTablePropertyViewStatus::ErrorNonexistentProperty;
250 std::span<const std::byte> values) noexcept
257 _arrayOffsetTypeSize{0},
260 _stringOffsetTypeSize{0} {}
278 std::span<const std::byte> values,
279 std::span<const std::byte> arrayOffsets,
280 std::span<const std::byte> stringOffsets,
287 _arrayOffsets{arrayOffsets},
288 _arrayOffsetType{arrayOffsetType},
290 _stringOffsets{stringOffsets},
291 _stringOffsetType{stringOffsetType},
309 std::optional<PropertyValueViewToCopy<ElementType>>
310 get(int64_t index)
const noexcept {
313 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
314 CESIUM_ASSERT(index < size() &&
"index must be less than size");
316 return propertyValueViewToCopy(this->defaultValue());
319 ElementType value = getRaw(index);
321 if (value == this->noData()) {
322 return propertyValueViewToCopy(this->defaultValue());
342 ElementType
getRaw(int64_t index)
const noexcept {
345 "Check the status() first to make sure view is valid");
348 "Check the size() of the view to make sure it's not empty");
349 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
350 CESIUM_ASSERT(index < size() &&
"index must be less than size");
353 return getNumericValue(index);
357 return getBooleanValue(index);
361 return getStringValue(index);
365 return getNumericArrayValues<
370 return getBooleanArrayValues(index);
374 return getStringArrayValues(index);
385 int64_t
size() const noexcept {
return _size; }
388 ElementType getNumericValue(int64_t index)
const noexcept {
389 return reinterpret_cast<const ElementType*
>(_values.data())[index];
392 bool getBooleanValue(int64_t index)
const noexcept {
393 const int64_t byteIndex = index / 8;
394 const int64_t bitIndex = index % 8;
395 const int bitValue =
static_cast<int>(_values[byteIndex] >> bitIndex) & 1;
396 return bitValue == 1;
399 std::string_view getStringValue(int64_t index)
const noexcept {
400 const size_t currentOffset =
401 getOffsetFromOffsetsBuffer(index, _stringOffsets, _stringOffsetType);
402 const size_t nextOffset = getOffsetFromOffsetsBuffer(
406 return std::string_view(
407 reinterpret_cast<const char*
>(_values.data() + currentOffset),
408 nextOffset - currentOffset);
411 template <
typename T>
412 PropertyArrayView<T> getNumericArrayValues(int64_t index)
const noexcept {
413 size_t count =
static_cast<size_t>(this->arrayCount());
416 size_t arraySize = count *
sizeof(T);
417 const std::span<const std::byte> values(
418 _values.data() + index * arraySize,
420 return PropertyArrayView<T>{values};
425 const size_t currentOffset =
426 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType) *
428 const size_t nextOffset =
429 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType) *
431 const std::span<const std::byte> values(
432 _values.data() + currentOffset,
433 nextOffset - currentOffset);
434 return PropertyArrayView<T>{values};
437 PropertyArrayView<std::string_view>
438 getStringArrayValues(int64_t index)
const noexcept {
439 size_t count =
static_cast<size_t>(this->arrayCount());
443 const size_t arraySize = count * _stringOffsetTypeSize;
444 const std::span<const std::byte> stringOffsetValues(
445 _stringOffsets.data() + index * arraySize,
446 arraySize + _stringOffsetTypeSize);
447 return PropertyArrayView<std::string_view>(
455 const size_t currentArrayOffset =
456 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType);
457 const size_t nextArrayOffset =
458 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType);
459 const size_t arraySize = nextArrayOffset - currentArrayOffset;
460 const std::span<const std::byte> stringOffsetValues(
461 _stringOffsets.data() + currentArrayOffset,
462 arraySize + _arrayOffsetTypeSize);
463 return PropertyArrayView<std::string_view>(
467 arraySize / _arrayOffsetTypeSize);
470 PropertyArrayView<bool> getBooleanArrayValues(int64_t index)
const noexcept {
471 size_t count =
static_cast<size_t>(this->arrayCount());
474 const size_t offsetBits = count * index;
475 const size_t nextOffsetBits = count * (index + 1);
476 const std::span<const std::byte> buffer(
477 _values.data() + offsetBits / 8,
478 (nextOffsetBits / 8 - offsetBits / 8 + 1));
479 return PropertyArrayView<bool>(buffer, offsetBits % 8, count);
483 const size_t currentOffset =
484 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType);
485 const size_t nextOffset =
486 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType);
487 const size_t totalBits = nextOffset - currentOffset;
488 const std::span<const std::byte> buffer(
489 _values.data() + currentOffset / 8,
490 (nextOffset / 8 - currentOffset / 8 + 1));
491 return PropertyArrayView<bool>(buffer, currentOffset % 8, totalBits);
494 std::span<const std::byte> _values;
497 std::span<const std::byte> _arrayOffsets;
499 int64_t _arrayOffsetTypeSize;
501 std::span<const std::byte> _stringOffsets;
503 int64_t _stringOffsetTypeSize;
520template <
typename ElementType>
536 _arrayOffsetTypeSize{0} {}
549 _arrayOffsetTypeSize{0} {
552 "An empty property view should not be constructed with a valid status");
570 _arrayOffsetTypeSize{0} {
581 this->_status = PropertyTablePropertyViewStatus::ErrorNonexistentProperty;
602 std::span<const std::byte> values) noexcept
609 _arrayOffsetTypeSize{0} {}
626 std::span<const std::byte> values,
627 std::span<const std::byte> arrayOffsets,
633 _arrayOffsets{arrayOffsets},
634 _arrayOffsetType{arrayOffsetType},
652 std::optional<PropertyValueViewToCopy<NormalizedType>>
653 get(int64_t index)
const noexcept {
656 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
657 CESIUM_ASSERT(index < size() &&
"index must be less than size");
659 return propertyValueViewToCopy(this->defaultValue());
662 ElementType value = getRaw(index);
663 if (this->noData() && value == *(this->noData())) {
664 return propertyValueViewToCopy(this->defaultValue());
671 constexpr glm::length_t N = ElementType::length();
672 using T =
typename ElementType::value_type;
673 using NormalizedT =
typename NormalizedType::value_type;
679 constexpr glm::length_t N = ElementType::length();
680 using T =
typename ElementType::value_type;
681 using NormalizedT =
typename NormalizedType::value_type;
694 constexpr glm::length_t N = ArrayElementType::length();
695 using T =
typename ArrayElementType::value_type;
701 constexpr glm::length_t N = ArrayElementType::length();
702 using T =
typename ArrayElementType::value_type;
721 ElementType
getRaw(int64_t index)
const noexcept {
724 "Check the status() first to make sure view is valid");
727 "Check the size() of the view to make sure it's not empty");
728 CESIUM_ASSERT(index >= 0 &&
"index must be non-negative");
729 CESIUM_ASSERT(index < size() &&
"index must be less than size");
732 return getValue(index);
736 return getArrayValues<typename MetadataArrayType<ElementType>::type>(
748 int64_t
size() const noexcept {
753 ElementType getValue(int64_t index)
const noexcept {
754 return reinterpret_cast<const ElementType*
>(_values.data())[index];
757 template <
typename T>
758 PropertyArrayView<T> getArrayValues(int64_t index)
const noexcept {
759 size_t count =
static_cast<size_t>(this->arrayCount());
762 size_t arraySize = count *
sizeof(T);
763 const std::span<const std::byte> values(
764 _values.data() + index * arraySize,
766 return PropertyArrayView<T>{values};
771 const size_t currentOffset =
772 getOffsetFromOffsetsBuffer(index, _arrayOffsets, _arrayOffsetType) *
774 const size_t nextOffset =
775 getOffsetFromOffsetsBuffer(index + 1, _arrayOffsets, _arrayOffsetType) *
777 const std::span<const std::byte> values(
778 _values.data() + currentOffset,
779 nextOffset - currentOffset);
780 return PropertyArrayView<T>{values};
783 std::span<const std::byte> _values;
786 std::span<const std::byte> _arrayOffsets;
788 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....