1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
#ifndef UNPLACEDBOOLEANVOLUME_H_
#define UNPLACEDBOOLEANVOLUME_H_
#include "VecGeom/base/Cuda.h"
#include "VecGeom/base/Global.h"
#include "VecGeom/base/AlignedBase.h"
#include "VecGeom/base/Vector3D.h"
#include "VecGeom/volumes/UnplacedVolume.h"
#include "VecGeom/volumes/PlacedVolume.h"
#include "VecGeom/volumes/BooleanStruct.h"
#include "VecGeom/volumes/kernel/BooleanImplementation.h"
#include "VecGeom/volumes/UnplacedVolumeImplHelper.h"
#ifndef VECCORE_CUDA
#include "VecGeom/volumes/UnplacedMultiUnion.h"
#endif
namespace vecgeom {
VECGEOM_DEVICE_DECLARE_CONV_TEMPLATE_1v(class, UnplacedBooleanVolume, BooleanOperation, Arg1);
inline namespace VECGEOM_IMPL_NAMESPACE {
#ifndef VECCORE_CUDA
namespace BooleanHelper {
VECCORE_ATT_HOST_DEVICE
BooleanStruct const *GetBooleanStruct(VUnplacedVolume const *unplaced);
VECCORE_ATT_HOST_DEVICE
size_t CountBooleanNodes(VUnplacedVolume const *unplaced, size_t &nunion, size_t &nintersection, size_t &nsubtraction);
UnplacedMultiUnion *Flatten(VUnplacedVolume const *unplaced, size_t min_unions = 3,
Transformation3D const *trbase = nullptr, UnplacedMultiUnion *munion = nullptr);
} // namespace BooleanHelper
#endif
/**
* A class representing a simple UNPLACED boolean volume A-B
* It takes two template arguments:
* 1.: the mother (or left) volume A in unplaced form
* 2.: the (or right) volume B in placed form, acting on A with a boolean operation;
* the placement is with respect to the left volume
*
*
*
* will be a boolean solid where two boxes are subtracted
* and B is only translated (not rotated) with respect to A
*
*/
template <BooleanOperation Op>
class UnplacedBooleanVolume : public LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>, public AlignedBase {
public:
BooleanStruct fBoolean;
using LoopUnplacedVolumeImplHelper<BooleanImplementation<Op>>::fGlobalConvexity;
// the constructor
VECCORE_ATT_HOST_DEVICE
UnplacedBooleanVolume(BooleanOperation op, VPlacedVolume const *left, VPlacedVolume const *right)
: fBoolean(op, left, right)
{
fGlobalConvexity = false;
VUnplacedVolume::ComputeBBox();
#ifndef VECCORE_CUDA
if (fBoolean.fLeftVolume->IsAssembly() || fBoolean.fRightVolume->IsAssembly()) {
throw std::runtime_error("Trying to make boolean out of assembly which is not supported\n");
}
#endif
}
virtual int MemorySize() const override { return sizeof(*this); }
#ifdef VECGEOM_CUDA_INTERFACE
virtual size_t DeviceSizeOf() const override { return DevicePtr<cuda::UnplacedBooleanVolume<Op>>::SizeOf(); }
virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu() const override;
virtual DevicePtr<cuda::VUnplacedVolume> CopyToGpu(DevicePtr<cuda::VUnplacedVolume> const gpu_ptr) const override;
#endif
VECCORE_ATT_HOST_DEVICE
VECGEOM_FORCE_INLINE
BooleanOperation GetOp() const { return fBoolean.fOp; }
VECCORE_ATT_HOST_DEVICE
BooleanStruct const &GetStruct() const { return fBoolean; }
VECCORE_ATT_HOST_DEVICE
bool Normal(Vector3D<Precision> const &point, Vector3D<Precision> &normal) const override;
Precision Capacity() const override
{
if (fBoolean.fCapacity < 0.) {
fBoolean.fCapacity = VUnplacedVolume::EstimateCapacity(1000000);
}
return fBoolean.fCapacity;
}
Precision SurfaceArea() const override
{
if (fBoolean.fSurfaceArea < 0.) {
fBoolean.fSurfaceArea = VUnplacedVolume::EstimateSurfaceArea(1000000);
}
return fBoolean.fSurfaceArea;
}
VECCORE_ATT_HOST_DEVICE
void Extent(Vector3D<Precision> &aMin, Vector3D<Precision> &aMax) const override;
Vector3D<Precision> SamplePointOnSurface() const override;
std::string GetEntityType() const { return "BooleanVolume"; }
VECCORE_ATT_HOST_DEVICE
virtual void Print() const override{};
virtual void Print(std::ostream & /*os*/) const override{};
template <TranslationCode transCodeT, RotationCode rotCodeT>
VECCORE_ATT_DEVICE
static VPlacedVolume *Create(LogicalVolume const *const logical_volume, Transformation3D const *const transformation,
#ifdef VECCORE_CUDA
const int id, const int copy_no, const int child_id,
#endif
VPlacedVolume *const placement = NULL);
VECCORE_ATT_HOST_DEVICE
VPlacedVolume const *GetLeft() const { return fBoolean.fLeftVolume; }
VECCORE_ATT_HOST_DEVICE
VPlacedVolume const *GetRight() const { return fBoolean.fRightVolume; }
#ifndef VECCORE_CUDA
/** @brief Count number of Boolean nodes of different types under this Boolean volume */
VECCORE_ATT_HOST_DEVICE
size_t CountNodes(size_t &nunion, size_t &nintersection, size_t &nsubtraction) const
{
return BooleanHelper::CountBooleanNodes(this, nunion, nintersection, nsubtraction);
}
/** @brief Flatten the Boolean node structure and create multiple union volumes if possible */
UnplacedMultiUnion *Flatten(size_t min_unions = 1, Transformation3D const *trbase = nullptr,
UnplacedMultiUnion *munion = nullptr)
{
return BooleanHelper::Flatten(this, min_unions, trbase, munion);
}
#endif
private:
VECCORE_ATT_DEVICE
virtual VPlacedVolume *SpecializedVolume(LogicalVolume const *const volume,
Transformation3D const *const transformation,
const TranslationCode trans_code, const RotationCode rot_code,
#ifdef VECCORE_CUDA
const int id, const int copy_no, const int child_id,
#endif
VPlacedVolume *const placement = NULL) const override;
void SetLeft(VPlacedVolume const *pvol) { fBoolean.fLeftVolume = pvol; }
void SetRight(VPlacedVolume const *pvol) { fBoolean.fRightVolume = pvol; }
friend class GeoManager;
}; // End class
} // namespace VECGEOM_IMPL_NAMESPACE
} // namespace vecgeom
#endif /* UNPLACEDBOOLEANVOLUME_H_ */
|