Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/sg/path is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 //
0005 // Helper functions to handle node(s) paths in a scene graph.
0006 //
0007 
0008 #ifndef tools_sg_path
0009 #define tools_sg_path
0010 
0011 #include "node"
0012 #include "noderef"
0013 #include "../pointer"
0014 
0015 namespace tools {
0016 namespace sg {
0017 
0018 typedef std::vector<node*> path_t;
0019 
0020 inline bool parent_class(const path_t& a_path,std::string& a_class) {
0021   if(a_path.size()<2) {a_class.clear();return false;}
0022   node* parent = a_path[a_path.size()-2];
0023   a_class = parent->s_cls();
0024   return true;
0025 }
0026 
0027 template <class NODE>
0028 inline NODE* rfind(const path_t& a_path) {
0029   path_t::const_reverse_iterator it;
0030   for(it=a_path.rbegin();it!=a_path.rend();++it){
0031     if(NODE* par = safe_cast<node,NODE>(*(*it))) return par;
0032   }
0033   return 0;
0034 }
0035 
0036 template <class NODE>
0037 inline NODE* tail(const path_t& a_path) {
0038   if(a_path.empty()) return 0;
0039   node* _node = a_path[a_path.size()-1];
0040   return safe_cast<node,NODE>(*_node);
0041 }
0042 
0043 inline bool remove_tail(path_t& a_path) {
0044   if(a_path.empty()) return false;
0045   a_path.resize(a_path.size()-1);
0046   return true;
0047 }
0048 
0049 template <class CONTAINER>
0050 inline CONTAINER* container(const path_t& a_path) {
0051   if(a_path.size()<2) return 0;
0052   node* parent = a_path[a_path.size()-2];
0053   return safe_cast<node,CONTAINER>(*parent);
0054 }
0055 
0056 template <class CONTAINER>
0057 inline CONTAINER* container_container(const path_t& a_path) {
0058   if(a_path.size()<3) return 0;
0059   node* parent = a_path[a_path.size()-3];
0060   return safe_cast<node,CONTAINER>(*parent);
0061 }
0062 
0063 inline void dump(std::ostream& a_out,const path_t& a_path) {
0064   a_out << "tools::sg::dump : path size " << a_path.size() << std::endl;
0065   std::string _s;
0066   path_t::const_iterator it;
0067   for(it=a_path.begin();it!=a_path.end();++it){
0068     if(!p2s(*it,_s)) {}
0069     a_out << " " << _s << " " << (*it)->s_cls();
0070     if(noderef* _ref = safe_cast<node,noderef>(*(*it))) {
0071       if(!p2s(&(_ref->node()),_s)) {}
0072       a_out << ", " << _s << " " << _ref->node().s_cls();
0073     }
0074     a_out << std::endl;
0075   }
0076 }
0077 
0078 //#define TOOLS_RFIND_DEBUG
0079 
0080 template <class WHAT,class CONTAINER>
0081 inline bool rfind(const path_t& a_path,const node& a_from,
0082                   CONTAINER*& a_container,WHAT*& a_what,
0083                   int& a_container_index){
0084   node* from = (node*)&a_from;
0085   path_t::size_type sz = a_path.size();
0086 #ifdef TOOLS_RFIND_DEBUG
0087   ::printf("debug : rfind : from %s, a_path.size() %d\n",a_from.s_cls().c_str(),sz);
0088   //::printf("debug : rfind : search node of class %s\n",typename WHAT::s_cls().c_str());
0089 #endif
0090   for(size_t index=1;index<sz;index++) {
0091     node* _node = a_path[sz-index-1];
0092 #ifdef TOOLS_RFIND_DEBUG
0093     ::printf("debug : rfind : index %d, node %s\n",index,_node->s_cls().c_str());
0094 #endif
0095     a_container = safe_cast<node,CONTAINER>(*_node);
0096     if(a_container) {
0097 #ifdef TOOLS_RFIND_DEBUG
0098       ::printf("debug : rfind : node is a container of size %d\n",a_container->size());
0099 #endif
0100       //the below does not compile.
0101       //a_what = a_container->rsearch_from<WHAT>(from);
0102       //if(a_what) return true;
0103 
0104       void* p = a_container->rsearch_from(from,WHAT::s_class(),false);
0105       if(p) {
0106 #ifdef TOOLS_RFIND_DEBUG
0107         ::printf("debug : rfind : found in container %lu\n",p);
0108 #endif
0109         a_what = (WHAT*)p;
0110         a_container_index = int(sz-index-1);
0111         return true;
0112       }
0113 
0114       from = a_container;
0115     } else if(noderef* _ref = safe_cast<node,noderef>(*_node)) {
0116 #ifdef TOOLS_RFIND_DEBUG
0117       ::printf("debug : rfind : node is a noderef with a %s\n",_ref->node().s_cls().c_str());
0118 #endif
0119       from = _ref;
0120     } else { // weird case :
0121 #ifdef TOOLS_RFIND_DEBUG
0122       ::printf("debug : rfind : weird case\n");
0123 #endif
0124       break;
0125     }
0126   }
0127 #ifdef TOOLS_RFIND_DEBUG
0128   ::printf("debug : rfind : failed\n");
0129 #endif
0130   a_what = 0;
0131   a_container = 0;
0132   a_container_index = -1;
0133   return false;
0134 }
0135 #ifdef TOOLS_RFIND_DEBUG
0136 #undef TOOLS_RFIND_DEBUG
0137 #endif
0138 
0139 template <class WHAT,class CONTAINER>
0140 inline bool find_top(const path_t& a_path,const node& a_from,
0141                      CONTAINER*& a_container,WHAT*& a_what,
0142                      int& a_container_index){
0143   a_what = 0;
0144   a_container = 0;
0145   a_container_index = -1;
0146   path_t _path = a_path;
0147   node* from = (node*)&a_from;
0148   while(true) {
0149     CONTAINER* container;
0150     WHAT* what;
0151     int idx; //index in path of container.
0152     if(!sg::rfind<WHAT,CONTAINER>(_path,*from,container,what,idx)) {
0153       break;
0154     }
0155     a_container = container;
0156     a_what = what;
0157     a_container_index = idx;
0158     _path.resize(idx+1);
0159     _path.push_back(what);
0160     from = what;
0161   }
0162   return a_container?true:false;
0163 }
0164 
0165 typedef std::vector<path_t> paths_t;
0166 
0167 }}
0168 
0169 #endif