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

126 lines
5.1 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#pragma once
#include "CoreMinimal.h"
#include "Dataflow/DataflowEngine.h"
#include "GeometryCollection/ManagedArrayCollection.h"
#include "Dataflow/ChaosFleshNodesUtility.h"
#include "ChaosFleshCreateTetrahedronNode.generated.h"
class FFleshCollection;
namespace UE {
namespace Geometry {
class FDynamicMesh3;
}
}
// Note: disabled deprecation warnings due to deprecated member: IdealEdgeLength. Can remove these disable/enable pragmas once that member variable is removed.
PRAGMA_DISABLE_DEPRECATION_WARNINGS
USTRUCT(meta = (DataflowFlesh))
struct FCreateTetrahedronDataflowNode : public FDataflowNode
{
GENERATED_USTRUCT_BODY()
PRAGMA_ENABLE_DEPRECATION_WARNINGS
DATAFLOW_NODE_DEFINE_INTERNAL(FCreateTetrahedronDataflowNode, "CreateTetrahedron", "Flesh", "")
DATAFLOW_NODE_RENDER_TYPE("SurfaceRender", FGeometryCollection::StaticType(), "Collection")
public:
typedef FManagedArrayCollection DataType;
// Tetrahedral meshing method (TetWild or ISO-stuffing)
UPROPERTY(EditAnywhere, Category = "Dataflow")
TEnumAsByte<TetMeshingMethod> Method = TetMeshingMethod::IsoStuffing;
// Name of the mesh in the collection. This is defined from the name of the mesh's
// parent transform. CollectionKey("BoneName","Vertices")
UPROPERTY(EditAnywhere, Category = "Dataflow")
TArray<FString> Selection;
//
// IsoStuffing
//
// General control for density for the tetrahedron.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "1", EditCondition = "Method == TetMeshingMethod::IsoStuffing", EditConditionHides))
int32 NumCells = 32;
// Surface offset percentage to increase or decrease the surface alignment.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "-0.5", ClampMax = "0.5", EditCondition = "Method == TetMeshingMethod::IsoStuffing", EditConditionHides))
double OffsetPercent = 0.05;
//
// TetWild
//
//! Desired relative edge length, as a fraction of bounding box size
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "0.0", EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
double IdealEdgeLengthRel = 0.05;
UE_DEPRECATED(5.6, "Use IdealEdgeLengthRel instead, which is relative to the bounding box size")
double IdealEdgeLength = 0.05;
//! Maximum number of optimization iterations.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "1", EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
int32 MaxIterations = 80;
//! Energy at which to stop optimizing tet quality and accept the result.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "0.0", EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
double StopEnergy = 10;
//! Relative tolerance, controlling how closely the mesh must follow the input surface.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (ClampMin = "0.0", EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
double EpsRel = 1e-3;
//! Coarsen the tet mesh result.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
bool bCoarsen = false;
//! Enforce that the output boundary surface should be manifold.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
bool bExtractManifoldBoundarySurface = false;
//! Skip the initial simplification step.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
bool bSkipSimplification = false;
//! Invert tetrahedra.
UPROPERTY(EditAnywhere, Category = "Dataflow", meta = (EditCondition = "Method == TetMeshingMethod::TetWild", EditConditionHides))
bool bInvertOutputTets = false;
//
// Common
//
UPROPERTY(EditAnywhere, Category = "Dataflow")
bool bDiscardInteriorTriangles = true;
// Input pass-through collection. When connected, the generated tetrahedron will be nested into
// its associated parents transform.
UPROPERTY(meta = (DataflowInput, DataflowOutput, DisplayName = "Collection"))
FManagedArrayCollection Collection;
// Source collection used to generate the tetrahedron from. Closed geometry within the collections geometry group will be used to
// generate tetrahedron.
UPROPERTY(meta = (DataflowInput, DisplayName = "SourceCollection"))
FManagedArrayCollection SourceCollection;
FCreateTetrahedronDataflowNode(const UE::Dataflow::FNodeParameters& InParam, FGuid InGuid = FGuid::NewGuid())
: FDataflowNode(InParam, InGuid)
{
RegisterInputConnection(&Collection);
RegisterOutputConnection(&Collection);
RegisterInputConnection(&SourceCollection);
}
virtual void Evaluate(UE::Dataflow::FContext& Context, const FDataflowOutput* Out) const override;
protected:
void EvaluateIsoStuffing(UE::Dataflow::FContext& Context, FFleshCollection& InCollection, const UE::Geometry::FDynamicMesh3& DynamicMesh) const;
void EvaluateTetWild(UE::Dataflow::FContext& Context, FFleshCollection& InCollection, const UE::Geometry::FDynamicMesh3& DynamicMesh) const;
};