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

185 lines
6.9 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Dataflow/GeometryCollectionEditNodes.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 "FractureEngineEdit.h"
#include "FractureEngineSelection.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(GeometryCollectionEditNodes)
namespace UE::Dataflow
{
void GeometryCollectionEditNodes()
{
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FPruneInCollectionDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FSetVisibilityInCollectionDataflowNode);
DATAFLOW_NODE_REGISTER_CREATION_FACTORY(FMergeInCollectionDataflowNode);
}
}
void FPruneInCollectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
const FDataflowTransformSelection& InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
const int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
if (InTransformSelection.Num() == NumTransforms)
{
if (InTransformSelection.AnySelected())
{
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
TArray<int32> BoneIndices;
InTransformSelection.AsArray(BoneIndices);
FFractureEngineEdit::DeleteBranch(*GeomCollection, BoneIndices);
SetValue<const FManagedArrayCollection&>(Context, *GeomCollection, &Collection);
return;
}
}
}
else
{
// ERROR: InTransformSelection's length doesn't much number of transforms in InCollection
FString ErrorStr = "TransformSelection's number of elements doesn't match number of transforms in Collection.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
SetValue(Context, InCollection, &Collection);
}
}
void FSetVisibilityInCollectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FDataflowTransformSelection& InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
const FDataflowFaceSelection& InFaceSelection = GetValue<FDataflowFaceSelection>(Context, &FaceSelection);
if (IsConnected<FDataflowTransformSelection>(&TransformSelection))
{
FManagedArrayCollection InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
const int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
if (InTransformSelection.Num() == NumTransforms)
{
if (InTransformSelection.AnySelected())
{
TArray<int32> BoneIndices;
InTransformSelection.AsArray(BoneIndices);
FFractureEngineEdit::SetVisibilityInCollectionFromTransformSelection(InCollection, BoneIndices, Visibility == EVisibiltyOptionsEnum::Dataflow_VisibilityOptions_Visible);
SetValue(Context, MoveTemp(InCollection), &Collection);
return;
}
}
else
{
// ERROR: InTransformSelection's length doesn't much number of transforms in InCollection
FString ErrorStr = "TransformSelection's number of elements doesn't match number of transforms in Collection.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
}
else if (IsConnected<FDataflowFaceSelection>(&FaceSelection))
{
FManagedArrayCollection InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
const int32 NumFaces = InCollection.NumElements(FGeometryCollection::FacesGroup);
if (InFaceSelection.Num() == NumFaces)
{
if (InFaceSelection.AnySelected())
{
TArray<int32> FaceIndexArr;
InFaceSelection.AsArray(FaceIndexArr);
FFractureEngineEdit::SetVisibilityInCollectionFromFaceSelection(InCollection, FaceIndexArr, Visibility == EVisibiltyOptionsEnum::Dataflow_VisibilityOptions_Visible);
SetValue(Context, MoveTemp(InCollection), &Collection);
return;
}
}
else
{
// ERROR: InTransformSelection's length doesn't much number of transforms in InCollection
FString ErrorStr = "TransformSelection's number of elements doesn't match number of transforms in Collection.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
}
else
{
// ERROR: InTransformSelection's length doesn't much number of transforms in InCollection
FString ErrorStr = "A TransformSelection or a FaceSelection must be connected as input.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
SetValue(Context, InCollection, &Collection);
}
}
void FMergeInCollectionDataflowNode::Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const
{
if (Out->IsA<FManagedArrayCollection>(&Collection))
{
const FManagedArrayCollection& InCollection = GetValue<FManagedArrayCollection>(Context, &Collection);
const FDataflowTransformSelection& InTransformSelection = GetValue<FDataflowTransformSelection>(Context, &TransformSelection);
const int32 NumTransforms = InCollection.NumElements(FGeometryCollection::TransformGroup);
if (InTransformSelection.Num() == NumTransforms)
{
if (InTransformSelection.AnySelected())
{
if (TUniquePtr<FGeometryCollection> GeomCollection = TUniquePtr<FGeometryCollection>(InCollection.NewCopy<FGeometryCollection>()))
{
TArray<int32> BoneIndices;
InTransformSelection.AsArray(BoneIndices);
FFractureEngineEdit::Merge(*GeomCollection, BoneIndices);
SetValue<const FManagedArrayCollection&>(Context, *GeomCollection, &Collection);
return;
}
}
}
else
{
// ERROR: InTransformSelection's length doesn't much number of transforms in InCollection
FString ErrorStr = "TransformSelection's number of elements doesn't match number of transforms in Collection.";
UE_LOG(LogTemp, Error, TEXT("[Dataflow ERROR] %s"), *ErrorStr);
}
SetValue(Context, InCollection, &Collection);
}
}