Belle II Software  release-08-01-10
EveGeometry.cc
1 /**************************************************************************
2  * basf2 (Belle II Analysis Software Framework) *
3  * Author: The Belle II Collaboration *
4  * *
5  * See git log for contributors and copyright holders. *
6  * This file is licensed under LGPL-3.0, see LICENSE.md. *
7  **************************************************************************/
8 #include <display/EveGeometry.h>
9 
10 #include <geometry/GeometryManager.h>
11 #include <framework/logging/Logger.h>
12 #include <framework/utilities/FileSystem.h>
13 #include <framework/utilities/ColorPalette.h>
14 
15 #include <TGeoManager.h>
16 #include <TPRegexp.h>
17 #include <TEveManager.h>
18 #include <TEveGeoNode.h>
19 #include <TEveGeoShape.h>
20 #include <TEveGeoShapeExtract.h>
21 #include <TFile.h>
22 
23 #include <cassert>
24 
25 using namespace Belle2;
26 using namespace Belle2::TangoPalette;
27 
28 namespace {
29  static TEveGeoTopNode* s_eveTopNode = nullptr;
30  static TEveGeoShape* s_simplifiedShape = nullptr;
31  static std::vector<std::string> s_hideVolumes = {};
32  static std::vector<std::string> s_deleteVolumes = {};
33  static std::string s_eveGeometryExtractPath = "/data/display/geometry_extract.root";
34 }
35 
37 {
38  B2DEBUG(100, "Setting up geometry for TEve...");
39  if (!gEve)
40  B2FATAL("gEve must be set up before EveGeometry!");
41 
42  if (visMode == c_Full) {
43  if (!gGeoManager) { //TGeo geometry not initialized, do it ourselves
44  //convert geant4 geometry to TGeo geometry
46  geoManager.createTGeoRepresentation();
47  if (!gGeoManager) {
48  B2FATAL("Couldn't create TGeo geometry! Please make sure you add the Geometry module before Display");
49  return;
50  }
51  }
52  //set colours by atomic mass number
53  gGeoManager->DefaultColors();
54 
55  setTransparency(90);
56  //set some nicer colors (at top level only)
57  setVolumeColor("PXD.Envelope", getTColorID("Chameleon", 2));
58  setVolumeColor("SVD.Envelope", getTColorID("Orange", 3));
59  setVolumeColor("logical_ecl", getTColorID("Orange", 1));
60  setVolumeColor("BKLM.EnvelopeLogical", getTColorID("Chameleon", 1));
61  setVolumeColor("Endcap_1", getTColorID("Chameleon", 1));
62  setVolumeColor("Endcap_2", getTColorID("Chameleon", 1));
63 
64  for (auto& volume : s_hideVolumes)
65  disableVolume(volume.c_str(), false);
66 
67  TGeoNode* top_node = gGeoManager->GetTopNode();
68  assert(top_node != NULL);
69  s_eveTopNode = new TEveGeoTopNode(gGeoManager, top_node);
70  s_eveTopNode->IncDenyDestroy();
71  s_eveTopNode->SetVisLevel(2);
72 
73  gEve->AddGlobalElement(s_eveTopNode);
74 
75  //expand geometry in eve list (otherwise one needs three clicks to see that it has children)
76  s_eveTopNode->ExpandIntoListTreesRecursively();
77 
78  }
79  B2DEBUG(100, "Loading geometry projections...");
80 
81  const std::string extractPath = FileSystem::findFile(s_eveGeometryExtractPath);
82  TFile* f = TFile::Open(extractPath.c_str(), "READ");
83  TEveGeoShapeExtract* gse = dynamic_cast<TEveGeoShapeExtract*>(f->Get("Extract"));
84  s_simplifiedShape = TEveGeoShape::ImportShapeExtract(gse, 0);
85  s_simplifiedShape->SetRnrSelf(false);
86  s_simplifiedShape->IncDenyDestroy();
87  s_simplifiedShape->SetName("Minimal geometry extract");
88  delete f;
89 
90  //I want to show full geo in unprojected view,
91  //but I still need to add the extract to the geometry scene...
92  gEve->AddGlobalElement(s_simplifiedShape);
93 
94  setVisualisationMode(visMode);
95 
96  // Allow deletion only for full geometry
97  if (s_eveTopNode) {
98  for (auto& volumeRegExp : s_deleteVolumes) {
99  removeChildrenByRegExp(s_eveTopNode, volumeRegExp);
100  }
101  }
102 
103  B2DEBUG(100, "Done.");
104 }
105 
106 void EveGeometry::removeChildrenByRegExp(TEveElement* parent, const std::string& pattern)
107 {
108  TPRegexp reAll(".*");
109  bool onlyChildren = false;
110  std::string regexp = pattern;
111 
112  // For patterns with leading '#', do delete only
113  // children elements (and remove the '#' for regexp)
114  if (pattern.substr(0, 1) == std::string("#")) {
115  regexp = pattern.substr(1);
116  onlyChildren = true;
117  }
118 
119  TPRegexp reMatch(regexp.c_str());
120 
121  std::list<TEveElement*> children;
122  parent->FindChildren(children, reAll);
123 
124  for (TEveElement* child : children) {
125  if (reMatch.MatchB(child->GetElementName())) {
126  if (onlyChildren) {
127  B2INFO("Removing children of " << child->GetElementName());
128  child->DestroyElements();
129  } else {
130  B2INFO("Removing " << child->GetElementName());
131  child->Destroy();
132  }
133  } else {
134  removeChildrenByRegExp(child, pattern);
135  }
136  }
137 }
138 
140 {
141  bool fullgeo = (visMode == c_Full);
142  if (s_eveTopNode)
143  s_eveTopNode->SetRnrSelfChildren(fullgeo, fullgeo);
144  s_simplifiedShape->SetRnrSelfChildren(false, !fullgeo);
145 }
146 
147 void EveGeometry::enableVolume(const char* name, bool only_daughters, bool enable)
148 {
149  if (!gGeoManager) return;
150  TGeoVolume* vol = gGeoManager->FindVolumeFast(name);
151  if (vol) {
152  if (!only_daughters)
153  vol->SetVisibility(enable);
154  vol->SetVisDaughters(enable);
155  } else {
156  B2DEBUG(100, "Volume " << name << " not found?");
157  }
158 }
159 
160 void EveGeometry::disableVolume(const char* name, bool only_daughters) { enableVolume(name, only_daughters, false); }
161 
162 void EveGeometry::setVolumeColor(const char* name, Color_t col)
163 {
164  if (!gGeoManager) return;
165  TGeoVolume* vol = gGeoManager->FindVolumeFast(name);
166  if (vol) {
167  //while TGeoVolume derives from TAttFill, the line color actually is important here
168  vol->SetLineColor(col);
169  } else {
170  B2DEBUG(100, "Volume " << name << " not found?");
171  }
172 }
173 
175 {
176  if (!gGeoManager) return;
177  TObjArray* volumes = gGeoManager->GetListOfVolumes();
178  for (int i = 0; i < volumes->GetEntriesFast(); i++) {
179  TGeoVolume* volume = static_cast<TGeoVolume*>(volumes->At(i));
180  volume->SetTransparency(percent);
181  }
182 }
183 
185 {
186  if (gGeoManager && gGeoManager->GetTopNode()) {
187  TGeoVolume* top_node = gGeoManager->GetTopNode()->GetVolume();
188  double p[3] = { 380.0, 0.0, 0.0 }; //ok for normal Belle II geometry
189  while (!top_node->Contains(p)) {
190  p[0] *= 0.8;
191  }
192  return p[0];
193  } else if (s_simplifiedShape) {
194  s_simplifiedShape->ComputeBBox();
195  const float* bbox = s_simplifiedShape->GetBBox();
196  return std::min(380.f, std::max({std::abs(bbox[0]), bbox[1], std::abs(bbox[2]), bbox[2]}));
197  }
198  // fallback to something reasonable
199  return 380.;
200 }
201 
203 {
204  TGeoManager* my_tgeomanager = gGeoManager;
205  if (!s_eveTopNode) {
206  B2ERROR("Couldn't find TEveGeoTopNode");
207  return;
208  }
209  s_eveTopNode->ExpandIntoListTrees();
210  s_eveTopNode->SaveExtract("geometry_extract.root", "Extract", false);
211 
212  //this doesn't work too well (i.e. crashes when geometry is drawn)
213  //s_eveTopNode->ExpandIntoListTreesRecursively();
214  //s_eveTopNode->SaveExtract("display_geometry_full.root", "Extract", false);
215  gGeoManager = my_tgeomanager;
216 }
217 
218 void EveGeometry::setCustomExtractPath(const std::string& extractPath)
219 {
220  s_eveGeometryExtractPath = extractPath;
221 }
222 
223 void EveGeometry::setHideVolumes(const std::vector<std::string>& volumes)
224 {
225  s_hideVolumes = volumes;
226 }
227 
228 void EveGeometry::setDeleteVolumes(const std::vector<std::string>& volumes)
229 {
230  s_deleteVolumes = volumes;
231 }
static std::string findFile(const std::string &path, bool silent=false)
Search for given file or directory in local or central release directory, and return absolute path if...
Definition: FileSystem.cc:148
Class to manage the creation and conversion of the geometry.
static GeometryManager & getInstance()
Return a reference to the instance.
void createTGeoRepresentation()
Create a TGeo representation of the native geometry description.
void setVolumeColor(const char *name, Color_t col)
set fill color of the volume 'name' to 'col'.
Definition: EveGeometry.cc:162
void setTransparency(int percent)
Recursively set transparency of geometry (0: opaque, 100: fully transparent).
Definition: EveGeometry.cc:174
void disableVolume(const char *name, bool only_daughters=false)
disable rendering of the volume 'name', or only its daughters if only_daughters is set.
Definition: EveGeometry.cc:160
void addGeometry(EType visMode)
Add TGeo geometry to Eve (only needs to be done once.)
Definition: EveGeometry.cc:36
void setDeleteVolumes(const std::vector< std::string > &volumes)
List of volumes to be removed.
Definition: EveGeometry.cc:228
void setVisualisationMode(EType visMode)
switch to given visualisation mode.
Definition: EveGeometry.cc:139
void enableVolume(const char *name, bool only_daughters=false, bool enable=true)
enable/disable rendering of the volume 'name', or only its daughters if only_daughters is set.
Definition: EveGeometry.cc:147
void setCustomExtractPath(const std::string &extractPath)
Set custom path to the geometry extract (to change originally hard-coded value)
Definition: EveGeometry.cc:218
void setHideVolumes(const std::vector< std::string > &volumes)
List of volumes to be hidden (can be re-enabled in Eve panel / Geometry scene.
Definition: EveGeometry.cc:223
void saveExtract()
Save a geometry extract from the current state of the TGeo geometry.
Definition: EveGeometry.cc:202
EType
Type of geometry shown.
Definition: EveGeometry.h:25
@ c_Full
Full geometry converted from Geant4 (use this for non-standard Belle II setups!).
Definition: EveGeometry.h:26
void removeChildrenByRegExp(TEveElement *parent, const std::string &pattern)
Recursive removal of volumes based on regular expression pattern.
Definition: EveGeometry.cc:106
double getMaxR()
find a point that is inside the top node.
Definition: EveGeometry.cc:184
Implements a colour palette, see http://sobac.com/sobac/tangocolors.htm.
Definition: ColorPalette.h:23
int getTColorID(const std::string &tangoName, int tangoId=1)
Get TColor ID for given name in tango colour palette.
Definition: ColorPalette.cc:39
Abstract base class for different kinds of events.