// Copyright 2020-2025 CesiumGS, Inc. and Contributors #pragma once #include "CesiumFeatureIdSet.h" #include "CesiumMetadataEncodingDetails.h" #include "CesiumMetadataPropertyDetails.h" #include "Containers/Array.h" #include "Containers/Map.h" #include "Templates/SharedPointer.h" #include "Templates/UniquePtr.h" #include "UObject/WeakObjectPtr.h" #include "Widgets/Input/SComboBox.h" #include "Widgets/SWindow.h" #include class SScrollBox; class ACesium3DTileset; class UCesiumFeaturesMetadataComponent; struct FCesiumModelMetadata; class CesiumFeaturesMetadataViewer : public SWindow { SLATE_BEGIN_ARGS(CesiumFeaturesMetadataViewer) {} /** * The tileset that is being queried for features and metadata. */ SLATE_ARGUMENT(TWeakObjectPtr, Tileset) SLATE_END_ARGS() public: static void Open(TWeakObjectPtr pTileset); void Construct(const FArguments& InArgs); /** * Syncs the window's UI with the current view of the tileset. */ void SyncAndRebuildUI(); private: /** * Encoding details for a `CesiumGltf::PropertyTableProperty` instance. */ struct PropertyInstanceEncodingDetails { /** * The possible conversion methods for this property. Contains a subset of * the values in ECesiumEncodedMetadataConversion. */ TArray> conversionMethods; /** * The combo box widget for selecting the conversion method. */ TSharedPtr>> pConversionCombo; /** * The option to set as the selected conversion, if previously specified * (e.g., by details queried from UCesiumFeatureMetadataComponent). */ TSharedPtr pConversionSelection; /** * The combo box widget for selecting the encoded type. */ TSharedPtr>> pEncodedTypeCombo; /** * The option to set as the selected encoded type, if previously specified * (e.g., by details queried from UCesiumFeatureMetadataComponent). */ TSharedPtr pEncodedTypeSelection; /** * The combo box widget for selecting the encoded component type. */ TSharedPtr>> pEncodedComponentTypeCombo; /** * The option to set as the selected encoded component type, if previously * specified (e.g., by details queried from * UCesiumFeatureMetadataComponent). */ TSharedPtr pEncodedComponentTypeSelection; }; /** * An instance of a CesiumGltf::PropertyTableProperty or * CesiumGltf::PropertyTextureProperty for a particular glTF in the tileset. * * It is technically possible for a tileset to have models with the same * property, but different schema definitions. This attempts to capture each * different instance so the user can make an informed choice about the * behavior. */ struct PropertyInstance { /** * The ID of the property of which this is an instance. */ TSharedRef pPropertyId; /** * The type and other details of this property instance. */ FCesiumMetadataPropertyDetails propertyDetails; /** * The name of the source with which this property is associated. */ TSharedRef pSourceName; /** * Additional details encoding this property instance. Only used for * `CesiumGltf::PropertyTableProperty`. */ std::optional encodingDetails; bool operator==(const PropertyInstance& rhs) const; bool operator!=(const PropertyInstance& rhs) const; }; /** * A view of a class property in EXT_structural_metadata. */ struct PropertyView { /** * The ID of the property. */ TSharedRef pId; /** * The instances of this property. */ TArray> instances; }; enum EPropertySource { PropertyTable, PropertyTexture }; /** * A view of either a CesiumGltf::PropertyTable or * CesiumGltf::PropertyTexture. */ struct PropertySourceView { /** * The name generated for this property source. */ TSharedRef pName; /** * The type of this source. */ EPropertySource type; /** * The properties belonging to this source. */ TArray> properties; }; /** * A view of an instance of a CesiumGltf::FeatureId for a particular glTF in * the tileset. Feature IDs in EXT_mesh_features are referenced by index, not * by name, so it is technically possible for two feature ID sets with the * same index to be differently typed, or to reference different property * tables. This attempts to capture each different instance so the user can * make an informed choice about the behavior. */ struct FeatureIdSetInstance { /** * The name of the feature ID set for which this is an instance. */ TSharedRef pFeatureIdSetName; /** * The type of this instance. */ ECesiumFeatureIdSetType type; /** * The name of the property table that this instance references. */ TSharedRef pPropertyTableName; bool operator==(const FeatureIdSetInstance& rhs) const; bool operator!=(const FeatureIdSetInstance& rhs) const; }; /** * A view of a CesiumGltf::FeatureId. */ struct FeatureIdSetView { /** * The name generated for this feature ID set. */ TSharedRef pName; /** * The instances of this feature ID set. */ TArray> instances; }; template < typename TSource, typename TSourceBlueprintLibrary, typename TSourceProperty, typename TSourcePropertyBlueprintLibrary> void gatherGltfPropertySources(const TArray& sources); void gatherGltfFeaturesMetadata(); /** * @brief Syncs with any property encoding details present on the * UCesiumFeaturesMetadataComponent. */ void syncPropertyEncodingDetails(); TSharedRef createPropertyInstanceRow( TSharedRef pItem, const TSharedRef& list); TSharedRef createGltfPropertyDropdown( TSharedRef pItem, const TSharedRef& list); void createGltfPropertySourceDropdown( TSharedRef& pContent, const PropertySourceView& source); template TSharedRef createEnumDropdownOption(TSharedRef pOption); template void createEnumComboBox( TSharedPtr>>& pComboBox, const TArray>& options, TEnum initialValue, const FString& tooltip); TSharedRef createFeatureIdSetInstanceRow( TSharedRef pItem, const TSharedRef& list); void createGltfFeatureIdSetDropdown( TSharedRef& pContent, const FeatureIdSetView& property); enum ComponentSearchResult { NoMatch, PartialMatch, ExactMatch }; ComponentSearchResult findOnComponent( TSharedRef pItem, bool compareEncodingDetails); ComponentSearchResult findOnComponent(TSharedRef pItem); void registerPropertyInstance(TSharedRef pItem); void registerFeatureIdSetInstance(TSharedRef pItem); void removePropertyInstance(TSharedRef pItem); void removeFeatureIdSetInstance(TSharedRef pItem); static TSharedRef getSharedRef(const FString& string); static void initializeStaticVariables(); static TSharedPtr _pExistingWindow; TSharedPtr _pContent; TWeakObjectPtr _pTileset; TWeakObjectPtr _pFeaturesMetadataComponent; // The current Features / Metadata implementation folds the class / property // schemas into each implementation of PropertyTable, PropertyTableProperty, // etc. So this functions as a property source-centric view instead of a // class-based one. TArray _metadataSources; TArray _featureIdSets; TSet _propertyTextureNames; // Avoid allocating numerous instances of simple enum values (because shared // pointers /refs are required for SComboBox). static TArray> _conversionOptions; static TArray> _encodedTypeOptions; static TArray> _encodedComponentTypeOptions; // Lookup map to reduce the number of strings allocated for duplicate property // names. static TMap> _stringMap; };