Files
UnrealEngine/Engine/Plugins/Experimental/GeometryCollectionPlugin/Source/GeometryCollectionNodes/Public/Dataflow/GeometryCollectionDebugNodes.h
2025-05-18 13:04:45 +08:00

180 lines
6.2 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Dataflow/DataflowEngine.h"
#include "GeometryCollection/ManagedArrayCollection.h"
#include "DynamicMesh/DynamicMesh3.h"
#include "UDynamicMesh.h"
#include "GeometryCollectionUtilityNodes.h"
#include "GeometryCollectionDebugNodes.generated.h"
#if UE_ENABLE_INCLUDE_ORDER_DEPRECATED_IN_5_5
namespace Dataflow = UE::Dataflow;
#else
namespace UE_DEPRECATED(5.5, "Use UE::Dataflow instead.") Dataflow {}
#endif
//~ Dataflow nodes that are useful for debugging a geometry collection-related dataflow graph
// Convert convex hulls on a geometry collection to a dynamic mesh
USTRUCT(meta = (DataflowGeometryCollection))
struct FConvexHullToMeshDataflowNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FConvexHullToMeshDataflowNode, "Convex Hull to Mesh", "GeometryCollection|Mesh", "")
private:
UPROPERTY(meta = (DataflowInput, DataflowIntrinsic))
FManagedArrayCollection Collection;
/** Optional transform selection to convert hulls from -- if not provided, all convex hulls will be converted. */
UPROPERTY(meta = (DataflowInput))
FDataflowTransformSelection OptionalSelectionFilter;
/** Whether to robustly extract valid/manifold meshes to represent the convex hulls. Note: Not necessary for simple visualization, but useful for downstream processing. */
UPROPERTY(EditAnywhere, Category = Options)
bool bUseRobustHulls = true;
/** Single mesh aggregating all the convex hulls together */
UPROPERTY(meta = (DataflowOutput))
TObjectPtr<UDynamicMesh> Mesh;
/** Array of meshes for each convex hull found */
UPROPERTY(meta = (DataflowOutput))
TArray<TObjectPtr<UDynamicMesh>> Meshes;
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
public:
FConvexHullToMeshDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid());
};
// Convert a sphere covering, as generated by the 'protect negative space' option on the "Generate Cluster Convex Hull" nodes, to a dynamic mesh
USTRUCT(meta = (DataflowGeometryCollection))
struct FSphereCoveringToMeshDataflowNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FSphereCoveringToMeshDataflowNode, "Sphere Covering to Mesh", "GeometryCollection|Mesh", "")
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FName("FDynamicMesh3"), "Mesh")
public:
// The sphere covering to convert to a mesh
UPROPERTY(meta = (DataflowInput, DataflowIntrinsic))
FDataflowSphereCovering SphereCovering;
// Number of vertices to use along each axis when creating a mesh for each sphere
UPROPERTY(EditAnywhere, Category = Options, meta = (ClampMin = 2))
int32 VerticesAlongEachSide = 8;
UPROPERTY(meta = (DataflowOutput))
TObjectPtr<UDynamicMesh> Mesh;
FSphereCoveringToMeshDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&SphereCovering);
RegisterOutputConnection(&Mesh);
}
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};
// Report the number of spheres in a sphere covering
USTRUCT(meta = (DataflowGeometryCollection))
struct FSphereCoveringCountSpheresNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FSphereCoveringCountSpheresNode, "Get Sphere Covering Sphere Count", "SphereCovering", "")
public:
// The sphere covering to evaluate
UPROPERTY(meta = (DataflowInput, DataflowIntrinsic))
FDataflowSphereCovering SphereCovering;
// Number of spheres in the sphere covering
UPROPERTY(meta = (DataflowOutput))
int32 NumSpheres = 0;
FSphereCoveringCountSpheresNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&SphereCovering);
RegisterOutputConnection(&NumSpheres);
}
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override
{
if (Out->IsA(&NumSpheres))
{
const FDataflowSphereCovering& InSphereCovering = GetValue(Context, &SphereCovering);
SetValue(Context, InSphereCovering.Spheres.Num(), &NumSpheres);
}
}
};
// Convert a mesh to a string formatted as an OBJ file, which can be read by many external mesh viewers
USTRUCT(meta = (DataflowGeometryCollection))
struct FMeshToOBJStringDebugDataflowNode: public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FMeshToOBJStringDebugDataflowNode, "Convert Mesh to OBJ String", "GeometryCollection|Development", "")
public:
UPROPERTY(meta = (DataflowInput))
TObjectPtr<UDynamicMesh> Mesh;
// Whether to flip the orientation of the triangles in the OBJ output
UPROPERTY(EditAnywhere, Category = Options, meta = (DataflowInput))
bool bInvertFaces = false;
// A string representing the input mesh in the OBJ file format
UPROPERTY(meta = (DataflowOutput))
FString StringOBJ;
FMeshToOBJStringDebugDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&Mesh);
RegisterInputConnection(&bInvertFaces);
RegisterOutputConnection(&StringOBJ);
}
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};
// Write a string to a file
USTRUCT(meta = (DataflowGeometryCollection))
struct FWriteStringToFile : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
DATAFLOW_NODE_DEFINE_INTERNAL(FWriteStringToFile, "Write String to File", "GeometryCollection|Development", "")
public:
// Where file should be written on disk
UPROPERTY(EditAnywhere, Category = Options, meta = (DataflowInput))
FString FilePath;
// Contents of the file to write
UPROPERTY(EditAnywhere, Category = Options, meta = (DataflowInput))
FString FileContents;
FWriteStringToFile(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&FileContents);
RegisterInputConnection(&FilePath);
}
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
};
namespace UE::Dataflow
{
void GeometryCollectionDebugNodes();
}