Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-19 08:25:20

0001 #ifndef UNPLACEDBOOLEANVOLUME_H_
0002 #define UNPLACEDBOOLEANVOLUME_H_
0003 
0004 #include "VecGeom/base/Cuda.h"
0005 #include "VecGeom/base/Global.h"
0006 #include "VecGeom/base/AlignedBase.h"
0007 #include "VecGeom/base/Vector3D.h"
0008 #include "VecGeom/volumes/UnplacedVolume.h"
0009 #include "VecGeom/volumes/PlacedVolume.h"
0010 #include "VecGeom/volumes/BooleanStruct.h"
0011 #include "VecGeom/volumes/kernel/BooleanImplementation.h"
0012 #include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
0013 #ifndef VECCORE_CUDA
0014 #include "VecGeom/volumes/UnplacedMultiUnion.h"
0015 #endif
0016 
0017 #include <string>
0018 
0019 namespace vecgeom {
0020 
0021 VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(class, UnplacedBooleanVolume, BooleanOperation, Arg1);
0022 
0023 inline namespace VECGEOM_IMPL_NAMESPACE {
0024 
0025 #ifndef VECCORE_CUDA
0026 namespace BooleanHelper {
0027 
0028 VECCORE_ATT_HOST_DEVICE
0029 BooleanStruct const *GetBooleanStruct(VUnplacedVolume const *unplaced);
0030 
0031 VECCORE_ATT_HOST_DEVICE
0032 size_t CountBooleanNodes(VUnplacedVolume const *unplaced, size_t &nunion, size_t &nintersection, size_t &nsubtraction);
0033 
0034 UnplacedMultiUnion *Flatten(VUnplacedVolume const *unplaced, size_t min_unions = 3,
0035                             Transformation3D const *trbase = nullptr, UnplacedMultiUnion *munion = nullptr);
0036 } // namespace BooleanHelper
0037 #endif
0038 
0039 /**
0040  * A class representing a simple UNPLACED boolean volume A-B
0041  * It takes two template arguments:
0042  * 1.: the mother (or left) volume A in unplaced form
0043  * 2.: the (or right) volume B in placed form, acting on A with a boolean operation;
0044  * the placement is with respect to the left volume
0045  *
0046  *
0047  *
0048  * will be a boolean solid where two boxes are subtracted
0049  * and B is only translated (not rotated) with respect to A
0050  *
0051  */
0052 template <BooleanOperation Op>
0053 class UnplacedBooleanVolume : public UnplacedVolumeImplHelper<BooleanImplementation<Op>>, public AlignedBase {
0054 
0055 public:
0056   BooleanStruct fBoolean;
0057   using UnplacedVolumeImplHelper<BooleanImplementation<Op>>::fGlobalConvexity;
0058 
0059   // the constructor
0060   VECCORE_ATT_HOST_DEVICE
0061   UnplacedBooleanVolume(BooleanOperation op, VPlacedVolume const *left, VPlacedVolume const *right)
0062       : fBoolean(op, left, right)
0063   {
0064     fGlobalConvexity = false;
0065     VUnplacedVolume::ComputeBBox();
0066 #ifndef VECCORE_CUDA
0067     if (fBoolean.fLeftVolume->IsAssembly() || fBoolean.fRightVolume->IsAssembly()) {
0068       throw std::runtime_error("Trying to make boolean out of assembly which is not supported\n");
0069     }
0070 #endif
0071   }
0072 
0073   VECCORE_ATT_HOST_DEVICE
0074   VECGEOM_FORCE_INLINE
0075   virtual bool IsBoolean() const override { return true; }
0076 
0077   VECCORE_ATT_HOST_DEVICE
0078   virtual ESolidType GetType() const override { return ESolidType::boolean; }
0079 
0080 #ifdef VECGEOM_CUDA_INTERFACE
0081   virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedBooleanVolume<Op>>::SizeOf(); }
0082   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0083   virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0084 #endif
0085 
0086   VECCORE_ATT_HOST_DEVICE
0087   VECGEOM_FORCE_INLINE
0088   BooleanOperation GetOp() const { return fBoolean.fOp; }
0089 
0090   VECCORE_ATT_HOST_DEVICE
0091   BooleanStruct const &GetStruct() const { return fBoolean; }
0092 
0093   VECCORE_ATT_HOST_DEVICE
0094   bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0095 
0096   Precision Capacity() const override
0097   {
0098     if (fBoolean.fCapacity < 0.) {
0099       fBoolean.fCapacity = VUnplacedVolume::EstimateCapacity(1000000);
0100     }
0101     return fBoolean.fCapacity;
0102   }
0103 
0104   Precision SurfaceArea() const override
0105   {
0106     if (fBoolean.fSurfaceArea < 0.) {
0107       fBoolean.fSurfaceArea = VUnplacedVolume::EstimateSurfaceArea(1000000);
0108     }
0109     return fBoolean.fSurfaceArea;
0110   }
0111 
0112   VECCORE_ATT_HOST_DEVICE
0113   void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0114 
0115   Vector3D<Precision> SamplePointOnSurface() const override;
0116 
0117   std::string GetEntityType() const { return "BooleanVolume"; }
0118 
0119   VECCORE_ATT_HOST_DEVICE
0120   virtual void Print() const override
0121   {
0122 #ifndef VECCORE_CUDA
0123     auto op            = this->GetOp();
0124     const char *opname = (op == kUnion ? "Union" : (op == kIntersection ? "Intersection" : "Subtraction"));
0125     printf("UnplacedBooleanVol<%s>{fLeft=[%i]<%s>, fRight=[%i]<%s>}", opname, this->GetLeft()->id(),
0126            this->GetLeft()->GetName(), this->GetRight()->id(), this->GetRight()->GetName());
0127 #else
0128     printf("UnplacedBooleanVol<%i>{fLeft=[%i], fRight=[%i]}", this->GetOp(), this->GetLeft()->id(),
0129            this->GetRight()->id());
0130 #endif
0131     printf("\n\t----------------------------------------");
0132     printf("\n\tfLeft:  [%i] ", this->GetLeft()->id());
0133     this->GetLeft()->GetUnplacedVolume()->Print();
0134     printf("\n\tfRight: [%i] ", this->GetRight()->id());
0135     this->GetRight()->GetUnplacedVolume()->Print();
0136     printf("\n\t----------------------------------------\n");
0137   }
0138 
0139   virtual void Print(std::ostream &os) const override
0140   {
0141 #ifndef VECCORE_CUDA
0142     auto op = this->GetOp();
0143     os << "UnplacedBooleanVol<" << (op == kUnion ? "Union" : (op == kIntersection ? "Intersection" : "Subtraction"))
0144        << ">{fLeft=<" << this->GetLeft()->id() << ">, fRight=<" << this->GetRight()->id() << ">}\n";
0145 #endif
0146     os << "fLeft:  [" << this->GetLeft()->id() << "] ";
0147     this->GetLeft()->GetUnplacedVolume()->Print(os);
0148     os << "fRight: [" << this->GetRight()->id() << "] ";
0149     this->GetRight()->GetUnplacedVolume()->Print(os);
0150     os << "\n";
0151   }
0152 
0153   VECCORE_ATT_DEVICE
0154   static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0155 #ifdef VECCORE_CUDA
0156                                const int id, const int copy_no, const int child_id,
0157 #endif
0158                                VPlacedVolume *const placement = NULL);
0159 
0160   VECCORE_ATT_HOST_DEVICE
0161   VPlacedVolume const *GetLeft() const { return fBoolean.fLeftVolume; }
0162   VECCORE_ATT_HOST_DEVICE
0163   VPlacedVolume const *GetRight() const { return fBoolean.fRightVolume; }
0164 
0165 #ifndef VECCORE_CUDA
0166   /** @brief Count number of Boolean nodes of different types under this Boolean volume */
0167   VECCORE_ATT_HOST_DEVICE
0168   size_t CountNodes(size_t &nunion, size_t &nintersection, size_t &nsubtraction) const
0169   {
0170     return BooleanHelper::CountBooleanNodes(this, nunion, nintersection, nsubtraction);
0171   }
0172 
0173   /** @brief Flatten the Boolean node structure and create multiple union volumes if possible */
0174   UnplacedMultiUnion *Flatten(size_t min_unions = 1, Transformation3D const *trbase = nullptr,
0175                               UnplacedMultiUnion *munion = nullptr)
0176   {
0177     return BooleanHelper::Flatten(this, min_unions, trbase, munion);
0178   }
0179 #endif
0180 
0181 private:
0182   VECCORE_ATT_DEVICE
0183   virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0184                                            Transformation3D const *const transformation,
0185 #ifdef VECCORE_CUDA
0186                                            const int id, const int copy_no, const int child_id,
0187 #endif
0188                                            VPlacedVolume *const placement = NULL) const override;
0189 
0190   void SetLeft(VPlacedVolume const *pvol) { fBoolean.fLeftVolume = pvol; }
0191   void SetRight(VPlacedVolume const *pvol) { fBoolean.fRightVolume = pvol; }
0192 
0193   friend class vecgeom::GeoManager;
0194 }; // End class
0195 
0196 } // namespace VECGEOM_IMPL_NAMESPACE
0197 
0198 } // namespace vecgeom
0199 
0200 #endif /* UNPLACEDBOOLEANVOLUME_H_ */