2020-08-11 01:36:57 -04:00
|
|
|
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
|
|
|
|
|
|
#include "Operations/RemoveOccludedTriangles.h"
|
|
|
|
|
|
2021-06-13 00:36:02 -04:00
|
|
|
#include "DynamicMesh/DynamicMeshAABBTree3.h"
|
2020-08-11 01:36:57 -04:00
|
|
|
|
|
|
|
|
#include "Selections/MeshConnectedComponents.h"
|
|
|
|
|
|
2021-03-09 19:33:56 -04:00
|
|
|
using namespace UE::Geometry;
|
|
|
|
|
|
2020-08-11 01:36:57 -04:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
GeometryProcessing: clean up mesh timestamps.
- remove FDynamicMesh3::Timestamp (unused), rename Shape/Topology Timestamps to Shape/TopologyChangeStamp, change to atomic<uint32>
- add FDynamicMesh3::bEnableShapeChangeStamp, default to false, to disable ShapeChange tracking. Add ::SetShapeChangeStampEnabled() and ::HasShapeChangeStampEnabled() to configure.
- replace FDynamicMesh3::UpdateTimestamps() with UpdateChangeStamps()
- add bTrackChange param to FDynamicMesh3::SetVertex(), optionally updates ShapeChangeStamp (if enabled). Default true. Remove SetVertex_NoTimeStampUpdate(), update call sites.
- add FDynamicMesh3::GetChangeStamp(), returns combination of Shape and Topology stamps as uint64
- rename TTriangleMeshAdapter::GetTimestamp() to GetChangeStamp(), update usages
- remove TPointSetAdapter::Timestamp() (was not used in code)
- update TMeshAABBTree3 to use GetChangeStamp(), update internal checks to call IsValid() instead
- update TFastWindingTree w/ similar changes
- update calls in UVEditor, may require further updates
#rb semion.piskarev
#rnx
#jira none
#preflight 6126904c72e9eb00011434fe
#ROBOMERGE-SOURCE: CL 17310271 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v861-17282326)
[CL 17315112 by ryan schmidt in ue5-release-engine-test branch]
2021-08-26 06:57:55 -04:00
|
|
|
FORCEINLINE uint64 GetChangeStamp() const
|
2020-08-11 01:36:57 -04:00
|
|
|
{
|
GeometryProcessing: clean up mesh timestamps.
- remove FDynamicMesh3::Timestamp (unused), rename Shape/Topology Timestamps to Shape/TopologyChangeStamp, change to atomic<uint32>
- add FDynamicMesh3::bEnableShapeChangeStamp, default to false, to disable ShapeChange tracking. Add ::SetShapeChangeStampEnabled() and ::HasShapeChangeStampEnabled() to configure.
- replace FDynamicMesh3::UpdateTimestamps() with UpdateChangeStamps()
- add bTrackChange param to FDynamicMesh3::SetVertex(), optionally updates ShapeChangeStamp (if enabled). Default true. Remove SetVertex_NoTimeStampUpdate(), update call sites.
- add FDynamicMesh3::GetChangeStamp(), returns combination of Shape and Topology stamps as uint64
- rename TTriangleMeshAdapter::GetTimestamp() to GetChangeStamp(), update usages
- remove TPointSetAdapter::Timestamp() (was not used in code)
- update TMeshAABBTree3 to use GetChangeStamp(), update internal checks to call IsValid() instead
- update TFastWindingTree w/ similar changes
- update calls in UVEditor, may require further updates
#rb semion.piskarev
#rnx
#jira none
#preflight 6126904c72e9eb00011434fe
#ROBOMERGE-SOURCE: CL 17310271 in //UE5/Main/...
#ROBOMERGE-BOT: STARSHIP (Main -> Release-Engine-Test) (v861-17282326)
[CL 17315112 by ryan schmidt in ue5-release-engine-test branch]
2021-08-26 06:57:55 -04:00
|
|
|
return 1;
|
2020-08-11 01:36:57 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FORCEINLINE FIndex3i GetTriangle(int32 Index) const
|
|
|
|
|
{
|
|
|
|
|
return Mesh->GetTriangle(Component->Indices[Index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FORCEINLINE FVector3d GetVertex(int32 Index) const
|
|
|
|
|
{
|
|
|
|
|
return Mesh->GetVertex(Index);
|
|
|
|
|
}
|
|
|
|
|
|
2021-05-05 15:07:25 -04:00
|
|
|
FORCEINLINE void GetTriVertices(int32 TriIndex, UE::Math::TVector<double>& V0, UE::Math::TVector<double>& V1, UE::Math::TVector<double>& V2) const
|
2020-08-11 01:36:57 -04:00
|
|
|
{
|
|
|
|
|
Mesh->GetTriVertices(Component->Indices[TriIndex], V0, V1, V2);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
bool DYNAMICMESH_API RemoveInternalTriangles(FDynamicMesh3& Mesh, bool bTestPerCompoment,
|
|
|
|
|
EOcclusionTriangleSampling SamplingMethod,
|
|
|
|
|
EOcclusionCalculationMode OcclusionMode,
|
2021-03-01 17:01:16 -04:00
|
|
|
int RandomSamplesPerTri, double WindingNumberThreshold, bool bTestOccludedByAny)
|
2020-08-11 01:36:57 -04:00
|
|
|
{
|
|
|
|
|
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]));
|
|
|
|
|
}
|
|
|
|
|
FTransform3d Id = FTransform3d::Identity();
|
|
|
|
|
TArrayView<FTransform3d> TransformsView(&Id, 1);
|
|
|
|
|
TArrayView<TMeshAABBTree3<FComponentMesh>*> SpatialsView(Spatials.GetData(), Spatials.Num());
|
|
|
|
|
TArrayView<TFastWindingTree<FComponentMesh>*> WindingsView(Windings.GetData(), Windings.Num());
|
2021-03-01 17:01:16 -04:00
|
|
|
return Remover.Apply(TransformsView, SpatialsView, WindingsView, TArrayView<const FTransform3d>(), bTestOccludedByAny);
|
2020-08-11 01:36:57 -04:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
TRemoveOccludedTriangles<FDynamicMesh3> Remover(&Mesh);
|
|
|
|
|
Remover.InsideMode = OcclusionMode;
|
|
|
|
|
Remover.TriangleSamplingMethod = SamplingMethod;
|
|
|
|
|
Remover.AddTriangleSamples = RandomSamplesPerTri;
|
|
|
|
|
FDynamicMeshAABBTree3 Spatial(&Mesh, true);
|
|
|
|
|
return Remover.Apply(FTransform3d::Identity(), &Spatial);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|