23 const std::shared_ptr<const TrackingVolumeArray>& containedVolumeArray,
24 const std::string& volumeName)
25 :
Volume(transform, std::move(volbounds)),
26 m_volumeMaterial(nullptr),
28 m_confinedLayers(nullptr),
29 m_confinedVolumes(containedVolumeArray),
38 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
39 std::unique_ptr<const LayerArray> staticLayerArray,
40 std::shared_ptr<const TrackingVolumeArray> containedVolumeArray,
42 const std::string& volumeName)
43 :
Volume(transform, std::move(volumeBounds)),
44 m_volumeMaterial(std::move(volumeMaterial)),
45 m_confinedLayers(std::move(staticLayerArray)),
46 m_confinedVolumes(std::move(containedVolumeArray)),
47 m_confinedDenseVolumes({}),
49 createBoundarySurfaces();
51 connectDenseBoundarySurfaces(denseVolumeVector);
57 std::vector<std::unique_ptr<Volume::BoundingBox>> boxStore,
58 std::vector<std::unique_ptr<const Volume>> descendants,
60 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
61 const std::string& volumeName)
62 :
Volume(transform, std::move(volbounds)),
63 m_volumeMaterial(std::move(volumeMaterial)),
65 m_descendantVolumes(std::move(descendants)),
70 for (
auto& uptr : boxStore) {
72 std::unique_ptr<Volume::BoundingBox>(uptr.release()));
77 delete m_glueVolumeDescriptor;
82 const double tol)
const {
84 if (m_confinedVolumes) {
85 return (m_confinedVolumes->object(position).get());
89 if (!m_confinedDenseVolumes.empty())
90 for (
auto& denseVolume : m_confinedDenseVolumes)
91 if (denseVolume->inside(position, tol))
92 return denseVolume.get();
100 return (m_boundarySurfaces);
105 if (!confinedDenseVolumes.empty()) {
108 for (
auto& confDenseVol : confinedDenseVolumes) {
110 auto& boundSur = confDenseVol->boundarySurfaces();
111 for (
unsigned int i = 0; i < boundSur.size(); i++) {
114 if (boundSur.at(i) ==
nullptr) {
123 if (mutableBs->m_oppositeVolume !=
nullptr &&
124 mutableBs->m_alongVolume ==
nullptr) {
126 mutableBs->attachVolume(
this, navDir);
128 if (mutableBs->m_oppositeVolume ==
nullptr &&
129 mutableBs->m_alongVolume !=
nullptr) {
131 mutableBs->attachVolume(
this, navDir);
139 m_confinedDenseVolumes.push_back(std::move(confDenseVol));
150 m_boundarySurfaces.reserve(orientedSurfaces.size());
151 for (
auto& osf : orientedSurfaces) {
159 m_boundarySurfaces.push_back(std::make_shared<const Boundary>(
160 std::move(osf.first), opposite, along));
174 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
175 boundarySurfaces().at(bsfMine);
179 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
185 if ((m_glueVolumeDescriptor ==
nullptr) ||
186 m_glueVolumeDescriptor->glueVolumes(bsfMine) ==
nullptr) {
188 auto mutableBSurfaceMine =
192 const Surface& neighborSurface =
195 const Surface& mySurface = bSurfaceMine->surfaceRepresentation();
198 if (myMaterial ==
nullptr and neighborMaterial !=
nullptr) {
209 const std::shared_ptr<TrackingVolumeArray>& neighbors,
213 std::shared_ptr<const TrackingVolume> nRefVolume =
214 neighbors->arrayObjects().at(0);
218 Vector3D(nRefVolume->binningPosition(gctx,
binR) - bPosition);
220 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
221 boundarySurfaces().at(bsfMine);
225 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
231 if ((m_glueVolumeDescriptor ==
nullptr) ||
232 !m_glueVolumeDescriptor->glueVolumes(bsfMine)) {
234 auto mutableBSurfaceMine =
238 for (
auto& nVolume : neighbors->arrayObjects()) {
240 (mutableNVolume->m_boundarySurfaces).
at(bsfNeighbor) = bSurfaceMine;
246 std::shared_ptr<const ISurfaceMaterial> surfaceMaterial,
248 auto bSurface = m_boundarySurfaces.at(bsFace);
256 bool checkmaterial) {
258 auto cMaterialPtr = m_boundarySurfaces.at(bsf)
259 ->surfaceRepresentation()
260 .surfaceMaterialSharedPtr();
261 auto bsMaterial = bs->surfaceRepresentation().surfaceMaterial();
262 if (cMaterialPtr !=
nullptr && bsMaterial ==
nullptr) {
267 m_boundarySurfaces.at(bsf) = std::move(bs);
272 delete m_glueVolumeDescriptor;
273 m_glueVolumeDescriptor = gvd;
277 if (m_glueVolumeDescriptor ==
nullptr) {
280 return (*m_glueVolumeDescriptor);
288 if (m_confinedLayers) {
292 for (
auto& clayIter : m_confinedLayers->arrayObjects()) {
307 if (m_confinedVolumes) {
311 for (
auto& cVolumesIter : m_confinedVolumes->arrayObjects()) {
312 cVolumesIter->synchronizeLayers(envelope);
318 if (m_confinedLayers) {
319 auto& layers = m_confinedLayers->arrayObjects();
323 const Layer* lastLayer =
nullptr;
324 for (
auto& layerPtr : layers) {
333 lastLayer = &mutableLayer;
337 for (
auto layerIter = layers.rbegin(); layerIter != layers.rend();
342 lastLayer = &mutableLayer;
349 std::map<std::string, const TrackingVolume*>& volumeMap,
size_t& vol) {
351 volumeMap[volumeName()] =
this;
360 if (materialDecorator !=
nullptr) {
361 materialDecorator->
decorate(*thisVolume);
363 if (thisVolume->volumeMaterial() ==
nullptr && thisVolume->motherVolume() &&
364 thisVolume->motherVolume()->volumeMaterial() !=
nullptr) {
366 thisVolume->motherVolume()->volumeMaterial());
367 if (protoMaterial ==
nullptr) {
368 thisVolume->assignVolumeMaterial(
369 thisVolume->motherVolume()->volumeMaterialSharedPtr());
373 this->assignGeometryId(volumeID);
377 for (
auto& bSurfIter : boundarySurfaces()) {
379 auto& bSurface = bSurfIter->surfaceRepresentation();
383 auto& mutableBSurface = *(
const_cast<Surface*
>(&bSurface));
384 mutableBSurface.assignGeometryId(boundaryID);
386 if (materialDecorator !=
nullptr) {
387 materialDecorator->
decorate(mutableBSurface);
392 if (!m_confinedVolumes) {
394 if (m_confinedLayers) {
397 for (
auto& layerPtr : m_confinedLayers->arrayObjects()) {
404 }
else if (m_bvhTop !=
nullptr) {
406 for (
const auto& descVol : m_descendantVolumes) {
410 if (avol !=
nullptr) {
412 for (
const auto& bnd : bndSrf) {
413 const auto& srf = bnd->surfaceRepresentation();
424 for (
auto& volumesIter : m_confinedVolumes->arrayObjects()) {
425 auto mutableVolumesIter =
428 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol);
432 if (!m_confinedDenseVolumes.empty()) {
433 for (
auto& volumesIter : m_confinedDenseVolumes) {
434 auto mutableVolumesIter =
437 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol);
443 const std::function<
void(
const Acts::Surface*)>& visitor)
const {
444 if (!m_confinedVolumes) {
446 if (m_confinedLayers) {
447 for (
const auto&
layer : m_confinedLayers->arrayObjects()) {
448 if (
layer->surfaceArray() ==
nullptr) {
452 for (
const auto& srf :
layer->surfaceArray()->surfaces()) {
459 for (
const auto&
volume : m_confinedVolumes->arrayObjects()) {
460 volume->visitSurfaces(visitor);
466 std::vector<Acts::BoundaryIntersection>
474 std::vector<BoundaryIntersection> bIntersections;
477 auto sDirection = options.
navDir * direction;
484 auto checkIntersection =
488 if (!sIntersection) {
493 << &bSurface->surfaceRepresentation());
495 ACTS_VERBOSE(
" -> pLimit, oLimit, cLimit: " << pLimit <<
", " << oLimit
505 std::copysign(1., options.
navDir);
517 ACTS_VERBOSE(
" -> pLimit, oLimit, cLimit: " << pLimit <<
", " << oLimit
519 withinLimit = (cLimit > oLimit and
524 std::copysign(1., options.
navDir);
539 auto processBoundaries =
543 for (
auto& bsIter : bSurfaces) {
545 const auto& bSurfaceRep = bsIter->surfaceRepresentation();
548 os <<
"Consider boundary surface " << &bSurfaceRep <<
" :\n";
549 std::stringstream strm;
550 bSurfaceRep.toStream(gctx, strm);
555 if (excludeObject != &bSurfaceRep) {
556 auto bCandidate = bSurfaceRep.intersect(gctx, position, sDirection,
559 auto bIntersection = checkIntersection(bCandidate, bsIter.get());
562 bIntersections.push_back(bIntersection);
573 auto& bSurfaces = boundarySurfaces();
574 ACTS_VERBOSE(
"Volume reports " << bSurfaces.size() <<
" boundary surfaces");
575 processBoundaries(bSurfaces);
578 auto confinedDenseVolumes = denseVolumes();
579 ACTS_VERBOSE(
"Volume reports " << confinedDenseVolumes.size()
580 <<
" confined dense volumes");
581 for (
const auto& dv : confinedDenseVolumes) {
582 auto& bSurfacesConfined = dv->boundarySurfaces();
583 ACTS_VERBOSE(
" -> " << bSurfacesConfined.size() <<
" boundary surfaces");
584 processBoundaries(bSurfacesConfined);
589 std::sort(bIntersections.begin(), bIntersections.end());
591 std::sort(bIntersections.begin(), bIntersections.end(), std::greater<>());
593 return bIntersections;
600 std::vector<LayerIntersection> lIntersections;
603 if (m_confinedLayers !=
nullptr) {
607 : associatedLayer(gctx, position);
608 while (tLayer !=
nullptr) {
617 auto atIntersection =
623 if (atIntersection &&
624 (atIntersection.object != options.
targetSurface) && withinLimit) {
627 atIntersection.intersection, tLayer, atIntersection.object));
638 std::sort(lIntersections.begin(), lIntersections.end());
640 std::sort(lIntersections.begin(), lIntersections.end(), std::greater<>());
644 return lIntersections;
648 template <
typename T>
649 std::vector<const Acts::Volume*> intersectSearchHierarchy(
651 std::vector<const Acts::Volume*> hits;
660 if (obb.intersect(obj.transformed(vol->
itransform()))) {
672 }
while (lnode !=
nullptr);
678 std::vector<Acts::SurfaceIntersection>
681 const Vector3D& direction,
double angle,
683 std::vector<SurfaceIntersection> sIntersections;
684 sIntersections.reserve(20);
690 if (m_bvhTop ==
nullptr || !options.
navDir) {
691 return sIntersections;
697 std::vector<const Volume*> hits;
700 Ray3D obj(position, sdir);
701 hits = intersectSearchHierarchy(std::move(obj), m_bvhTop);
704 hits = intersectSearchHierarchy(std::move(obj), m_bvhTop);
708 for (
const Volume* vol : hits) {
710 const std::vector<std::shared_ptr<const BoundarySurfaceT<AbstractVolume>>>&
712 for (
const auto& bs : boundarySurfaces) {
713 const Surface& srf = bs->surfaceRepresentation();
714 auto sfi = srf.
intersect(gctx, position, sdir,
false);
715 if (sfi and sfi.intersection.pathLength > oLimit and
716 sfi.intersection.pathLength <= pLimit) {
717 sIntersections.push_back(std::move(sfi));
724 std::sort(sIntersections.begin(), sIntersections.end());
726 std::sort(sIntersections.begin(), sIntersections.end(), std::greater<>());
729 return sIntersections;