Files
UnrealEngineUWP/Engine/Plugins/Experimental/GeometryCollectionPlugin/Source/GeometryCollectionNodes/Private/Dataflow/GeometryCollectionSelectionNodes.cpp
gustav melich 4b1e78f31b Dataflow:
- Moved GeometryCollection Dataflow nodes into separate implemetation files by category
- Changed Dataflow node category to "Terminal" on terminal nodes
- Added DataflowGeoemtryCollection, DataflowFlesh categories to nodes
- Addded black default color to terminal category and changed default color for non-specified categories to yellow
- Added comments to all GeometryCollection nodes
- Updated existing Dataflow nodes

#rb Brice.Criswell, Cedric.Caillaud, Harsha.Reddy
#preflight 6377d7d5e30d4388499a07c0

[CL 23206811 by gustav melich in ue5-main branch]
2022-11-18 17:11:01 -05:00

641 lines
24 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Dataflow/GeometryCollectionSelectionNodes.h"
#include "Dataflow/DataflowCore.h"
#include "Engine/StaticMesh.h"
#include "GeometryCollection/GeometryCollectionObject.h"
#include "GeometryCollection/ManagedArrayCollection.h"
#include "GeometryCollection/GeometryCollection.h"
#include "GeometryCollection/GeometryCollectionEngineUtility.h"
#include "GeometryCollection/GeometryCollectionEngineConversion.h"
#include "Logging/LogMacros.h"
#include "Templates/SharedPointer.h"
#include "UObject/UnrealTypePrivate.h"
#include "DynamicMeshToMeshDescription.h"
#include "MeshDescriptionToDynamicMesh.h"
#include "StaticMeshAttributes.h"
#include "DynamicMeshEditor.h"
#include "Operations/MeshBoolean.h"
#include "EngineGlobals.h"
#include "GeometryCollection/GeometryCollectionAlgo.h"
#include "GeometryCollection/GeometryCollectionClusteringUtility.h"
#include "GeometryCollection/GeometryCollectionConvexUtility.h"
#include "Voronoi/Voronoi.h"
#include "PlanarCut.h"
#include "GeometryCollection/GeometryCollectionProximityUtility.h"
#include "FractureEngineClustering.h"
#include "FractureEngineSelection.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GeometryCollectionSelectionNodes)
namespace Dataflow
{
void GeometryCollectionSelectionNodes()
{
static const FLinearColor CDefaultNodeBodyTintColor = FLinearColor(0.f, 0.f, 0.f, 0.5f);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionAllDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionSetOperationDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionInfoDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionNoneDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionInvertDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionRandomDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionRootDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionCustomDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionParentDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionByPercentageDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionChildrenDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionSiblingsDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionLevelDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionContactDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionLeafDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionClusterDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionBySizeDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FCollectionTransformSelectionByVolumeDataflowNode);
// GeometryCollection|Selection
DATAFLOW_NODE_REGISTER_CREATION_FACTORY_NODE_COLORS_BY_CATEGORY("GeometryCollection|Selection", FLinearColor(1.f, 1.f, 0.05f), CDefaultNodeBodyTintColor);
}
}
void FCollectionTransformSelectionAllDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, true);
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionSetOperationDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FDataflowTransformSelection& InTransformSelectionA = GetValue<FDataflowTransformSelection>(Context, &TransformSelectionA);
const FDataflowTransformSelection& InTransformSelectionB = GetValue<FDataflowTransformSelection>(Context, &TransformSelectionB);
FDataflowTransformSelection NewTransformSelection;
if (InTransformSelectionA.Num() == InTransformSelectionB.Num())
{
if (Operation == ESetOperationEnum::Dataflow_SetOperation_AND)
{
InTransformSelectionA.AND(InTransformSelectionB, NewTransformSelection);
}
else if (Operation == ESetOperationEnum::Dataflow_SetOperation_OR)
{
InTransformSelectionA.OR(InTransformSelectionB, NewTransformSelection);
}
else if (Operation == ESetOperationEnum::Dataflow_SetOperation_XOR)
{
InTransformSelectionA.XOR(InTransformSelectionB, NewTransformSelection);
}
}
else
{
// ERROR: INPUT TRANSFORMSELECTIONS HAVE DIFFERENT NUMBER OF ELEMENTS
FString ErrorStr = "Input TransformSelections have different number of elements.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
}
namespace {
struct BoneInfo {
int32 BoneIndex;
int32 Level;
};
}
static void ExpandRecursive(const int32 BoneIndex, int32 Level, const TManagedArray<TSet<int32>>& Children, TArray<BoneInfo>& BoneHierarchy)
{
BoneHierarchy.Add({ BoneIndex, Level });
TSet<int32> ChildrenSet = Children[BoneIndex];
if (ChildrenSet.Num() > 0)
{
for (auto& Child : ChildrenSet)
{
ExpandRecursive(Child, Level + 1, Children, BoneHierarchy);
}
}
}
static void BuildHierarchicalOutput(const TManagedArray<int32>& Parents,
const TManagedArray<TSet<int32>>& Children,
const TManagedArray<FString>& BoneNames,
const FDataflowTransformSelection& TransformSelection,
FString& OutputStr)
{
TArray<BoneInfo> BoneHierarchy;
int32 NumElements = Parents.Num();
for (int32 Index = 0; Index < NumElements; ++Index)
{
if (Parents[Index] == FGeometryCollection::Invalid)
{
ExpandRecursive(Index, 0, Children, BoneHierarchy);
}
}
// Get level max
int32 LevelMax = -1;
int32 BoneNameLengthMax = -1;
for (int32 Idx = 0; Idx < BoneHierarchy.Num(); ++Idx)
{
if (BoneHierarchy[Idx].Level > LevelMax)
{
LevelMax = BoneHierarchy[Idx].Level;
}
int32 BoneNameLength = BoneNames[Idx].Len();
if (BoneNameLength > BoneNameLengthMax)
{
BoneNameLengthMax = BoneNameLength;
}
}
const int32 BoneIndexWidth = 2 + LevelMax * 2 + 6;
const int32 BoneNameWidth = BoneNameLengthMax + 2;
const int32 SelectedWidth = 10;
for (int32 Idx = 0; Idx < BoneHierarchy.Num(); ++Idx)
{
FString BoneIndexStr, BoneNameStr;
BoneIndexStr.Reserve(BoneIndexWidth);
BoneNameStr.Reserve(BoneNameWidth);
if (BoneHierarchy[Idx].Level == 0)
{
BoneIndexStr.Appendf(TEXT("[%d]"), BoneHierarchy[Idx].BoneIndex);
}
else
{
BoneIndexStr.Appendf(TEXT(" |"));
for (int32 Idx1 = 0; Idx1 < BoneHierarchy[Idx].Level; ++Idx1)
{
BoneIndexStr.Appendf(TEXT("--"));
}
BoneIndexStr.Appendf(TEXT("[%d]"), BoneHierarchy[Idx].BoneIndex);
}
BoneIndexStr = BoneIndexStr.RightPad(BoneIndexWidth);
BoneNameStr.Appendf(TEXT("%s"), *BoneNames[Idx]);
BoneNameStr = BoneNameStr.RightPad(BoneNameWidth);
OutputStr.Appendf(TEXT("%s%s%s\n\n"), *BoneIndexStr, *BoneNameStr, (TransformSelection.IsSelected(BoneHierarchy[Idx].BoneIndex) ? TEXT("Selected") : TEXT("---")));
}
}
void FCollectionTransformSelectionInfoDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FString>(&String))
{
const FDataflowTransformSelection& InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FString OutputStr;
OutputStr.Appendf(TEXT("\n----------------------------------------\n"));
OutputStr.Appendf(TEXT("Number of Elements: %d\n"), InTransformSelection.Num());
// Hierarchical display
if (InCollection.HasGroup(FGeometryCollection::TransformGroup) &&
InCollection.HasAttribute("Parent", FGeometryCollection::TransformGroup) &&
InCollection.HasAttribute("Children", FGeometryCollection::TransformGroup) &&
InCollection.HasAttribute("BoneName", FGeometryCollection::TransformGroup))
{
if (InTransformSelection.Num() == InCollection.NumElements(FGeometryCollection::TransformGroup))
{
const TManagedArray<int32>& Parents = InCollection.GetAttribute<int32>("Parent", FGeometryCollection::TransformGroup);
const TManagedArray<TSet<int32>>& Children = InCollection.GetAttribute<TSet<int32>>("Children", FGeometryCollection::TransformGroup);
const TManagedArray<FString>& BoneNames = InCollection.GetAttribute<FString>("BoneName", FGeometryCollection::TransformGroup);
BuildHierarchicalOutput(Parents, Children, BoneNames, InTransformSelection, OutputStr);
}
else
{
// ERROR: TransformSelection doesn't match the Collection
FString ErrorStr = "TransformSelection doesn't match the Collection.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
}
else
// Simple display
{
for (int32 Idx = 0; Idx < InTransformSelection.Num(); ++Idx)
{
OutputStr.Appendf(TEXT("%4d: %s\n"), Idx, (InTransformSelection.IsSelected(Idx) ? TEXT("Selected") : TEXT("---")));
}
}
OutputStr.Appendf(TEXT("----------------------------------------\n"));
SetValue<FString>(Context, OutputStr, &String);
}
}
void FCollectionTransformSelectionNoneDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, false);
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionInvertDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
InTransformSelection.Invert();
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
}
void FCollectionTransformSelectionRandomDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, false);
float RandomSeedVal = GetValue<float>(Context, &RandomSeed);
float RandomThresholdVal = GetValue<float>(Context, &RandomThreshold);
FRandomStream Stream(RandomSeedVal);
for (int32 Idx = 0; Idx < NumTransforms; ++Idx)
{
if (Deterministic)
{
float RandomVal = Stream.FRandRange(0.f, 1.f);
if (RandomVal > RandomThresholdVal)
{
NewTransformSelection.SetSelected(Idx);
}
}
else
{
float RandomVal = FMath::FRandRange(0.f, 1.f);
if (RandomVal > RandomThresholdVal)
{
NewTransformSelection.SetSelected(Idx);
}
}
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionRootDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
if (InCollection.HasGroup(FGeometryCollection::TransformGroup) &&
InCollection.HasAttribute("Parent", FGeometryCollection::TransformGroup))
{
TArray<int32> RootBones;
FFractureEngineSelection::GetRootBones(InCollection, RootBones);
int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, false);
NewTransformSelection.SetFromArray(RootBones);
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else
{
SetValue<FDataflowTransformSelection>(Context, FDataflowTransformSelection(), &TransformSelection);
}
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionCustomDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
if (InCollection.HasGroup(FGeometryCollection::TransformGroup))
{
const int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, false);
const FString InBoneIndices = GetValue<FString>(Context, &BoneIndicies);
TArray<FString> Indicies;
InBoneIndices.ParseIntoArray(Indicies, TEXT(" "), true);
for (FString IndexStr : Indicies)
{
if (IndexStr.IsNumeric())
{
int32 Index = FCString::Atoi(*IndexStr);
if (Index >= 0 && Index < NumTransforms)
{
NewTransformSelection.SetSelected(Index);
}
else
{
// ERROR: INVALID INDEX
FString ErrorStr = "Invalid specified index found.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
}
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else
{
SetValue<FDataflowTransformSelection>(Context, FDataflowTransformSelection(), &TransformSelection);
}
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionParentDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
FFractureEngineSelection::SelectParent(InCollection, InTransformSelection);
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionByPercentageDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
int32 InPercentage = GetValue<int32>(Context, &Percentage);
float InRandomSeed = GetValue<float>(Context, &RandomSeed);
FFractureEngineSelection::SelectByPercentage(InTransformSelection, InPercentage, Deterministic, InRandomSeed);
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
}
void FCollectionTransformSelectionChildrenDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
FFractureEngineSelection::SelectChildren(InCollection, InTransformSelection);
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionSiblingsDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
FFractureEngineSelection::SelectSiblings(InCollection, InTransformSelection);
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionLevelDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
FFractureEngineSelection::SelectLevel(InCollection, InTransformSelection);
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionContactDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
FFractureEngineSelection::SelectContact(*GeomCollection, InTransformSelection);
}
SetValue<FDataflowTransformSelection>(Context, InTransformSelection, &TransformSelection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionLeafDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
FDataflowTransformSelection NewTransformSelection;
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
FFractureEngineSelection::SelectLeaf(*GeomCollection, NewTransformSelection);
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionClusterDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
const int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
// TODO: Convert FractureEngine API to use only FManagedArrayCollection
FDataflowTransformSelection NewTransformSelection;
NewTransformSelection.Initialize(NumTransforms, false);
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
FFractureEngineSelection::SelectCluster(*GeomCollection, NewTransformSelection);
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionBySizeDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
float InSizeMin = GetValue<float>(Context, &SizeMin);
float InSizeMax = GetValue<float>(Context, &SizeMax);
FDataflowTransformSelection NewTransformSelection;
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
FFractureEngineSelection::SelectBySize(*GeomCollection, NewTransformSelection, InSizeMin, InSizeMax);
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}
void FCollectionTransformSelectionByVolumeDataflowNode::Evaluate(Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FDataflowTransformSelection>(&TransformSelection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
float InVolumeMin = GetValue<float>(Context, &VolumeMin);
float InVolumeMax = GetValue<float>(Context, &VolumeMax);
FDataflowTransformSelection NewTransformSelection;
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
FFractureEngineSelection::SelectByVolume(*GeomCollection, NewTransformSelection, InVolumeMin, InVolumeMax);
}
SetValue<FDataflowTransformSelection>(Context, NewTransformSelection, &TransformSelection);
}
else if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue<FManagedArrayCollection>(Context, InCollection, &Collection);
}
}