31 #include <type_traits>
35 class ISurfaceMaterial;
40 const std::shared_ptr<const TrackingVolumeArray>& containedVolumeArray,
43 m_volumeMaterial(nullptr),
45 m_confinedLayers(nullptr),
46 m_confinedVolumes(containedVolumeArray),
55 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
56 std::unique_ptr<const LayerArray> staticLayerArray,
57 std::shared_ptr<const TrackingVolumeArray> containedVolumeArray,
61 m_volumeMaterial(std::
move(volumeMaterial)),
62 m_confinedLayers(std::
move(staticLayerArray)),
63 m_confinedVolumes(std::
move(containedVolumeArray)),
64 m_confinedDenseVolumes({}),
66 createBoundarySurfaces();
68 connectDenseBoundarySurfaces(denseVolumeVector);
74 std::vector<std::unique_ptr<Volume::BoundingBox>> boxStore,
75 std::vector<std::unique_ptr<const Volume>> descendants,
77 std::shared_ptr<const IVolumeMaterial> volumeMaterial,
80 m_volumeMaterial(std::
move(volumeMaterial)),
82 m_descendantVolumes(std::
move(descendants)),
87 for (
auto& uptr : boxStore) {
89 std::unique_ptr<Volume::BoundingBox>(uptr.release()));
94 delete m_glueVolumeDescriptor;
99 const double tol)
const {
101 if (m_confinedVolumes) {
102 return (m_confinedVolumes->object(position).get());
106 if (!m_confinedDenseVolumes.empty()) {
107 for (
auto& denseVolume : m_confinedDenseVolumes) {
108 if (denseVolume->inside(position, tol)) {
109 return denseVolume.get();
120 return (m_boundarySurfaces);
125 if (!confinedDenseVolumes.empty()) {
128 for (
auto& confDenseVol : confinedDenseVolumes) {
130 auto& boundSur = confDenseVol->boundarySurfaces();
131 for (
unsigned int i = 0;
i < boundSur.size();
i++) {
134 if (boundSur.at(
i) ==
nullptr) {
143 if (mutableBs->m_oppositeVolume !=
nullptr &&
144 mutableBs->m_alongVolume ==
nullptr) {
146 mutableBs->attachVolume(
this, dir);
148 if (mutableBs->m_oppositeVolume ==
nullptr &&
149 mutableBs->m_alongVolume !=
nullptr) {
151 mutableBs->attachVolume(
this, dir);
159 m_confinedDenseVolumes.push_back(
std::move(confDenseVol));
170 m_boundarySurfaces.reserve(orientedSurfaces.size());
171 for (
auto& osf : orientedSurfaces) {
179 m_boundarySurfaces.push_back(std::make_shared<const Boundary>(
193 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
194 boundarySurfaces().at(bsfMine);
198 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
203 if ((m_glueVolumeDescriptor ==
nullptr) ||
204 m_glueVolumeDescriptor->glueVolumes(bsfMine) ==
nullptr) {
206 auto mutableBSurfaceMine =
210 const Surface& neighborSurface =
213 const Surface& mySurface = bSurfaceMine->surfaceRepresentation();
216 if (myMaterial ==
nullptr and neighborMaterial !=
nullptr) {
227 const std::shared_ptr<TrackingVolumeArray>& neighbors,
231 std::shared_ptr<const TrackingVolume> nRefVolume =
232 neighbors->arrayObjects().at(0);
236 Vector3(nRefVolume->binningPosition(gctx,
binR) - bPosition);
238 std::shared_ptr<const BoundarySurfaceT<TrackingVolume>> bSurfaceMine =
239 boundarySurfaces().at(bsfMine);
243 bSurfaceMine->surfaceRepresentation().normal(gctx, bPosition);
248 if ((m_glueVolumeDescriptor ==
nullptr) ||
249 !m_glueVolumeDescriptor->glueVolumes(bsfMine)) {
251 auto mutableBSurfaceMine =
255 for (
auto& nVolume : neighbors->arrayObjects()) {
257 (mutableNVolume->m_boundarySurfaces).
at(bsfNeighbor) = bSurfaceMine;
263 std::shared_ptr<const ISurfaceMaterial> surfaceMaterial,
265 auto bSurface = m_boundarySurfaces.at(bsFace);
273 bool checkmaterial) {
275 auto cMaterialPtr = m_boundarySurfaces.at(bsf)
276 ->surfaceRepresentation()
277 .surfaceMaterialSharedPtr();
278 auto bsMaterial = bs->surfaceRepresentation().surfaceMaterial();
279 if (cMaterialPtr !=
nullptr && bsMaterial ==
nullptr) {
284 m_boundarySurfaces.at(bsf) =
std::move(bs);
289 delete m_glueVolumeDescriptor;
290 m_glueVolumeDescriptor = gvd;
294 if (m_glueVolumeDescriptor ==
nullptr) {
297 return (*m_glueVolumeDescriptor);
305 if (m_confinedLayers) {
309 for (
auto& clayIter : m_confinedLayers->arrayObjects()) {
324 if (m_confinedVolumes) {
328 for (
auto& cVolumesIter : m_confinedVolumes->arrayObjects()) {
329 cVolumesIter->synchronizeLayers(envelope);
335 if (m_confinedLayers) {
336 auto& layers = m_confinedLayers->arrayObjects();
340 const Layer* lastLayer =
nullptr;
341 for (
auto& layerPtr : layers) {
350 lastLayer = &mutableLayer;
354 for (
auto layerIter = layers.rbegin(); layerIter != layers.rend();
359 lastLayer = &mutableLayer;
366 std::unordered_map<GeometryIdentifier, const TrackingVolume*>& volumeMap,
373 ACTS_DEBUG(
"volumeID: " << volumeID <<
", name: " << volumeName());
375 volumeMap[volumeID] = thisVolume;
378 if (materialDecorator !=
nullptr) {
379 materialDecorator->
decorate(*thisVolume);
381 if (thisVolume->volumeMaterial() ==
nullptr &&
382 thisVolume->motherVolume() !=
nullptr &&
383 thisVolume->motherVolume()->volumeMaterial() !=
nullptr) {
385 thisVolume->motherVolume()->volumeMaterial());
386 if (protoMaterial ==
nullptr) {
387 thisVolume->assignVolumeMaterial(
388 thisVolume->motherVolume()->volumeMaterialSharedPtr());
392 this->assignGeometryId(volumeID);
396 for (
auto& bSurfIter : boundarySurfaces()) {
398 auto& bSurface = bSurfIter->surfaceRepresentation();
402 auto& mutableBSurface = *(
const_cast<Surface*
>(&bSurface));
403 mutableBSurface.assignGeometryId(boundaryID);
405 if (materialDecorator !=
nullptr) {
406 materialDecorator->
decorate(mutableBSurface);
411 if (!m_confinedVolumes) {
413 if (m_confinedLayers) {
416 for (
auto& layerPtr : m_confinedLayers->arrayObjects()) {
421 mutableLayerPtr->
closeGeometry(materialDecorator, layerID, hook,
424 }
else if (m_bvhTop !=
nullptr) {
426 for (
const auto& descVol : m_descendantVolumes) {
430 if (avol !=
nullptr) {
432 for (
const auto& bnd : bndSrf) {
433 const auto& srf = bnd->surfaceRepresentation();
444 for (
auto& volumesIter : m_confinedVolumes->arrayObjects()) {
445 auto mutableVolumesIter =
448 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol, hook,
453 if (!m_confinedDenseVolumes.empty()) {
454 for (
auto& volumesIter : m_confinedDenseVolumes) {
455 auto mutableVolumesIter =
458 mutableVolumesIter->closeGeometry(materialDecorator, volumeMap, vol, hook,
465 boost::container::small_vector<Acts::BoundaryIntersection, 4>
473 boost::container::small_vector<Acts::BoundaryIntersection, 4> bIntersections;
483 for (
const auto& sIntersection : smIntersection.
split()) {
484 if (!sIntersection) {
489 const bool coCriterion =
490 std::abs(sIntersection.pathLength()) < std::abs(oLimit);
492 << bSurface->surfaceRepresentation().geometryId());
496 << std::abs(sIntersection.pathLength())
497 <<
" < overstep limit " << std::abs(oLimit));
499 sIntersection.object(),
500 sIntersection.index());
504 << std::abs(sIntersection.pathLength())
505 <<
" > overstep limit " << std::abs(oLimit));
509 << bSurface->surfaceRepresentation().geometryId());
512 sIntersection.intersection(), pLimit, oLimit,
515 sIntersection.object(),
516 sIntersection.index());
525 auto processBoundaries =
529 for (
auto& bsIter : bSurfaces) {
531 const auto& bSurfaceRep = bsIter->surfaceRepresentation();
532 ACTS_VERBOSE(
"Consider boundary surface " << bSurfaceRep.geometryId()
534 << std::tie(bSurfaceRep, gctx));
537 if (excludeObject != &bSurfaceRep) {
538 auto bCandidate = bSurfaceRep.intersect(gctx, position, direction,
544 bIntersections.push_back(bIntersection);
555 auto& bSurfaces = boundarySurfaces();
556 ACTS_VERBOSE(
"Volume reports " << bSurfaces.size() <<
" boundary surfaces");
557 processBoundaries(bSurfaces);
560 auto confinedDenseVolumes = denseVolumes();
561 ACTS_VERBOSE(
"Volume reports " << confinedDenseVolumes.size()
562 <<
" confined dense volumes");
563 for (
const auto& dv : confinedDenseVolumes) {
564 auto& bSurfacesConfined = dv->boundarySurfaces();
565 ACTS_VERBOSE(
" -> " << bSurfacesConfined.size() <<
" boundary surfaces");
566 processBoundaries(bSurfacesConfined);
569 auto comparator = [](
double a,
double b) {
571 if ((a > 0 &&
b > 0) || (a < 0 &&
b < 0)) {
580 std::sort(bIntersections.begin(), bIntersections.end(),
581 [&](
const auto&
a,
const auto&
b) {
582 return comparator(a.pathLength(),
b.pathLength());
584 return bIntersections;
587 boost::container::small_vector<Acts::LayerIntersection, 10>
592 boost::container::small_vector<Acts::LayerIntersection, 10> lIntersections;
595 if (m_confinedLayers !=
nullptr) {
599 : associatedLayer(gctx, position);
600 while (tLayer !=
nullptr) {
609 auto atIntersection =
611 auto path = atIntersection.pathLength();
612 bool withinLimit = std::abs(
path) <= std::abs(options.
pathLimit);
614 if (atIntersection &&
615 (atIntersection.object() != options.
targetSurface) && withinLimit) {
618 atIntersection.intersection(), tLayer, atIntersection.object(),
619 atIntersection.index()));
625 : tLayer->
nextLayer(gctx, position, direction);
627 std::sort(lIntersections.begin(), lIntersections.end(),
631 return lIntersections;
635 template <
typename T>
636 std::vector<const Acts::Volume*> intersectSearchHierarchy(
638 std::vector<const Acts::Volume*> hits;
647 if (obb.intersect(obj.transformed(vol->
itransform()))) {
659 }
while (lnode !=
nullptr);
665 std::vector<Acts::SurfaceIntersection>
668 const Vector3& direction,
double angle,
670 std::vector<SurfaceIntersection> sIntersections;
671 sIntersections.reserve(20);
677 if (m_bvhTop ==
nullptr) {
678 return sIntersections;
681 std::vector<const Volume*> hits;
684 Ray3D obj(position, direction);
685 hits = intersectSearchHierarchy(
std::move(obj), m_bvhTop);
688 hits = intersectSearchHierarchy(
std::move(obj), m_bvhTop);
692 for (
const Volume* vol : hits) {
694 const std::vector<std::shared_ptr<const BoundarySurfaceT<AbstractVolume>>>&
696 for (
const auto& bs : boundarySurfaces) {
697 const Surface& srf = bs->surfaceRepresentation();
698 auto sfmi = srf.
intersect(gctx, position, direction,
false);
699 for (
const auto& sfi : sfmi.split()) {
700 if (sfi and sfi.pathLength() > oLimit and sfi.pathLength() <= pLimit) {
701 sIntersections.push_back(sfi);
708 std::sort(sIntersections.begin(), sIntersections.end(),
711 return sIntersections;