CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
eve_macros.cc
Go to the documentation of this file.
1 #include <vector>
2 #include <list>
3 #include <string>
4 #include <cmath>
5 
6 #include <TEveElement.h>
7 #include <TEveGeoNode.h>
8 #include <TGeoNode.h>
9 
10 #include "eve_macros.h"
11 
12 // get the name from an object derived from both TEveElement and TNamed
13 const char* get_name( const TEveElement * element ) {
14  // try as a TEveGeoNode or TEveGeoShape
15  if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element ))
16  return node->GetName();
17  if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element ))
18  return shape->GetName();
19 
20  // try to access the element as a generic named object
21  if (const TNamed * named = dynamic_cast<const TNamed *>( element ))
22  return named->GetName();
23 
24  return 0;
25 }
26 
27 // get the title from an object derived from both TEveElement and TNamed
28 const char* get_title( const TEveElement * element ) {
29  // try as a TEveGeoNode or TEveGeoShape
30  if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element ))
31  return node->GetTitle();
32  if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element ))
33  return shape->GetTitle();
34 
35  // try to access the element as a generic named object
36  if (const TNamed * named = dynamic_cast<const TNamed *>( element ))
37  return named->GetTitle();
38 
39  return 0;
40 }
41 
42 // force a node to expand its internal reprsentation, so all children are actually present
43 void expand_node( TEveElement * element )
44 {
45  // force a TEveGeoNode to load all its children
46  if (TEveGeoNode * node = dynamic_cast<TEveGeoNode *>( element )) {
47  if (node->GetNChildren() == 0 && node->GetNode()->GetVolume()->GetNdaughters() > 0) {
48  TIter next(node->GetNode()->GetVolume()->GetNodes());
49  TGeoNode* dnode;
50  while ((dnode = (TGeoNode*) next()) != 0) {
51  TEveGeoNode* node_re = new TEveGeoNode(dnode);
52  node->AddElement(node_re);
53  }
54  }
55  return;
56  }
57  // a TEveGeoShape is always exanded
58  //if (TEveGeoShape * shape __attribute__ ((unused)) = dynamic_cast<TEveGeoShape *>( element )) {
59  // return;
60  //}
61  // a generic TEveElement has no knwledge on children expansion
62  return;
63 }
64 
65 // retrieves a TShape from a TEveElement
66 const TGeoShape * get_shape( const TEveElement * element ) {
67  // a TEveGeoNode, can look into its TGeoNode and retrieve the shape
68  if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
69  return node->GetNode()->GetVolume()->GetShape();
70  }
71  // a TEveGeoShape owns its shape
72  if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
73  TEveGeoShape * nc_shape = const_cast<TEveGeoShape *>( shape );
74  return const_cast<const TGeoShape *>( nc_shape->GetShape() );
75  }
76  // a TEveElement is too generic, no way to get a shape
77  return 0;
78 }
79 
80 // overloaded non-const TShape retrieval, allowed from a TGeoShape only
81 TGeoShape * get_shape( TEveElement * element ) {
82  // a TEveGeoNode cannot modify its shape
83  //if (const TEveGeoNode * node __attribute__ ((unused)) = dynamic_cast<const TEveGeoNode *>( element )) {
84  // return 0;
85  //}
86  // a TEveGeoShape owns its shape, and can modifiy it
87  if (TEveGeoShape * shape = dynamic_cast<TEveGeoShape *>( element )) {
88  return shape->GetShape();
89  }
90  // a TEveElement is too generic, no way to get a shape
91  return 0;
92 }
93 
94 // return a copy of the local-to-global transformation applied to a TEveElement
95 TGeoMatrix * get_transform( const TEveElement * element ) {
96  if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
97  // a TEveGeoNode is a proxy to a TGeoNode, which knows its relative transformation wrt. its parent
98  // so we follow the TEveGeoNode hierarchy up to a TEveGeoTopNode, then jump to its TGeoManager, and go back down the branches to the TEveGeoNode's TGeoNode
99  std::vector< const TEveGeoNode * > nodes;
100  const TEveGeoTopNode * top = 0;
101 
102  while ((top = dynamic_cast<const TEveGeoTopNode *>( node )) == 0) {
103  // save the current node
104  nodes.push_back(node);
105 
106  // check that the node actually has any parents
107  TEveGeoNode * nc_node = const_cast<TEveGeoNode *>( node );
108  if (nc_node->BeginParents() == nc_node->EndParents())
109  return 0;
110 
111  // assume the firt parent is the good one, and check that the parent type is correct
112  node = dynamic_cast<const TEveGeoNode *>( * nc_node->BeginParents() );
113  if (node == 0)
114  return 0;
115  }
116  // reached the top level node, start from its (optional) global transormation
117  TGeoHMatrix * matrix = new TGeoHMatrix();
118  (const_cast<TEveGeoTopNode *>(top))->RefGlobalTrans().SetGeoHMatrix( *matrix );
119  for (unsigned int i = 0; i < nodes.size(); ++i)
120  *matrix *= *(nodes[i]->GetNode()->GetMatrix());
121  return matrix;
122  }
123 
124  if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
125  // a TEveGeoShape knows the absolute transformation of its shape
126  TGeoHMatrix * matrix = new TGeoHMatrix();
127  (const_cast<TEveGeoShape *>(shape))->RefHMTrans().SetGeoHMatrix( *matrix );
128  return matrix;
129  }
130 
131  return 0;
132 }
133 
134 // clone a TEveGeoShape or TEveGeoNode into a new TEveGeoShape, and add it as a child to a parent if one is given
135 TEveGeoShape * clone( const TEveElement * element, TEveElement * parent /* = 0 */)
136 {
137  TEveGeoShape* shape = new TEveGeoShape( get_name(element), get_title(element) );
138 
139  std::auto_ptr<TGeoMatrix> matrix( get_transform(element) );
140  shape->SetTransMatrix( matrix.get() );
141  delete matrix;
142 
143  TEveGeoShapeExtract extract; // FIXME put name and title here...
144  extract.SetShape( (TGeoShape *) get_shape(element)->Clone() );
145  extract.SetTrans( trans.Array() );
146  extract.SetRnrSelf( true );
147  extract.SetRnrElements( true );
148 
149  TEveGeoShape * clone = TEveGeoShape::ImportShapeExtract( &extract, parent );
150  return clone;
151 }
152 
153 // set an element's color and alpha, and possibly its children's up to levels levels deep
154 void set_color( TEveElement * element, Color_t color, float alpha /* = 1.0 */, unsigned int levels /* = 0 */)
155 {
156  if (not element)
157  return;
158 
159  // set this node's color
160  element->SetMainColor( color );
161  if (alpha > 1.) alpha = 1.;
162  if (alpha < 0.) alpha = 0.;
163  unsigned char transparency = (unsigned char) roundf(100. - (alpha * 100.));
164  element->SetMainTransparency( transparency );
165 
166  if (levels > 0) {
167  // set the node's children's color
168  expand_node( element );
169  for (std::list<TEveElement*>::iterator i = element->BeginChildren(); i != element->EndChildren(); ++i)
170  set_color( *i, color, alpha, levels - 1);
171  }
172  // notify the element that it has changed
173  element->ElementChanged(true, true);
174 }
175 
176 // check if a node has any children or if it's a leaf node
177 bool is_leaf_node( const TEveElement * element )
178 {
179  // a TEveGeoNode can have unaccounted-for children
180  if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
181  return ((node->GetNChildren() == 0) and (node->GetNode()->GetVolume()->GetNdaughters() == 0));
182  }
183  // a TEveGeoShape always knows its children
184  if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
185  return (shape->GetNChildren() == 0);
186  }
187  // default implementation
188  return (element->GetNChildren() == 0);
189 }
190 
191 // toggle an elements's children visibility, based on their name
192 // names are checked only up to their length, so for example tec:TEC will match both tec:TEC_1 and tec:TEC_2
193 void set_children_visibility( TEveElement * element, const std::string & node_name, const std::vector<std::string> & children_name, bool visibility )
194 {
195  // try to access the element as a named thingy
196  const char * name = get_name( element );
197  if (not name or strncmp(name, node_name.c_str(), node_name.size()))
198  // unnamed node, or wrong node
199  return;
200 
201  for (std::list<TEveElement *>::iterator j = element->BeginChildren(); j != element->EndChildren(); ++j) {
202  TEveElement * child = *j;
203  name = get_name( child );
204  if (not name)
205  // unnamed node, ignore it
206  continue;
207 
208  for (unsigned int i = 0; i < children_name.size(); ++i)
209  if (not strncmp(name, children_name[i].c_str(), children_name[i].size())) {
210  // change this child visibility
211  if (is_leaf_node( child )) {
212  child->SetRnrSelf( visibility );
213  child->SetRnrChildren( false );
214  } else {
215  child->SetRnrSelf( false );
216  child->SetRnrChildren( visibility );
217  }
218  break;
219  }
220  }
221  // notify the element that is had changed
222  element->ElementChanged(true, true);
223 }
224 
225 // set Tracker's Endcaps visibility
226 void set_tracker_endcap_visibility( TEveElement * tracker, bool visibility )
227 {
228  std::vector<std::string> endcap;
229  endcap.push_back("tec:TEC");
230  endcap.push_back("tidf:TIDF");
231  endcap.push_back("tidb:TIDB");
232  endcap.push_back("pixfwd:PixelForwardZPlus");
233  endcap.push_back("pixfwd:PixelForwardZMinus");
234  set_children_visibility( tracker, "tracker:Tracker", endcap, visibility );
235 }
236 
237 // show Tracker's Endcaps
238 void show_tracker_endcap( TEveElement * tracker )
239 {
240  set_tracker_endcap_visibility( tracker, true );
241 }
242 
243 // hide Tracker's Endcaps
244 void hide_tracker_endcap( TEveElement * tracker )
245 {
246  set_tracker_endcap_visibility( tracker, false );
247 }
248 
int i
Definition: DBlmapReader.cc:9
float alpha
Definition: AMPTWrapper.h:95
list parent
Definition: dbtoconf.py:74
const char * get_title(const TEveElement *element)
Definition: eve_macros.cc:28
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventIDconst &, edm::Timestampconst & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
void show_tracker_endcap(TEveElement *tracker)
Definition: eve_macros.cc:238
void hide_tracker_endcap(TEveElement *tracker)
Definition: eve_macros.cc:244
const TGeoShape * get_shape(const TEveElement *element)
Definition: eve_macros.cc:66
void set_children_visibility(TEveElement *element, const std::string &node_name, const std::vector< std::string > &children_name, bool visibility)
Definition: eve_macros.cc:193
tuple node
Definition: Node.py:50
void set_tracker_endcap_visibility(TEveElement *tracker, bool visibility)
Definition: eve_macros.cc:226
void set_color(TEveElement *element, Color_t color, float alpha, unsigned int levels)
Definition: eve_macros.cc:154
int j
Definition: DBlmapReader.cc:9
TGeoMatrix * get_transform(const TEveElement *element)
Definition: eve_macros.cc:95
int extract(std::vector< int > *output, const std::string &dati)
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
void expand_node(TEveElement *element)
Definition: eve_macros.cc:43
const char * get_name(const TEveElement *element)
Definition: eve_macros.cc:13
tuple size
Write out results.
bool is_leaf_node(const TEveElement *element)
Definition: eve_macros.cc:177