EBGeometry
Compact, header-only C++ library for fast evaluation of signed distance functions
Loading...
Searching...
No Matches
EBGeometry_BVHUnion.hpp
Go to the documentation of this file.
1// SPDX-FileCopyrightText: 2022 Robert Marskar <robert.marskar@sintef.no>
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
13#ifndef EBGEOMETRY_BVHUNION_HPP
14#define EBGEOMETRY_BVHUNION_HPP
15
16// Std includes
17#include <cstddef>
18#include <type_traits>
19#include <utility>
20#include <vector>
21
22// Our includes
23#include "EBGeometry_BVH.hpp"
24#include "EBGeometry_Blend.hpp"
26#include "EBGeometry_GPU.hpp"
27#include "EBGeometry_Macros.hpp"
28#include "EBGeometry_Math.hpp"
29#include "EBGeometry_Pool.hpp"
30#include "EBGeometry_Vec.hpp"
31
32namespace EBGeometry {
33
37namespace CSGDetail {
38
46template <class P, bool = isPoolHandle<P>>
48{
52 using type = P;
53};
54
59template <class P>
60struct StoredAs<P, true>
61{
65 using type = typename P::Layout;
66};
67
72template <class P>
73using Stored = typename StoredAs<P>::type;
74
81template <class P>
82[[nodiscard]] EBGEOMETRY_HOST
83inline Stored<P>
84toStored(const P& a_primitive) noexcept
85{
86 if constexpr (isPoolHandle<P>) {
87 return a_primitive.layout();
88 }
89 else {
90 return a_primitive;
91 }
92}
93
104template <class P>
105[[nodiscard]] EBGEOMETRY_HOST_DEVICE
106inline P
107fromStored(const Stored<P>& a_stored, [[maybe_unused]] const PoolLocation& a_location) noexcept
108{
109 if constexpr (isPoolHandle<P>) {
110 return P(a_stored, a_location);
111 }
112 else {
113 return a_stored;
114 }
115}
116
125template <class T, class P, size_t K>
138
139} // namespace CSGDetail
140
176template <class T, class P, size_t K>
177class BVHUnion : public PoolHandle
178{
179public:
180 static_assert(std::is_floating_point_v<T>, "BVHUnion requires a floating-point type T");
181 static_assert(std::is_trivially_copyable_v<P>, "BVHUnion requires a trivially copyable primitive type");
182 static_assert(K > 1, "BVHUnion BVH branching factor K must be at least 2");
183
191
196
201
205 BVHUnion() = delete;
206
214 [[nodiscard]] EBGEOMETRY_HOST
220
231 BVHUnion(Pool& a_pool,
232 const std::vector<P>& a_primitives,
233 const std::vector<BV>& a_boundingVolumes,
235
247 BVHUnion(Pool& a_pool,
248 const std::vector<P>& a_primitives,
249 const std::vector<BV>& a_boundingVolumes,
250 BVH::Construction a_construction,
251 const BVH::ConstructionOptions& a_options);
252
260 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
261 inline T
262 signedDistance(const Vec3T<T>& a_point) const noexcept;
263
268 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
269 inline BV
270 computeBoundingVolume() const noexcept;
271
277 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
278 inline Root
279 getBVH() const noexcept;
280
287 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
288 inline PODSpan<const CSGDetail::Stored<P>>
289 getUnboundedPrimitives() const noexcept;
290
301 [[nodiscard]] EBGEOMETRY_HOST
302 inline BVHUnion
303 rebasedView(const Pool& a_pool) const noexcept;
304
310 [[nodiscard]] EBGEOMETRY_HOST
311 inline BVHUnion
312 deepCopy(Pool& a_dstPool) const;
313
318 struct Layout
319 {
324
329 };
330
339 BVHUnion(const Layout& a_layout, const PoolLocation& a_location) noexcept
340 : PoolHandle(a_location), m_bvh(a_layout.m_bvh), m_unbounded(a_layout.m_unbounded)
341 {}
342
347 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
348 Layout
349 layout() const noexcept
350 {
351 return Layout{m_bvh, m_unbounded};
352 }
353
354private:
360 explicit BVHUnion(const CSGDetail::UnionParts<T, P, K>& a_parts) noexcept
361 : PoolHandle(a_parts.bvh.location()), m_bvh(a_parts.bvh.layout()), m_unbounded(a_parts.unbounded.layout())
362 {}
363
367 typename Root::Layout m_bvh;
368
372 typename Root::Layout m_unbounded;
373};
374
388template <class T, class P, size_t K, class Blend = SmoothMinOp<T>>
390{
391public:
392 static_assert(std::is_floating_point_v<T>, "BVHSmoothUnion requires a floating-point type T");
393 static_assert(std::is_trivially_copyable_v<P>, "BVHSmoothUnion requires a trivially copyable primitive type");
394 static_assert(std::is_trivially_copyable_v<Blend>, "BVHSmoothUnion requires a trivially copyable blend operator");
395 static_assert(K > 1, "BVHSmoothUnion BVH branching factor K must be at least 2");
396
404
409
414
418 BVHSmoothUnion() = delete;
419
424 [[nodiscard]] EBGEOMETRY_HOST
430
443 const std::vector<P>& a_primitives,
444 const std::vector<BV>& a_boundingVolumes,
445 T a_smoothLen,
446 Blend a_blend = Blend{},
448
463 const std::vector<P>& a_primitives,
464 const std::vector<BV>& a_boundingVolumes,
465 T a_smoothLen,
466 Blend a_blend,
467 BVH::Construction a_construction,
468 const BVH::ConstructionOptions& a_options);
469
477 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
478 inline T
479 signedDistance(const Vec3T<T>& a_point) const noexcept;
480
485 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
486 inline BV
487 computeBoundingVolume() const noexcept;
488
494 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
495 inline Root
496 getBVH() const noexcept;
497
504 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
505 inline PODSpan<const CSGDetail::Stored<P>>
506 getUnboundedPrimitives() const noexcept;
507
514 [[nodiscard]] EBGEOMETRY_HOST
515 inline BVHSmoothUnion
516 rebasedView(const Pool& a_pool) const noexcept;
517
523 [[nodiscard]] EBGEOMETRY_HOST
524 inline BVHSmoothUnion
525 deepCopy(Pool& a_dstPool) const;
526
531 struct Layout
532 {
537
542
547
551 Blend m_blend;
552 };
553
561 BVHSmoothUnion(const Layout& a_layout, const PoolLocation& a_location) noexcept
562 : PoolHandle(a_location),
563 m_bvh(a_layout.m_bvh),
564 m_unbounded(a_layout.m_unbounded),
565 m_smoothLen(a_layout.m_smoothLen),
566 m_blend(a_layout.m_blend)
567 {}
568
574 [[nodiscard]] EBGEOMETRY_HOST_DEVICE
575 Layout
576 layout() const noexcept
577 {
578 return Layout{m_bvh, m_unbounded, m_smoothLen, m_blend};
579 }
580
581private:
590 BVHSmoothUnion(const CSGDetail::UnionParts<T, P, K>& a_parts, T a_smoothLen, Blend a_blend) noexcept
591 : PoolHandle(a_parts.bvh.location()),
592 m_bvh(a_parts.bvh.layout()),
593 m_unbounded(a_parts.unbounded.layout()),
594 m_smoothLen(Math::max(a_smoothLen, Math::Limits<T>::min())),
595 m_blend(a_blend)
596 {}
597
601 typename Root::Layout m_bvh;
602
606 typename Root::Layout m_unbounded;
607
611 T m_smoothLen;
612
616 Blend m_blend;
617};
618
619} // namespace EBGeometry
620
621#include "EBGeometry_BVHUnionImplem.hpp"
622
623// The ray forms, through the fused operations: firstHit() is a template, and a file that included this header
624// without them would march a BVH union that another file traces exactly, two definitions of one function.
625// Included last, after the classes they specialize for, since those headers include this one.
626#include "EBGeometry_Fused.hpp"
627
628#endif
Bounding volume hierarchies: everything in EBGeometry_PackedBVH.hpp, EBGeometry_TreeBVH....
The blend operators that smooth unions, intersections and differences use: ExpMinOp,...
How far a function's value can be trusted as a distance: DistanceQuality, and the distanceQualityOf t...
Fused CSG: the operations of the expression builder (EBGeometry_Expr.hpp) as types,...
GPU portability layer: host/device decoration macros and backend detection.
#define EBGEOMETRY_HOST_DEVICE
Mark a function as callable from both host and device code (no-op on host compilers).
Definition EBGeometry_GPU.hpp:80
#define EBGEOMETRY_HOST
Mark a function as callable from host code only (no-op on host compilers).
Definition EBGeometry_GPU.hpp:83
Utility macros for EBGeometry.
Scalar helpers and numeric limits that compile for both host and device.
Growable bump arena for the GPU memory foundation.
Declaration of 2D and 3D point/vector classes with templated precision, and free functions on them.
BVH-accelerated smooth union of many primitives of one type.
Definition EBGeometry_BVHUnion.hpp:390
static constexpr DistanceQuality distanceQuality
How far signedDistance() can be trusted as a distance: a bound, or only a sign if the primitives' val...
Definition EBGeometry_BVHUnion.hpp:402
BV computeBoundingVolume() const noexcept
The axis-aligned bounding box enclosing all primitives.
Layout layout() const noexcept
The union's arrays and parameters without its location, for storing it inside an outer union.
Definition EBGeometry_BVHUnion.hpp:576
BVHSmoothUnion()=delete
Disallowed, use the full constructor.
Root getBVH() const noexcept
Get the packed BVH over the primitives whose bounding box is bounded.
BVHSmoothUnion deepCopy(Pool &a_dstPool) const
Duplicate this smooth union's storage into a_dstPool; see BVHUnion::deepCopy().
static BVH::ConstructionOptions defaultConstructionOptions() noexcept
The leaf-size settings the constructor without options uses; the same as BVHUnion's.
Definition EBGeometry_BVHUnion.hpp:426
BVHSmoothUnion rebasedView(const Pool &a_pool) const noexcept
Produce a copy of this smooth union that resolves against a_pool; see BVHUnion::rebasedView().
PODSpan< const CSGDetail::Stored< P > > getUnboundedPrimitives() const noexcept
Get the primitives whose bounding box is unbounded, which every query evaluates.
BVHSmoothUnion(Pool &a_pool, const std::vector< P > &a_primitives, const std::vector< BV > &a_boundingVolumes, T a_smoothLen, Blend a_blend=Blend{}, BVH::Construction a_construction=BVH::Construction::SAH)
Build the smooth union.
T signedDistance(const Vec3T< T > &a_point) const noexcept
Evaluate the smooth union at a point.
BVHSmoothUnion(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; see BVHUnion.
Definition EBGeometry_BVHUnion.hpp:561
BVHSmoothUnion(Pool &a_pool, const std::vector< P > &a_primitives, const std::vector< BV > &a_boundingVolumes, T a_smoothLen, Blend a_blend, BVH::Construction a_construction, const BVH::ConstructionOptions &a_options)
Build the smooth union with leaf-size settings.
BVH-accelerated union of many primitives of one type.
Definition EBGeometry_BVHUnion.hpp:178
T signedDistance(const Vec3T< T > &a_point) const noexcept
Evaluate the union at a point.
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.
Definition EBGeometry_BVHUnion.hpp:339
BVHUnion rebasedView(const Pool &a_pool) const noexcept
Produce a copy of this union that resolves against a_pool.
BV computeBoundingVolume() const noexcept
The axis-aligned bounding box enclosing all primitives.
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.
Root getBVH() const noexcept
Get the packed BVH over the primitives whose bounding box is bounded.
BVHUnion deepCopy(Pool &a_dstPool) const
Duplicate this union's storage, and that of any pool-resident primitive, into a_dstPool.
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.
static BVH::ConstructionOptions defaultConstructionOptions() noexcept
The leaf-size settings the constructor without options uses.
Definition EBGeometry_BVHUnion.hpp:216
Layout layout() const noexcept
The union's arrays without its location, for storing it inside an outer union.
Definition EBGeometry_BVHUnion.hpp:349
BVHUnion()=delete
Disallowed, use the full constructor.
static constexpr DistanceQuality distanceQuality
How far signedDistance() can be trusted as a distance: a bound, or only a sign if the primitives' val...
Definition EBGeometry_BVHUnion.hpp:189
PODSpan< const CSGDetail::Stored< P > > getUnboundedPrimitives() const noexcept
Get the primitives whose bounding box is unbounded, which every query evaluates.
Forward declaration of the linearised BVH, defined below.
Definition EBGeometry_PackedBVH.hpp:357
static BVH::ConstructionOptions defaultConstructionOptions() noexcept
The leaf-size settings build() uses when it is given none.
Definition EBGeometry_PackedBVH.hpp:603
Axis-aligned bounding box (AABB) enclosing a set of 3D points.
Definition EBGeometry_BoundingVolumes.hpp:37
Base of every pool-resident handle: the one PoolLocation its arrays resolve against.
Definition EBGeometry_Pool.hpp:499
PoolHandle() noexcept=default
An unset location; the first reservation attaches it.
Growable bump arena over a MemoryResource.
Definition EBGeometry_Pool.hpp:183
Three-dimensional vector class with arithmetic operators.
Definition EBGeometry_Vec.hpp:258
Construction
The preset BVH construction methods that the library's own BVH users accept.
Definition EBGeometry_PackedBVH.hpp:65
Stored< P > toStored(const P &a_primitive) noexcept
Convert a primitive to the form a BVH union stores.
Definition EBGeometry_BVHUnion.hpp:84
typename StoredAs< P >::type Stored
Shorthand for the type a BVH union stores for a primitive of type P.
Definition EBGeometry_BVHUnion.hpp:73
P fromStored(const Stored< P > &a_stored, const PoolLocation &a_location) noexcept
The primitive a stored entry stands for, resolving against a_location.
Definition EBGeometry_BVHUnion.hpp:107
constexpr T max(const T &a_a, const T &a_b) noexcept
The larger of two values.
Definition EBGeometry_Math.hpp:61
Namespace containing all of EBGeometry's functionality.
Definition EBGeometry_Affine.hpp:26
DistanceQuality
How far the value of a signed distance function can be trusted, from strongest to weakest.
Definition EBGeometry_DistanceQuality.hpp:25
@ 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...
The smooth union's arrays and parameters, with no location: what an outer union stores when this one ...
Definition EBGeometry_BVHUnion.hpp:532
Root::Layout m_bvh
BVH over the primitives with bounded boxes.
Definition EBGeometry_BVHUnion.hpp:536
T m_smoothLen
Smoothing length.
Definition EBGeometry_BVHUnion.hpp:546
Root::Layout m_unbounded
The primitives with unbounded boxes, as one leaf.
Definition EBGeometry_BVHUnion.hpp:541
Blend m_blend
Smooth-minimum operator.
Definition EBGeometry_BVHUnion.hpp:551
The union's arrays as offsets into its pool, with no location: what an outer union stores when this u...
Definition EBGeometry_BVHUnion.hpp:319
Root::Layout m_bvh
BVH over the primitives with bounded boxes.
Definition EBGeometry_BVHUnion.hpp:323
Root::Layout m_unbounded
The primitives with unbounded boxes, as one leaf.
Definition EBGeometry_BVHUnion.hpp:328
Leaf-size settings for the preset construction methods, one per family of methods.
Definition EBGeometry_PackedBVH.hpp:115
The BVH's arrays as offsets into its pool, and its root box: a PackedBVH minus its location.
Definition EBGeometry_PackedBVH.hpp:1105
typename P::Layout type
The stored type: P's layout.
Definition EBGeometry_BVHUnion.hpp:65
How a BVH union stores a primitive of type P: as is, or, for a pool-resident handle,...
Definition EBGeometry_BVHUnion.hpp:48
P type
The stored type: P itself.
Definition EBGeometry_BVHUnion.hpp:52
What a BVH union is built into: a BVH over the primitives whose bounding box is bounded,...
Definition EBGeometry_BVHUnion.hpp:127
BVH::PackedBVH< T, Stored< P >, K > unbounded
The primitives with unbounded boxes, as one leaf; empty if there are none.
Definition EBGeometry_BVHUnion.hpp:136
BVH::PackedBVH< T, Stored< P >, K > bvh
BVH over the primitives with bounded boxes.
Definition EBGeometry_BVHUnion.hpp:131
Numeric limits, with the meanings of the std::numeric_limits members of the same names.
Definition EBGeometry_Math.hpp:91
Raw pointer + size view into a Pool block, for hot inner loops.
Definition EBGeometry_PODVector.hpp:52
Where a pool-resident descriptor resolves its offsets, and the rules for moving it.
Definition EBGeometry_Pool.hpp:99