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

#include <SparseNarrowBandMeshSDF.h>

Classes

struct  FScatterCounter
 
struct  FTriBBox
 
struct  FTriIDBlockGrid
 

Public Types

enum  EComputeModes { NarrowBandOnly = 1 , NarrowBand_SpatialFloodFill = 2 }
 
enum  EInsideModes { CrossingCount = 0 , WindingCount = 1 }
 

Public Member Functions

 TSparseNarrowBandMeshSDF (const TriangleMeshType *Mesh=nullptr, float CellSize=1.f, TMeshAABBTree3< TriangleMeshType > *Spatial=nullptr)
 
TTriLinearGridInterpolant< TSparseNarrowBandMeshSDFMakeInterpolant ()
 
bool Validate (const FAxisAlignedBox3d &Bounds)
 
bool Compute (FAxisAlignedBox3d Bounds)
 
FVector3i Dimensions () const
 
const FBlockedGrid3iGetClosestTriGrid () const
 
const FBlockedGrid3iGetIntersectionsGrid () const
 
float At (int32 I, int32 J, int32 K) const
 
float operator[] (const FVector3i &ijk) const
 
float GetValue (const FVector3i &ijk) const
 
FVector3f CellCenter (int32 I, int32 J, int32 K) const
 

Static Public Member Functions

static bool ShouldUseSpatial (int32 ExactCells, double CellSize, double AvgEdgeLen)
 

Public Attributes

const TriangleMeshTypeMesh = nullptr
 
TMeshAABBTree3< TriangleMeshType > * Spatial = nullptr
 
TUniqueFunction< bool(const FVector3d &)> IsInsideFunction
 
float 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 = true
 
TFunction< bool()> CancelF
 
FVector3f GridOrigin
 
FBlockedGrid3f Grid
 

Protected Attributes

FBlockedGrid3i ClosestTriGrid
 
FBlockedGrid3i IntersectionsGrid
 

Detailed Description

template<class TriangleMeshType>
class UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >

Compute discretely-sampled (ie gridded) signed distance field for a mesh within a specified narrow band.

The basic approach is, first compute exact Distances in a narrow band, and then The resulting unsigned Grid is then signed using ray-intersection counting, which is also computed on the Grid, so no BVH is necessary

The underlying grid data structures are blocked grids where spatial blocks are allocated as needed, so the memory footprint will generally be much lower than the TSweepingMeshSDF, or TCachingMeshSDF. But if distances in the full grid domain are desired (not just a narrow band), then the TSweepingMeshSDF should be used.

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

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

Member Enumeration Documentation

◆ EComputeModes

Enumerator
NarrowBandOnly 
NarrowBand_SpatialFloodFill 

◆ EInsideModes

Enumerator
CrossingCount 
WindingCount 

Constructor & Destructor Documentation

◆ TSparseNarrowBandMeshSDF()

template<class TriangleMeshType >
UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::TSparseNarrowBandMeshSDF ( const TriangleMeshType Mesh = nullptr,
float  CellSize = 1.f,
TMeshAABBTree3< TriangleMeshType > *  Spatial = nullptr 
)
inline
Parameters
MeshTriangle mesh to build an SDF around
CellSizeSpacing 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 >
float UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::At ( int32  I,
int32  J,
int32  K 
) const
inline
Returns
the distance value at the specified grid cell.

◆ CellCenter()

template<class TriangleMeshType >
FVector3f UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::CellCenter ( int32  I,
int32  J,
int32  K 
) const
inline
Returns
the physical space location of specified grid point.

◆ Compute()

Compute the SDF

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

◆ Dimensions()

template<class TriangleMeshType >
FVector3i UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::Dimensions ( ) const
inline
Returns
the number of cells in each direction

◆ GetClosestTriGrid()

template<class TriangleMeshType >
const FBlockedGrid3i & UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::GetClosestTriGrid ( ) const
inline
Returns
a grid that can be sampled within the narrow band to find the ID of the closest triangle. Note: this is populated during Compute()

◆ GetIntersectionsGrid()

template<class TriangleMeshType >
const FBlockedGrid3i & UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::GetIntersectionsGrid ( ) const
inline
Returns
a grid that can be sampled within the narrow band to find cells that actually contain mesh triangles. Note: this is populated during Compute()

◆ GetValue()

template<class TriangleMeshType >
float UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::GetValue ( const FVector3i ijk) const
inline
Returns
the distance value at the specified grid cell.

◆ MakeInterpolant()

◆ operator[]()

template<class TriangleMeshType >
float UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::operator[] ( const FVector3i ijk) const
inline
Returns
the distance value at the specified grid cell.

◆ ShouldUseSpatial()

template<class TriangleMeshType >
static bool UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::ShouldUseSpatial ( int32  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 ...

◆ Validate()

template<class TriangleMeshType >
bool UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::Validate ( const FAxisAlignedBox3d Bounds)
inline

Member Data Documentation

◆ ApproxMaxCellsPerDimension

template<class TriangleMeshType >
int UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::ApproxMaxCellsPerDimension = 4096

◆ bComputeSigns

◆ bUseParallel

◆ bWantClosestTriGrid

◆ bWantIntersectionsGrid

template<class TriangleMeshType >
bool UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::bWantIntersectionsGrid = true

◆ CancelF

Initial value:
= []()
{
return false;
}

if this function returns true, the calculation will abort

◆ CellSize

◆ ClosestTriGrid

◆ ComputeMode

◆ ExactBandWidth

template<class TriangleMeshType >
int UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::ExactBandWidth = 1

◆ ExpandBounds

◆ Grid

◆ GridOrigin

◆ InsideMode

◆ IntersectionsGrid

◆ IsInsideFunction

◆ Mesh

◆ NarrowBandMaxDistance

template<class TriangleMeshType >
double UE::Geometry::TSparseNarrowBandMeshSDF< TriangleMeshType >::NarrowBandMaxDistance = 0

◆ Spatial


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