EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | List of all members
EBGeometry::MeshSDF< T, K > Class Template Reference

A FlatMeshSDF must be trivially copyable: that is what lets a rebasedView() be byte-copied into a device address space with no pointer patching. More...

#include <EBGeometry_MeshDistanceFunctions.hpp>

Inheritance diagram for EBGeometry::MeshSDF< T, K >:
Inheritance graph
[legend]
Collaboration diagram for EBGeometry::MeshSDF< T, K >:
Collaboration graph
[legend]

Classes

struct  Layout
 The object's arrays as offsets into its pool, with no location (see PoolHandle). More...
 

Public Types

using Face = typename EBGeometry::DCEL::FaceT< T >
 Alias for DCEL face type.
 
using Mesh = typename EBGeometry::DCEL::MeshT< T >
 Alias for DCEL mesh type.
 
using Root = EBGeometry::BVH::PackedBVH< T, uint32_t, K >
 Alias for the linearized BVH root. Its primitives are face ids.
 
using Node = typename Root::Node
 Alias for a single linearized node.
 

Public Member Functions

 MeshSDF ()=delete
 Default disallowed constructor.
 
 MeshSDF (const Layout &a_layout, const PoolLocation &a_location) noexcept
 Rebuild a handle from a stored layout and the location of the pool that holds it.
 
Layout layout () const noexcept
 The object's arrays without its location, for storing it inside another pool-resident object.
 
 MeshSDF (const Mesh &a_mesh, Pool &a_pool, const BVH::Construction a_construction)
 Full constructor. Copies the mesh descriptor and builds the BVH over its faces.
 
 MeshSDF (const Mesh &a_mesh, Pool &a_pool, const BVH::Construction a_construction, const BVH::ConstructionOptions &a_options)
 Full constructor with leaf-size settings.
 
T signedDistance (const Vec3T< T > &a_point) const noexcept
 Compute the signed distance from a_point to the mesh.
 
ClosestFace< T > getClosestFace (const Vec3T< T > &a_point) const noexcept
 Find the face closest to a_point, and the signed distance to it.
 
Root getRoot () const noexcept
 Get the PackedBVH enclosing the mesh.
 
Mesh getMesh () const noexcept
 Get the DCEL mesh descriptor the BVH's faces resolve against.
 
EBGeometry::BoundingVolumes::AABBT< T > computeBoundingVolume () const noexcept
 Compute the AABB enclosing the entire mesh.
 
MeshSDF rebasedView (const Pool &a_pool) const noexcept
 Produce a copy of this object that resolves against a_pool.
 
MeshSDF deepCopy (Pool &a_dstPool) const
 Duplicate the mesh's and the BVH's storage into a_dstPool.
 
- Public Member Functions inherited from EBGeometry::PoolHandle
PoolLocation location () const noexcept
 Where this handle's arrays live.
 
bool isAttachedTo (const Pool &a_pool) const noexcept
 Check whether this handle's arrays were reserved from a_pool.
 

Static Public Member Functions

static BVH::ConstructionOptions defaultConstructionOptions () noexcept
 The leaf-size settings the constructor without options uses.
 

Static Public Attributes

static constexpr DistanceQuality distanceQuality = DistanceQuality::Exact
 How far signedDistance() can be trusted as a distance: the Euclidean distance to a watertight mesh.
 

Additional Inherited Members

- Protected Member Functions inherited from EBGeometry::PoolHandle
 PoolHandle () noexcept=default
 An unset location; the first reservation attaches it.
 
 PoolHandle (const PoolLocation &a_location) noexcept
 Adopt a location, as a handle rebuilt from a stored layout does.
 
 PoolHandle (const PoolHandle &) noexcept=default
 Copy a handle, as a derived handle's copy does.
 
 PoolHandle (PoolHandle &&) noexcept=default
 Move a handle; the same as a copy.
 
PoolHandle & operator= (const PoolHandle &) noexcept=default
 Copy-assign a handle, as a derived handle's assignment does.
 
PoolHandle & operator= (PoolHandle &&) noexcept=default
 Move-assign a handle; the same as a copy.
 
 ~PoolHandle () noexcept=default
 Destructor; protected, since a PoolHandle exists only as the base of a handle.
 
void * base () noexcept
 The base address this handle's offsets resolve against; see PoolLocation::base().
 
const void * base () const noexcept
 The base address this handle's offsets resolve against, for read-only access.
 
void attach (const Pool &a_pool, const char *a_who) noexcept
 Follow a_pool, as the first reservation does; see PoolLocation::attach().
 
PoolLocation rebasedLocation (const Pool &a_pool, uint64_t a_endByte, const char *a_who) const noexcept
 The location of this handle's arrays in another pool of its mirror chain; see PoolLocation::rebasedOnto().
 
void setLocation (const PoolLocation &a_location) noexcept
 Replace the location, for a view or a copy made by a derived handle.
 

Detailed Description

template<class T, size_t K>
class EBGeometry::MeshSDF< T, K >

A FlatMeshSDF must be trivially copyable: that is what lets a rebasedView() be byte-copied into a device address space with no pointer patching.

Signed distance function for a DCEL mesh, accelerated by a PackedBVH over its faces. Accepts any polygon, not just triangles.

The BVH's primitives are face ids: indices into the mesh's face array, four bytes each. Every query resolves a face through the mesh, which MeshSDF holds as well, so the mesh is the only copy of the geometry: flipping the mesh (DCEL::MeshT::flip()) after building flips every distance, and after moving vertices, reconciling the mesh and refitting the BVH (see getRoot()) is enough. The price of four bytes per face rather than the 88 of a face copy is reading faces in mesh order rather than leaf order, which made queries on the armadillo (100k faces) about 15% slower than with copies, near the surface and away from it alike. SIMD node pruning is used when T and K match an available ISA path.

A plain value type, like FlatMeshSDF: it holds the mesh descriptor and the BVH by value, both resolving against the one Pool passed to the constructor, so it is trivially copyable and signedDistance() is callable on the host and on a device. It has no virtual functions: a class with them can never be passed to a kernel. Copies share the pool memory, and the pool must outlive all of them. To evaluate on a device, freeze and mirror the pool and pass rebasedView() into a kernel.

Template Parameters
TFloating-point precision type (float or double).
KBVH branching factor (number of children per internal node).

Constructor & Destructor Documentation

◆ MeshSDF() [1/3]

template<class T , size_t K>
EBGeometry::MeshSDF< T, K >::MeshSDF ( const Layout &  a_layout,
const PoolLocation &  a_location 
)
inlinenoexcept

Rebuild a handle from a stored layout and the location of the pool that holds it.

How an outer pool-resident object, such as a BVHUnion, evaluates a MeshSDF it stores as a layout. a_location must belong to the pool the layout was reserved from, or to a mirror of it; nothing is checked, since a device has no pool to check against.

Parameters
[in]a_layoutThe arrays.
[in]a_locationWhere they live.

◆ MeshSDF() [2/3]

template<class T , size_t K>
EBGeometry::MeshSDF< T, K >::MeshSDF ( const Mesh &  a_mesh,
Pool &  a_pool,
const BVH::Construction  a_construction 
)
inline

Full constructor. Copies the mesh descriptor and builds the BVH over its faces.

No default arguments: this is a low-level constructor, and callers working at this level must consciously choose a construction method. Use Parser::readIntoMeshSDF for sensible defaults. The BVH is reserved from a_pool, which must be the pool a_mesh was built in, so that one rebasedView() rebases both. a_pool must outlive this object and every copy of it.

Parameters
[in]a_meshInput mesh, built against a_pool.
[in,out]a_poolPool a_mesh's storage was reserved from; the BVH is reserved here too.
[in]a_constructionPreset construction method; every BVH::Construction value is supported. SAH (binned Surface Area Heuristic) is recommended. The leaf sizes are defaultConstructionOptions(): the top-down methods stop at fewer than K faces per leaf, and ClusterSAH uses the default ClusterSpec, so a leaf holds up to (K-1) clusters of faces.

◆ MeshSDF() [3/3]

template<class T , size_t K>
EBGeometry::MeshSDF< T, K >::MeshSDF ( const Mesh &  a_mesh,
Pool &  a_pool,
const BVH::Construction  a_construction,
const BVH::ConstructionOptions &  a_options 
)
inline

Full constructor with leaf-size settings.

As the constructor without options, which uses defaultConstructionOptions(). The chosen method reads only its own field of a_options; see BVH::ConstructionOptions.

Parameters
[in]a_meshInput mesh, built against a_pool.
[in,out]a_poolPool a_mesh's storage was reserved from; the BVH is reserved here too.
[in]a_constructionPreset construction method; every BVH::Construction value is supported.
[in]a_optionsLeaf-size settings, in faces.

Member Function Documentation

◆ computeBoundingVolume()

template<class T , size_t K>
EBGeometry::BoundingVolumes::AABBT< T > EBGeometry::MeshSDF< T, K >::computeBoundingVolume ( ) const
inlinenoexcept

Compute the AABB enclosing the entire mesh.

Returns
Axis-aligned bounding box of the mesh.

◆ deepCopy()

template<class T , size_t K>
MeshSDF EBGeometry::MeshSDF< T, K >::deepCopy ( Pool &  a_dstPool) const
inline

Duplicate the mesh's and the BVH's storage into a_dstPool.

The copy constructor copies descriptors only. This gives genuinely independent storage. The copied face ids still name the right faces of the copied mesh, since a mesh deep copy preserves every element's index.

Parameters
[in,out]a_dstPoolPool to reserve the copy from; may be this object's own pool.
Returns
A MeshSDF over independent copies of the mesh and BVH, attached to a_dstPool.

◆ defaultConstructionOptions()

template<class T , size_t K>
static BVH::ConstructionOptions EBGeometry::MeshSDF< T, K >::defaultConstructionOptions ( )
inlinestaticnoexcept

The leaf-size settings the constructor without options uses.

K-1 faces per leaf for the top-down methods (a node with fewer than K faces is a leaf), a target of 1 for the space-filling curves (the deepest balanced tree, at most K faces per leaf), and the default ClusterSpec for ClusterSAH. Start from these to change one method's setting; see BVH::ConstructionOptions.

Returns
The default settings.

◆ getClosestFace()

template<class T , size_t K>
ClosestFace< T > EBGeometry::MeshSDF< T, K >::getClosestFace ( const Vec3T< T > &  a_point) const
inlinenoexcept

Find the face closest to a_point, and the signed distance to it.

The same BVH traversal as signedDistance() (PackedBVH::traverse() with a PointQuery), keeping the winning face's id as well, so it is callable on a device too.

Parameters
[in]a_pointQuery point. Must be finite.
Returns
The closest face's id (its index in the mesh) and signed distance. The signed distance equals what signedDistance() returns for the same point.

◆ getMesh()

template<class T , size_t K>
Mesh EBGeometry::MeshSDF< T, K >::getMesh ( ) const
inlinenoexcept

Get the DCEL mesh descriptor the BVH's faces resolve against.

Returns
The mesh.

◆ getRoot()

template<class T , size_t K>
Root EBGeometry::MeshSDF< T, K >::getRoot ( ) const
inlinenoexcept

Get the PackedBVH enclosing the mesh.

Mutable, so that PackedBVH::refit() can be called on it. After moving the mesh's vertices, reconcile the mesh (DCEL::MeshT::reconcile()), which recomputes its normals, then refit with each face's new bounding box:

sdf.getRoot().refit([&mesh](uint32_t a_face) {
return BoundingVolumes::AABBT<T>(mesh.getFace(a_face).getAllVertexCoordinates(mesh));
});
Axis-aligned bounding box (AABB) enclosing a set of 3D points.
Definition EBGeometry_BoundingVolumes.hpp:37

This is enough because the BVH stores face ids and reads the faces from the mesh. A deformation large enough to degrade the tree still calls for a rebuild.

Returns
The packed BVH.

◆ layout()

template<class T , size_t K>
Layout EBGeometry::MeshSDF< T, K >::layout ( ) const
inlinenoexcept

The object's arrays without its location, for storing it inside another pool-resident object.

Returns
The layout.

◆ rebasedView()

template<class T , size_t K>
MeshSDF EBGeometry::MeshSDF< T, K >::rebasedView ( const Pool &  a_pool) const
inlinenoexcept

Produce a copy of this object that resolves against a_pool.

Rebases the mesh descriptor and the BVH together; see DCEL::MeshT::rebasedView() and BVH::PackedBVH::rebasedView() for the contract. This is the one sanctioned crossing to a device.

Parameters
[in]a_poolPool to rebase onto: the object's own pool or one in its mirror chain.
Returns
A MeshSDF resolving against a_pool.

◆ signedDistance()

template<class T , size_t K>
T EBGeometry::MeshSDF< T, K >::signedDistance ( const Vec3T< T > &  a_point) const
inlinenoexcept

Compute the signed distance from a_point to the mesh.

Parameters
[in]a_pointQuery point.
Returns
Signed distance to the nearest face; negative inside the mesh.

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