/** Generates a sub-level Blueprints sub-menu */ static void MakeSubLevelsMenu(FMenuBuilder& InMenuBuilder, TWeakPtr< SLevelEditor > InLvlEditor) { FSlateIcon EditBP(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")); InMenuBuilder.BeginSection(NAME_None, LOCTEXT("SubLevelsHeading", "Sub-Level Blueprints")); { UWorld* World = InLvlEditor.Pin()->GetWorld(); for (int32 iLevel = 0; iLevel < World->GetNumLevels(); iLevel++) { ULevel* Level = World->GetLevel(iLevel); if (Level != NULL && Level->GetOutermost() != NULL) { if (!Level->IsPersistentLevel()) { FUIAction UIAction ( FExecuteAction::CreateStatic(&FLevelEditorToolBar::OnOpenSubLevelBlueprint, Level) ); FText DisplayName = FText::Format(LOCTEXT("SubLevelBlueprintItem", "Edit {LevelName}"), FText::FromString(FPaths::GetCleanFilename(Level->GetOutermost()->GetName()))); InMenuBuilder.AddMenuEntry(DisplayName, FText::GetEmpty(), EditBP, UIAction); } } } } InMenuBuilder.EndSection(); }
bool IsAnySurfaceSelected( UWorld* InWorld ) { UWorld* World = InWorld; if (!World) { World = GWorld; // Fallback to GWorld } if (World) { const int32 NumLevels = World->GetNumLevels(); for (int32 LevelIndex = 0; LevelIndex < NumLevels; LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); UModel* Model = Level->Model; check(Model); const int32 NumSurfaces = Model->Surfs.Num(); // Count the number of selected surfaces for (int32 Surface = 0; Surface < NumSurfaces; ++Surface) { FBspSurf *Poly = &Model->Surfs[Surface]; if (Poly->PolyFlags & PF_Selected) { return true; } } } } return false; }
/** Restores systems that need references to classes in the renderer module. */ void RestoreReferencesToRendererModuleClasses( const TMap<UWorld*, bool>& WorldsToUpdate, const TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData, const TScopedPointer<TArray<uint8> >& GlobalShaderData, const TMap<FShaderType*, FString>& ShaderTypeNames, const TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames) { FlushShaderFileCache(); // Initialize cached shader type data InitializeShaderTypes(); IRendererModule& RendererModule = GetRendererModule(); FSceneViewStateReference::AllocateAll(); // Recreate all renderer scenes for (TMap<UWorld*, bool>::TConstIterator It(WorldsToUpdate); It; ++It) { UWorld* World = It.Key(); RendererModule.AllocateScene(World, World->RequiresHitProxies(), It.Value(), World->FeatureLevel); for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); Level->InitializeRenderingResources(); } } // Restore FShaders from the serialized memory blobs // Shader maps may still not be complete after this due to code changes picked up in the recompile RestoreGlobalShaderMap(GRHIShaderPlatform_DEPRECATED, *GlobalShaderData); UMaterial::RestoreMaterialShadersFromMemory(GRHIShaderPlatform_DEPRECATED, ShaderMapToSerializedShaderData); FMaterialShaderMap::FixupShaderTypes(GRHIShaderPlatform_DEPRECATED, ShaderTypeNames, VertexFactoryTypeNames); TArray<FShaderType*> OutdatedShaderTypes; TArray<const FVertexFactoryType*> OutdatedFactoryTypes; FShaderType::GetOutdatedTypes(OutdatedShaderTypes, OutdatedFactoryTypes); // Recompile any missing shaders UMaterialInterface::IterateOverActiveFeatureLevels([&](ERHIFeatureLevel::Type FeatureLevel) { auto ShaderPlatform = GShaderPlatformForFeatureLevel[FeatureLevel]; BeginRecompileGlobalShaders(OutdatedShaderTypes, ShaderPlatform); UMaterial::UpdateMaterialShaders(OutdatedShaderTypes, OutdatedFactoryTypes, ShaderPlatform); }); // Block on global shader jobs FinishRecompileGlobalShaders(); }
/** Clears and optionally backs up all references to renderer module classes in other modules, particularly engine. */ void ClearReferencesToRendererModuleClasses( TMap<UWorld*, bool>& WorldsToUpdate, TMap<FMaterialShaderMap*, TScopedPointer<TArray<uint8> > >& ShaderMapToSerializedShaderData, TScopedPointer<TArray<uint8> >& GlobalShaderData, TMap<FShaderType*, FString>& ShaderTypeNames, TMap<FVertexFactoryType*, FString>& VertexFactoryTypeNames) { // Destroy all renderer scenes for (TObjectIterator<UWorld> WorldIt; WorldIt; ++WorldIt) { UWorld* World = *WorldIt; if (World->Scene) { WorldsToUpdate.Add(World, World->FXSystem != NULL); for (int32 LevelIndex = 0; LevelIndex < World->GetNumLevels(); LevelIndex++) { ULevel* Level = World->GetLevel(LevelIndex); Level->ReleaseRenderingResources(); } if (World->FXSystem != NULL) { FFXSystemInterface::Destroy(World->FXSystem); World->FXSystem = NULL; } World->Scene->Release(); World->Scene = NULL; } } // Save off shaders by serializing them into memory, and remove all shader map references to FShaders GlobalShaderData = TScopedPointer<TArray<uint8> >(BackupGlobalShaderMap(GRHIShaderPlatform_DEPRECATED)); UMaterial::BackupMaterialShadersToMemory(ShaderMapToSerializedShaderData); // Verify no FShaders still in memory for(TLinkedList<FShaderType*>::TIterator It(FShaderType::GetTypeList()); It; It.Next()) { FShaderType* ShaderType = *It; check(ShaderType->GetNumShaders() == 0); ShaderTypeNames.Add(ShaderType, ShaderType->GetName()); } for(TLinkedList<FVertexFactoryType*>::TIterator It(FVertexFactoryType::GetTypeList()); It; It.Next()) { FVertexFactoryType* VertexFactoryType = *It; VertexFactoryTypeNames.Add(VertexFactoryType, VertexFactoryType->GetName()); } // Destroy misc renderer module classes and remove references FSceneViewStateReference::DestroyAll(); FSlateApplication::Get().InvalidateAllViewports(); // Invalidate cached shader type data UninitializeShaderTypes(); // Delete pending cleanup objects to remove those references, which are potentially renderer module classes FPendingCleanupObjects* PendingCleanupObjects = GetPendingCleanupObjects(); delete PendingCleanupObjects; GEngine->EngineLoop->ClearPendingCleanupObjects(); ResetCachedRendererModule(); }
TSharedRef< SWidget > FLevelEditorToolBar::GenerateOpenBlueprintMenuContent( TSharedRef<FUICommandList> InCommandList, TWeakPtr< SLevelEditor > InLevelEditor ) { #define LOCTEXT_NAMESPACE "LevelToolBarViewMenu" struct FBlueprintMenus { /** Generates a sub-level Blueprints sub-menu */ static void MakeSubLevelsMenu(FMenuBuilder& InMenuBuilder, TWeakPtr< SLevelEditor > InLvlEditor) { FSlateIcon EditBP(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")); InMenuBuilder.BeginSection(NAME_None, LOCTEXT("SubLevelsHeading", "Sub-Level Blueprints")); { UWorld* World = InLvlEditor.Pin()->GetWorld(); for (int32 iLevel = 0; iLevel < World->GetNumLevels(); iLevel++) { ULevel* Level = World->GetLevel(iLevel); if (Level != NULL && Level->GetOutermost() != NULL) { if (!Level->IsPersistentLevel()) { FUIAction UIAction ( FExecuteAction::CreateStatic(&FLevelEditorToolBar::OnOpenSubLevelBlueprint, Level) ); FText DisplayName = FText::Format(LOCTEXT("SubLevelBlueprintItem", "Edit {LevelName}"), FText::FromString(FPaths::GetCleanFilename(Level->GetOutermost()->GetName()))); InMenuBuilder.AddMenuEntry(DisplayName, FText::GetEmpty(), EditBP, UIAction); } } } } InMenuBuilder.EndSection(); } /** Handle BP being selected from popup picker */ static void OnBPSelected(const class FAssetData& AssetData) { UBlueprint* SelectedBP = Cast<UBlueprint>(AssetData.GetAsset()); if(SelectedBP) { FAssetEditorManager::Get().OpenEditorForAsset(SelectedBP); } } /** Generates 'eopn blueprint' sub-menu */ static void MakeOpenClassBPMenu(FMenuBuilder& InMenuBuilder) { FContentBrowserModule& ContentBrowserModule = FModuleManager::Get().LoadModuleChecked<FContentBrowserModule>(TEXT("ContentBrowser")); // Configure filter for asset picker FAssetPickerConfig Config; Config.Filter.ClassNames.Add(UBlueprint::StaticClass()->GetFName()); Config.InitialAssetViewType = EAssetViewType::List; Config.ThumbnailScale = 0; // make thumbnails as small as possible Config.OnAssetSelected = FOnAssetSelected::CreateStatic(&FBlueprintMenus::OnBPSelected); Config.bAllowDragging = false; // Don't show stuff in Engine Config.Filter.PackagePaths.Add("/Game"); Config.Filter.bRecursivePaths = true; TSharedRef<SWidget> Widget = SNew(SBox) .WidthOverride(300.f) .HeightOverride(300.f) [ ContentBrowserModule.Get().CreateAssetPicker(Config) ]; InMenuBuilder.BeginSection(NAME_None, LOCTEXT("BrowseHeader", "Browse")); { InMenuBuilder.AddWidget(Widget, FText::GetEmpty()); } InMenuBuilder.EndSection(); } }; const bool bShouldCloseWindowAfterMenuSelection = true; FMenuBuilder MenuBuilder( bShouldCloseWindowAfterMenuSelection, InCommandList ); MenuBuilder.BeginSection(NAME_None, LOCTEXT("LevelScriptBlueprints", "Level Blueprints")); { MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenLevelBlueprint ); // If there are any sub-levels, display the sub-menu. A single level means there is only the persistent level UWorld* World = InLevelEditor.Pin()->GetWorld(); if(World->GetNumLevels() > 1) { MenuBuilder.AddSubMenu( LOCTEXT( "SubLevelsSubMenu", "Sub-Levels" ), LOCTEXT( "SubLevelsSubMenu_ToolTip", "Shows available sub-level Blueprints that can be edited." ), FNewMenuDelegate::CreateStatic( &FBlueprintMenus::MakeSubLevelsMenu, InLevelEditor ), FUIAction(), NAME_None, EUserInterfaceActionType::Button, false, FSlateIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("LevelEditor.OpenLevelBlueprint")) ); } } MenuBuilder.EndSection(); MenuBuilder.BeginSection(NAME_None, LOCTEXT("GameBlueprints", "Game Blueprints")); { FSlateIcon EditBPIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("PropertyWindow.Button_Edit")); FSlateIcon NewBPIcon(FEditorStyle::Get().GetStyleSetName(), TEXT("PropertyWindow.Button_AddToArray")); // Game Mode TAttribute<FText>::FGetter DynamicGameModeGetter; DynamicGameModeGetter.BindStatic(&FLevelEditorToolBar::GetOpenGameModeBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicGameModeLabel = TAttribute<FText>::Create(DynamicGameModeGetter); TAttribute<FText>::FGetter DynamicGameModeGetter_Tooltip; DynamicGameModeGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenGameModeBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicGameModeTooltip = TAttribute<FText>::Create(DynamicGameModeGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenGameModeBlueprint, NAME_None, DynamicGameModeLabel, DynamicGameModeTooltip, IsValidGameModeBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Game State TAttribute<FText>::FGetter DynamicGameStateGetter; DynamicGameStateGetter.BindStatic(&FLevelEditorToolBar::GetOpenGameStateBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicGameStateLabel = TAttribute<FText>::Create(DynamicGameStateGetter); TAttribute<FText>::FGetter DynamicGameStateGetter_Tooltip; DynamicGameStateGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenGameStateBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicGameStateTooltip = TAttribute<FText>::Create(DynamicGameStateGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenGameStateBlueprint, NAME_None, DynamicGameStateLabel, DynamicGameStateTooltip, IsValidGameStateBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Pawn TAttribute<FText>::FGetter DynamicDefaultPawnGetter; DynamicDefaultPawnGetter.BindStatic(&FLevelEditorToolBar::GetOpenPawnBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicDefaultPawnLabel = TAttribute<FText>::Create(DynamicDefaultPawnGetter); TAttribute<FText>::FGetter DynamicDefaultPawnGetter_Tooltip; DynamicDefaultPawnGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenPawnBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicDefaultPawnTooltip = TAttribute<FText>::Create(DynamicDefaultPawnGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenDefaultPawnBlueprint, NAME_None, DynamicDefaultPawnLabel, DynamicDefaultPawnTooltip, IsValidPawnBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // HUD TAttribute<FText>::FGetter DynamicHUDGetter; DynamicHUDGetter.BindStatic(&FLevelEditorToolBar::GetOpenHUDBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicHUDLabel = TAttribute<FText>::Create(DynamicHUDGetter); TAttribute<FText>::FGetter DynamicHUDGetter_Tooltip; DynamicHUDGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenHUDBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicHUDTooltip = TAttribute<FText>::Create(DynamicHUDGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenHUDBlueprint, NAME_None, DynamicHUDLabel, DynamicHUDTooltip, IsValidHUDBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); // Player Controller TAttribute<FText>::FGetter DynamicPlayerControllerGetter; DynamicPlayerControllerGetter.BindStatic(&FLevelEditorToolBar::GetOpenPlayerControllerBlueprintLabel, InLevelEditor); TAttribute<FText> DynamicPlayerControllerLabel = TAttribute<FText>::Create(DynamicPlayerControllerGetter); TAttribute<FText>::FGetter DynamicPlayerControllerGetter_Tooltip; DynamicPlayerControllerGetter_Tooltip.BindStatic(&FLevelEditorToolBar::GetOpenPlayerControllerBlueprintTooltip, InLevelEditor); TAttribute<FText> DynamicPlayerControllerTooltip = TAttribute<FText>::Create(DynamicPlayerControllerGetter_Tooltip); MenuBuilder.AddMenuEntry( FLevelEditorCommands::Get().OpenPlayerControllerBlueprint, NAME_None, DynamicPlayerControllerLabel, DynamicPlayerControllerTooltip, IsValidPlayerControllerBlueprint(InLevelEditor)? EditBPIcon : NewBPIcon ); } MenuBuilder.EndSection(); MenuBuilder.BeginSection(NAME_None, LOCTEXT("ClassBlueprints", "Class Blueprints")); { // New Class Blueprint... MenuBuilder.AddMenuEntry(FLevelEditorCommands::Get().CreateClassBlueprint, NAME_None, LOCTEXT("NewClassBlueprint", "New Class Blueprint...")); // Open Class Blueprint... FSlateIcon OpenBPIcon(FEditorStyle::GetStyleSetName(), "LevelEditor.OpenClassBlueprint"); MenuBuilder.AddSubMenu( LOCTEXT("OpenClassBlueprintSubMenu", "Open Class Blueprint..."), LOCTEXT("OpenClassBlueprintSubMenu_ToolTip", "Open an existing Class Blueprint in this project"), FNewMenuDelegate::CreateStatic(&FBlueprintMenus::MakeOpenClassBPMenu), false, OpenBPIcon ); } MenuBuilder.EndSection(); #undef LOCTEXT_NAMESPACE return MenuBuilder.MakeWidget(); }