From 79bf759419587470cd18c46677b29ea28bd6c57d Mon Sep 17 00:00:00 2001 From: Johannes Josef Junggeburth <johannes.josef.junggeburth@cern.ch> Date: Fri, 17 Jan 2025 12:00:16 +0100 Subject: [PATCH] Add clone volume function --- .../GeoModelHelpers/GeoDeDuplicator.h | 8 +++- .../GeoModelHelpers/src/GeoDeDuplicator.cxx | 44 +++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h index 1e0dbd8c..547252a6 100644 --- a/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h +++ b/GeoModelCore/GeoModelHelpers/GeoModelHelpers/GeoDeDuplicator.h @@ -7,6 +7,9 @@ #include "GeoModelKernel/GeoPhysVol.h" #include "GeoModelKernel/GeoShape.h" #include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" #include "GeoModelKernel/GeoSerialIdentifier.h" #include "GeoModelKernel/GeoNameTag.h" #include "GeoModelKernel/GeoIdentifierTag.h" @@ -109,6 +112,10 @@ class GeoDeDuplicator { /** @brief Returns a new GeoIdentifier tag */ GeoIdPtr geoId(const int id) const; + /** @brief Clones a physical volume. All components in the tree are + * parsed through the deduplication chain */ + PVLink clone(PVConstLink vol) const; + /** @brief Toggles whether shape deduplication shall be enabled */ void setShapeDeDuplication(bool enable); /** @brief Toggles whether logVol deduplication shall be enabled */ @@ -117,7 +124,6 @@ class GeoDeDuplicator { void setTransformDeDuplication(bool enable); /** @brief Toggles whether physVol node deduplication shall be enabled */ void setPhysVolDeDuplication(bool enable); - /** @brief Clears the shared Shape / Transform / SerialId & NameTag cache */ static void clearSharedCaches(); private: diff --git a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx index f8ecad11..e4b88500 100644 --- a/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx +++ b/GeoModelCore/GeoModelHelpers/src/GeoDeDuplicator.cxx @@ -109,4 +109,48 @@ GeoDeDuplicator::GeoIdPtr GeoIdPtr newId = make_intrusive<GeoIdentifierTag>(id); s_geoIds.insert(std::make_pair(id, newId)); return newId; +} + +PVLink GeoDeDuplicator::clone(PVConstLink vol) const { + PVLink newVol{}; + bool tryPhysVolDeDup{m_deDuplicatePhysVol}; + GeoLogVolPtr logVol{const_cast<GeoLogVol*>(vol->getLogVol())}; + if (dynamic_cast<const GeoPhysVol*>(vol.get())) { + newVol = make_intrusive<GeoPhysVol>(cacheVolume(logVol)); + } else { + newVol = make_intrusive<GeoFullPhysVol>(cacheVolume(logVol)); + tryPhysVolDeDup = false; + } + for(unsigned int chNode =0; chNode < newVol->getNChildNodes(); ++chNode) { + GeoIntrusivePtr<const GeoGraphNode>node{*newVol->getChildNode(chNode)}; + /** transform nodes */ + if (typeid(*node) == typeid(GeoAlignableTransform)) { + const auto geoTrf = dynamic_pointer_cast<const GeoAlignableTransform>(node); + newVol->add(make_intrusive<GeoAlignableTransform>(geoTrf->getDefTransform())); + } else if (typeid(*node) == typeid(GeoTransform)) { + const auto geoTrf = dynamic_pointer_cast<const GeoTransform>(node); + auto geoTrfNonConst = const_pointer_cast(geoTrf); + newVol->add(cacheTransform(geoTrfNonConst)); + } + /** physical volumes */ + else if (auto physVol = dynamic_pointer_cast<const GeoVPhysVol>(node); physVol) { + newVol->add(clone(physVol)); + } else if (auto geoId = dynamic_pointer_cast<const GeoIdentifierTag>(node); geoId) { + std::lock_guard guard{s_mutex}; + newVol->add(s_geoIds.insert(std::make_pair(geoId->getIdentifier(), const_pointer_cast(geoId))).first->second); + } else if (auto serialId = dynamic_pointer_cast<const GeoSerialIdentifier>(node); serialId) { + std::lock_guard guard{s_mutex}; + newVol->add(s_serialIds.insert(std::make_pair(serialId->getBaseId(), const_pointer_cast(serialId))).first->second); + } else if (auto nameTag = dynamic_pointer_cast<const GeoNameTag>(node); nameTag) { + std::lock_guard guard{s_mutex}; + newVol->add(s_nameTags.insert(std::make_pair(nameTag->getName(), const_pointer_cast(nameTag))).first->second); + } else { + /// Just copy what's left + newVol->add(const_pointer_cast(node)); + } + } + if (tryPhysVolDeDup){ + newVol = cacheVolume(dynamic_pointer_cast<GeoPhysVol>(newVol)); + } + return newVol; } \ No newline at end of file -- GitLab