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 
0014 namespace tools {
0015 namespace sg {
0016 
0017 typedef std::vector<node*> path_t;
0018 
0019 inline bool parent_class(const path_t& a_path,std::string& a_class) {
0020   if(a_path.size()<2) {a_class.clear();return false;}
0021   node* parent = a_path[a_path.size()-2];
0022   a_class = parent->s_cls();
0023   return true;
0024 }
0025 
0026 template <class NODE>
0027 inline NODE* rfind(const path_t& a_path) {
0028   path_t::const_reverse_iterator it;
0029   for(it=a_path.rbegin();it!=a_path.rend();++it){
0030     if(NODE* par = safe_cast<node,NODE>(*(*it))) return par;
0031   }
0032   return 0;
0033 }
0034 
0035 template <class NODE>
0036 inline NODE* tail(const path_t& a_path) {
0037   if(a_path.empty()) return 0;
0038   node* _node = a_path[a_path.size()-1];
0039   return safe_cast<node,NODE>(*_node);
0040 }
0041 
0042 inline bool remove_tail(path_t& a_path) {
0043   if(a_path.empty()) return false;
0044   a_path.resize(a_path.size()-1);
0045   return true;
0046 }
0047 
0048 template <class CONTAINER>
0049 inline CONTAINER* container(const path_t& a_path) {
0050   if(a_path.size()<2) return 0;
0051   node* parent = a_path[a_path.size()-2];
0052   return safe_cast<node,CONTAINER>(*parent);
0053 }
0054 
0055 template <class CONTAINER>
0056 inline CONTAINER* container_container(const path_t& a_path) {
0057   if(a_path.size()<3) return 0;
0058   node* parent = a_path[a_path.size()-3];
0059   return safe_cast<node,CONTAINER>(*parent);
0060 }
0061 
0062 template <class WHAT,class CONTAINER>
0063 inline bool rfind(const path_t& a_path,const node& a_from,
0064                   CONTAINER*& a_container,WHAT*& a_what,
0065                   int& a_container_index){
0066   node* from = (node*)&a_from;
0067   path_t::size_type sz = a_path.size();
0068   for(size_t index=1;index<sz;index++) {
0069     node* _node = a_path[sz-index-1];
0070     a_container = safe_cast<node,CONTAINER>(*_node);
0071     if(a_container) {
0072       //the below does not compile.
0073       //a_what = a_container->rsearch_from<WHAT>(from);
0074       //if(a_what) return true;
0075 
0076       void* p = a_container->rsearch_from(from,WHAT::s_class(),false);
0077       if(p) {
0078         a_what = (WHAT*)p;
0079         a_container_index = int(sz-index-1);
0080         return true;
0081       }
0082 
0083       from = a_container;
0084     } else if(noderef* _ref = safe_cast<node,noderef>(*_node)) {
0085       from = _ref;
0086     } else { // weird case :
0087       break;
0088     }
0089   }
0090   a_what = 0;
0091   a_container = 0;
0092   a_container_index = -1;
0093   return false;
0094 }
0095 
0096 template <class WHAT,class CONTAINER>
0097 inline bool find_top(const path_t& a_path,const node& a_from,
0098                      CONTAINER*& a_container,WHAT*& a_what,
0099                      int& a_container_index){
0100   a_what = 0;
0101   a_container = 0;
0102   a_container_index = -1;
0103   path_t _path = a_path;
0104   node* from = (node*)&a_from;
0105   while(true) {
0106     CONTAINER* container;
0107     WHAT* what;
0108     int idx; //index in path of container.
0109     if(!sg::rfind<WHAT,CONTAINER>(_path,*from,container,what,idx)) {
0110       break;
0111     }
0112     a_container = container;
0113     a_what = what;
0114     a_container_index = idx;
0115     _path.resize(idx+1);
0116     _path.push_back(what);
0117     from = what;
0118   }
0119   return a_container?true:false;
0120 }
0121 
0122 typedef std::vector<path_t> paths_t;
0123 
0124 }}
0125 
0126 #endif