File indexing completed on 2025-07-06 07:54:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <DD4hep/Detector.h>
0016 #include <DD4hep/GeoHandler.h>
0017 #include <DD4hep/detail/ObjectsInterna.h>
0018
0019
0020 #include <TGeoManager.h>
0021 #include <TGeoCompositeShape.h>
0022 #include <TGeoBoolNode.h>
0023 #include <TClass.h>
0024
0025
0026
0027 using namespace dd4hep;
0028
0029 namespace {
0030
0031 void collectSolid(detail::GeoHandler::GeometryInfo& geo,
0032 const std::string& name,
0033 const std::string& node,
0034 TGeoShape* shape,
0035 TGeoMatrix* matrix)
0036 {
0037 if ( 0 == ::strncmp(shape->GetName(), "TGeo", 4) ) {
0038 shape->SetName(name.c_str());
0039 }
0040 if ( shape->IsA() == TGeoCompositeShape::Class() ) {
0041 const TGeoCompositeShape* s = (const TGeoCompositeShape*) shape;
0042 const TGeoBoolNode* boolean = s->GetBoolNode();
0043 collectSolid(geo, name + "_left", name + "_left", boolean->GetLeftShape(), boolean->GetLeftMatrix());
0044 collectSolid(geo, name + "_right", name + "_right", boolean->GetRightShape(), boolean->GetRightMatrix());
0045 }
0046 if(geo.solid_set.emplace(shape).second) {
0047 geo.solids.push_back(shape);
0048 }
0049 geo.trafos.emplace_back(node, matrix);
0050 }
0051 }
0052
0053
0054 detail::GeoHandler::GeoHandler() {
0055 m_data = new std::map<int, std::vector<const TGeoNode*> >();
0056 m_set_data = new std::map<int, std::set<const TGeoNode*> >();
0057 }
0058
0059
0060 detail::GeoHandler::GeoHandler(std::map<int, std::vector<const TGeoNode*> >* ptr,
0061 std::map<int, std::set<const TGeoNode*> >* ptr_set,
0062 std::map<const TGeoNode*, std::vector<TGeoNode*> >* daus)
0063 : m_data(ptr), m_set_data(ptr_set), m_daughters(daus)
0064 {
0065 }
0066
0067
0068 detail::GeoHandler::~GeoHandler() {
0069 if (m_data)
0070 delete m_data;
0071 if (m_set_data)
0072 delete m_set_data;
0073
0074 m_data = nullptr;
0075 m_set_data = nullptr;
0076 }
0077
0078 std::map<int, std::vector<const TGeoNode*> >* detail::GeoHandler::release() {
0079
0080 std::map<int, std::vector<const TGeoNode*> >* d = m_data;
0081 m_data = nullptr;
0082
0083
0084
0085
0086 delete m_set_data;
0087 m_set_data = nullptr;
0088
0089 return d;
0090 }
0091
0092
0093 bool detail::GeoHandler::setPropagateRegions(bool value) {
0094 bool old = m_propagateRegions;
0095 m_propagateRegions = value;
0096 return old;
0097 }
0098
0099 detail::GeoHandler& detail::GeoHandler::collect(DetElement element) {
0100 DetElement par = element.parent();
0101 TGeoNode* par_node = par.isValid() ? par.placement().ptr() : nullptr;
0102 m_data->clear();
0103 m_set_data->clear();
0104 return i_collect(par_node, element.placement().ptr(), 0, Region(), LimitSet());
0105 }
0106
0107 detail::GeoHandler& detail::GeoHandler::collect(DetElement element, GeometryInfo& info) {
0108 DetElement par = element.parent();
0109 TGeoNode* par_node = par.isValid() ? par.placement().ptr() : nullptr;
0110 m_data->clear();
0111 m_set_data->clear();
0112 i_collect(par_node, element.placement().ptr(), 0, Region(), LimitSet());
0113 for ( auto i = m_data->rbegin(); i != m_data->rend(); ++i ) {
0114 const auto& mapped = (*i).second;
0115 for ( const TGeoNode* n : mapped ) {
0116 TGeoVolume* v = n->GetVolume();
0117 if ( v ) {
0118 Material mat(v->GetMedium());
0119 Volume vol(v);
0120
0121 if ( info.volumeSet.find(vol) == info.volumeSet.end() ) {
0122 info.volumeSet.emplace(vol);
0123 info.volumes.emplace_back(vol);
0124 }
0125 if ( mat.isValid() )
0126 info.materials.emplace(mat);
0127 if (dynamic_cast<Volume::Object*>(v)) {
0128 VisAttr vis = vol.visAttributes();
0129
0130
0131
0132
0133 if (vis.isValid())
0134 info.vis.emplace(vis);
0135
0136
0137
0138 }
0139 collectSolid(info, v->GetName(), n->GetName(), v->GetShape(), n->GetMatrix());
0140 }
0141 }
0142 }
0143 return *this;
0144 }
0145
0146 detail::GeoHandler& detail::GeoHandler::i_collect(const TGeoNode* ,
0147 const TGeoNode* current,
0148 int level, Region rg, LimitSet ls)
0149 {
0150 TGeoVolume* vol = current->GetVolume();
0151 TObjArray* nodes = vol->GetNodes();
0152 Volume volume = vol;
0153 Region region = volume.region();
0154 LimitSet limits = volume.limitSet();
0155
0156 if ( m_propagateRegions ) {
0157 if ( !region.isValid() && rg.isValid() ) {
0158 region = rg;
0159 volume.setRegion(region);
0160 }
0161 if ( !limits.isValid() && ls.isValid() ) {
0162 limits = ls;
0163 volume.setLimitSet(limits);
0164 }
0165 }
0166
0167
0168 if ( (*m_set_data)[level].emplace(current).second ) {
0169 (*m_data)[level].push_back(current);
0170 }
0171 int num = nodes ? nodes->GetEntriesFast() : 0;
0172 for (int i = 0; i < num; ++i)
0173 i_collect(current, (TGeoNode*)nodes->At(i), level + 1, region, limits);
0174
0175 if ( m_daughters && m_daughters->find(current) == m_daughters->end() ) {
0176 auto [idau,success] = m_daughters->emplace(current, std::vector<TGeoNode*>());
0177 for (int i = 0; i < num; ++i)
0178 idau->second.push_back((TGeoNode*)nodes->At(i));
0179 }
0180 return *this;
0181 }
0182
0183
0184 detail::GeoScan::GeoScan(DetElement e) {
0185 m_data = GeoHandler().collect(e).release();
0186 }
0187
0188
0189 detail::GeoScan::GeoScan(DetElement e, bool propagate) {
0190 GeoHandler h;
0191 h.setPropagateRegions(propagate);
0192 m_data = h.collect(e).release();
0193 }
0194
0195
0196 detail::GeoScan::~GeoScan() {
0197 delete m_data;
0198 m_data = nullptr;
0199 }
0200
0201
0202 detail::GeoScan& detail::GeoScan::operator()() {
0203 return *this;
0204 }
0205