CMS 3D CMS Logo

CMSSW_4_4_3_patch1/src/Fireworks/Core/src/vis_macros.cc

Go to the documentation of this file.
00001 #include <list>
00002 #include <cmath>
00003 
00004 #include <TEveElement.h>
00005 #include <TEveGeoNode.h>
00006 #include <TGeoNode.h>
00007 
00008 #include "vis_macros.h"
00009 
00010 // get the named from an object derived from both TEveElement and TNamed
00011 const char* get_name( const TEveElement * element ) {
00012    // try as a TEveGeoNode or TEveGeoShape
00013    if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element ))
00014       return node->GetName();
00015    if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element ))
00016       return shape->GetName();
00017 
00018    // try to access the element as a named thingy
00019    if (const TNamed * named = dynamic_cast<const TNamed *>( element ))
00020       return named->GetName();
00021 
00022    return 0;
00023 }
00024 
00025 // force a node to expand its internal reprsentation, so all children are actually present
00026 void expand_node( TEveElement * element )
00027 {
00028    // force a TEveGeoNode to load all its children
00029    if (TEveGeoNode * node = dynamic_cast<TEveGeoNode *>( element )) {
00030       if (node->NumChildren() == 0 && node->GetNode()->GetVolume()->GetNdaughters() > 0) {
00031          TIter next(node->GetNode()->GetVolume()->GetNodes());
00032          TGeoNode* dnode;
00033          while ((dnode = (TGeoNode*) next()) != 0) {
00034             TEveGeoNode* node_re = new TEveGeoNode(dnode);
00035             node->AddElement(node_re);
00036          }
00037       }
00038       return;
00039    }
00040    // a TEveGeoShape is always exanded
00041    //if (TEveGeoShape * shape __attribute__ ((unused)) = dynamic_cast<TEveGeoShape *>( element )) {
00042    //  return;
00043    //}
00044    // a generic TEveElement has no knwledge on children expansion
00045    return;
00046 }
00047 
00048 // retrieves a TShape from a TEveElement
00049 const TGeoShape * get_shape( const TEveElement * element ) {
00050    // a TEveGeoNode, can look into its TGeoNode and retrieve the shape
00051    if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
00052       return node->GetNode()->GetVolume()->GetShape();
00053    }
00054    // a TEveGeoShape owns its shape
00055    if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
00056       TEveGeoShape * nc_shape = const_cast<TEveGeoShape *>( shape );
00057       return const_cast<const TGeoShape *>( nc_shape->GetShape() );
00058    }
00059    // a TEveElement is too generic, no way to get a shape
00060    return 0;
00061 }
00062 
00063 // overloaded non-const TShape retrieval, allowed from a TGeoShape only
00064 TGeoShape * get_shape( TEveElement * element ) {
00065    // a TEveGeoNode cannot modify its shape
00066    //if (const TEveGeoNode * node __attribute__ ((unused)) = dynamic_cast<const TEveGeoNode *>( element )) {
00067    //  return 0;
00068    //}
00069    // a TEveGeoShape owns its shape, and can modifiy it
00070    if (TEveGeoShape * shape = dynamic_cast<TEveGeoShape *>( element )) {
00071       return shape->GetShape();
00072    }
00073    // a TEveElement is too generic, no way to get a shape
00074    return 0;
00075 }
00076 // set an element's color and alpha, and possibly its children's up to levels levels deep
00077 void set_color( TEveElement * element, Color_t color, float alpha, unsigned int levels )
00078 {
00079    if (not element)
00080       return;
00081 
00082    // set this node's color
00083    element->SetMainColor( color );
00084    if (alpha > 1.) alpha = 1.;
00085    if (alpha < 0.) alpha = 0.;
00086    unsigned char transparency = (unsigned char) roundf(100. - (alpha * 100.));
00087    element->SetMainTransparency( transparency );
00088 
00089    if (levels > 0) {
00090       // set the node's children's color
00091       expand_node( element );
00092       for (std::list<TEveElement*>::iterator i = element->BeginChildren(); i != element->EndChildren(); ++i)
00093          set_color( *i, color, alpha, levels - 1);
00094    }
00095    // notify the element that it has changed
00096    element->ElementChanged(true, true);
00097 }
00098 
00099 // check if a node has any children or if it's a leaf node
00100 bool is_leaf_node( const TEveElement * element )
00101 {
00102    // a TEveGeoNode can have unaccounted-for children
00103    if (const TEveGeoNode * node = dynamic_cast<const TEveGeoNode *>( element )) {
00104       return ((node->NumChildren() == 0) and (node->GetNode()->GetVolume()->GetNdaughters() == 0));
00105    }
00106    // a TEveGeoShape always knows its children
00107    if (const TEveGeoShape * shape = dynamic_cast<const TEveGeoShape *>( element )) {
00108       return (shape->NumChildren() == 0);
00109    }
00110    // default implementation
00111    return (element->NumChildren() == 0);
00112 }
00113 
00114 // toggle an elements's children visibility, based on their name
00115 // names are checked only up to their length, so for example tec:TEC will match both tec:TEC_1 and tec:TEC_2
00116 void set_children_visibility( TEveElement * element, const std::string & node_name, const std::vector<std::string> & children_name, bool visibility )
00117 {
00118    // try to access the element as a named thingy
00119    const char * name = get_name( element );
00120    if (not name or strncmp(name, node_name.c_str(), node_name.size()))
00121       // unnamed node, or wrong node
00122       return;
00123 
00124    for (std::list<TEveElement *>::iterator j = element->BeginChildren(); j != element->EndChildren(); ++j) {
00125       TEveElement * child = *j;
00126       name = get_name( child );
00127       if (not name)
00128          // unnamed node, ignore it
00129          continue;
00130 
00131       for (unsigned int i = 0; i < children_name.size(); ++i)
00132          if (not strncmp(name, children_name[i].c_str(), children_name[i].size())) {
00133             // change this child visibility
00134             if (is_leaf_node( child )) {
00135                child->SetRnrSelf( visibility );
00136                child->SetRnrChildren( false );
00137             } else {
00138                child->SetRnrSelf( false );
00139                child->SetRnrChildren( visibility );
00140             }
00141             break;
00142          }
00143    }
00144    // notify the element that is had changed
00145    element->ElementChanged(true, true);
00146 }
00147 
00148 // set Tracker's Endcaps visibility
00149 void set_tracker_endcap_visibility( TEveElement * tracker, bool visibility )
00150 {
00151    std::vector<std::string> endcap;
00152    endcap.push_back("tec:TEC");
00153    endcap.push_back("tidf:TIDF");
00154    endcap.push_back("tidb:TIDB");
00155    endcap.push_back("pixfwd:PixelForwardZPlus");
00156    endcap.push_back("pixfwd:PixelForwardZMinus");
00157    set_children_visibility( tracker, "tracker:Tracker", endcap, visibility );
00158 }
00159 
00160 // show Tracker's Endcaps
00161 void show_tracker_endcap( TEveElement * tracker )
00162 {
00163    set_tracker_endcap_visibility( tracker, true );
00164 }
00165 
00166 // hide Tracker's Endcaps
00167 void hide_tracker_endcap( TEveElement * tracker )
00168 {
00169    set_tracker_endcap_visibility( tracker, false );
00170 }
00171