Belle II Software development
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
25using namespace Belle2;
26using namespace Belle2::TangoPalette;
27
28namespace {
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
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
106void 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
147void 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
160void EveGeometry::disableVolume(const char* name, bool only_daughters) { enableVolume(name, only_daughters, false); }
161
162void 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
218void EveGeometry::setCustomExtractPath(const std::string& extractPath)
219{
220 s_eveGeometryExtractPath = extractPath;
221}
222
223void EveGeometry::setHideVolumes(const std::vector<std::string>& volumes)
224{
225 s_hideVolumes = volumes;
226}
227
228void 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:151
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.