Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:11:48

0001 #include <vector>
0002 #include <list>
0003 #include <string>
0004 #include <cmath>
0005 
0006 #include <TEveElement.h>
0007 #include <TEveGeoNode.h>
0008 #include <TGeoNode.h>
0009 
0010 #include "eve_macros.h"
0011 
0012 // get the name from an object derived from both TEveElement and TNamed
0013 const char* get_name( const TEveElement * element ) {
0014   // try as a TEveGeoNode or TEveGeoShape
0015   if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element ))
0016     return node->GetName();
0017   if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element ))
0018     return shape->GetName();
0019 
0020   // try to access the element as a generic named object
0021   if (const TNamed * named = dynamic_cast<const TNamed *>( element ))
0022     return named->GetName();
0023 
0024   return 0;
0025 }
0026 
0027 // get the title from an object derived from both TEveElement and TNamed
0028 const char* get_title( const TEveElement * element ) {
0029   // try as a TEveGeoNode or TEveGeoShape
0030   if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element ))
0031     return node->GetTitle();
0032   if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element ))
0033     return shape->GetTitle();
0034 
0035   // try to access the element as a generic named object
0036   if (const TNamed * named = dynamic_cast<const TNamed *>( element ))
0037     return named->GetTitle();
0038 
0039   return 0;
0040 }
0041 
0042 // force a node to expand its internal reprsentation, so all children are actually present
0043 void expand_node( TEveElement * element )
0044 {
0045   // force a TEveGeoNode to load all its children
0046   if (TEveGeoNode * node = dynamic_cast<TEveGeoNode *>( element )) {
0047     if (node->GetNChildren() == 0 && node->GetNode()->GetVolume()->GetNdaughters() > 0) {
0048       TIter next(node->GetNode()->GetVolume()->GetNodes());
0049       TGeoNode* dnode;
0050       while ((dnode = (TGeoNode*) next()) != 0) {
0051         TEveGeoNode* node_re = new TEveGeoNode(dnode);
0052         node->AddElement(node_re);
0053       }
0054     }
0055     return;
0056   }
0057   // a TEveGeoShape is always exanded
0058   //if (TEveGeoShape * shape __attribute__ ((unused)) = dynamic_cast<TEveGeoShape *>( element )) {
0059   //  return;
0060   //}
0061   // a generic TEveElement has no knwledge on children expansion
0062   return;
0063 }
0064 
0065 // retrieves a TShape from a TEveElement
0066 const TGeoShape * get_shape( const TEveElement * element ) {
0067   // a TEveGeoNode, can look into its TGeoNode and retrieve the shape
0068   if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
0069     return node->GetNode()->GetVolume()->GetShape();
0070   }
0071   // a TEveGeoShape owns its shape
0072   if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
0073     TEveGeoShape * nc_shape = const_cast<TEveGeoShape *>( shape );
0074     return const_cast<const TGeoShape *>( nc_shape->GetShape() );
0075   }
0076   // a TEveElement is too generic, no way to get a shape
0077   return 0;
0078 }
0079 
0080 // overloaded non-const TShape retrieval, allowed from a TGeoShape only
0081 TGeoShape * get_shape( TEveElement * element ) {
0082   // a TEveGeoNode cannot modify its shape
0083   //if (const TEveGeoNode * node __attribute__ ((unused)) = dynamic_cast<const TEveGeoNode *>( element )) {
0084   //  return 0;
0085   //}
0086   // a TEveGeoShape owns its shape, and can modifiy it
0087   if (TEveGeoShape * shape = dynamic_cast<TEveGeoShape *>( element )) {
0088     return shape->GetShape();
0089   }
0090   // a TEveElement is too generic, no way to get a shape
0091   return 0;
0092 }
0093 
0094 // return a copy of the local-to-global transformation applied to a TEveElement
0095 TGeoMatrix * get_transform( const TEveElement * element ) {
0096   if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
0097     // a TEveGeoNode is a proxy to a TGeoNode, which knows its relative transformation wrt. its parent
0098     // 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
0099     std::vector< const TEveGeoNode * > nodes;
0100     const TEveGeoTopNode * top = 0;
0101 
0102     while ((top = dynamic_cast<const TEveGeoTopNode *>( node )) == 0) {
0103       // save the current node
0104       nodes.push_back(node);
0105 
0106       // check that the node actually has any parents
0107       TEveGeoNode * nc_node = const_cast<TEveGeoNode *>( node );
0108       if (nc_node->BeginParents() == nc_node->EndParents())
0109         return 0;
0110 
0111       // assume the firt parent is the good one, and check that the parent type is correct
0112       node = dynamic_cast<const TEveGeoNode *>( * nc_node->BeginParents() );
0113       if (node == 0)
0114         return 0;
0115     }
0116     // reached the top level node, start from its (optional) global transormation
0117     TGeoHMatrix * matrix = new TGeoHMatrix();
0118     (const_cast<TEveGeoTopNode *>(top))->RefGlobalTrans().SetGeoHMatrix( *matrix );
0119     for (unsigned int i = 0; i < nodes.size(); ++i)
0120       *matrix *= *(nodes[i]->GetNode()->GetMatrix());
0121     return matrix;
0122   }
0123 
0124   if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
0125     // a TEveGeoShape knows the absolute transformation of its shape
0126     TGeoHMatrix * matrix = new TGeoHMatrix();
0127     (const_cast<TEveGeoShape *>(shape))->RefHMTrans().SetGeoHMatrix( *matrix );
0128     return matrix;
0129   }
0130 
0131   return 0;
0132 }
0133 
0134 // clone a TEveGeoShape or TEveGeoNode into a new TEveGeoShape, and add it as a child to a parent if one is given
0135 TEveGeoShape * clone( const TEveElement * element, TEveElement * parent /* = 0 */)
0136 {
0137   TEveGeoShape* shape = new TEveGeoShape( get_name(element), get_title(element) );
0138 
0139   std::unique_ptr<TGeoMatrix> matrix( get_transform(element) );
0140   shape->SetTransMatrix( matrix.get() );
0141   delete matrix;
0142 
0143   TEveGeoShapeExtract extract;                  // FIXME put name and title here...
0144   extract.SetShape( (TGeoShape *) get_shape(element)->Clone() );
0145   extract.SetTrans( trans.Array() );
0146   extract.SetRnrSelf( true );
0147   extract.SetRnrElements( true );
0148 
0149   TEveGeoShape * clone = TEveGeoShape::ImportShapeExtract( &extract, parent );
0150   return clone;
0151 }
0152 
0153 // set an element's color and alpha, and possibly its children's up to levels levels deep
0154 void set_color( TEveElement * element, Color_t color, float alpha /* = 1.0 */, unsigned int levels /* = 0 */)
0155 {
0156   if (not element)
0157     return;
0158 
0159   // set this node's color
0160   element->SetMainColor( color );
0161   if (alpha > 1.) alpha = 1.;
0162   if (alpha < 0.) alpha = 0.;
0163   unsigned char transparency = (unsigned char) roundf(100. - (alpha * 100.));
0164   element->SetMainTransparency( transparency );
0165 
0166   if (levels > 0) {
0167     // set the node's children's color
0168     expand_node( element );
0169     for (std::list<TEveElement*>::iterator i = element->BeginChildren(); i != element->EndChildren(); ++i)
0170       set_color( *i, color, alpha, levels - 1);
0171   }
0172   // notify the element that it has changed
0173   element->ElementChanged(true, true);
0174 }
0175 
0176 // check if a node has any children or if it's a leaf node
0177 bool is_leaf_node( const TEveElement * element )
0178 {
0179   // a TEveGeoNode can have unaccounted-for children
0180   if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
0181     return ((node->GetNChildren() == 0) and (node->GetNode()->GetVolume()->GetNdaughters() == 0));
0182   }
0183   // a TEveGeoShape always knows its children
0184   if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
0185     return (shape->GetNChildren() == 0);
0186   }
0187   // default implementation
0188   return (element->GetNChildren() == 0);
0189 }
0190 
0191 // toggle an elements's children visibility, based on their name
0192 // names are checked only up to their length, so for example tec:TEC will match both tec:TEC_1 and tec:TEC_2
0193 void set_children_visibility( TEveElement * element, const std::string & node_name, const std::vector<std::string> & children_name, bool visibility )
0194 {
0195   // try to access the element as a named thingy
0196   const char * name = get_name( element );
0197   if (not name or strncmp(name, node_name.c_str(), node_name.size()))
0198     // unnamed node, or wrong node
0199     return;
0200 
0201   for (std::list<TEveElement *>::iterator j = element->BeginChildren(); j != element->EndChildren(); ++j) {
0202     TEveElement * child = *j;
0203     name = get_name( child );
0204     if (not name)
0205       // unnamed node, ignore it
0206       continue;
0207 
0208     for (unsigned int i = 0; i < children_name.size(); ++i)
0209       if (not strncmp(name, children_name[i].c_str(), children_name[i].size())) {
0210         // change this child visibility
0211         if (is_leaf_node( child )) {
0212           child->SetRnrSelf( visibility );
0213           child->SetRnrChildren( false );
0214         } else {
0215           child->SetRnrSelf( false );
0216           child->SetRnrChildren( visibility );
0217         }
0218         break;
0219       }
0220   }
0221   // notify the element that is had changed
0222   element->ElementChanged(true, true);
0223 }
0224 
0225 // set Tracker's Endcaps visibility
0226 void set_tracker_endcap_visibility( TEveElement * tracker, bool visibility )
0227 {
0228   std::vector<std::string> endcap;
0229   endcap.push_back("tec:TEC");
0230   endcap.push_back("tidf:TIDF");
0231   endcap.push_back("tidb:TIDB");
0232   endcap.push_back("pixfwd:PixelForwardZPlus");
0233   endcap.push_back("pixfwd:PixelForwardZMinus");
0234   set_children_visibility( tracker, "tracker:Tracker", endcap, visibility );
0235 }
0236 
0237 // show Tracker's Endcaps
0238 void show_tracker_endcap( TEveElement * tracker )
0239 {
0240   set_tracker_endcap_visibility( tracker, true );
0241 }
0242 
0243 // hide Tracker's Endcaps
0244 void hide_tracker_endcap( TEveElement * tracker )
0245 {
0246   set_tracker_endcap_visibility( tracker, false );
0247 }
0248