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::BVHUnion< T, P, K > Class Template Reference

BVH-accelerated union of many primitives of one type. More...

#include <EBGeometry_BVHUnion.hpp>

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

Classes

struct  Layout
 The union's arrays as offsets into its pool, with no location: what an outer union stores when this union is its primitive (see PoolHandle). More...
 

Public Types

using Root = BVH::PackedBVH< T, CSGDetail::Stored< P >, K >
 Alias for the packed BVH type. Its primitives are P, or P's layout for a pool-resident P.
 
using BV = BoundingVolumes::AABBT< T >
 Alias for the bounding volume type.
 

Public Member Functions

 BVHUnion ()=delete
 Disallowed, use the full constructor.
 
 BVHUnion (Pool &a_pool, const std::vector< P > &a_primitives, const std::vector< BV > &a_boundingVolumes, BVH::Construction a_construction=BVH::Construction::SAH)
 Build the union.
 
 BVHUnion (Pool &a_pool, const std::vector< P > &a_primitives, const std::vector< BV > &a_boundingVolumes, BVH::Construction a_construction, const BVH::ConstructionOptions &a_options)
 Build the union with leaf-size settings.
 
T signedDistance (const Vec3T< T > &a_point) const noexcept
 Evaluate the union at a point.
 
BV computeBoundingVolume () const noexcept
 The axis-aligned bounding box enclosing all primitives.
 
Root getBVH () const noexcept
 Get the packed BVH over the primitives whose bounding box is bounded.
 
PODSpan< const CSGDetail::Stored< P > > getUnboundedPrimitives () const noexcept
 Get the primitives whose bounding box is unbounded, which every query evaluates.
 
BVHUnion rebasedView (const Pool &a_pool) const noexcept
 Produce a copy of this union that resolves against a_pool.
 
BVHUnion deepCopy (Pool &a_dstPool) const
 Duplicate this union's storage, and that of any pool-resident primitive, into a_dstPool.
 
 BVHUnion (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 union's arrays without its location, for storing it inside an outer union.
 
- 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
 How far signedDistance() can be trusted as a distance: a bound, or only a sign if the primitives' values are not distances. With exact primitives the union is the exact minimum, which is exact outside but underestimates inside overlapping primitives.
 

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, class P, size_t K>
class EBGeometry::BVHUnion< T, P, K >

BVH-accelerated union of many primitives of one type.

A PackedBVH over the primitives, stored by value in a Pool. At query time the BVH culls primitives whose bounding volume lies further than the current best distance, giving sub-linear cost on large scenes. The value is the minimum over all primitives, negative inside the union.

This is a plain, trivially copyable value type with no virtual functions. signedDistance() is callable on the host and on a device: mirror the pool, call rebasedView(), and pass the result to a kernel. Because every primitive has the same type P, no runtime dispatch is needed. For primitives of different types, compose them with Union() and compile the result into a Tape, which evaluates a union of many operands with a BVH too.

P can be any trivially copyable type with an EBGEOMETRY_HOST_DEVICE signedDistance(const Vec3T<T>&): an analytic shape, a mesh distance function, or another BVH union. Pruning needs only that each bounding volume encloses its primitive's object (where the primitive's value is not positive): a primitive skipped because its box is further away than the best value so far is positive at the query point, so skipping it never changes the union's sign. Its value is a distance bound if the primitives' values are, and only a sign if they are DistanceQuality::NotADistance (see distanceQuality).

A primitive whose bounding box is unbounded in some direction (it reaches plus or minus Math::Limits<T>::max(), as an InfiniteCylinderSDF's does along its axis) is kept out of the BVH: such boxes would make every ancestor's box unbounded and the build heuristics meaningless. Those primitives are evaluated at every query instead, before the traversal, so their values can prune it. A union of many bounded primitives and a few unbounded ones costs the BVH query plus one evaluation per unbounded primitive.

A pool-resident primitive (a mesh distance function or a union; see PoolHandle) must have been built in the same Pool as this union. The union stores its layout, and rebuilds it with the union's own location as it evaluates it. The constructor checks the pool, and that there is one bounding volume per primitive, in every build, and aborts with a message if either fails.

Template Parameters
TFloating-point precision.
PPrimitive type.
KBVH branching factor.

Constructor & Destructor Documentation

◆ BVHUnion() [1/3]

template<class T , class P , size_t K>
EBGeometry::BVHUnion< T, P, K >::BVHUnion ( Pool &  a_pool,
const std::vector< P > &  a_primitives,
const std::vector< BV > &  a_boundingVolumes,
BVH::Construction  a_construction = BVH::Construction::SAH 
)

Build the union.

Parameters
[in,out]a_poolPool the BVH is reserved from; pool-resident primitives must live in it too. Must outlive this object and every copy of it.
[in]a_primitivesPrimitives (must be non-empty).
[in]a_boundingVolumesBounding box of each primitive (same length as a_primitives).
[in]a_constructionPreset construction method; every BVH::Construction value is supported. The leaf sizes are defaultConstructionOptions().

◆ BVHUnion() [2/3]

template<class T , class P , size_t K>
EBGeometry::BVHUnion< T, P, K >::BVHUnion ( Pool &  a_pool,
const std::vector< P > &  a_primitives,
const std::vector< BV > &  a_boundingVolumes,
BVH::Construction  a_construction,
const BVH::ConstructionOptions &  a_options 
)

Build the union 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,out]a_poolPool the BVH is reserved from; see the constructor without options.
[in]a_primitivesPrimitives (must be non-empty).
[in]a_boundingVolumesBounding box of each primitive (same length as a_primitives).
[in]a_constructionPreset construction method; every BVH::Construction value is supported.
[in]a_optionsLeaf-size settings, in primitives.

◆ BVHUnion() [3/3]

template<class T , class P , size_t K>
EBGeometry::BVHUnion< T, P, K >::BVHUnion ( 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.

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 union's arrays.
[in]a_locationWhere they live.

Member Function Documentation

◆ computeBoundingVolume()

template<class T , class P , size_t K>
BV EBGeometry::BVHUnion< T, P, K >::computeBoundingVolume ( ) const
inlinenoexcept

The axis-aligned bounding box enclosing all primitives.

Returns
The BVH's root box merged with the boxes of the unbounded primitives.

◆ deepCopy()

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

Duplicate this union's storage, and that of any pool-resident primitive, into a_dstPool.

Parameters
[in,out]a_dstPoolPool to reserve the copy from.
Returns
A BVHUnion with the same structure, backed by a_dstPool.

◆ defaultConstructionOptions()

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

The leaf-size settings the constructor without options uses.

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

Returns
The default settings.

◆ getBVH()

template<class T , class P , size_t K>
Root EBGeometry::BVHUnion< T, P, K >::getBVH ( ) const
inlinenoexcept

Get the packed BVH over the primitives whose bounding box is bounded.

The primitives with unbounded boxes are not in it; see getUnboundedPrimitives().

Returns
The BVH.

◆ getUnboundedPrimitives()

template<class T , class P , size_t K>
PODSpan< const CSGDetail::Stored< P > > EBGeometry::BVHUnion< T, P, K >::getUnboundedPrimitives ( ) const
inlinenoexcept

Get the primitives whose bounding box is unbounded, which every query evaluates.

The span is a resolved address into pool memory; the lifetime caveat of BVH::PackedBVH::getPrimitives() applies.

Returns
Span over those primitives; empty if there are none.

◆ layout()

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

The union's arrays without its location, for storing it inside an outer union.

Returns
The layout.

◆ rebasedView()

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

Produce a copy of this union that resolves against a_pool.

Rebases the BVH; see BVH::PackedBVH::rebasedView() for the contract. Pool-resident primitives are stored as layouts and resolve against the union's location; each is still rebased once here, and the result discarded, purely so that the checks rebasedView() makes (a mirror of the right pool, a BVH shallow enough for the device traversal stack) run for them too. This is the one sanctioned crossing to a device.

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

◆ signedDistance()

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

Evaluate the union at a point.

Returns the minimum value over all primitives not pruned by the BVH. Negative when inside the union.

Parameters
[in]a_point3D query point.
Returns
Minimum signed distance among all non-culled primitives.

Member Data Documentation

◆ distanceQuality

template<class T , class P , size_t K>
constexpr DistanceQuality EBGeometry::BVHUnion< T, P, K >::distanceQuality
staticconstexpr
Initial value:
=
@ Bound
The value's magnitude never exceeds the distance to the surface: it may underestimate,...
@ NotADistance
Only the sign is meaningful, so the function describes a surface (its zero level set) but says nothin...

How far signedDistance() can be trusted as a distance: a bound, or only a sign if the primitives' values are not distances. With exact primitives the union is the exact minimum, which is exact outside but underestimates inside overlapping primitives.


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