File indexing completed on 2025-01-30 10:26:24
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 }
0037 #endif
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052 template <BooleanOperation Op>
0053 class UnplacedBooleanVolume : public LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>, public AlignedBase {
0054
0055 public:
0056 BooleanStruct fBoolean;
0057 using LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>::fGlobalConvexity;
0058
0059
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 virtual int MemorySize() const override { return sizeof(*this); }
0074
0075 #ifdef VECGEOM_CUDA_INTERFACE
0076 virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedBooleanVolume<Op>>::SizeOf(); }
0077 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
0078 virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
0079 #endif
0080
0081 VECCORE_ATT_HOST_DEVICE
0082 VECGEOM_FORCE_INLINE
0083 BooleanOperation GetOp() const { return fBoolean.fOp; }
0084
0085 VECCORE_ATT_HOST_DEVICE
0086 BooleanStruct const &GetStruct() const { return fBoolean; }
0087
0088 VECCORE_ATT_HOST_DEVICE
0089 bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
0090
0091 Precision Capacity() const override
0092 {
0093 if (fBoolean.fCapacity < 0.) {
0094 fBoolean.fCapacity = VUnplacedVolume::EstimateCapacity(1000000);
0095 }
0096 return fBoolean.fCapacity;
0097 }
0098
0099 Precision SurfaceArea() const override
0100 {
0101 if (fBoolean.fSurfaceArea < 0.) {
0102 fBoolean.fSurfaceArea = VUnplacedVolume::EstimateSurfaceArea(1000000);
0103 }
0104 return fBoolean.fSurfaceArea;
0105 }
0106
0107 VECCORE_ATT_HOST_DEVICE
0108 void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
0109
0110 Vector3D<Precision> SamplePointOnSurface() const override;
0111
0112 std::string GetEntityType() const { return "BooleanVolume"; }
0113
0114 VECCORE_ATT_HOST_DEVICE
0115 virtual void Print() const override {
0116 #ifndef VECCORE_CUDA
0117 auto op = this->GetOp();
0118 const char* opname = (op == kUnion ? "Union"
0119 : (op == kIntersection ? "Intersection" : "Subtraction"));
0120 printf("UnplacedBooleanVol<%s>{fLeft=[%i]<%s>, fRight=[%i]<%s>}", opname,
0121 this->GetLeft()->id(), this->GetLeft()->GetName(),
0122 this->GetRight()->id(), this->GetRight()->GetName());
0123 #else
0124 printf("UnplacedBooleanVol<%i>{fLeft=[%i], fRight=[%i]}",
0125 this->GetOp(), this->GetLeft()->id(), this->GetRight()->id());
0126 #endif
0127 printf("\nfLeft: [%i] ", this->GetLeft()->id());
0128 this->GetLeft()->GetUnplacedVolume()->Print();
0129 printf("\nfRight: [%i] ", this->GetRight()->id());
0130 this->GetRight()->GetUnplacedVolume()->Print();
0131 printf("\n");
0132 }
0133
0134 virtual void Print(std::ostream& os) const override {
0135 #ifndef VECCORE_CUDA
0136 auto op = this->GetOp();
0137 os << "UnplacedBooleanVol<"<< (op == kUnion ? "Union"
0138 : (op == kIntersection ? "Intersection" : "Subtraction"))
0139 <<">{fLeft=<"<< this->GetLeft()->id()
0140 << ">, fRight=<"<< this->GetRight()->id() <<">}\n";
0141 #endif
0142 os << "fLeft: [" << this->GetLeft()->id() <<"] ";
0143 this->GetLeft()->GetUnplacedVolume()->Print(os);
0144 os << "fRight: [" << this->GetRight()->id() <<"] ";
0145 this->GetRight()->GetUnplacedVolume()->Print(os);
0146 os <<"\n";
0147 }
0148
0149 template <TranslationCode transCodeT, RotationCode rotCodeT>
0150 VECCORE_ATT_DEVICE
0151 static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
0152 #ifdef VECCORE_CUDA
0153 const int id, const int copy_no, const int child_id,
0154 #endif
0155 VPlacedVolume *const placement = NULL);
0156
0157 VECCORE_ATT_HOST_DEVICE
0158 VPlacedVolume const *GetLeft() const { return fBoolean.fLeftVolume; }
0159 VECCORE_ATT_HOST_DEVICE
0160 VPlacedVolume const *GetRight() const { return fBoolean.fRightVolume; }
0161
0162 #ifndef VECCORE_CUDA
0163
0164 VECCORE_ATT_HOST_DEVICE
0165 size_t CountNodes(size_t &nunion, size_t &nintersection, size_t &nsubtraction) const
0166 {
0167 return BooleanHelper::CountBooleanNodes(this, nunion, nintersection, nsubtraction);
0168 }
0169
0170
0171 UnplacedMultiUnion *Flatten(size_t min_unions = 1, Transformation3D const *trbase = nullptr,
0172 UnplacedMultiUnion *munion = nullptr)
0173 {
0174 return BooleanHelper::Flatten(this, min_unions, trbase, munion);
0175 }
0176 #endif
0177
0178 private:
0179 VECCORE_ATT_DEVICE
0180 virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
0181 Transformation3D const *const transformation,
0182 const TranslationCode trans_code, const RotationCode rot_code,
0183 #ifdef VECCORE_CUDA
0184 const int id, const int copy_no, const int child_id,
0185 #endif
0186 VPlacedVolume *const placement = NULL) const override;
0187
0188 void SetLeft(VPlacedVolume const *pvol) { fBoolean.fLeftVolume = pvol; }
0189 void SetRight(VPlacedVolume const *pvol) { fBoolean.fRightVolume = pvol; }
0190
0191 friend class GeoManager;
0192 };
0193
0194 }
0195
0196 }
0197
0198 #endif