44template <
class TriangleMeshType,
bool bScalarCellSize = true>
50 using CellSizeType = std::conditional_t<bScalarCellSize, float, FVector3f>;
52 using CellSizeTyped = std::conditional_t<bScalarCellSize, double, FVector3d>;
162 template<
typename InterpolantRealType =
double>
241 for (
int32 Idx = 0; Idx < 3; ++Idx)
272 if (
NI < 0 ||
NJ < 0 ||
NK < 0)
328 float At(
int I,
int J,
int K)
const
361 float cell_tri_dist(
const FVector3i& Idx,
int TID)
const
372 Distances.Resize(
NI,
NJ,
NK);
373 Distances.Assign(upper_bound(Distances));
418 for (
int K = k0; K <= k1; ++K) {
419 for (
int J =
j0; J <=
j1; ++J) {
420 for (
int I =
i0; I <=
i1; ++I) {
423 if (d < Distances.At(I, J, K)) {
424 Distances.At(I, J, K) = d;
491 Distances.Resize(
NI,
NJ,
NK);
492 Distances.Assign(upper_bound(
Grid));
517 ParallelFor(
Mesh->MaxTriangleID(), [
this, &Origin, DX,
NI,
NJ,
NK, &Distances,
ExactBand, &
closest_tri, &
intersection_count,
ox,
oy,
oz,
invdx,
wi,
wj,
wk, &
GridSections, &bAbort](
int TID)
519 if (!Mesh->IsTriangle(TID))
550 for (
int K = k0; K <= k1; ++K) {
551 for (
int J =
j0; J <=
j1; ++J) {
554 for (
int I =
i0; I <=
i1; ++I) {
557 if (d < Distances.At(I, J, K)) {
561 if (d < Distances.At(I, J, K)) {
562 Distances.At(I, J, K) = d;
623 Distances.Resize(
NI,
NJ,
NK);
624 float upper_bound = this->upper_bound(Distances);
625 Distances.Assign(upper_bound);
630 ClosestTriGrid.
Assign(-1);
635 IntersectionsGrid.
Assign(0);
638 CellSizeTyped
invdx = CellSizeTyped(UnitCellSize()) / (CellSizeTyped)DX;
650 ParallelFor(
Mesh->MaxTriangleID(), [
this, &Origin, DX,
NI,
NJ,
NK, &Distances,
ExactBand, upper_bound, &
closest_tri, &
intersection_count,
ox,
oy,
oz,
invdx, &bAbort](
int TID)
652 if (!Mesh->IsTriangle(TID))
683 for (
int K = k0; K <= k1; ++K) {
684 for (
int J =
j0; J <=
j1; ++J) {
685 for (
int I =
i0; I <=
i1; ++I) {
686 Distances.At(I, J, K) = 1;
693 ParallelFor(
Grid.Size(), [
this, &Origin, DX,
NI,
NJ,
NK, &Distances,
max_dist, upper_bound, &
closest_tri](
int LinearIdx)
695 FVector3i Idx = Grid.ToIndex(LinearIdx);
696 if (Distances[Idx] == 1) {
697 int I = Idx.X, J = Idx.Y, K = Idx.Z;
698 FVector3d p((float)I * GetDim(DX, 0) + Origin[0], (float)J * GetDim(DX, 1) + Origin[1], (float)K * GetDim(DX, 2) + Origin[2]);
700 int near_tid = Spatial->FindNearestTriangle(p, dsqr, max_dist);
701 if (near_tid == IndexConstants::InvalidID) {
702 Distances[Idx] = upper_bound;
705 Distances[Idx] = (float)FMath::Sqrt(dsqr);
706 closest_tri[Idx] = near_tid;
717 if (bComputeSigns ==
true)
725 if (ComputeMode == EComputeModes::FullGrid) {
744 if (!bWantIntersectionsGrid)
751 if (!bWantClosestTriGrid)
772 void make_level_set3_parallel_floodfill(
FVector3f Origin, CellSizeType DX,
int NI,
int NJ,
int NK, FDenseGrid3f& Distances)
774 Distances.Resize(
NI,
NJ,
NK);
775 float upper_bound = this->upper_bound(Distances);
776 Distances.Assign(upper_bound);
781 ClosestTriGrid.
Assign(-1);
786 IntersectionsGrid.
Assign(0);
789 CellSizeTyped
invdx = CellSizeTyped(UnitCellSize()) / (CellSizeTyped)DX;
795 int32 NumSections = 256;
846 if (!Mesh->IsVertex(vid))
869 if (Distances[Idx] < upper_bound)
895 FAxisAlignedBox3i Bounds = Distances.BoundsInclusive();
896 double max_dist = NarrowBandMaxDistance;
904 int cur_linear_index = PendingCellQueue[QIdx];
905 FVector3i cur_idx = Distances.ToIndex(cur_linear_index);
906 for (FVector3i idx_offset : IndexUtil::GridOffsets26)
908 FVector3i nbr_idx = cur_idx + idx_offset;
909 if (Bounds.Contains(nbr_idx) == false)
913 int nbr_linear_idx = Distances.ToLinear(nbr_idx);
922 if (done[nbr_linear_idx])
927 FVector3d p = (FVector3d)cell_center(nbr_idx);
929 int near_tid = Spatial->FindNearestTriangle(p, dsqr, max_query_dist);
932 FScopeLock GridLock(GetGridSectionLock(nbr_idx));
933 done[nbr_linear_idx] = true;
936 double dist = FMathd::Sqrt(dsqr);
940 FScopeLock GridLock(GetGridSectionLock(nbr_idx));
941 if (done[nbr_linear_idx] == false)
943 Distances[nbr_linear_idx] = (float)dist;
944 closest_tri[nbr_linear_idx] = near_tid;
945 done[nbr_linear_idx] = true;
948 AddToSectionQueue(nbr_linear_idx);
964 if (bComputeSigns ==
true)
973 if (ComputeMode == EComputeModes::FullGrid)
1002 void CleanupUnwanted()
1004 if (!bWantIntersectionsGrid)
1008 if (!bWantClosestTriGrid)
1018 void sweep_pass(
FVector3f Origin, CellSizeType DX, FDenseGrid3f& Distances, FDenseGrid3i&
closest_tri)
1020 sweep(Distances,
closest_tri, Origin, DX, +1, +1, +1);
1021 if (CancelF())
return;
1022 sweep(Distances,
closest_tri, Origin, DX, -1, -1, -1);
1023 if (CancelF())
return;
1024 sweep(Distances,
closest_tri, Origin, DX, +1, +1, -1);
1025 if (CancelF())
return;
1026 sweep(Distances,
closest_tri, Origin, DX, -1, -1, +1);
1027 if (CancelF())
return;
1028 sweep(Distances,
closest_tri, Origin, DX, +1, -1, +1);
1029 if (CancelF())
return;
1030 sweep(Distances,
closest_tri, Origin, DX, -1, +1, -1);
1031 if (CancelF())
return;
1032 sweep(Distances,
closest_tri, Origin, DX, +1, -1, -1);
1033 if (CancelF())
return;
1034 sweep(Distances,
closest_tri, Origin, DX, -1, +1, +1);
1039 void sweep(FDenseGrid3f&
phi, FDenseGrid3i&
closest_tri,
FVector3f Origin, CellSizeType DX,
int di,
int dj,
int dk)
1042 if (di > 0) {
i0 = 1;
i1 =
phi.GetDimensions().X; }
1043 else {
i0 =
phi.GetDimensions().X - 2;
i1 = -1; }
1045 if (dj > 0) {
j0 = 1;
j1 =
phi.GetDimensions().Y; }
1046 else {
j0 =
phi.GetDimensions().Y - 2;
j1 = -1; }
1048 if (dk > 0) { k0 = 1; k1 =
phi.GetDimensions().Z; }
1049 else { k0 =
phi.GetDimensions().Z - 2; k1 = -1; }
1050 for (
int K = k0; K != k1; K += dk)
1056 for (
int J =
j0; J !=
j1; J += dj)
1058 for (
int I =
i0; I !=
i1; I += di)
1060 FVector3d gx(
float(I) * GetDim(DX, 0) + Origin[0],
float(J) * GetDim(DX, 1) + Origin[1],
float(K) * GetDim(DX, 2) + Origin[2]);
1096 CellSizeTyped
invdx = CellSizeTyped(UnitCellSize()) / (CellSizeTyped)DX;
1103 [
this, &Origin, &
NI, &
NJ, &
NK,
1106 if (!Mesh->IsTriangle(TID))
1110 if (
TID % 100 == 0 && CancelF() ==
true)
1124 if (InsideMode == EInsideModes::WindingCount)
1142 for (
int K = k0; K <= k1; ++K)
1144 for (
int J =
j0; J <=
j1; ++J)
1147 if (
PointInTriangle2d(J, K,
fjp,
fkp,
fjq,
fkq,
fjr,
fkr,
A,
B,
C))
1188 int32 total_count = 0;
1189 for (
int I = 0; I <
NI; ++I) {
1192 (InsideMode == EInsideModes::WindingCount && total_count > 0) ||
1193 (InsideMode == EInsideModes::CrossingCount && total_count % 2 == 1)
1196 Distances.At(I, J, K) = -Distances.At(I, J, K);
1204 for (
int K = 0; K <
NK; ++K)
1211 for (
int J = 0; J <
NJ; ++J)
1213 int total_count = 0;
1214 for (
int I = 0; I <
NI; ++I)
1218 (InsideMode == EInsideModes::WindingCount && total_count > 0) ||
1219 (InsideMode == EInsideModes::CrossingCount && total_count % 2 == 1)
1222 Distances.At(I, J, K) = -Distances.At(I, J, K);
1250 else if (Y2 > Y1)
return 1;
1251 else if (Y2 < Y1)
return -1;
1252 else if (X1 > X2)
return 1;
1253 else if (X1 < X2)
return -1;
1260 static bool PointInTriangle2d(
double X0,
double Y0,
double X1,
double Y1,
double X2,
double Y2,
double X3,
double Y3,
double&
A,
double&
B,
double&
C)
1266 if (
signa == 0)
return false;
1274 checkf(
sum != 0,
TEXT(
"TCachingMeshSDF::PointInTriangle2d: impossible config?"));
1331 float invdet = 1.0f / FMath::Max(
m13 *
m23 - d * d, 1e-30f);
1367 double invdet = 1.0 / FMath::Max(
m13 *
m23 - d * d, 1e-30);
1399 return (
double)CellSize;
1403 return (
double)CellSize[
Axis];
1410 return (
float)CellSize;
1414 return (
float)CellSize[
Axis];
1421 return CellSize * FMathf::Sqrt3;
1425 return CellSize.Length();
1430 if constexpr (std::is_floating_point_v<CellSizeType>)
1432 return CellSize > 0 && FMath::IsFinite(CellSize);
1436 return CellMinDim(CellSize) > 0 && FMath::IsFinite(CellSize[0]) && FMath::IsFinite(CellSize[1]) && FMath::IsFinite(CellSize[2]);
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define ensureMsgf( InExpression, InFormat,...)
Definition AssertionMacros.h:465
#define ensure( InExpression)
Definition AssertionMacros.h:464
#define checkf(expr, format,...)
Definition AssertionMacros.h:315
void ParallelFor(int32 Num, TFunctionRef< void(int32)> Body, bool bForceSingleThread, bool bPumpRenderingThread=false)
Definition ParallelFor.h:481
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
Definition CpuProfilerTrace.h:528
UE::FPlatformRecursiveMutex FCriticalSection
Definition CriticalSection.h:53
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
UE::Math::TVector< double > FVector3d
Definition MathFwd.h:60
const bool
Definition NetworkReplayStreaming.h:178
#define MAX_int32
Definition NumericLimits.h:25
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
if(Failed) console_printf("Failed.\n")
Definition ScopeLock.h:141
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
Definition AndroidPlatformMisc.h:14
static RealType Sqrt(const RealType Value)
Definition MathUtil.h:342
ElemType GetValue(int32 X, int32 Y, int32 Z) const
Definition DenseGrid3.h:136
const FVector3i & GetDimensions() const
Definition DenseGrid3.h:56
void Assign(ElemType Value)
Definition DenseGrid3.h:73
void Resize(int DimX, int DimY, int DimZ, EAllowShrinking AllowShrinking=EAllowShrinking::Default)
Definition DenseGrid3.h:61
Definition MeshAABBTree3.h:61
Definition SweepingMeshSDF.h:46
EComputeModes ComputeMode
Definition SweepingMeshSDF.h:92
FVector3i Dimensions() const
Definition SweepingMeshSDF.h:311
static int Orientation(double X1, double Y1, double X2, double Y2, double &TwiceSignedArea)
Definition SweepingMeshSDF.h:1245
FDenseGrid3i IntersectionsGrid
Definition SweepingMeshSDF.h:138
const FDenseGrid3i & GetIntersectionsGrid() const
Definition SweepingMeshSDF.h:322
bool Compute(FAxisAlignedBox3d Bounds)
Definition SweepingMeshSDF.h:207
static bool PointInTriangle2d(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3, double &A, double &B, double &C)
Definition SweepingMeshSDF.h:1260
std::conditional_t< bScalarCellSize, double, FVector3d > CellSizeTyped
Definition SweepingMeshSDF.h:52
TMeshAABBTree3< TriangleMeshType > * Spatial
Definition SweepingMeshSDF.h:59
FDenseGrid3f Grid
Definition SweepingMeshSDF.h:132
static float PointSegmentDistance(const FVector3f &x0, const FVector3f &x1, const FVector3f &x2)
Definition SweepingMeshSDF.h:1283
bool bComputeSigns
Definition SweepingMeshSDF.h:101
bool Validate(const FAxisAlignedBox3d &Bounds)
Definition SweepingMeshSDF.h:185
static float PointTriangleDistance(const FVector3f &x0, const FVector3f &x1, const FVector3f &x2, const FVector3f &x3)
Definition SweepingMeshSDF.h:1324
static double GetDim(CellSizeTyped CellSize, int32 Axis)
Definition SweepingMeshSDF.h:1395
TSweepingMeshSDF(const TriangleMeshType *Mesh=nullptr, CellSizeType InCellSize=UnitCellSize(), TMeshAABBTree3< TriangleMeshType > *Spatial=nullptr)
Definition SweepingMeshSDF.h:147
static CellSizeType UnitCellSize()
Definition SweepingMeshSDF.h:54
static double PointSegmentDistance(const FVector3d &x0, const FVector3d &x1, const FVector3d &x2)
Definition SweepingMeshSDF.h:1303
float operator[](const FVector3i &Idx) const
Definition SweepingMeshSDF.h:333
float GetValue(FVector3i Idx) const
Definition SweepingMeshSDF.h:343
static float GetDiagLength(CellSizeType CellSize)
Definition SweepingMeshSDF.h:1417
void Empty()
Definition SweepingMeshSDF.h:154
void SetCellSize(float InCellSize)
Definition SweepingMeshSDF.h:62
bool bWantClosestTriGrid
Definition SweepingMeshSDF.h:118
int ApproxMaxCellsPerDimension
Definition SweepingMeshSDF.h:79
static float GetDim(CellSizeType CellSize, int32 Axis)
Definition SweepingMeshSDF.h:1406
TTriLinearGridInterpolant< FDenseGrid3f, InterpolantRealType, bScalarCellSize > MakeInterpolant()
Definition SweepingMeshSDF.h:163
CellSizeType CellSize
Definition SweepingMeshSDF.h:60
FDenseGrid3i ClosestTriGrid
Definition SweepingMeshSDF.h:136
TFunction< bool()> CancelF
Definition SweepingMeshSDF.h:124
const FDenseGrid3i & GetClosestTriGrid() const
Definition SweepingMeshSDF.h:317
EInsideModes InsideMode
Definition SweepingMeshSDF.h:114
bool bWantIntersectionsGrid
Definition SweepingMeshSDF.h:121
double NarrowBandMaxDistance
Definition SweepingMeshSDF.h:98
static double PointTriangleDistance(const FVector3d &x0, const FVector3d &x1, const FVector3d &x2, const FVector3d &x3)
Definition SweepingMeshSDF.h:1360
EComputeModes
Definition SweepingMeshSDF.h:87
@ NarrowBand_SpatialFloodFill
Definition SweepingMeshSDF.h:90
@ NarrowBandOnly
Definition SweepingMeshSDF.h:89
@ FullGrid
Definition SweepingMeshSDF.h:88
float At(int I, int J, int K) const
Definition SweepingMeshSDF.h:328
FVector3f CellCenter(int I, int J, int K) const
Definition SweepingMeshSDF.h:338
bool bUseParallel
Definition SweepingMeshSDF.h:76
static bool ShouldUseSpatial(int ExactCells, double CellSize, double AvgEdgeLen)
Definition SweepingMeshSDF.h:178
static bool IsValid(CellSizeType CellSize)
Definition SweepingMeshSDF.h:1428
bool Compute(FVector3f InGridOrigin, FVector3i InDimensions)
Definition SweepingMeshSDF.h:264
FVector3f GridOrigin
Definition SweepingMeshSDF.h:131
EInsideModes
Definition SweepingMeshSDF.h:110
@ CrossingCount
Definition SweepingMeshSDF.h:111
@ WindingCount
Definition SweepingMeshSDF.h:112
const TriangleMeshType * Mesh
Definition SweepingMeshSDF.h:58
FVector3d ExpandBounds
Definition SweepingMeshSDF.h:73
int ExactBandWidth
Definition SweepingMeshSDF.h:69
std::conditional_t< bScalarCellSize, float, FVector3f > CellSizeType
Definition SweepingMeshSDF.h:50
Definition GridInterpolant.h:29
int Max3Index(const ValueVecType &Vector3)
Definition VectorUtil.h:194
GEOMETRYCORE_API bool PointInTriangle2d(double X0, double Y0, double X1, double Y1, double X2, double Y2, double X3, double Y3, double &A, double &B, double &C)
Definition SDFCalculationUtils.cpp:84
TDenseGrid3< int > FDenseGrid3i
Definition DenseGrid3.h:235
TDenseGrid3< float > FDenseGrid3f
Definition DenseGrid3.h:233
GEOMETRYCORE_API double PointTriangleDistance(const FVector3d &x0, const FVector3d &x1, const FVector3d &x2, const FVector3d &x3)
Definition SDFCalculationUtils.cpp:9
RealType PointSegmentDistance(const TVector< RealType > &x0, const TVector< RealType > &x1, const TVector< RealType > &x2)
Definition SDFCalculationUtils.h:28
Definition AdvancedWidgetsModule.cpp:13
float v
Definition radaudio_mdct.cpp:62
static constexpr UE_FORCEINLINE_HINT T Clamp(const T X, const T MinValue, const T MaxValue)
Definition UnrealMathUtility.h:592
static constexpr UE_FORCEINLINE_HINT T Min3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:558
static constexpr UE_FORCEINLINE_HINT T Max3(const T A, const T B, const T C)
Definition UnrealMathUtility.h:551
Definition IntVectorTypes.h:252
TVector< RealType > Max
Definition BoxTypes.h:249
bool IsEmpty() const
Definition BoxTypes.h:613
TVector< RealType > Diagonal() const
Definition BoxTypes.h:608
RealType MaxDim() const
Definition BoxTypes.h:598
TVector< RealType > Min
Definition BoxTypes.h:248
static TVector< float > One()
Definition Vector.h:115
T Z
Definition Vector.h:68
static TVector< double > Zero()
Definition Vector.h:112
T Y
Definition Vector.h:65
T X
Definition Vector.h:62
T SquaredLength() const
Definition Vector.h:1734
UE_FORCEINLINE_HINT T Dot(const TVector< T > &V) const
Definition Vector.h:1553