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