@@ -142,16 +142,16 @@ void CesiumFeaturesMetadataViewer::createClassStatisticsDropdown(
142142TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow (
143143 TSharedRef<PropertyInstanceView> pItem,
144144 const TSharedRef<STableViewBase>& list) {
145- FString typeString = pItem->type .ToString ();
146- if (pItem->isNormalized ) {
145+ FString typeString = pItem->propertyDetails . GetValueType () .ToString ();
146+ if (pItem->propertyDetails . bIsNormalized ) {
147147 typeString += TEXT (" (Normalized)" );
148148 }
149149
150- if (pItem->type .bIsArray ) {
151- typeString +=
152- pItem-> arraySize > 0
153- ? FString::Printf (TEXT (" with %d elements" ), pItem-> arraySize )
154- : TEXT (" of variable size" );
150+ if (pItem->propertyDetails .bIsArray ) {
151+ int64 arraySize = pItem-> propertyDetails . ArraySize ;
152+ typeString += arraySize > 0
153+ ? FString::Printf (TEXT (" with %d elements" ), arraySize)
154+ : TEXT (" of variable size" );
155155 }
156156
157157 FString sourceString;
@@ -166,13 +166,32 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow(
166166
167167 sourceString += FString::Printf (TEXT (" (%s)" ), **pItem->pSourceName );
168168
169+ TArray<FString> qualifierList;
170+ if (pItem->propertyDetails .bHasOffset ) {
171+ qualifierList.Add (" Offset" );
172+ }
173+ if (pItem->propertyDetails .bHasScale ) {
174+ qualifierList.Add (" Scale" );
175+ }
176+ if (pItem->propertyDetails .bHasNoDataValue ) {
177+ qualifierList.Add (" 'No Data' Value" );
178+ }
179+ if (pItem->propertyDetails .bHasDefaultValue ) {
180+ qualifierList.Add (" Default Value" );
181+ }
182+
183+ FString qualifierString =
184+ qualifierList.IsEmpty ()
185+ ? FString ()
186+ : " Contains " + FString::Join (qualifierList, TEXT (" , " ));
187+
169188 return SNew (STableRow<TSharedRef<StatisticView>>, list)
170189 .Content ()
171190 [SNew (SBox)
172191 .HAlign (EHorizontalAlignment::HAlign_Fill)
173192 .Content ()
174193 [SNew (SHorizontalBox) +
175- SHorizontalBox::Slot ().FillWidth (0 .5f ).Padding (5 .0f ).VAlign (
194+ SHorizontalBox::Slot ().FillWidth (0 .4f ).Padding (5 .0f ).VAlign (
176195 EVerticalAlignment::VAlign_Center)
177196 [SNew (STextBlock)
178197 .AutoWrapText (true )
@@ -182,6 +201,11 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow(
182201 [SNew (STextBlock)
183202 .AutoWrapText (true )
184203 .Text (FText::FromString (sourceString))] +
204+ SHorizontalBox::Slot ().AutoWidth ().Padding (5 .0f ).VAlign (
205+ EVerticalAlignment::VAlign_Center)
206+ [SNew (STextBlock)
207+ .AutoWrapText (true )
208+ .Text (FText::FromString (qualifierString))] +
185209 SHorizontalBox::Slot ()
186210 .AutoWidth ()
187211 .HAlign (EHorizontalAlignment::HAlign_Right)
@@ -192,7 +216,9 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow(
192216 }),
193217 FText::FromString (TEXT (
194218 " Add this property to the tileset's CesiumFeaturesMetadataComponent" )),
195- true )]]];
219+ TAttribute<bool >::Create ([this , pItem]() {
220+ return this ->canBeRegistered (pItem);
221+ }))]]];
196222}
197223
198224void CesiumFeaturesMetadataViewer::createGltfPropertyDropdown (
@@ -259,7 +285,6 @@ void CesiumFeaturesMetadataViewer::Sync() {
259285 pContent->AddSlot ().AutoHeight ()
260286 [SNew (STextBlock)
261287 .AutoWrapText (true )
262- .Margin (FMargin (0 .0f , 15 .0f ))
263288 .Text (FText::FromString (TEXT (
264289 " This tileset does not contain any pre-computed statistics." )))];
265290 } else {
@@ -281,7 +306,6 @@ void CesiumFeaturesMetadataViewer::Sync() {
281306 pContent->AddSlot ().AutoHeight ()
282307 [SNew (STextBlock)
283308 .AutoWrapText (true )
284- .Margin (FMargin (0 .0f , 15 .0f ))
285309 .Text (FText::FromString (
286310 TEXT (" This tileset does not contain any glTF metadata." )))];
287311 } else {
@@ -424,14 +448,11 @@ void CesiumFeaturesMetadataViewer::gatherGltfMetadata() {
424448 this ->gatherGltfPropertyTables (modelMetadata);
425449 }
426450}
427-
428451bool CesiumFeaturesMetadataViewer::PropertyInstanceView::operator ==(
429452 const PropertyInstanceView& property) const {
430- return *pPropertyId == *property.pPropertyId && type == property.type &&
431- arraySize == property.arraySize &&
432- isNormalized == property.isNormalized && source == property.source &&
433- *pSourceName == *property.pSourceName &&
434- qualifiers == property.qualifiers ;
453+ return *pPropertyId == *property.pPropertyId &&
454+ propertyDetails == property.propertyDetails &&
455+ source == property.source && *pSourceName == *property.pSourceName ;
435456}
436457
437458bool CesiumFeaturesMetadataViewer::PropertyInstanceView::operator !=(
@@ -480,54 +501,50 @@ void CesiumFeaturesMetadataViewer::gatherGltfPropertyTables(
480501
481502 PropertyView& property = *pProperty;
482503
504+ FCesiumMetadataPropertyDetails propertyDetails;
505+
483506 const FCesiumMetadataValueType valueType =
484507 UCesiumPropertyTablePropertyBlueprintLibrary::GetValueType (
485508 propertyIt.Value );
486- int64 arraySize =
509+ propertyDetails.Type = valueType.Type ;
510+ propertyDetails.ComponentType = valueType.ComponentType ;
511+ propertyDetails.bIsArray = valueType.bIsArray ;
512+ propertyDetails.ArraySize =
487513 UCesiumPropertyTablePropertyBlueprintLibrary::GetArraySize (
488514 propertyIt.Value );
489- bool isNormalized =
515+ propertyDetails. bIsNormalized =
490516 UCesiumPropertyTablePropertyBlueprintLibrary::IsNormalized (
491517 propertyIt.Value );
492518
493- uint8 propertyQualifiers = 0 ;
494-
495519 FCesiumMetadataValue offset =
496520 UCesiumPropertyTablePropertyBlueprintLibrary::GetOffset (
497521 propertyIt.Value );
498- propertyQualifiers |=
499- uint8 (!UCesiumMetadataValueBlueprintLibrary::IsEmpty (offset))
500- << uint8 (EPropertyQualifiers::Offset);
522+ propertyDetails.bHasOffset =
523+ !UCesiumMetadataValueBlueprintLibrary::IsEmpty (offset);
501524
502525 FCesiumMetadataValue scale =
503- UCesiumPropertyTablePropertyBlueprintLibrary::GetOffset (
526+ UCesiumPropertyTablePropertyBlueprintLibrary::GetScale (
504527 propertyIt.Value );
505- propertyQualifiers |=
506- uint8 (!UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale))
507- << uint8 (EPropertyQualifiers::Scale);
528+ propertyDetails.bHasScale =
529+ !UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale);
508530
509531 FCesiumMetadataValue noData =
510532 UCesiumPropertyTablePropertyBlueprintLibrary::GetNoDataValue (
511533 propertyIt.Value );
512- propertyQualifiers |=
513- uint8 (!UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale))
514- << uint8 (EPropertyQualifiers::NoData);
534+ propertyDetails.bHasNoDataValue =
535+ !UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale);
515536
516537 FCesiumMetadataValue defaultValue =
517538 UCesiumPropertyTablePropertyBlueprintLibrary::GetDefaultValue (
518539 propertyIt.Value );
519- propertyQualifiers |=
520- uint8 (!UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale))
521- << uint8 (EPropertyQualifiers::Default);
540+ propertyDetails.bHasDefaultValue =
541+ !UCesiumMetadataValueBlueprintLibrary::IsEmpty (scale);
522542
523543 PropertyInstanceView instance{
524544 .pPropertyId = MakeShared<FString>(propertyIt.Key ),
525- .type = valueType,
526- .arraySize = arraySize,
527- .isNormalized = isNormalized,
545+ .propertyDetails = std::move (propertyDetails),
528546 .source = EPropertySource::PropertyTable,
529- .pSourceName = MakeShared<FString>(propertyTableName),
530- .qualifiers = propertyQualifiers};
547+ .pSourceName = MakeShared<FString>(propertyTableName)};
531548
532549 bool instanceExists = false ;
533550 for (const TSharedRef<PropertyInstanceView>& propertyInstance :
@@ -546,6 +563,42 @@ void CesiumFeaturesMetadataViewer::gatherGltfPropertyTables(
546563 }
547564}
548565
566+ namespace {
567+ template <typename TPropertySource, typename TProperty>
568+ TProperty* findProperty (
569+ TArray<TPropertySource>& sources,
570+ const FString& sourceName,
571+ const FString& propertyName,
572+ bool createIfMissing) {
573+ TPropertySource* pPropertySource = sources.FindByPredicate (
574+ [&sourceName](const TPropertySource& existingSource) {
575+ return sourceName == existingSource.Name ;
576+ });
577+
578+ if (!pPropertySource && !createIfMissing) {
579+ return nullptr ;
580+ }
581+
582+ if (!pPropertySource) {
583+ int32 index = sources.Emplace (sourceName, TArray<TProperty>());
584+ pPropertySource = &sources[index];
585+ }
586+
587+ TProperty* pProperty = pPropertySource->Properties .FindByPredicate (
588+ [&propertyName](const TProperty& existingProperty) {
589+ return propertyName == existingProperty.Name ;
590+ });
591+
592+ if (!pProperty && createIfMissing) {
593+ int32 index = pPropertySource->Properties .Emplace ();
594+ pProperty = &pPropertySource->Properties [index];
595+ pProperty->Name = propertyName;
596+ }
597+
598+ return pProperty;
599+ }
600+ } // namespace
601+
549602bool CesiumFeaturesMetadataViewer::canBeRegistered (
550603 TSharedRef<StatisticView> pItem) {
551604 if (!this ->_pFeaturesMetadataComponent .IsValid ()) {
@@ -588,6 +641,49 @@ bool CesiumFeaturesMetadataViewer::canBeRegistered(
588641 }) == nullptr ;
589642}
590643
644+ bool CesiumFeaturesMetadataViewer::canBeRegistered (
645+ TSharedRef<PropertyInstanceView> pItem) {
646+ if (pItem->propertyDetails .Type == ECesiumMetadataType::Invalid) {
647+ return false ;
648+ }
649+
650+ if (!this ->_pFeaturesMetadataComponent .IsValid ()) {
651+ return false ;
652+ }
653+ UCesiumFeaturesMetadataComponent& featuresMetadata =
654+ *this ->_pFeaturesMetadataComponent ;
655+
656+ if (pItem->source == EPropertySource::PropertyTable) {
657+ FCesiumPropertyTablePropertyDescription* pProperty = findProperty<
658+ FCesiumPropertyTableDescription,
659+ FCesiumPropertyTablePropertyDescription>(
660+ featuresMetadata.Description .ModelMetadata .PropertyTables ,
661+ *pItem->pSourceName ,
662+ *pItem->pPropertyId ,
663+ false );
664+ if (!pProperty)
665+ return true ;
666+
667+ return pProperty->PropertyDetails != pItem->propertyDetails ;
668+ }
669+
670+ if (pItem->source == EPropertySource::PropertyTexture) {
671+ FCesiumPropertyTexturePropertyDescription* pProperty = findProperty<
672+ FCesiumPropertyTextureDescription,
673+ FCesiumPropertyTexturePropertyDescription>(
674+ featuresMetadata.Description .ModelMetadata .PropertyTextures ,
675+ *pItem->pSourceName ,
676+ *pItem->pPropertyId ,
677+ false );
678+ if (!pProperty)
679+ return true ;
680+
681+ return pProperty->PropertyDetails != pItem->propertyDetails ;
682+ }
683+
684+ return false ;
685+ }
686+
591687void CesiumFeaturesMetadataViewer::registerStatistic (
592688 TSharedRef<StatisticView> pItem) {
593689 if (!this ->_pFeaturesMetadataComponent .IsValid ()) {
@@ -687,18 +783,6 @@ void CesiumFeaturesMetadataViewer::registerPropertyInstance(
687783 }
688784
689785 FCesiumPropertyTablePropertyDescription& property = *pProperty;
690- property.PropertyDetails .Type = pItem->type .Type ;
691- property.PropertyDetails .ComponentType = pItem->type .ComponentType ;
692- property.PropertyDetails .bIsArray = pItem->type .bIsArray ;
693- property.PropertyDetails .ArraySize = pItem->arraySize ;
694- property.PropertyDetails .bIsNormalized = pItem->isNormalized ;
695- property.PropertyDetails .bHasOffset =
696- pItem->qualifiers & 1u << uint8 (EPropertyQualifiers::Offset);
697- property.PropertyDetails .bHasScale =
698- pItem->qualifiers & 1u << uint8 (EPropertyQualifiers::Scale);
699- property.PropertyDetails .bHasNoDataValue =
700- pItem->qualifiers & 1u << uint8 (EPropertyQualifiers::NoData);
701- property.PropertyDetails .bHasDefaultValue =
702- pItem->qualifiers & 1u << uint8 (EPropertyQualifiers::Default);
786+ property.PropertyDetails = pItem->propertyDetails ;
703787 }
704788}
0 commit comments