CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/Fireworks/Macros/eve_filter.cc

Go to the documentation of this file.
00001 #include <vector>
00002 #include <string>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <utility>
00006 
00007 #define private public
00008 #include "TPRegexp.h"
00009 #undef private
00010 
00011 #include "TEveManager.h"
00012 #include "TEveScene.h"
00013 #include "TEveElement.h"
00014 #include "TEveGeoNode.h"
00015 #include "TGeoNode.h"
00016 #include "TCollection.h"
00017 #include "TObjString.h"
00018 
00019 #include "split.h"
00020 #include "eve_filter.h"
00021 #include "eve_macros.h"
00022 
00023 // global variables... FIXME all this stuff should be incapsulated ina a class !
00024 TPRegexp parents;
00025 std::vector<TPRegexp> filters;
00026 std::vector<Color_t>  colors;
00027 unsigned int matching_nodes;
00028 
00029 void split_path(const std::string & path, std::string & name, std::vector<std::string> & parents) {
00030   split( path, parents, '/', false );
00031   if (parents.empty()) {
00032     name = "";
00033   } else {
00034     name = parents.back();
00035     parents.pop_back();
00036   }
00037 }
00038 
00039 static TPRegexp ns_name_index( "([[:alnum:]]+:[[:alnum:]-\\[\\]]+)(_[0-9]+)+" );
00040 
00041 // generalizes a node name of the form namespace:Name_NUM into a (regexp) filter that allows any number
00042 TPRegexp make_filter(const std::string & token) {
00043   std::string filter;
00044   filter += "(";
00045   if (ns_name_index.MatchB( token ))
00046     filter += ((TObjString*)(ns_name_index.MatchS( token )->At(1)))->GetString();
00047   else
00048     filter += token;
00049   filter += ")_[0-9]+";
00050   return TPRegexp( filter.c_str() );
00051 }
00052 
00053 // generalizes a list of node names of the form namespace:Name_NUM into a (regexp) filter that allows any of the "namespace:Name" followd by any number
00054 TPRegexp make_filter(const std::vector<std::string> & tokens) {
00055   if (tokens.empty())
00056     return TPRegexp();
00057 
00058   std::string filter;
00059   filter += "(";
00060   if (ns_name_index.MatchB( tokens[0] ))
00061     filter += ((TObjString*)(ns_name_index.MatchS( tokens[0] )->At(1)))->GetString();
00062   else
00063     filter += tokens[0];
00064   for (unsigned int i = 1; i < tokens.size(); ++i) {
00065     filter += "|";
00066     if (ns_name_index.MatchB( tokens[i] ))
00067       filter += ((TObjString*)(ns_name_index.MatchS( tokens[i] )->At(1)))->GetString();
00068     else
00069       filter += tokens[i];
00070   }
00071   filter += ")_[0-9]+";
00072   return TPRegexp( filter.c_str() );
00073 }
00074 
00075 // apply the filters to a node, specifying if the removed elements should be hidden (default), deleted (does not work) or ignored
00076 void node_filter(TEveElement * node, int simplify /* = do_hide */, bool verbose /* = false */) {
00077   static int indent = 0;
00078   ++indent;
00079 
00080   expand_node(node);
00081 
00082   for (TEveElement::List_i i = node->BeginChildren(); i != node->EndChildren(); ++i)
00083   {
00084     bool found = false;
00085     TEveGeoNode * child = (TEveGeoNode*)(*i);
00086     for (unsigned int det = 0; det < filters.size(); ++det) {
00087       if (filters[det].MatchB( child->GetName() )) {
00088         // found a selcted leaf
00089         if (verbose) {
00090           for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
00091           std::cout << child->GetName() << " (found)" << std::endl;
00092         }
00093         child->SetRnrSelf( true );
00094         child->SetMainColor( colors[det] );
00095         // simplify - hide or delete its children
00096         switch (simplify) {
00097           case do_hide:
00098             child->SetRnrSelf( true );
00099             child->SetRnrChildren( false );
00100             break;
00101           case do_remove:
00102             child->Destroy();
00103             break;
00104           case do_nothing:
00105             break;
00106         }
00107 
00108         found = true;
00109         ++matching_nodes;
00110         break;  // breaks out of the loop on "det"
00111       }
00112     }
00113     if (found)
00114       continue;
00115     else if (parents.MatchB( child->GetName() )) {
00116       // found a possible parent
00117       if (verbose) {
00118         for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
00119         std::cout << child->GetName() << " (look inside...)" << std::endl;
00120       }
00121       child->SetRnrSelf( false );
00122       child->SetRnrChildren( true );
00123       node_filter( child );
00124     } else {
00125       // enything else
00126       if (verbose) {
00127         for (int _t = 0; _t < indent; ++_t) std::cout << "  ";
00128         std::cout << child->GetName() << " (unused)" << std::endl;
00129       }
00130       // simplify - hide or delete this
00131       switch (simplify) {
00132         case do_hide:
00133           child->SetRnrSelf( false );
00134           child->SetRnrChildren( false );
00135           break;
00136         case do_remove:
00137           child->Destroy();
00138           break;
00139         case do_nothing:
00140           break;
00141       }
00142     }
00143   }
00144 
00145   --indent;
00146 }
00147 
00148 // initializes the filter static variables from a list of elements to display and colors to use
00149 void init_filter(const std::vector< std::pair< std::string, Color_t> > & elements) {
00150   std::vector< std::string > all_parents;
00151   std::vector< std::string > all_names;
00152 
00153   for (unsigned int i = 0; i < elements.size(); ++i) {
00154     std::vector< std::string > s_parents;
00155     std::string s_name;
00156     split_path( elements[i].first, s_name, s_parents );
00157     all_names.push_back( s_name );
00158     all_parents.insert( all_parents.end(), s_parents.begin(), s_parents.end() );
00159 
00160     colors.push_back( elements[i].second );
00161   }
00162 
00163   parents = make_filter( all_parents );
00164   for (unsigned int i = 0; i < all_names.size(); ++i)
00165     filters.push_back( make_filter( all_names[i] ) );
00166 
00167   matching_nodes = 0;
00168 }
00169 
00170 // dump the filters
00171 void dump(void) {
00172   std::cout << parents.fPattern << std::endl;
00173   for (unsigned int i = 0; i < filters.size(); ++i)
00174     std::cout << '\t' << std::setw(32) << std::left << filters[i].fPattern << '\t' << colors[i] << std::endl;
00175 }
00176 
00177 // apply the filters to a node, then notify it to update itself and its children for redrawing
00178 void apply_filter(TEveElement * node, int simplify /* = do_hide */, bool verbose /* = false */) {
00179   if (node == 0)
00180     return;
00181 
00182   if (verbose)
00183     std::cout << get_name(node) << " (look inside...)" << std::endl;
00184 
00185   node_filter( node, simplify );
00186   node->ElementChanged( true, true );
00187 
00188   std::cout << "found " << matching_nodes << " matching nodes" << std::endl;
00189 }
00190 
00191 // find a TEve root object (could be a TEveGeoRootNode or a TEveGeoShape) by its name
00192 TEveElement * get_root_object(const char* name)
00193 {
00194   for (TEveElement::List_i i = gEve->GetScenes()->BeginChildren(); i != gEve->GetScenes()->EndChildren(); ++i) {
00195     TEveScene * scene = dynamic_cast<TEveScene *> (*i);
00196     if (not scene)
00197       continue;
00198     for (TEveElement::List_i n = scene->BeginChildren(); n != scene->EndChildren(); ++n) {
00199       const char* obj_name = get_name( *n );
00200       if (obj_name == 0 or strcmp(name, obj_name))
00201         continue;
00202 
00203       return *n;
00204     }
00205   }
00206 
00207   return 0;
00208 }