From 80b33d08692baa1d491ca6f870fc274e5fe22f06 Mon Sep 17 00:00:00 2001
From: Nicholas Styles <nicholas.styles@desy.de>
Date: Thu, 9 Jan 2025 17:37:20 +0100
Subject: [PATCH] Allow duplication of GeoAlignableTransforms for alignable
 elements

---
 .../GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h  | 2 +-
 .../GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx        | 4 ++--
 .../GeoModelXML/GeoModelXml/src/TransformProcessor.cxx     | 7 +++++--
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
index e4dde0f1f..1379f4bcf 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/GeoModelXml/Element2GeoItem.h
@@ -32,7 +32,7 @@ class Element2GeoItem: public GeoDeDuplicator {
 public:
     Element2GeoItem() = default;
     virtual ~Element2GeoItem() = default;
-    GeoIntrusivePtr<RCBase> process(const xercesc::DOMElement *element, GmxUtil &gmxUtil);
+    GeoIntrusivePtr<RCBase> process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, const bool &allowDuplication=false);
     virtual GeoIntrusivePtr<RCBase> make(const xercesc::DOMElement *element, GmxUtil &gmxUtil) const;
 protected:
     using EntryMap = std::map<std::string, GeoIntrusivePtr<RCBase>>;
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
index e780aac18..0716cda2c 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/Element2GeoItem.cxx
@@ -18,7 +18,7 @@ using namespace std;
 using namespace xercesc;
 
 
-GeoIntrusivePtr<RCBase> Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &gmxUtil) {
+GeoIntrusivePtr<RCBase> Element2GeoItem::process(const xercesc::DOMElement *element, GmxUtil &gmxUtil, const bool &allowDuplication) {
 
     char *name2release;
     XMLCh * name_tmp = XMLString::transcode("name");
@@ -30,7 +30,7 @@ GeoIntrusivePtr<RCBase> Element2GeoItem::process(const xercesc::DOMElement *elem
 
     GeoIntrusivePtr<RCBase> item{nullptr};
     EntryMap::iterator entry;
-    if (name.empty()) { // Unnamed item; cannot store in the map; make a new one 
+    if (name.empty() || allowDuplication) { // Unnamed item or an item that can be duplicated; cannot store in the map; make a new one 
         item = make(element, gmxUtil);
     } else if ((entry = m_map.find(name)) == m_map.end()) { // Not in; make a new one
         item = make(element, gmxUtil);
diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
index 85127dacb..097aa6bec 100644
--- a/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
+++ b/GeoModelTools/GeoModelXML/GeoModelXml/src/TransformProcessor.cxx
@@ -39,7 +39,7 @@ void TransformProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, Ge
     XMLCh * alignable_tmp;
 
     alignable_tmp = XMLString::transcode("alignable");
-    bool alignable = element->hasAttribute(alignable_tmp);
+    const bool alignable = element->hasAttribute(alignable_tmp);
     //
     //    Do second element first, to find what sort of transform is needed (shape or logvol etc.?)
     //
@@ -57,8 +57,11 @@ void TransformProcessor::process(const DOMElement *element, GmxUtil &gmxUtil, Ge
     tagName = XMLString::transcode(transformation->getTagName()); // transformation or transformationref
  
     // TODO:  ******* Should check here that an alignable transform is given an alignable transformation and object; to be done
+    // If alignable is true, this is passed on to Element2GeoItem::process in order to allow multiple transforms to be created with the same name
+    // This is necessary because we need an AlignableTransform for each element we want to align, even if the initial transform is identical.
+    // Without this, the de-duplication will return an already-exisiting transform if one already exists with that name
  
-    toAdd.push_back(dynamic_pointer_cast<GeoGraphNode>(gmxUtil.geoItemRegistry.find(string(tagName))->process(transformation, gmxUtil)));
+    toAdd.push_back(dynamic_pointer_cast<GeoGraphNode>(gmxUtil.geoItemRegistry.find(string(tagName))->process(transformation, gmxUtil, alignable)));
     XMLString::release(&tagName);
     //
     //    Add transformation to DetectorManager via GmxInterface, if it is alignable
-- 
GitLab