File indexing completed on 2025-12-16 09:24:24
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "ActsPlugins/GeoModel/GeoModelToDetectorVolume.hpp"
0010
0011 #include "Acts/Geometry/CuboidVolumeBounds.hpp"
0012 #include "Acts/Geometry/CutoutCylinderVolumeBounds.hpp"
0013 #include "Acts/Geometry/CylinderVolumeBounds.hpp"
0014 #include "Acts/Geometry/GeometryIdentifier.hpp"
0015 #include "Acts/Geometry/TrapezoidVolumeBounds.hpp"
0016
0017 #include <numbers>
0018
0019 #include <GeoModelHelpers/GeoShapeUtils.h>
0020 #include <GeoModelKernel/GeoBox.h>
0021 #include <GeoModelKernel/GeoPcon.h>
0022 #include <GeoModelKernel/GeoShapeShift.h>
0023 #include <GeoModelKernel/GeoShapeSubtraction.h>
0024 #include <GeoModelKernel/GeoShapeUnion.h>
0025 #include <GeoModelKernel/GeoSimplePolygonBrep.h>
0026 #include <GeoModelKernel/GeoTrd.h>
0027 #include <GeoModelKernel/GeoTube.h>
0028 #include <GeoModelKernel/GeoTubs.h>
0029 #include <GeoModelKernel/GeoVFullPhysVol.h>
0030
0031 using namespace Acts;
0032
0033 namespace ActsPlugins::GeoModel {
0034
0035 Transform3 volumePosInSpace(const PVConstLink& physVol) {
0036 if (auto fullPhys = dynamic_pointer_cast<const GeoVFullPhysVol>(physVol);
0037 fullPhys != nullptr) {
0038 return fullPhys->getAbsoluteTransform();
0039 }
0040
0041
0042
0043 class GeoVolumePositioner : public GeoNodePositioning {
0044 public:
0045 explicit GeoVolumePositioner(const GeoVPhysVol* physVol)
0046 : GeoNodePositioning{physVol} {}
0047 };
0048
0049 GeoVolumePositioner positioner{physVol};
0050 return positioner.getAbsoluteTransform();
0051 }
0052 std::shared_ptr<Volume> convertVolume(const Transform3& trf,
0053 const GeoShape* shape,
0054 VolumeBoundFactory& boundFactory) {
0055 assert(shape);
0056 std::shared_ptr<VolumeBounds> bounds{};
0057 GeoTrf::Transform3D newTrf = trf;
0058 const ShapeType id = shape->typeID();
0059 if (id == GeoTube::getClassTypeID()) {
0060 const auto* tube = dynamic_cast<const GeoTube*>(shape);
0061 bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0062 tube->getRMin(), tube->getRMax(), tube->getZHalfLength());
0063 } else if (id == GeoTubs::getClassTypeID()) {
0064 const auto* tubs = dynamic_cast<const GeoTubs*>(shape);
0065 bounds = boundFactory.makeBounds<CylinderVolumeBounds>(
0066 tubs->getRMin(), tubs->getRMax(), tubs->getZHalfLength(),
0067 tubs->getDPhi() / 2);
0068 newTrf = trf * GeoTrf::RotateZ3D(tubs->getSPhi() + 0.5 * tubs->getDPhi());
0069 } else if (id == GeoBox::getClassTypeID()) {
0070 const auto* box = dynamic_cast<const GeoBox*>(shape);
0071 bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0072 box->getXHalfLength(), box->getYHalfLength(), box->getZHalfLength());
0073 } else if (id == GeoSimplePolygonBrep::getClassTypeID() ||
0074
0075 id == GeoShapeUnion::getClassTypeID() ||
0076
0077 id == GeoPcon::getClassTypeID()) {
0078 double xmin{0}, xmax{0}, ymin{0}, ymax{0}, zmin{0}, zmax{0};
0079 shape->extent(xmin, ymin, zmin, xmax, ymax, zmax);
0080 bounds = boundFactory.makeBounds<CuboidVolumeBounds>(
0081 (xmax - xmin) / 2, (ymax - ymin) / 2, (zmax - zmin) / 2);
0082 } else if (id == GeoTrd::getClassTypeID()) {
0083 const auto* trd = dynamic_cast<const GeoTrd*>(shape);
0084 double x1 = trd->getXHalfLength1();
0085 double x2 = trd->getXHalfLength2();
0086 double y1 = trd->getYHalfLength1();
0087 double y2 = trd->getYHalfLength2();
0088 double z = trd->getZHalfLength();
0089 if (y1 == y2) {
0090 if (x1 <= x2) {
0091
0092 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x1, x2, z, y1);
0093 constexpr double rotationAngle = std::numbers::pi / 2.;
0094 newTrf = trf * GeoTrf::RotateX3D(rotationAngle);
0095 } else {
0096 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(x2, x1, z, y1);
0097 constexpr double rotationAngle = std::numbers::pi;
0098 newTrf = trf * GeoTrf::RotateY3D(rotationAngle) *
0099 GeoTrf::RotateZ3D(rotationAngle);
0100 }
0101 } else if (x1 == x2) {
0102 if (y1 < y2) {
0103 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y1, y2, z, x1);
0104 auto rotationAngle = std::numbers::pi / 2.;
0105 newTrf = trf * GeoTrf::RotateZ3D(rotationAngle) *
0106 GeoTrf::RotateX3D(rotationAngle);
0107 } else {
0108 bounds = boundFactory.makeBounds<TrapezoidVolumeBounds>(y2, y1, z, x1);
0109 auto rotationAngle = std::numbers::pi;
0110 newTrf = trf * GeoTrf::RotateX3D(rotationAngle) *
0111 GeoTrf::RotateZ3D(rotationAngle / 2) *
0112 GeoTrf::RotateX3D(rotationAngle / 2);
0113 }
0114 } else {
0115 throw std::runtime_error("convertVolume() - Translating the GeoTrd " +
0116 printGeoShape(shape) + " to ACTS failed");
0117 }
0118
0119 } else if (id == GeoShapeSubtraction::getClassTypeID()) {
0120 return convertVolume(newTrf, getOps(shape).first, boundFactory);
0121 } else if (id == GeoShapeShift::getClassTypeID()) {
0122 auto compressed = compressShift(shape);
0123 if (compressed->typeID() != GeoShapeShift::getClassTypeID()) {
0124 return convertVolume(newTrf, compressed, boundFactory);
0125 }
0126 const auto shiftShape =
0127 dynamic_pointer_cast<const GeoShapeShift>(compressed);
0128 const GeoShape* shapeOp = shiftShape->getOp();
0129 return convertVolume(newTrf * shiftShape->getX(), shapeOp, boundFactory);
0130 } else {
0131 throw std::runtime_error("Cannot convert " + printGeoShape(shape));
0132 }
0133 return std::make_shared<Volume>(newTrf, bounds);
0134 }
0135
0136 }