Files
2025-05-18 13:04:45 +08:00

109 lines
2.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Selections/GeometrySelection.h"
#include "DynamicMesh/DynamicMesh3.h"
#include "Algo/Find.h"
using namespace UE::Geometry;
void FGeometrySelectionEditor::Initialize(FGeometrySelection* TargetSelectionIn, const FGeometrySelectionHitQueryConfig& QueryConfigIn, bool bEnableTopologyIDFilteringIn)
{
check(TargetSelectionIn != nullptr);
TargetSelection = TargetSelectionIn;
UpdateQueryConfig(QueryConfigIn, bEnableTopologyIDFilteringIn);
}
void FGeometrySelectionEditor::Initialize(FGeometrySelection* TargetSelectionIn, bool bEnableTopologyIDFilteringIn)
{
check(TargetSelectionIn != nullptr);
TargetSelection = TargetSelectionIn;
FGeometrySelectionHitQueryConfig TmpQueryConfig{TargetSelection->TopologyType, TargetSelection->ElementType, false};
UpdateQueryConfig(TmpQueryConfig, bEnableTopologyIDFilteringIn);
}
void FGeometrySelectionEditor::UpdateQueryConfig(const FGeometrySelectionHitQueryConfig& NewConfig, bool bEnableTopologyIDFilteringIn)
{
check(NewConfig.ElementType == TargetSelection->ElementType);
check(NewConfig.TopologyType == TargetSelection->TopologyType);
QueryConfig = NewConfig;
bEnableTopologyIDFiltering = bEnableTopologyIDFilteringIn;
}
void FGeometrySelectionEditor::ClearSelection(FGeometrySelectionDelta& DeltaOut)
{
for (uint64 ID : TargetSelection->Selection)
{
DeltaOut.Removed.Add(ID);
}
TargetSelection->Reset();
}
bool FGeometrySelectionEditor::IsSelected(uint64 ID) const
{
if (bEnableTopologyIDFiltering)
{
bool bFound;
RemapToExistingTopologyID(ID, bFound);
return bFound;
}
return TargetSelection->Selection.Contains(ID);
}
bool FGeometrySelectionEditor::RemoveFromSelection(uint64 ID)
{
if (bEnableTopologyIDFiltering)
{
bool bFound;
ID = RemapToExistingTopologyID(ID, bFound);
if (!bFound)
{
return false;
}
}
int32 NumRemoved = TargetSelection->Selection.Remove(ID);
checkSlow(NumRemoved == 0 || NumRemoved == 1);
return (NumRemoved > 0);
}
uint64 FGeometrySelectionEditor::RemapToExistingTopologyID(uint64 ID, bool& bFound) const
{
bFound = false;
uint32 TopologyID = FGeoSelectionID(ID).TopologyID;
const uint64* Found = Algo::FindByPredicate(TargetSelection->Selection, [&](uint64 Item)
{
return FGeoSelectionID(Item).TopologyID == TopologyID;
});
if (Found != nullptr)
{
bFound = true;
return *Found;
}
return ID;
}
bool FGeometrySelectionEditor::Replace(const FGeometrySelection& NewSelection, FGeometrySelectionDelta& DeltaOut)
{
// currently hard-enforcing this...maybe we can allow switches?
if (ensure(TargetSelection->ElementType == NewSelection.ElementType) == false ||
ensure(TargetSelection->TopologyType == NewSelection.TopologyType) == false)
{
return false;
}
for (uint64 ID : TargetSelection->Selection)
{
DeltaOut.Removed.Add(ID);
}
TargetSelection->Selection.Reset();
for (uint64 ID : NewSelection.Selection)
{
TargetSelection->Selection.Add(ID);
DeltaOut.Added.Add(ID);
}
return true;
}