UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize > Class Template Reference

#include <SweepingMeshSDF.h>

Public Types

enum  EComputeModes { FullGrid = 0 , NarrowBandOnly = 1 , NarrowBand_SpatialFloodFill = 2 }
 
enum  EInsideModes { CrossingCount = 0 , WindingCount = 1 }
 
using CellSizeType = std::conditional_t< bScalarCellSize, float, FVector3f >
 
using CellSizeTyped = std::conditional_t< bScalarCellSize, double, FVector3d >
 

Public Member Functions

void SetCellSize (float InCellSize)
 
 TSweepingMeshSDF (const TriangleMeshType *Mesh=nullptr, CellSizeType InCellSize=UnitCellSize(), TMeshAABBTree3< TriangleMeshType > *Spatial=nullptr)
 
void Empty ()
 
template<typename InterpolantRealType = double>
TTriLinearGridInterpolant< FDenseGrid3f, InterpolantRealType, bScalarCellSizeMakeInterpolant ()
 
bool Validate (const FAxisAlignedBox3d &Bounds)
 
bool Compute (FAxisAlignedBox3d Bounds)
 
bool Compute (FVector3f InGridOrigin, FVector3i InDimensions)
 
FVector3i Dimensions () const
 
const FDenseGrid3iGetClosestTriGrid () const
 
const FDenseGrid3iGetIntersectionsGrid () const
 
float At (int I, int J, int K) const
 
float operator[] (const FVector3i &Idx) const
 
FVector3f CellCenter (int I, int J, int K) const
 
float GetValue (FVector3i Idx) const
 

Static Public Member Functions

static CellSizeType UnitCellSize ()
 
static bool ShouldUseSpatial (int ExactCells, double CellSize, double AvgEdgeLen)
 
static int Orientation (double X1, double Y1, double X2, double Y2, double &TwiceSignedArea)
 
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)
 
static float PointSegmentDistance (const FVector3f &x0, const FVector3f &x1, const FVector3f &x2)
 
static double PointSegmentDistance (const FVector3d &x0, const FVector3d &x1, const FVector3d &x2)
 
static float PointTriangleDistance (const FVector3f &x0, const FVector3f &x1, const FVector3f &x2, const FVector3f &x3)
 
static double PointTriangleDistance (const FVector3d &x0, const FVector3d &x1, const FVector3d &x2, const FVector3d &x3)
 
static double GetDim (CellSizeTyped CellSize, int32 Axis)
 
static float GetDim (CellSizeType CellSize, int32 Axis)
 
static float GetDiagLength (CellSizeType CellSize)
 
static bool IsValid (CellSizeType CellSize)
 

Public Attributes

const TriangleMeshTypeMesh
 
TMeshAABBTree3< TriangleMeshType > * Spatial
 
CellSizeType CellSize
 
int ExactBandWidth = 1
 
FVector3d ExpandBounds = FVector3d::Zero()
 
bool bUseParallel = true
 
int ApproxMaxCellsPerDimension = 4096
 
EComputeModes ComputeMode = EComputeModes::NarrowBandOnly
 
double NarrowBandMaxDistance = 0
 
bool bComputeSigns = true
 
EInsideModes InsideMode = EInsideModes::WindingCount
 
bool bWantClosestTriGrid = false
 
bool bWantIntersectionsGrid = false
 
TFunction< bool()> CancelF
 
FVector3f GridOrigin
 
FDenseGrid3f Grid
 

Protected Attributes

FDenseGrid3i ClosestTriGrid
 
FDenseGrid3i IntersectionsGrid
 

Detailed Description

template<class TriangleMeshType, bool bScalarCellSize = true>
class UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >

Compute discretely-sampled (ie gridded) signed distance field for a mesh The basic approach is, first compute exact Distances in a narrow band, and then extend out to rest of Grid using fast "sweeping" (ie like a distance transform). The resulting unsigned Grid is then signed using ray-intersection counting, which is also computed on the Grid, so no BVH is necessary

If you set ComputeMode to NarrowBandOnly, result is a narrow-band signed distance field. This is quite a bit faster as the sweeping is the most computationally-intensive step.

You can optionally provide a spatial data structure to allow faster computation of narrow-band Distances; this is most beneficial if we want a wider band

Caveats:

  • the "narrow band" is based on triangle bounding boxes, so it is not necessarily that "narrow" if you have large triangles on a diagonal to Grid axes

TODO: a number of utility function could & should be shared between this and CachingMeshSDF!

This code is based on the implementation found at https://github.com/christopherbatty/SDFGen

Member Typedef Documentation

◆ CellSizeType

template<class TriangleMeshType , bool bScalarCellSize = true>
using UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::CellSizeType = std::conditional_t<bScalarCellSize, float, FVector3f>

◆ CellSizeTyped

template<class TriangleMeshType , bool bScalarCellSize = true>
using UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::CellSizeTyped = std::conditional_t<bScalarCellSize, double, FVector3d>

Member Enumeration Documentation

◆ EComputeModes

template<class TriangleMeshType , bool bScalarCellSize = true>
enum UE::Geometry::TSweepingMeshSDF::EComputeModes
Enumerator
FullGrid 
NarrowBandOnly 
NarrowBand_SpatialFloodFill 

◆ EInsideModes

template<class TriangleMeshType , bool bScalarCellSize = true>
enum UE::Geometry::TSweepingMeshSDF::EInsideModes
Enumerator
CrossingCount 
WindingCount 

Constructor & Destructor Documentation

◆ TSweepingMeshSDF()

template<class TriangleMeshType , bool bScalarCellSize = true>
UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::TSweepingMeshSDF ( const TriangleMeshType Mesh = nullptr,
CellSizeType  InCellSize = UnitCellSize(),
TMeshAABBTree3< TriangleMeshType > *  Spatial = nullptr 
)
inline
Parameters
MeshTriangle mesh to build an SDF around
InCellSizeSpacing between Grid points
SpatialOptional AABB tree; note it must be provided if ComputeMode is set to NarrowBand_SpatialFloodFill

Member Function Documentation

◆ At()

template<class TriangleMeshType , bool bScalarCellSize = true>
float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::At ( int  I,
int  J,
int  K 
) const
inline

◆ CellCenter()

template<class TriangleMeshType , bool bScalarCellSize = true>
FVector3f UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::CellCenter ( int  I,
int  J,
int  K 
) const
inline

◆ Compute() [1/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Compute ( FAxisAlignedBox3d  Bounds)
inline

Compute the SDF enclosing the given bounds, with a 'safe' buffer zone

Parameters
BoundsBounding box for the mesh data (passed as param it is usually already available, depending on TriangleMeshType and whether an AABB tree was provided)
Returns
false if cancelled or failed (e.g. due to invalid arguments); true otherwise

◆ Compute() [2/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Compute ( FVector3f  InGridOrigin,
FVector3i  InDimensions 
)
inline

Compute the SDF with exactly specified grid origin and dimensions

Parameters
InGridOriginOrigin of the output grid
InDimensionsDimensions of the output grid
Returns
false if cancelled or failed (e.g. due to invalid arguments); true otherwise

◆ Dimensions()

template<class TriangleMeshType , bool bScalarCellSize = true>
FVector3i UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Dimensions ( ) const
inline

◆ Empty()

template<class TriangleMeshType , bool bScalarCellSize = true>
void UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Empty ( )
inline

Empty out all computed result data (leaves input data alone)

◆ GetClosestTriGrid()

template<class TriangleMeshType , bool bScalarCellSize = true>
const FDenseGrid3i & UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetClosestTriGrid ( ) const
inline

◆ GetDiagLength()

template<class TriangleMeshType , bool bScalarCellSize = true>
static float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetDiagLength ( CellSizeType  CellSize)
inlinestatic

◆ GetDim() [1/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetDim ( CellSizeType  CellSize,
int32  Axis 
)
inlinestatic

◆ GetDim() [2/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static double UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetDim ( CellSizeTyped  CellSize,
int32  Axis 
)
inlinestatic

◆ GetIntersectionsGrid()

template<class TriangleMeshType , bool bScalarCellSize = true>
const FDenseGrid3i & UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetIntersectionsGrid ( ) const
inline

◆ GetValue()

template<class TriangleMeshType , bool bScalarCellSize = true>
float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GetValue ( FVector3i  Idx) const
inline

◆ IsValid()

template<class TriangleMeshType , bool bScalarCellSize = true>
static bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::IsValid ( CellSizeType  CellSize)
inlinestatic

◆ MakeInterpolant()

◆ operator[]()

template<class TriangleMeshType , bool bScalarCellSize = true>
float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::operator[] ( const FVector3i Idx) const
inline

◆ Orientation()

template<class TriangleMeshType , bool bScalarCellSize = true>
static int UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Orientation ( double  X1,
double  Y1,
double  X2,
double  Y2,
double TwiceSignedArea 
)
inlinestatic

◆ PointInTriangle2d()

template<class TriangleMeshType , bool bScalarCellSize = true>
static bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::PointInTriangle2d ( double  X0,
double  Y0,
double  X1,
double  Y1,
double  X2,
double  Y2,
double  X3,
double  Y3,
double A,
double B,
double C 
)
inlinestatic

◆ PointSegmentDistance() [1/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static double UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::PointSegmentDistance ( const FVector3d x0,
const FVector3d x1,
const FVector3d x2 
)
inlinestatic

◆ PointSegmentDistance() [2/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::PointSegmentDistance ( const FVector3f x0,
const FVector3f x1,
const FVector3f x2 
)
inlinestatic

◆ PointTriangleDistance() [1/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static double UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::PointTriangleDistance ( const FVector3d x0,
const FVector3d x1,
const FVector3d x2,
const FVector3d x3 
)
inlinestatic

◆ PointTriangleDistance() [2/2]

template<class TriangleMeshType , bool bScalarCellSize = true>
static float UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::PointTriangleDistance ( const FVector3f x0,
const FVector3f x1,
const FVector3f x2,
const FVector3f x3 
)
inlinestatic

◆ SetCellSize()

template<class TriangleMeshType , bool bScalarCellSize = true>
void UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::SetCellSize ( float  InCellSize)
inline

◆ ShouldUseSpatial()

template<class TriangleMeshType , bool bScalarCellSize = true>
static bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::ShouldUseSpatial ( int  ExactCells,
double  CellSize,
double  AvgEdgeLen 
)
inlinestatic

Encodes heuristic for deciding whether it will be faster to use

  • NarrowBand_SpatialFloodFill
  • Or NarrowBandOnly The heuristic is to use the Spatial method unless you have relatively long edges relative to the width of the narrow band. For a 1-cell wide band, or one where few triangles interact w/ each cell in the band the spatial overhead will probably not be worthwhile. TODO: test and tune this ...

◆ UnitCellSize()

template<class TriangleMeshType , bool bScalarCellSize = true>
static CellSizeType UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::UnitCellSize ( )
inlinestatic

◆ Validate()

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Validate ( const FAxisAlignedBox3d Bounds)
inline

Member Data Documentation

◆ ApproxMaxCellsPerDimension

template<class TriangleMeshType , bool bScalarCellSize = true>
int UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::ApproxMaxCellsPerDimension = 4096

◆ bComputeSigns

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::bComputeSigns = true

◆ bUseParallel

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::bUseParallel = true

◆ bWantClosestTriGrid

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::bWantClosestTriGrid = false

◆ bWantIntersectionsGrid

template<class TriangleMeshType , bool bScalarCellSize = true>
bool UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::bWantIntersectionsGrid = false

◆ CancelF

template<class TriangleMeshType , bool bScalarCellSize = true>
TFunction<bool()> UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::CancelF
Initial value:
= []()
{
return false;
}

if this function returns true, we should abort calculation

◆ CellSize

template<class TriangleMeshType , bool bScalarCellSize = true>
CellSizeType UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::CellSize

◆ ClosestTriGrid

template<class TriangleMeshType , bool bScalarCellSize = true>
FDenseGrid3i UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::ClosestTriGrid
protected

◆ ComputeMode

◆ ExactBandWidth

template<class TriangleMeshType , bool bScalarCellSize = true>
int UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::ExactBandWidth = 1

◆ ExpandBounds

template<class TriangleMeshType , bool bScalarCellSize = true>
FVector3d UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::ExpandBounds = FVector3d::Zero()

◆ Grid

◆ GridOrigin

template<class TriangleMeshType , bool bScalarCellSize = true>
FVector3f UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::GridOrigin

◆ InsideMode

◆ IntersectionsGrid

template<class TriangleMeshType , bool bScalarCellSize = true>
FDenseGrid3i UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::IntersectionsGrid
protected

◆ Mesh

template<class TriangleMeshType , bool bScalarCellSize = true>
const TriangleMeshType* UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::Mesh

◆ NarrowBandMaxDistance

template<class TriangleMeshType , bool bScalarCellSize = true>
double UE::Geometry::TSweepingMeshSDF< TriangleMeshType, bScalarCellSize >::NarrowBandMaxDistance = 0

◆ Spatial


The documentation for this class was generated from the following file: