Files
UnrealEngine/Engine/Plugins/Runtime/GeometryProcessing/Source/DynamicMesh/Private/Operations/RemoveOccludedTriangles.cpp
2025-05-18 13:04:45 +08:00

116 lines
3.6 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
#include "Operations/RemoveOccludedTriangles.h"
#include "DynamicMesh/DynamicMeshAABBTree3.h"
#include "Selections/MeshConnectedComponents.h"
using namespace UE::Geometry;
namespace UE
{
namespace MeshAutoRepair
{
// simple adapter to directly work with mesh components rather than creating a copy per component
struct FComponentMesh
{
FDynamicMesh3* Mesh;
FMeshConnectedComponents::FComponent* Component;
FComponentMesh(FDynamicMesh3* Mesh, FMeshConnectedComponents::FComponent* Component) : Mesh(Mesh), Component(Component)
{}
int32 MaxTriangleID() const
{
return Component->Indices.Num();
}
int32 MaxVertexID() const
{
return Mesh->MaxVertexID();
}
bool IsTriangle(int32 Index) const
{
return Component->Indices.IsValidIndex(Index) && Mesh->IsTriangle(Component->Indices[Index]);
}
bool IsVertex(int32 Index) const
{
return Mesh->IsVertex(Index);
}
int32 TriangleCount() const
{
return Component->Indices.Num();
}
FORCEINLINE int32 VertexCount() const
{
return Mesh->VertexCount();
}
FORCEINLINE uint64 GetChangeStamp() const
{
return 1;
}
FORCEINLINE FIndex3i GetTriangle(int32 Index) const
{
return Mesh->GetTriangle(Component->Indices[Index]);
}
FORCEINLINE FVector3d GetVertex(int32 Index) const
{
return Mesh->GetVertex(Index);
}
FORCEINLINE void GetTriVertices(int32 TriIndex, UE::Math::TVector<double>& V0, UE::Math::TVector<double>& V1, UE::Math::TVector<double>& V2) const
{
Mesh->GetTriVertices(Component->Indices[TriIndex], V0, V1, V2);
}
};
bool DYNAMICMESH_API RemoveInternalTriangles(FDynamicMesh3& Mesh, bool bTestPerCompoment,
EOcclusionTriangleSampling SamplingMethod,
EOcclusionCalculationMode OcclusionMode,
int RandomSamplesPerTri, double WindingNumberThreshold, bool bTestOccludedByAny)
{
if (bTestPerCompoment)
{
TRemoveOccludedTriangles<FComponentMesh> Remover(&Mesh);
Remover.InsideMode = OcclusionMode;
Remover.TriangleSamplingMethod = SamplingMethod;
Remover.AddTriangleSamples = RandomSamplesPerTri;
FMeshConnectedComponents Components(&Mesh);
Components.FindConnectedTriangles();
TArray<FComponentMesh> ComponentMeshes; ComponentMeshes.Reserve(Components.Num());
TIndirectArray<TMeshAABBTree3<FComponentMesh>> Spatials; Spatials.Reserve(Components.Num());
TIndirectArray<TFastWindingTree<FComponentMesh>> Windings; Windings.Reserve(Components.Num());
for (int ComponentIdx = 0; ComponentIdx < Components.Num(); ComponentIdx++)
{
ComponentMeshes.Emplace(&Mesh, &Components.GetComponent(ComponentIdx));
Spatials.Add(new TMeshAABBTree3<FComponentMesh>(&ComponentMeshes[ComponentIdx]));
Windings.Add(new TFastWindingTree<FComponentMesh>(&Spatials[ComponentIdx]));
}
FTransformSRT3d Id = FTransformSRT3d::Identity();
TArrayView<FTransformSRT3d> TransformsView(&Id, 1);
TArrayView<TMeshAABBTree3<FComponentMesh>*> SpatialsView(Spatials.GetData(), Spatials.Num());
TArrayView<TFastWindingTree<FComponentMesh>*> WindingsView(Windings.GetData(), Windings.Num());
return Remover.Apply(TransformsView, SpatialsView, WindingsView, TArrayView<const FTransformSRT3d>(), bTestOccludedByAny);
}
else
{
TRemoveOccludedTriangles<FDynamicMesh3> Remover(&Mesh);
Remover.InsideMode = OcclusionMode;
Remover.TriangleSamplingMethod = SamplingMethod;
Remover.AddTriangleSamples = RandomSamplesPerTri;
FDynamicMeshAABBTree3 Spatial(&Mesh, true);
return Remover.Apply(FTransformSRT3d::Identity(), &Spatial);
}
}
}
}