diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h new file mode 100644 index 0000000000000000000000000000000000000000..944e1a0c4238eb4250e84c897278885906791234 --- /dev/null +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/cloneVolume.h @@ -0,0 +1,18 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELUTILS_CLONEVOLUME_H +#define GEOMODELUTILS_CLONEVOLUME_H +#include "GeoModelKernel/GeoVPhysVol.h" + + +/** @brief Creates a deep copy of the physical volume if the volume hosts full physical volumes in its subtrees + * or if the allowShared flag is disabled. GeoNameTags, GeoTransforms etc. are appended to the new + * physical volume + * @param volume: Link to the Volume to clone + * @param allowShared: Switch to allow that GeoPhysVols that don't host GeoFullPhysVols are simply moved to the copied + * volume and hence become shared objects. +*/ +PVLink cloneVolume(PVLink volume, bool allowShared = true); + +#endif diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h index 78e79a6b8e599fbcc2ba08eaaeb1312ac84af443..f8818abcf9398a608f7a2e93e45e954a2ddad447 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/getChildNodesWithTrf.h @@ -32,8 +32,15 @@ struct GeoChildNodeWithTrf { GeoChildNodeWithTrf(GeoVolumeCursor& curs); }; -std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink& physVol, +std::vector <GeoChildNodeWithTrf> getChildrenWithRef (PVConstLink physVol, bool summarizeEqualVol = true); +/** + * Returns whether a volume has fullPhysical volume nodes in + * it's children and grand children tree +*/ +bool hasFullPhysVolInTree(PVConstLink physVol); + + #endif \ No newline at end of file diff --git a/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx b/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ef8fc56bb9fb835a3387e0e45ba5304744dcb759 --- /dev/null +++ b/GeoModelCore/GeoModelHelpers/src/cloneVolume.cxx @@ -0,0 +1,32 @@ + +#include "GeoModelHelpers/cloneVolume.h" +#include "GeoModelHelpers/getChildNodesWithTrf.h" + +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoPhysVol.h" + +PVLink cloneVolume(PVLink volume, + bool allowShared) { + PVLink newVolume{volume}; + if (!allowShared || hasFullPhysVolInTree(volume)) { + if (typeid(*volume) == typeid(GeoPhysVol)) { + newVolume = new GeoPhysVol(volume->getLogVol()); + } else if (typeid(*volume) == typeid(GeoFullPhysVol)) { + newVolume = new GeoFullPhysVol(volume->getLogVol()); + } + for (unsigned int ch = 0; ch < volume->getNChildNodes(); ++ch){ + const GeoGraphNode* node = (*volume->getChildNode(ch)); + + if (typeid(*node) == typeid(GeoPhysVol) || typeid(*node) == typeid(GeoFullPhysVol)) { + const GeoVPhysVol* childConstVol{static_cast<const GeoVPhysVol*>(node)}; + GeoVPhysVol* childVol{const_cast<GeoVPhysVol*>(childConstVol)}; + newVolume->add(cloneVolume(childVol, allowShared)); + } else { + newVolume->add(const_cast<GeoGraphNode*>(node)); + } + } + + } + return newVolume; + +} \ No newline at end of file diff --git a/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx b/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx index b28b918a7a3256e75c41ef2523d96fb4ec491319..ebf851eaffd7f0fc4e5229094280c474ee5c1e00 100644 --- a/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx +++ b/GeoModelCore/GeoModelHelpers/src/defineWorld.cxx @@ -2,6 +2,7 @@ Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration */ #include "GeoModelHelpers/defineWorld.h" +#include "GeoModelHelpers/cloneVolume.h" #include "GeoModelKernel/GeoElement.h" #include "GeoModelKernel/GeoMaterial.h" #include "GeoModelKernel/GeoBox.h" @@ -42,97 +43,52 @@ GeoIntrusivePtr<GeoPhysVol> createGeoWorld(const double worldBoxX, return world; } -GeoIntrusivePtr<GeoPhysVol> resizeGeoWorld(GeoIntrusivePtr<GeoPhysVol> world) -{ - if (world) - { - //resize the world volume to the real needed volume - - // get number of children volumes - unsigned int nChild=world->getNChildVols(); - - //Dimensions of the bounding boxes - double xmin=0.,ymin=0.,zmin=0.,xmax=0.,ymax=0.,zmax=0.; - double xworld=0.,yworld=0.,zworld=0.; +GeoIntrusivePtr<GeoPhysVol> resizeGeoWorld(GeoIntrusivePtr<GeoPhysVol> world) { + if (!world) return world; + + //resize the world volume to the real needed volume + + // get number of children volumes + unsigned int nChild=world->getNChildVols(); + + //Dimensions of the bounding boxes + double xmin=0.,ymin=0.,zmin=0.,xmax=0.,ymax=0.,zmax=0.; + double xworld=0.,yworld=0.,zworld=0.; - // loop over all children volumes - for (unsigned int i=0; i<nChild; i++) + // loop over all children volumes + for (unsigned int i=0; i<nChild; i++) { + PVConstLink nodeLink = world->getChildVol(i); + if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) ) { - PVConstLink nodeLink = world->getChildVol(i); - if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) ) - { - const GeoVPhysVol *childVolV = &(*( nodeLink )); - - if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) { - const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV); - childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax); - } - else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) { - const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV); - childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax); - - } - xworld=std::max({xworld,std::abs(xmin),std::abs(xmax)}); - yworld=std::max({yworld,std::abs(ymin),std::abs(ymax)}); - zworld=std::max({zworld,std::abs(zmin),std::abs(zmax)}); - } - } - - GeoIntrusivePtr<GeoPhysVol> resizedWorld{createGeoWorld(xworld, yworld, zworld)}; - - for (unsigned int i=0; i< world->getNChildNodes(); i++){ - const GeoGraphNode * node = *(world->getChildNode(i)); - - - if (dynamic_cast<const GeoVPhysVol*>( node )) - { - if ( dynamic_cast<const GeoFullPhysVol*>(node) ){ - const GeoFullPhysVol* nodeFullPhysVol = dynamic_cast<const GeoFullPhysVol*>(node); - resizedWorld->add((GeoGraphNode *)nodeFullPhysVol); - - } - else if ( dynamic_cast<const GeoPhysVol*>(node) ){ - const GeoPhysVol* nodePhysVol = dynamic_cast<const GeoPhysVol*>(node); - resizedWorld->add((GeoGraphNode *)nodePhysVol); - - } - } - else if (dynamic_cast<const GeoNameTag*>( node )){ - const GeoNameTag* nodeTag = dynamic_cast<const GeoNameTag*>(node); - resizedWorld->add((GeoGraphNode *)nodeTag); - - } + const GeoVPhysVol *childVolV = &(*( nodeLink )); - else if (dynamic_cast<const GeoAlignableTransform*>( node )){ - const GeoAlignableTransform* nodeAT = dynamic_cast<const GeoAlignableTransform*>(node); - resizedWorld->add((GeoGraphNode *)nodeAT); - + if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) { + const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV); + childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax); } - - else if (dynamic_cast<const GeoSerialTransformer*>( node )){ - const GeoSerialTransformer* nodeST = dynamic_cast<const GeoSerialTransformer*>(node); - resizedWorld->add((GeoGraphNode *)nodeST); - - } - - else if (dynamic_cast<const GeoSerialDenominator*>( node )){ - const GeoSerialDenominator* nodeSD = dynamic_cast<const GeoSerialDenominator*>(node); - resizedWorld->add((GeoGraphNode *)nodeSD); - - } - else if (dynamic_cast<const GeoTransform*>( node )){ - const GeoTransform* nodeTransform = dynamic_cast<const GeoTransform*>(node); - resizedWorld->add((GeoGraphNode *)nodeTransform); - - }else if (dynamic_cast<const GeoIdentifierTag*>( node )){ - const GeoIdentifierTag* nodeIT = dynamic_cast<const GeoIdentifierTag*>(node); - resizedWorld->add((GeoGraphNode *)nodeIT); + else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) { + const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV); + childVol->getLogVol()->getShape()->extent(xmin, ymin, zmin, xmax, ymax, zmax); } + xworld=std::max({xworld,std::abs(xmin),std::abs(xmax)}); + yworld=std::max({yworld,std::abs(ymin),std::abs(ymax)}); + zworld=std::max({zworld,std::abs(zmin),std::abs(zmax)}); } - - return resizedWorld; - } - return world; + + GeoIntrusivePtr<GeoPhysVol> resizedWorld{createGeoWorld(xworld, yworld, zworld)}; + for (unsigned int ch = 0; ch < world->getNChildNodes(); ++ch) { + const GeoGraphNode * node = *(world->getChildNode(ch)); + if (typeid(*node) == typeid(GeoFullPhysVol) || + typeid(*node) == typeid(GeoPhysVol)) { + const GeoVPhysVol* subVol{dynamic_cast<const GeoVPhysVol*>(node)}; + GeoVPhysVol* nonConstVol{const_cast<GeoVPhysVol*>(subVol)}; + resizedWorld->add(cloneVolume(nonConstVol)); + } else { + resizedWorld->add(const_cast<GeoGraphNode*>(node)); + } + } + + return resizedWorld; } diff --git a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx index cc16ee76af27c4f6934cefae40ab664a5fe2e2a1..91389b27acf0a9865133fd84f4108e25d4100f83 100644 --- a/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx +++ b/GeoModelCore/GeoModelHelpers/src/getChildNodesWithTrf.cxx @@ -26,7 +26,7 @@ namespace { } } -std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink& physVol, +std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink physVol, bool summarizeEqualVol) { std::vector<GeoChildNodeWithTrf> children{}; @@ -64,3 +64,14 @@ std::vector <GeoChildNodeWithTrf> getChildrenWithRef(PVConstLink& physVol, } return children; } +bool hasFullPhysVolInTree(PVConstLink physVol) { + if (typeid(*physVol) == typeid(GeoFullPhysVol) || + typeid(*physVol) == typeid(GeoVFullPhysVol)){ + return true; + } + for (unsigned int ch = 0; ch < physVol->getNChildVols(); ++ch) { + if (hasFullPhysVolInTree(physVol->getChildVol(ch))) return true; + } + + return false; +} \ No newline at end of file