void UEditorEngine::polySelectMatchingBrush(UModel *InModel) { TArray<ABrush*> Brushes; GetListOfUniqueBrushes( &Brushes, InModel ); // Select all the faces. for( int32 i = 0 ; i < InModel->Surfs.Num() ; i++ ) { FBspSurf* Surf = &InModel->Surfs[i]; ABrush* SurfBrushActor = Cast<ABrush>(Surf->Actor); if ( SurfBrushActor ) { // Select all the polys on each brush in the unique list. for( int32 brush = 0 ; brush < Brushes.Num() ; brush++ ) { ABrush* CurBrush = Brushes[brush]; if( SurfBrushActor == CurBrush ) { for( int32 poly = 0 ; poly < CurBrush->Brush->Polys->Element.Num() ; poly++ ) { if( Surf->iBrushPoly == poly ) { InModel->ModifySurf( i, 0 ); GEditor->SelectBSPSurf( InModel, i, true, false ); } } } } } } NoteSelectionChange(); }
void UEditorEngine::polySelectMatchingGroups( UModel* Model ) { // @hack: polySelectMatchingGroups: do nothing for now as temp fix until this can be rewritten (crashes a lot) #if 0 FMemory::Memzero( GFlags1, sizeof(GFlags1) ); for( int32 i=0; i<Model->Surfs.Num(); i++ ) { FBspSurf *Surf = &Model->Surfs(i); if( Surf->PolyFlags&PF_Selected ) { FPoly Poly; polyFindMaster(Model,i,Poly); GFlags1[Poly.Actor->Layer.GetIndex()]=1; } } for( int32 i=0; i<Model->Surfs.Num(); i++ ) { FBspSurf *Surf = &Model->Surfs(i); FPoly Poly; polyFindMaster(Model,i,Poly); if ( (GFlags1[Poly.Actor->Layer.GetIndex()]) && (!(Surf->PolyFlags & PF_Selected)) ) { Model->ModifySurf( i, 0 ); GEditor->SelectBSPSurf( Model, i, true, false ); } } NoteSelectionChange(); #endif }
void UUnrealEdEngine::SelectBSPSurf(UModel* InModel, int32 iSurf, bool bSelected, bool bNoteSelectionChange) { if( GEdSelectionLock ) { return; } FBspSurf& Surf = InModel->Surfs[ iSurf ]; InModel->ModifySurf( iSurf, false ); if( bSelected ) { Surf.PolyFlags |= PF_Selected; } else { Surf.PolyFlags &= ~PF_Selected; } if( bNoteSelectionChange ) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; }
void UUnrealEdEngine::SelectGroup(AGroupActor* InGroupActor, bool bForceSelection/*=false*/, bool bInSelected/*=true*/, bool bNotify/*=true*/) { USelection* SelectedActors = GetSelectedActors(); SelectedActors->BeginBatchSelectOperation(); SelectedActors->Modify(); static bool bIteratingGroups = false; if( !bIteratingGroups ) { bIteratingGroups = true; // Select all actors within the group (if locked or forced) if( bForceSelection || InGroupActor->IsLocked() ) { TArray<AActor*> GroupActors; InGroupActor->GetGroupActors(GroupActors); for( int32 ActorIndex=0; ActorIndex < GroupActors.Num(); ++ActorIndex ) { SelectActor(GroupActors[ActorIndex], bInSelected, false ); } bForceSelection = true; // Recursively select any subgroups TArray<AGroupActor*> SubGroups; InGroupActor->GetSubGroups(SubGroups); for( int32 GroupIndex=0; GroupIndex < SubGroups.Num(); ++GroupIndex ) { SelectGroup(SubGroups[GroupIndex], bForceSelection, bInSelected, false); } } SelectedActors->EndBatchSelectOperation(bNotify); if (bNotify) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; bIteratingGroups = false; } }
void UUnrealEdEngine::SelectComponent(UActorComponent* Component, bool bInSelected, bool bNotify, bool bSelectEvenIfHidden) { // Don't do any work if the component's selection state matches the target selection state const bool bComponentSelected = GetSelectedComponents()->IsSelected(Component); if (( bComponentSelected && !bInSelected ) || ( !bComponentSelected && bInSelected )) { if (bInSelected) { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Selected Component: %s"), *Component->GetClass()->GetName()); } else { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Deselected Component: %s"), *Component->GetClass()->GetName()); } GetSelectedComponents()->Select(Component, bInSelected); // Make sure the override delegate is bound properly auto SceneComponent = Cast<USceneComponent>(Component); if (SceneComponent) { FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, true); } // Update the selection visualization AActor* ComponentOwner = Component->GetOwner(); if (ComponentOwner != nullptr) { TInlineComponentArray<UPrimitiveComponent*> PrimitiveComponents; ComponentOwner->GetComponents(PrimitiveComponents); for (int32 Idx = 0; Idx < PrimitiveComponents.Num(); ++Idx) { PrimitiveComponents[Idx]->PushSelectionToProxy(); } } if (bNotify) { NoteSelectionChange(); } } }
void UEditorEngine::polySelectMatchingItems(UModel *InModel) { #if 0 FMemory::Memzero(GFlags1,sizeof(GFlags1)); FMemory::Memzero(GFlags2,sizeof(GFlags2)); for( int32 i=0; i<InModel->Surfs.Num(); i++ ) { FBspSurf *Surf = &InModel->Surfs(i); if( Surf->Actor ) { if( Surf->PolyFlags & PF_Selected ) GFlags2[Surf->Actor->Brush->GetIndex()]=1; } if( Surf->PolyFlags&PF_Selected ) { FPoly Poly; polyFindMaster(InModel,i,Poly); GFlags1[Poly.ItemName.GetIndex()]=1; } } for( int32 i=0; i<InModel->Surfs.Num(); i++ ) { FBspSurf *Surf = &InModel->Surfs(i); if( Surf->Actor ) { FPoly Poly; polyFindMaster(InModel,i,Poly); if ((GFlags1[Poly.ItemName.GetIndex()]) && ( GFlags2[Surf->Actor->Brush->GetIndex()]) && (!(Surf->PolyFlags & PF_Selected))) { InModel->ModifySurf( i, 0 ); GEditor->SelectBSPSurf( InModel, i, true, false ); } } } NoteSelectionChange(); #endif }
void UEditorEngine::polySelectMatchingResolution(UWorld* InWorld, bool bCurrentLevelOnly) { // true if at least one surface was selected. bool bSurfaceWasSelected = false; TArray<float> SelectedResolutions; if (bCurrentLevelOnly == true) { for (TSelectedSurfaceIterator<FCurrentLevelSurfaceLevelFilter> It(InWorld); It; ++It) { SelectedResolutions.AddUnique(It->LightMapScale); } if (SelectedResolutions.Num() > 0) { if (SelectedResolutions.Num() > 1) { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "BSPSelect_DifferentResolutionsSelected", "Different selected resolutions.\nCan only select matching for a single resolution.")); } else { // Select all surfaces with matching materials. for (TSurfaceIterator<FCurrentLevelSurfaceLevelFilter> It(InWorld); It; ++It) { if (SelectedResolutions.Contains(It->LightMapScale)) { UModel* Model = It.GetModel(); const int32 SurfaceIndex = It.GetSurfaceIndex(); Model->ModifySurf( SurfaceIndex, 0 ); GEditor->SelectBSPSurf( Model, SurfaceIndex, true, false ); bSurfaceWasSelected = true; } } } } } else { for (TSelectedSurfaceIterator<> It(InWorld); It; ++It) { SelectedResolutions.AddUnique(It->LightMapScale); } if (SelectedResolutions.Num() > 0) { if (SelectedResolutions.Num() > 1) { FMessageDialog::Open( EAppMsgType::Ok, NSLOCTEXT("UnrealEd", "BSPSelect_DifferentResolutionsSelected", "Different selected resolutions.\nCan only select matching for a single resolution.")); } else { // Select all surfaces with matching materials. for (TSurfaceIterator<> It(InWorld); It; ++It) { if (SelectedResolutions.Contains(It->LightMapScale)) { UModel* Model = It.GetModel(); const int32 SurfaceIndex = It.GetSurfaceIndex(); Model->ModifySurf( SurfaceIndex, 0 ); GEditor->SelectBSPSurf( Model, SurfaceIndex, true, false ); bSurfaceWasSelected = true; } } } } } if ( bSurfaceWasSelected ) { NoteSelectionChange(); } }
void UEditorEngine::polySelectMatchingMaterial(UWorld* InWorld, bool bCurrentLevelOnly) { // true if at least one surface was selected. bool bSurfaceWasSelected = false; // true if default material representations have already been added to the materials list. bool bDefaultMaterialAdded = false; TArray<UMaterialInterface*> Materials; if ( bCurrentLevelOnly ) { // Get list of unique materials that are on selected faces. for ( TSelectedSurfaceIterator<FCurrentLevelSurfaceLevelFilter> It(InWorld) ; It ; ++It ) { if ( It->Material && It->Material != UMaterial::GetDefaultMaterial(MD_Surface) ) { Materials.AddUnique( It->Material ); } else if ( !bDefaultMaterialAdded ) { bDefaultMaterialAdded = true; // Add both representations of the default material. Materials.AddUnique( NULL ); Materials.AddUnique( UMaterial::GetDefaultMaterial(MD_Surface) ); } } // Select all surfaces with matching materials. for ( TSurfaceIterator<FCurrentLevelSurfaceLevelFilter> It(InWorld) ; It ; ++It ) { // Map the default material to NULL, so that NULL assignments match manual default material assignments. if( Materials.Contains( It->Material ) ) { UModel* Model = It.GetModel(); const int32 SurfaceIndex = It.GetSurfaceIndex(); Model->ModifySurf( SurfaceIndex, 0 ); GEditor->SelectBSPSurf( Model, SurfaceIndex, true, false ); bSurfaceWasSelected = true; } } } else { // Get list of unique materials that are on selected faces. for ( TSelectedSurfaceIterator<> It(InWorld) ; It ; ++It ) { if ( It->Material && It->Material != UMaterial::GetDefaultMaterial(MD_Surface) ) { Materials.AddUnique( It->Material ); } else if ( !bDefaultMaterialAdded ) { bDefaultMaterialAdded = true; // Add both representations of the default material. Materials.AddUnique( NULL ); Materials.AddUnique( UMaterial::GetDefaultMaterial(MD_Surface) ); } } // Select all surfaces with matching materials. for ( TSurfaceIterator<> It(InWorld) ; It ; ++It ) { // Map the default material to NULL, so that NULL assignments match manual default material assignments. if( Materials.Contains( It->Material ) ) { UModel* Model = It.GetModel(); const int32 SurfaceIndex = It.GetSurfaceIndex(); Model->ModifySurf( SurfaceIndex, 0 ); GEditor->SelectBSPSurf( Model, SurfaceIndex, true, false ); bSurfaceWasSelected = true; } } } if ( bSurfaceWasSelected ) { NoteSelectionChange(); } }
void UUnrealEdEngine::SelectNone(bool bNoteSelectionChange, bool bDeselectBSPSurfs, bool WarnAboutManyActors) { if( GEdSelectionLock ) { return; } bool bShowProgress = false; // If there are a lot of actors to process, pop up a warning "are you sure?" box if( WarnAboutManyActors ) { int32 NumSelectedActors = GEditor->GetSelectedActorCount(); if( NumSelectedActors >= EditorActorSelectionDefs::MaxActorsToSelectBeforeWarning ) { bShowProgress = true; const FText ConfirmText = FText::Format( NSLOCTEXT("UnrealEd", "Warning_ManyActorsForDeselect", "There are {0} selected actors. Are you sure you want to deselect them all?" ), FText::AsNumber(NumSelectedActors) ); FSuppressableWarningDialog::FSetupInfo Info( ConfirmText, NSLOCTEXT( "UnrealEd", "Warning_ManyActors", "Warning: Many Actors" ), "Warning_ManyActors" ); Info.ConfirmText = NSLOCTEXT("ModalDialogs", "ManyActorsForDeselectConfirm", "Continue Deselection"); Info.CancelText = NSLOCTEXT("ModalDialogs", "ManyActorsForDeselectCancel", "Keep Current Selection"); FSuppressableWarningDialog ManyActorsWarning( Info ); if( ManyActorsWarning.ShowModal() == FSuppressableWarningDialog::Cancel ) { return; } } } if( bShowProgress ) { GWarn->BeginSlowTask( LOCTEXT("BeginDeselectingActorsTaskMessage", "Deselecting Actors"), true ); } // Make a list of selected actors . . . TArray<AActor*> ActorsToDeselect; for ( FSelectionIterator It( GetSelectedActorIterator() ) ; It ; ++It ) { AActor* Actor = static_cast<AActor*>( *It ); checkSlow( Actor->IsA(AActor::StaticClass()) ); ActorsToDeselect.Add( Actor ); } USelection* SelectedActors = GetSelectedActors(); SelectedActors->BeginBatchSelectOperation(); SelectedActors->Modify(); // . . . and deselect them. for ( int32 ActorIndex = 0 ; ActorIndex < ActorsToDeselect.Num() ; ++ActorIndex ) { AActor* Actor = ActorsToDeselect[ ActorIndex ]; SelectActor( Actor, false, false ); } uint32 NumDeselectSurfaces = 0; UWorld* World = GWorld; if( bDeselectBSPSurfs && World ) { // Unselect all surfaces in all levels. NumDeselectSurfaces += DeselectAllSurfacesForLevel( World->PersistentLevel ); for( int32 LevelIndex = 0 ; LevelIndex < World->StreamingLevels.Num() ; ++LevelIndex ) { ULevelStreaming* StreamingLevel = World->StreamingLevels[LevelIndex]; if( StreamingLevel ) { ULevel* Level = StreamingLevel->GetLoadedLevel(); if ( Level != NULL ) { NumDeselectSurfaces += DeselectAllSurfacesForLevel( Level ); } } } } SelectedActors->EndBatchSelectOperation(bNoteSelectionChange); //prevents clicking on background multiple times spamming selection changes if (ActorsToDeselect.Num() || NumDeselectSurfaces) { GetSelectedActors()->DeselectAll(); if( bNoteSelectionChange ) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; } if( bShowProgress ) { GWarn->EndSlowTask(); } }
void UUnrealEdEngine::SelectActor(AActor* Actor, bool bInSelected, bool bNotify, bool bSelectEvenIfHidden, bool bForceRefresh) { const bool bWarnIfLevelLocked = true; if( !CanSelectActor( Actor, bInSelected, bSelectEvenIfHidden, bWarnIfLevelLocked ) ) { return; } bool bSelectionHandled = false; TArray<FEdMode*> ActiveModes; GLevelEditorModeTools().GetActiveModes( ActiveModes ); for( int32 ModeIndex = 0; ModeIndex < ActiveModes.Num(); ++ModeIndex ) { bSelectionHandled |= ActiveModes[ModeIndex]->Select( Actor, bInSelected ); } // Select the actor and update its internals. if( !bSelectionHandled ) { if(bInSelected) { // If trying to select an Actor spawned by a ChildACtorComponent, instead select Actor that spawned us if(Actor->ParentComponentActor.IsValid()) { Actor = Actor->ParentComponentActor.Get(); } } if (GEditor->bGroupingActive) { // if this actor is a group, do a group select/deselect AGroupActor* SelectedGroupActor = Cast<AGroupActor>(Actor); if (SelectedGroupActor) { SelectGroup(SelectedGroupActor, true, bInSelected, bNotify); } else { // Select/Deselect this actor's entire group, starting from the top locked group. // If none is found, just use the actor. AGroupActor* ActorLockedRootGroup = AGroupActor::GetRootForActor(Actor, true); if (ActorLockedRootGroup) { SelectGroup(ActorLockedRootGroup, false, bInSelected, bNotify); } } } // Don't do any work if the actor's selection state is already the selected state. const bool bActorSelected = Actor->IsSelected(); if ( (bActorSelected && !bInSelected) || (!bActorSelected && bInSelected) ) { if(bInSelected) { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Selected Actor: %s"), *Actor->GetClass()->GetName()); } else { UE_LOG(LogEditorSelectUtils, Verbose, TEXT("Deselected Actor: %s"), *Actor->GetClass()->GetName() ); } GetSelectedActors()->Select( Actor, bInSelected ); if (!bInSelected) { if (GetSelectedComponentCount() > 0) { GetSelectedComponents()->Modify(); } for (UActorComponent* Component : Actor->GetComponents()) { GetSelectedComponents()->Deselect( Component ); // Remove the selection override delegates from the deselected components auto SceneComponent = Cast<USceneComponent>(Component); FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, false); } } else { // Bind the override delegates for the components in the selected actor for (UActorComponent* Component : Actor->GetComponents()) { auto SceneComponent = Cast<USceneComponent>(Component); FComponentEditorUtils::BindComponentSelectionOverride(SceneComponent, true); } } //A fast path to mark selection rather than reconnecting ALL components for ALL actors that have changed state SetActorSelectionFlags (Actor); if( bNotify ) { NoteSelectionChange(); } //whenever selection changes, recompute whether the selection contains a locked actor bCheckForLockActors = true; //whenever selection changes, recompute whether the selection contains a world info actor bCheckForWorldSettingsActors = true; } else { if (bNotify || bForceRefresh) { //reset the property windows. In case something has changed since previous selection UpdateFloatingPropertyWindows(bForceRefresh); } } } }