Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-13 11:00:39

0001 /// @file UnplacedHalfSpace.h
0002 /// @brief Unplaced half-space primitive for Boolean CSG cutters.
0003 
0004 #ifndef VECGEOM_VOLUMES_UNPLACEDHALFSPACE_H_
0005 #define VECGEOM_VOLUMES_UNPLACEDHALFSPACE_H_
0006 
0007 #include "VecGeom/base/AlignedBase.h"
0008 #include "VecGeom/base/Cuda.h"
0009 #include "VecGeom/base/Global.h"
0010 #include "VecGeom/base/Vector3D.h"
0011 #include "VecGeom/volumes/HalfSpaceStruct.h"
0012 #include "VecGeom/volumes/UnplacedVolume.h"
0013 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0014 #include "VecGeom/volumes/kernel/HalfSpaceImplementation.h"
0015 
0016 namespace vecgeom {
0017 
0018 VECGEOM_DEVICE_FORWARD_DECLARE(class UnplacedHalfSpace;);
0019 VECGEOM_DEVICE_DECLARE_CONV(class, UnplacedHalfSpace);
0020 
0021 inline namespace VECGEOM_IMPL_NAMESPACE {
0022 
0023 /// @brief Infinite half-space represented by a plane point and outward normal.
0024 /// @details The primitive is intended for Boolean CSG trees. It is infinite and
0025 /// must not be installed directly as a world or daughter volume. The material
0026 /// side is the half-space where `(p - point).Dot(normal) <= 0`.
0027 class UnplacedHalfSpace : public UnplacedVolumeImplHelper<HalfSpaceImplementation>, public AlignedBase {
0028 private:
0029   HalfSpaceStruct<Precision> fHalfSpace;
0030 
0031 public:
0032   using Kernel = HalfSpaceImplementation;
0033 
0034   /// @brief Construct a half-space from a plane point and outward normal.
0035   /// @param point Point lying on the limiting plane.
0036   /// @param normal Non-zero normal pointing outside; normalized on storage.
0037   VECCORE_ATT_HOST_DEVICE
0038   UnplacedHalfSpace(Vector3D<Precision> const &point, Vector3D<Precision> const &normal);
0039 
0040   /// @brief Construct a half-space from scalar point and normal components.
0041   VECCORE_ATT_HOST_DEVICE
0042   UnplacedHalfSpace(Precision px, Precision py, Precision pz, Precision nx, Precision ny, Precision nz)
0043       : UnplacedHalfSpace(Vector3D<Precision>(px, py, pz), Vector3D<Precision>(nx, ny, nz))
0044   {
0045   }
0046 
0047   VECCORE_ATT_HOST_DEVICE
0048   VECGEOM_FORCE_INLINE
0049   virtual ESolidType GetType() const override { return ESolidType::halfspace; }
0050 
0051   /// @brief Return the normalized half-space runtime data.
0052   VECCORE_ATT_HOST_DEVICE
0053   HalfSpaceStruct<Precision> const &GetStruct() const { return fHalfSpace; }
0054 
0055   /// @brief Return one point on the limiting plane.
0056   VECCORE_ATT_HOST_DEVICE
0057   Vector3D<Precision> const &GetPoint() const { return fHalfSpace.fPoint; }
0058 
0059   /// @brief Return the unit outward normal of the limiting plane.
0060   VECCORE_ATT_HOST_DEVICE
0061   Vector3D<Precision> const &GetNormal() const { return fHalfSpace.fNormal; }
0062 
0063   /// @brief Return zero for the infinite primitive placeholder capacity.
0064   /// @details Half-space capacity is not finite; Boolean results containing a
0065   /// subtracted half-space estimate their own finite capacity from their extent.
0066   Precision Capacity() const override { return 0.; }
0067 
0068   /// @brief Return zero for the infinite primitive placeholder surface area.
0069   /// @details The plane surface is infinite until clipped by a finite Boolean
0070   /// result, so standalone half-space surface area is intentionally unavailable.
0071   Precision SurfaceArea() const override { return 0.; }
0072 
0073   /// @brief Return the unbounded extent of the standalone half-space.
0074   VECCORE_ATT_HOST_DEVICE
0075   void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0076 
0077 #ifndef VECCORE_CUDA
0078   /// @brief Return a conservative clipped extent without transforming the unbounded box.
0079   /// @param axis Mother-frame axis queried after applying `transform`.
0080   /// @param limits Mother-frame voxel limits used to clip the extent.
0081   /// @param transform Local-to-mother transform; ignored because the extent is unbounded.
0082   /// @param[out] min Lower extent along `axis` when the limits are non-empty.
0083   /// @param[out] max Upper extent along `axis` when the limits are non-empty.
0084   /// @return True when `limits` are non-empty.
0085   bool CalculateClippedExtent(Axis axis, VoxelLimits const &limits, Transformation3D const &transform, Precision &min,
0086                               Precision &max) const override;
0087 #endif
0088 
0089   /// @brief Return a deterministic point on the limiting plane.
0090   /// @details Standalone uniform plane sampling is undefined for an infinite
0091   /// plane. Boolean samplers clip half-space planes to their finite result box.
0092   Vector3D<Precision> SamplePointOnSurface() const override;
0093 
0094   /// @brief Return the outward plane normal at a surface point.
0095   /// @param p Query point in half-space local coordinates.
0096   /// @param[out] normal Unit outward normal.
0097   /// @return True when @p p is within tolerance of the limiting plane.
0098   VECCORE_ATT_HOST_DEVICE
0099   virtual bool Normal(Vector3D<Precision> const &p, Vector3D<Precision> &normal) const override
0100   {
0101     bool valid;
0102     normal = HalfSpaceImplementation::NormalKernel(fHalfSpace, p, valid);
0103     return valid;
0104   }
0105 
0106   VECCORE_ATT_HOST_DEVICE
0107   virtual void Print() const override;
0108 
0109   /// @brief Stream a compact textual representation of the half-space data.
0110   virtual void Print(std::ostream &os) const override;
0111 
0112 #ifndef VECCORE_CUDA
0113   /// @brief Return an empty mesh because the primitive is unbounded.
0114   virtual SolidMesh *CreateMesh3D(Transformation3D const &trans, size_t nSegments) const override;
0115 #endif
0116 
0117 #ifdef VECGEOM_CUDA_INTERFACE
0118   /// @brief Return the CUDA-side allocation size for this unplaced volume.
0119   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedHalfSpace>::SizeOf(); }
0120   /// @brief Copy this half-space to newly allocated GPU memory.
0121   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0122   /// @brief Construct this half-space at an existing GPU allocation.
0123   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0124 #endif
0125 
0126 #ifndef VECCORE_CUDA
0127   /// @brief Create a placed half-space instance for Boolean tree operands.
0128   static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0129                                VPlacedVolume *const placement = NULL);
0130 
0131   /// @brief Create the specialized placed volume for the requested transform.
0132   VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume, Transformation3D const *const transformation,
0133                                    VPlacedVolume *const placement) const override;
0134 #else
0135   /// @brief Device-side placed half-space factory.
0136   VECCORE_ATT_DEVICE
0137   static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0138                                const int id, const int copy_no, const int child_id,
0139                                VPlacedVolume *const placement = NULL);
0140 
0141   /// @brief Device-side specialized placed volume factory.
0142   VECCORE_ATT_DEVICE
0143   VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume, Transformation3D const *const transformation,
0144                                    const int id, const int copy_no, const int child_id,
0145                                    VPlacedVolume *const placement) const override;
0146 #endif
0147 
0148 #ifndef VECCORE_CUDA
0149 #ifdef VECGEOM_ROOT
0150   /// @brief Convert to ROOT's `TGeoHalfSpace`.
0151   TGeoShape const *ConvertToRoot(char const *label = "") const;
0152 #endif
0153 #endif
0154 };
0155 
0156 using GenericUnplacedHalfSpace = UnplacedHalfSpace;
0157 
0158 } // namespace VECGEOM_IMPL_NAMESPACE
0159 } // namespace vecgeom
0160 
0161 #endif // VECGEOM_VOLUMES_UNPLACEDHALFSPACE_H_