diff --git a/DDCore/include/DD4hep/DetectorImp.h b/DDCore/include/DD4hep/DetectorImp.h index c7c2f6e978cc1662e7512a18468210f166c5bcb4..ca3d4f16caee070338ed64e5d027438aea2a3960 100644 --- a/DDCore/include/DD4hep/DetectorImp.h +++ b/DDCore/include/DD4hep/DetectorImp.h @@ -92,9 +92,6 @@ namespace dd4hep { /// Local method (no interface): Load volume manager. void imp_loadVolumeManager(); - - /// Build reflections the ROOT way. To be called once the geometry is closed - void buildReflections(); /// Default constructor used by ROOT I/O DetectorImp(); diff --git a/DDCore/include/DD4hep/Volumes.h b/DDCore/include/DD4hep/Volumes.h index 4aaa34c93c9ed9513c34fbd4648a7cc22ff8705c..f15d175007dd497a4fb9fb456a42f25d1dc705cb 100644 --- a/DDCore/include/DD4hep/Volumes.h +++ b/DDCore/include/DD4hep/Volumes.h @@ -44,6 +44,28 @@ namespace dd4hep { class Volume; class PlacedVolume; + /// Scan geometry and create reflected volumes + /** + * Build reflections the ROOT way. To be called once the geometry is closed. + * + * For any further documentation please see the following ROOT documentation: + * \see http://root.cern.ch/root/html/TGeoManager.html + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_CORE + */ + class ReflectionBuilder { + Detector& detector; + public: + /// Initializing constructor + ReflectionBuilder(Detector& desc) : detector(desc) {} + /// Default descructor + ~ReflectionBuilder() = default; + /// Perform scan + void execute() const; + }; + /// Implementation class extending the ROOT placed volume /** * For any further documentation please see the following ROOT documentation: diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp index 60306c36df40288fb9c7d0b41c3714b39fcade1c..0d49b27aafc09b3830fd4fc3588ea665d80106de 100644 --- a/DDCore/src/DetectorImp.cpp +++ b/DDCore/src/DetectorImp.cpp @@ -652,27 +652,6 @@ namespace { }; } -/// Build reflections the ROOT way. To be called once the geometry is closed -void DetectorImp::buildReflections() { - TGeoIterator next(manager().GetTopVolume()); - TGeoNode *node; - while ((node=next())) { - TGeoMatrix* m = node->GetMatrix(); - if (m->IsReflection()) { - Volume vol(node->GetVolume()); - TGeoMatrix* mclone = new TGeoCombiTrans(*m); - mclone->RegisterYourself(); - // Reflect just the rotation component - mclone->ReflectZ(kFALSE, kTRUE); - TGeoNodeMatrix* nodematrix = (TGeoNodeMatrix*)node; - nodematrix->SetMatrix(mclone); - printout(INFO,"Detector","Reflecting volume: %s ",vol.name()); - Volume refl = vol.reflect(vol.sensitiveDetector()); - node->SetVolume(refl.ptr()); - } - } -} - /// Finalize/close the geometry void DetectorImp::endDocument(bool close_geometry) { TGeoManager* mgr = m_manager; diff --git a/DDCore/src/Volumes.cpp b/DDCore/src/Volumes.cpp index 454abad2a4bb86598a686eac9703c97e33b4c9e0..69f246aba4e44d312f3eaab5e4d8c81b5d1b6900 100644 --- a/DDCore/src/Volumes.cpp +++ b/DDCore/src/Volumes.cpp @@ -275,6 +275,28 @@ namespace { } + +/// Perform scan +void ReflectionBuilder::execute() const { + TGeoIterator next(detector.manager().GetTopVolume()); + TGeoNode *node; + while ( (node=next()) ) { + TGeoMatrix* m = node->GetMatrix(); + if (m->IsReflection()) { + Volume vol(node->GetVolume()); + TGeoMatrix* mclone = new TGeoCombiTrans(*m); + mclone->RegisterYourself(); + // Reflect just the rotation component + mclone->ReflectZ(kFALSE, kTRUE); + TGeoNodeMatrix* nodematrix = (TGeoNodeMatrix*)node; + nodematrix->SetMatrix(mclone); + printout(INFO,"Detector","Reflecting volume: %s ",vol.name()); + Volume refl = vol.reflect(vol.sensitiveDetector()); + node->SetVolume(refl.ptr()); + } + } +} + /// Default constructor PlacedVolume::Processor::Processor() { } diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index ac8d6948c3c50af1c24f957b3d5925e4e7d2dd6a..f5044b1c51b81134a8d399f53f2b176c4184f784 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -1463,6 +1463,7 @@ template <> void Converter<Compact>::operator()(xml_h element) const { bool open_geometry = true; bool close_document = true; bool close_geometry = true; + bool build_reflections = false; if (element.hasChild(_U(debug))) (Converter<Debug>(description))(xml_h(compact.child(_U(debug)))); @@ -1554,10 +1555,20 @@ template <> void Converter<Compact>::operator()(xml_h element) const { description.addConstant(Constant("compact_checksum", text)); description.endDocument(close_geometry); } + if ( build_reflections ) { + ReflectionBuilder rb(description); + rb.execute(); + } xml_coll_t(compact, _U(plugins)).for_each(_U(plugin), Converter<Plugin> (description)); } #ifdef _WIN32 + void buildReflections(); + +/// Build reflections the ROOT way. To be called once the geometry is closed +void DetectorImp::buildReflections() { +} + template Converter<Plugin>; template Converter<Constant>; template Converter<Material>; diff --git a/examples/ClientTests/eve/NestedBoxReflection.xml b/examples/ClientTests/eve/NestedBoxReflection.xml new file mode 100644 index 0000000000000000000000000000000000000000..86b1fa6287eb2c7e39b95c0a6a27cf23ec30e718 --- /dev/null +++ b/examples/ClientTests/eve/NestedBoxReflection.xml @@ -0,0 +1,19 @@ +<ddeve> + <display visLevel="7" loadLevel="3"/> + <collection name="NestedBoxHits" hits="PointSet" color="kMagenta" size="0.3" type="20"/> + <collection name="MCParticles" hits="Particles" size="0.2" width="1" type="kCircle"/> +<!-- + <view name="3D Trackers R-Phi (Global)" type="RhoPhiProjection"> + <detelement name="NestedBox" load_geo="-1" alpha="0.5"/> + </view> + + <view name="3D Trackers R-Phi (Local)" type="RhoPhiProjection"> + <detelement name="NestedBox" load_geo="3" alpha="0.5"/> + </view> + + <view name="3D Trackers" type="View3D"> + <detelement name="NestedBox" load_geo="-1" alpha="0.5"/> + </view> +--> + <include ref="${DD4hepExamplesINSTALL}/examples/ClientTests/compact/NestedBoxReflection.xml"/> +</ddeve>