Skip to content

Commit 1cc3ad5

Browse files
committed
Fix broken CesiumMetadataValue visualization, other UI tweaks
1 parent 7d2111c commit 1cc3ad5

File tree

4 files changed

+111
-81
lines changed

4 files changed

+111
-81
lines changed

Source/CesiumEditor/Private/CesiumFeaturesMetadataViewer.cpp

Lines changed: 80 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,9 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createStatisticRow(
9595
}),
9696
FText::FromString(TEXT(
9797
"Add this property to the tileset's CesiumFeaturesMetadataComponent")),
98-
true)]]];
98+
TAttribute<bool>::Create([this, pItem]() {
99+
return this->canBeRegistered(pItem);
100+
}))]]];
99101
}
100102

101103
TSharedRef<ITableRow>
@@ -117,9 +119,10 @@ CesiumFeaturesMetadataViewer::createPropertyStatisticsDropdown(
117119
}
118120

119121
void CesiumFeaturesMetadataViewer::createClassStatisticsDropdown(
120-
TSharedRef<SVerticalBox>& pVertical,
122+
TSharedRef<SScrollBox>& pContent,
121123
const ClassStatisticsView& classStatistics) {
122-
pVertical->AddSlot().AutoHeight()
124+
125+
pContent->AddSlot()
123126
[SNew(SExpandableArea)
124127
.InitiallyCollapsed(true)
125128
.HeaderContent()[SNew(STextBlock)
@@ -129,6 +132,7 @@ void CesiumFeaturesMetadataViewer::createClassStatisticsDropdown(
129132
SHorizontalBox::Slot()
130133
[SNew(SListView<TSharedRef<PropertyStatisticsView>>)
131134
.ListItemsSource(&classStatistics.properties)
135+
.SelectionMode(ESelectionMode::None)
132136
.OnGenerateRow(
133137
this,
134138
&CesiumFeaturesMetadataViewer::
@@ -140,23 +144,27 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow(
140144
const TSharedRef<STableViewBase>& list) {
141145
FString typeString = pItem->type.ToString();
142146
if (pItem->isNormalized) {
143-
typeString += " (Normalized)";
147+
typeString += TEXT(" (Normalized)");
144148
}
145149

146150
if (pItem->type.bIsArray) {
151+
typeString +=
152+
pItem->arraySize > 0
153+
? FString::Printf(TEXT(" with %d elements"), pItem->arraySize)
154+
: TEXT(" of variable size");
147155
}
148156

149157
FString sourceString;
150158
switch (pItem->source) {
151159
case EPropertySource::PropertyTable:
152-
sourceString = "Property Table";
160+
sourceString = TEXT("Property Table");
153161
break;
154162
case EPropertySource::PropertyTexture:
155-
sourceString = "Property Texture";
163+
sourceString = TEXT("Property Texture");
156164
break;
157165
}
158166

159-
sourceString += " (" + *pItem->sourceName + ")";
167+
sourceString += FString::Printf(TEXT(" (%s)"), **pItem->pSourceName);
160168

161169
return SNew(STableRow<TSharedRef<StatisticView>>, list)
162170
.Content()
@@ -188,9 +196,9 @@ TSharedRef<ITableRow> CesiumFeaturesMetadataViewer::createPropertyInstanceRow(
188196
}
189197

190198
void CesiumFeaturesMetadataViewer::createGltfPropertyDropdown(
191-
TSharedRef<SVerticalBox>& pVertical,
199+
TSharedRef<SScrollBox>& pContent,
192200
const PropertyView& property) {
193-
pVertical->AddSlot().AutoHeight()
201+
pContent->AddSlot()
194202
[SNew(SExpandableArea)
195203
.InitiallyCollapsed(true)
196204
.HeaderContent()[SNew(STextBlock)
@@ -223,16 +231,16 @@ void CesiumFeaturesMetadataViewer::Construct(const FArguments& InArgs) {
223231
.AutoCenter(EAutoCenter::PreferredWorkArea)
224232
.SizingRule(ESizingRule::UserSized)
225233
.ClientSize(FVector2D(
226-
600,
227-
800))[SNew(SBorder)
234+
800,
235+
600))[SNew(SBorder)
228236
.Visibility(EVisibility::Visible)
229237
.BorderImage(FAppStyle::GetBrush("Menu.Background"))
230238
.Padding(FMargin(10.0f))[pVertical]]);
231239
}
232240

233241
void CesiumFeaturesMetadataViewer::Sync() {
234242
this->_statisticsClasses.Empty();
235-
// this->_classes.Empty();
243+
this->_metadataProperties.Empty();
236244

237245
this->gatherTilesetStatistics();
238246
this->gatherGltfMetadata();
@@ -244,7 +252,7 @@ void CesiumFeaturesMetadataViewer::Sync() {
244252
[SNew(SHeader)
245253
.Content()[SNew(STextBlock)
246254
.TextStyle(FCesiumEditorModule::GetStyle(), "Heading")
247-
.Text(FText::FromString("Tileset Statistics"))
255+
.Text(FText::FromString(TEXT("Tileset Statistics")))
248256
.Margin(FMargin(0.f, 10.f))]];
249257

250258
if (this->_statisticsClasses.IsEmpty()) {
@@ -255,16 +263,18 @@ void CesiumFeaturesMetadataViewer::Sync() {
255263
.Text(FText::FromString(TEXT(
256264
"This tileset does not contain any pre-computed statistics.")))];
257265
} else {
266+
TSharedRef<SScrollBox> pStatisticsContent = SNew(SScrollBox);
258267
for (const ClassStatisticsView& theClass : this->_statisticsClasses) {
259-
this->createClassStatisticsDropdown(pContent, theClass);
268+
this->createClassStatisticsDropdown(pStatisticsContent, theClass);
260269
}
270+
pContent->AddSlot().AutoHeight()[pStatisticsContent];
261271
}
262272

263273
pContent->AddSlot().AutoHeight()
264274
[SNew(SHeader)
265275
.Content()[SNew(STextBlock)
266276
.TextStyle(FCesiumEditorModule::GetStyle(), "Heading")
267-
.Text(FText::FromString("glTF Metadata"))
277+
.Text(FText::FromString(TEXT("glTF Metadata")))
268278
.Margin(FMargin(0.f, 10.f))]];
269279

270280
if (this->_metadataProperties.IsEmpty()) {
@@ -275,9 +285,11 @@ void CesiumFeaturesMetadataViewer::Sync() {
275285
.Text(FText::FromString(
276286
TEXT("This tileset does not contain any glTF metadata.")))];
277287
} else {
288+
TSharedRef<SScrollBox> pGltfContent = SNew(SScrollBox);
278289
for (const PropertyView& property : this->_metadataProperties) {
279-
this->createGltfPropertyDropdown(pContent, property);
290+
this->createGltfPropertyDropdown(pGltfContent, property);
280291
}
292+
pContent->AddSlot().FillHeight(1.0)[pGltfContent];
281293
}
282294
}
283295

@@ -410,47 +422,6 @@ void CesiumFeaturesMetadataViewer::gatherGltfMetadata() {
410422
UCesiumModelMetadataBlueprintLibrary::GetModelMetadata(pPrimitive);
411423

412424
this->gatherGltfPropertyTables(modelMetadata);
413-
414-
// AutoFillPropertyTextureDescriptions(
415-
// this->Description.ModelMetadata.PropertyTextures,
416-
// modelMetadata);
417-
418-
// TArray<USceneComponent*> childComponents;
419-
// pGltf->GetChildrenComponents(false, childComponents);
420-
421-
// for (const USceneComponent* pChildComponent : childComponents) {
422-
// const auto* pCesiumPrimitive =
423-
// Cast<ICesiumPrimitive>(pChildComponent); if (!pCesiumPrimitive) {
424-
// continue;
425-
// }
426-
// const CesiumPrimitiveData& primData =
427-
// pCesiumPrimitive->getPrimitiveData();
428-
// const FCesiumPrimitiveFeatures& primitiveFeatures =
429-
// primData.Features; const TArray<FCesiumPropertyTable>& propertyTables
430-
// =
431-
// UCesiumModelMetadataBlueprintLibrary::GetPropertyTables(
432-
// modelMetadata);
433-
// const FCesiumPrimitiveFeatures* pInstanceFeatures = nullptr;
434-
// const auto* pInstancedComponent =
435-
// Cast<UCesiumGltfInstancedComponent>(pChildComponent);
436-
// if (pInstancedComponent) {
437-
// pInstanceFeatures = pInstancedComponent->pInstanceFeatures.Get();
438-
// }
439-
// AutoFillFeatureIdSetDescriptions(
440-
// this->Description.PrimitiveFeatures.FeatureIdSets,
441-
// primitiveFeatures,
442-
// pInstanceFeatures,
443-
// propertyTables);
444-
445-
// const FCesiumPrimitiveMetadata& primitiveMetadata = primData.Metadata;
446-
// const TArray<FCesiumPropertyTexture>& propertyTextures =
447-
// UCesiumModelMetadataBlueprintLibrary::GetPropertyTextures(
448-
// modelMetadata);
449-
// AutoFillPropertyTextureNames(
450-
// this->Description.PrimitiveMetadata.PropertyTextureNames,
451-
// primitiveMetadata,
452-
// propertyTextures);
453-
//}
454425
}
455426
}
456427

@@ -459,7 +430,7 @@ bool CesiumFeaturesMetadataViewer::PropertyInstanceView::operator==(
459430
return *pPropertyId == *property.pPropertyId && type == property.type &&
460431
arraySize == property.arraySize &&
461432
isNormalized == property.isNormalized && source == property.source &&
462-
*sourceName == *property.sourceName &&
433+
*pSourceName == *property.pSourceName &&
463434
qualifiers == property.qualifiers;
464435
}
465436

@@ -555,7 +526,7 @@ void CesiumFeaturesMetadataViewer::gatherGltfPropertyTables(
555526
.arraySize = arraySize,
556527
.isNormalized = isNormalized,
557528
.source = EPropertySource::PropertyTable,
558-
.sourceName = MakeShared<FString>(propertyTableName),
529+
.pSourceName = MakeShared<FString>(propertyTableName),
559530
.qualifiers = propertyQualifiers};
560531

561532
bool instanceExists = false;
@@ -575,17 +546,54 @@ void CesiumFeaturesMetadataViewer::gatherGltfPropertyTables(
575546
}
576547
}
577548

578-
void CesiumFeaturesMetadataViewer::registerStatistic(
549+
bool CesiumFeaturesMetadataViewer::canBeRegistered(
579550
TSharedRef<StatisticView> pItem) {
580-
if (!this->_pTileset.IsValid()) {
581-
return;
551+
if (!this->_pFeaturesMetadataComponent.IsValid()) {
552+
return false;
553+
}
554+
555+
UCesiumFeaturesMetadataComponent& featuresMetadata =
556+
*this->_pFeaturesMetadataComponent;
557+
558+
TArray<FCesiumMetadataClassStatisticsDescription>& statistics =
559+
featuresMetadata.Description.Statistics;
560+
561+
FCesiumMetadataClassStatisticsDescription* pClass =
562+
statistics.FindByPredicate(
563+
[classId = *pItem->pClassId](
564+
const FCesiumMetadataClassStatisticsDescription& existingClass) {
565+
return existingClass.Id == classId;
566+
});
567+
568+
if (!pClass) {
569+
return true;
570+
}
571+
572+
FCesiumMetadataPropertyStatisticsDescription* pProperty =
573+
pClass->Properties.FindByPredicate(
574+
[propertyId = *pItem->pPropertyId](
575+
const FCesiumMetadataPropertyStatisticsDescription&
576+
existingProperty) {
577+
return existingProperty.Id == propertyId;
578+
});
579+
580+
if (!pProperty) {
581+
return true;
582582
}
583583

584+
return pProperty->Values.FindByPredicate(
585+
[semantic = pItem->semantic](
586+
const FCesiumMetadataPropertyStatisticValue& existingValue) {
587+
return existingValue.Semantic == semantic;
588+
}) == nullptr;
589+
}
590+
591+
void CesiumFeaturesMetadataViewer::registerStatistic(
592+
TSharedRef<StatisticView> pItem) {
584593
if (!this->_pFeaturesMetadataComponent.IsValid()) {
585594
return;
586595
}
587596

588-
ACesium3DTileset& tileset = *this->_pTileset;
589597
UCesiumFeaturesMetadataComponent& featuresMetadata =
590598
*this->_pFeaturesMetadataComponent;
591599

@@ -618,7 +626,6 @@ void CesiumFeaturesMetadataViewer::registerStatistic(
618626
int32 index = pClass->Properties.Emplace(*pItem->pPropertyId);
619627
pProperty = &pClass->Properties[index];
620628
}
621-
622629
if (FCesiumMetadataPropertyStatisticValue* pValue =
623630
pProperty->Values.FindByPredicate(
624631
[semantic = pItem->semantic](
@@ -634,11 +641,13 @@ void CesiumFeaturesMetadataViewer::registerStatistic(
634641

635642
void CesiumFeaturesMetadataViewer::registerPropertyInstance(
636643
TSharedRef<PropertyInstanceView> pItem) {
637-
if (!this->_pTileset.IsValid()) {
638-
return;
639-
}
640-
641-
if (!this->_pFeaturesMetadataComponent.IsValid()) {
644+
if (!this->_pTileset.IsValid() ||
645+
!this->_pFeaturesMetadataComponent.IsValid()) {
646+
UE_LOG(
647+
LogCesiumEditor,
648+
Error,
649+
TEXT(
650+
"This window was opened for a now invalid CesiumFeaturesMetadataComponent."))
642651
return;
643652
}
644653

@@ -651,14 +660,14 @@ void CesiumFeaturesMetadataViewer::registerPropertyInstance(
651660
featuresMetadata.Description.ModelMetadata.PropertyTables;
652661
FCesiumPropertyTableDescription* pPropertyTable =
653662
propertyTables.FindByPredicate(
654-
[&name = *pItem->sourceName](
663+
[&name = *pItem->pSourceName](
655664
const FCesiumPropertyTableDescription& existingTable) {
656665
return name == existingTable.Name;
657666
});
658667

659668
if (!pPropertyTable) {
660669
int32 index = propertyTables.Emplace(
661-
*pItem->sourceName,
670+
*pItem->pSourceName,
662671
TArray<FCesiumPropertyTablePropertyDescription>());
663672
pPropertyTable = &propertyTables[index];
664673
}

Source/CesiumEditor/Private/CesiumFeaturesMetadataViewer.h

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,18 @@ class CesiumFeaturesMetadataViewer : public SWindow {
4545
FCesiumMetadataValue value;
4646
};
4747

48+
/**
49+
* A view of an instance of Cesium3DTileset::PropertyStatistics.
50+
*/
4851
struct PropertyStatisticsView {
4952
TSharedRef<FString> pClassId;
5053
TSharedRef<FString> pId;
5154
TArray<TSharedRef<StatisticView>> statistics;
5255
};
5356

57+
/**
58+
* A view of an instance of Cesium3DTileset::ClassStatistics.
59+
*/
5460
struct ClassStatisticsView {
5561
TSharedRef<FString> pId;
5662
TArray<TSharedRef<PropertyStatisticsView>> properties;
@@ -66,19 +72,29 @@ class CesiumFeaturesMetadataViewer : public SWindow {
6672

6773
enum EPropertySource { PropertyTable = 0, PropertyTexture = 1 };
6874

75+
/**
76+
* A view of an instance of a CesiumGltf::Property for a particular model in a
77+
* tileset. It is technically possible for a tileset to have models with the
78+
* same property, but different schema definitions. This attempts to capture
79+
* each different instance so the user can make an informed choice about the
80+
* behavior.
81+
*/
6982
struct PropertyInstanceView {
7083
TSharedRef<FString> pPropertyId;
7184
FCesiumMetadataValueType type;
7285
int64 arraySize;
7386
bool isNormalized;
7487
EPropertySource source;
75-
TSharedRef<FString> sourceName;
88+
TSharedRef<FString> pSourceName;
7689
uint8 qualifiers; // Bitmask
7790

7891
bool operator==(const PropertyInstanceView& property) const;
7992
bool operator!=(const PropertyInstanceView& property) const;
8093
};
8194

95+
/**
96+
* A view of an instance of a CesiumGltf::Property.
97+
*/
8298
struct PropertyView {
8399
TSharedRef<FString> pId;
84100
TArray<TSharedRef<PropertyInstanceView>> instances;
@@ -95,16 +111,18 @@ class CesiumFeaturesMetadataViewer : public SWindow {
95111
TSharedRef<PropertyStatisticsView> pItem,
96112
const TSharedRef<STableViewBase>& list);
97113
void createClassStatisticsDropdown(
98-
TSharedRef<SVerticalBox>& pVertical,
114+
TSharedRef<SScrollBox>& pContent,
99115
const ClassStatisticsView& classStatistics);
100116

101117
TSharedRef<ITableRow> createPropertyInstanceRow(
102118
TSharedRef<PropertyInstanceView> pItem,
103119
const TSharedRef<STableViewBase>& list);
104120
void createGltfPropertyDropdown(
105-
TSharedRef<SVerticalBox>& pVertical,
121+
TSharedRef<SScrollBox>& pContent,
106122
const PropertyView& property);
107123

124+
bool canBeRegistered(TSharedRef<StatisticView> pItem);
125+
108126
void registerStatistic(TSharedRef<StatisticView> pItem);
109127
void registerPropertyInstance(TSharedRef<PropertyInstanceView> pItem);
110128

0 commit comments

Comments
 (0)