Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights 1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 2 // See the file tools.license for terms. 3 3 4 // 4 // 5 // Helper functions to handle node(s) paths in 5 // Helper functions to handle node(s) paths in a scene graph. 6 // 6 // 7 7 8 #ifndef tools_sg_path 8 #ifndef tools_sg_path 9 #define tools_sg_path 9 #define tools_sg_path 10 10 11 #include "node" 11 #include "node" 12 #include "noderef" 12 #include "noderef" 13 #include "../pointer" 13 #include "../pointer" 14 14 15 namespace tools { 15 namespace tools { 16 namespace sg { 16 namespace sg { 17 17 18 typedef std::vector<node*> path_t; 18 typedef std::vector<node*> path_t; 19 19 20 inline bool parent_class(const path_t& a_path, 20 inline bool parent_class(const path_t& a_path,std::string& a_class) { 21 if(a_path.size()<2) {a_class.clear();return 21 if(a_path.size()<2) {a_class.clear();return false;} 22 node* parent = a_path[a_path.size()-2]; 22 node* parent = a_path[a_path.size()-2]; 23 a_class = parent->s_cls(); 23 a_class = parent->s_cls(); 24 return true; 24 return true; 25 } 25 } 26 26 27 template <class NODE> 27 template <class NODE> 28 inline NODE* rfind(const path_t& a_path) { 28 inline NODE* rfind(const path_t& a_path) { 29 path_t::const_reverse_iterator it; 29 path_t::const_reverse_iterator it; 30 for(it=a_path.rbegin();it!=a_path.rend();++i 30 for(it=a_path.rbegin();it!=a_path.rend();++it){ 31 if(NODE* par = safe_cast<node,NODE>(*(*it) 31 if(NODE* par = safe_cast<node,NODE>(*(*it))) return par; 32 } 32 } 33 return 0; 33 return 0; 34 } 34 } 35 35 36 template <class NODE> 36 template <class NODE> 37 inline NODE* tail(const path_t& a_path) { 37 inline NODE* tail(const path_t& a_path) { 38 if(a_path.empty()) return 0; 38 if(a_path.empty()) return 0; 39 node* _node = a_path[a_path.size()-1]; 39 node* _node = a_path[a_path.size()-1]; 40 return safe_cast<node,NODE>(*_node); 40 return safe_cast<node,NODE>(*_node); 41 } 41 } 42 42 43 inline bool remove_tail(path_t& a_path) { 43 inline bool remove_tail(path_t& a_path) { 44 if(a_path.empty()) return false; 44 if(a_path.empty()) return false; 45 a_path.resize(a_path.size()-1); 45 a_path.resize(a_path.size()-1); 46 return true; 46 return true; 47 } 47 } 48 48 49 template <class CONTAINER> 49 template <class CONTAINER> 50 inline CONTAINER* container(const path_t& a_pa 50 inline CONTAINER* container(const path_t& a_path) { 51 if(a_path.size()<2) return 0; 51 if(a_path.size()<2) return 0; 52 node* parent = a_path[a_path.size()-2]; 52 node* parent = a_path[a_path.size()-2]; 53 return safe_cast<node,CONTAINER>(*parent); 53 return safe_cast<node,CONTAINER>(*parent); 54 } 54 } 55 55 56 template <class CONTAINER> 56 template <class CONTAINER> 57 inline CONTAINER* container_container(const pa 57 inline CONTAINER* container_container(const path_t& a_path) { 58 if(a_path.size()<3) return 0; 58 if(a_path.size()<3) return 0; 59 node* parent = a_path[a_path.size()-3]; 59 node* parent = a_path[a_path.size()-3]; 60 return safe_cast<node,CONTAINER>(*parent); 60 return safe_cast<node,CONTAINER>(*parent); 61 } 61 } 62 62 63 inline void dump(std::ostream& a_out,const pat 63 inline void dump(std::ostream& a_out,const path_t& a_path) { 64 a_out << "tools::sg::dump : path size " << a 64 a_out << "tools::sg::dump : path size " << a_path.size() << std::endl; 65 std::string _s; 65 std::string _s; 66 path_t::const_iterator it; 66 path_t::const_iterator it; 67 for(it=a_path.begin();it!=a_path.end();++it) 67 for(it=a_path.begin();it!=a_path.end();++it){ 68 if(!p2s(*it,_s)) {} 68 if(!p2s(*it,_s)) {} 69 a_out << " " << _s << " " << (*it)->s_cls( 69 a_out << " " << _s << " " << (*it)->s_cls(); 70 if(noderef* _ref = safe_cast<node,noderef> 70 if(noderef* _ref = safe_cast<node,noderef>(*(*it))) { 71 if(!p2s(&(_ref->node()),_s)) {} 71 if(!p2s(&(_ref->node()),_s)) {} 72 a_out << ", " << _s << " " << _ref->node 72 a_out << ", " << _s << " " << _ref->node().s_cls(); 73 } 73 } 74 a_out << std::endl; 74 a_out << std::endl; 75 } 75 } 76 } 76 } 77 77 78 //#define TOOLS_RFIND_DEBUG 78 //#define TOOLS_RFIND_DEBUG 79 79 80 template <class WHAT,class CONTAINER> 80 template <class WHAT,class CONTAINER> 81 inline bool rfind(const path_t& a_path,const n 81 inline bool rfind(const path_t& a_path,const node& a_from, 82 CONTAINER*& a_container,WHAT 82 CONTAINER*& a_container,WHAT*& a_what, 83 int& a_container_index){ 83 int& a_container_index){ 84 node* from = (node*)&a_from; 84 node* from = (node*)&a_from; 85 path_t::size_type sz = a_path.size(); 85 path_t::size_type sz = a_path.size(); 86 #ifdef TOOLS_RFIND_DEBUG 86 #ifdef TOOLS_RFIND_DEBUG 87 ::printf("debug : rfind : from %s, a_path.si 87 ::printf("debug : rfind : from %s, a_path.size() %d\n",a_from.s_cls().c_str(),sz); 88 //::printf("debug : rfind : search node of c 88 //::printf("debug : rfind : search node of class %s\n",typename WHAT::s_cls().c_str()); 89 #endif 89 #endif 90 for(size_t index=1;index<sz;index++) { 90 for(size_t index=1;index<sz;index++) { 91 node* _node = a_path[sz-index-1]; 91 node* _node = a_path[sz-index-1]; 92 #ifdef TOOLS_RFIND_DEBUG 92 #ifdef TOOLS_RFIND_DEBUG 93 ::printf("debug : rfind : index %d, node % 93 ::printf("debug : rfind : index %d, node %s\n",index,_node->s_cls().c_str()); 94 #endif 94 #endif 95 a_container = safe_cast<node,CONTAINER>(*_ 95 a_container = safe_cast<node,CONTAINER>(*_node); 96 if(a_container) { 96 if(a_container) { 97 #ifdef TOOLS_RFIND_DEBUG 97 #ifdef TOOLS_RFIND_DEBUG 98 ::printf("debug : rfind : node is a cont 98 ::printf("debug : rfind : node is a container of size %d\n",a_container->size()); 99 #endif 99 #endif 100 //the below does not compile. 100 //the below does not compile. 101 //a_what = a_container->rsearch_from<WHA 101 //a_what = a_container->rsearch_from<WHAT>(from); 102 //if(a_what) return true; 102 //if(a_what) return true; 103 103 104 void* p = a_container->rsearch_from(from 104 void* p = a_container->rsearch_from(from,WHAT::s_class(),false); 105 if(p) { 105 if(p) { 106 #ifdef TOOLS_RFIND_DEBUG 106 #ifdef TOOLS_RFIND_DEBUG 107 ::printf("debug : rfind : found in con 107 ::printf("debug : rfind : found in container %lu\n",p); 108 #endif 108 #endif 109 a_what = (WHAT*)p; 109 a_what = (WHAT*)p; 110 a_container_index = int(sz-index-1); 110 a_container_index = int(sz-index-1); 111 return true; 111 return true; 112 } 112 } 113 113 114 from = a_container; 114 from = a_container; 115 } else if(noderef* _ref = safe_cast<node,n 115 } else if(noderef* _ref = safe_cast<node,noderef>(*_node)) { 116 #ifdef TOOLS_RFIND_DEBUG 116 #ifdef TOOLS_RFIND_DEBUG 117 ::printf("debug : rfind : node is a node 117 ::printf("debug : rfind : node is a noderef with a %s\n",_ref->node().s_cls().c_str()); 118 #endif 118 #endif 119 from = _ref; 119 from = _ref; 120 } else { // weird case : 120 } else { // weird case : 121 #ifdef TOOLS_RFIND_DEBUG 121 #ifdef TOOLS_RFIND_DEBUG 122 ::printf("debug : rfind : weird case\n") 122 ::printf("debug : rfind : weird case\n"); 123 #endif 123 #endif 124 break; 124 break; 125 } 125 } 126 } 126 } 127 #ifdef TOOLS_RFIND_DEBUG 127 #ifdef TOOLS_RFIND_DEBUG 128 ::printf("debug : rfind : failed\n"); 128 ::printf("debug : rfind : failed\n"); 129 #endif 129 #endif 130 a_what = 0; 130 a_what = 0; 131 a_container = 0; 131 a_container = 0; 132 a_container_index = -1; 132 a_container_index = -1; 133 return false; 133 return false; 134 } 134 } 135 #ifdef TOOLS_RFIND_DEBUG 135 #ifdef TOOLS_RFIND_DEBUG 136 #undef TOOLS_RFIND_DEBUG 136 #undef TOOLS_RFIND_DEBUG 137 #endif 137 #endif 138 138 139 template <class WHAT,class CONTAINER> 139 template <class WHAT,class CONTAINER> 140 inline bool find_top(const path_t& a_path,cons 140 inline bool find_top(const path_t& a_path,const node& a_from, 141 CONTAINER*& a_container,W 141 CONTAINER*& a_container,WHAT*& a_what, 142 int& a_container_index){ 142 int& a_container_index){ 143 a_what = 0; 143 a_what = 0; 144 a_container = 0; 144 a_container = 0; 145 a_container_index = -1; 145 a_container_index = -1; 146 path_t _path = a_path; 146 path_t _path = a_path; 147 node* from = (node*)&a_from; 147 node* from = (node*)&a_from; 148 while(true) { 148 while(true) { 149 CONTAINER* container; 149 CONTAINER* container; 150 WHAT* what; 150 WHAT* what; 151 int idx; //index in path of container. 151 int idx; //index in path of container. 152 if(!sg::rfind<WHAT,CONTAINER>(_path,*from, 152 if(!sg::rfind<WHAT,CONTAINER>(_path,*from,container,what,idx)) { 153 break; 153 break; 154 } 154 } 155 a_container = container; 155 a_container = container; 156 a_what = what; 156 a_what = what; 157 a_container_index = idx; 157 a_container_index = idx; 158 _path.resize(idx+1); 158 _path.resize(idx+1); 159 _path.push_back(what); 159 _path.push_back(what); 160 from = what; 160 from = what; 161 } 161 } 162 return a_container?true:false; 162 return a_container?true:false; 163 } 163 } 164 164 165 typedef std::vector<path_t> paths_t; 165 typedef std::vector<path_t> paths_t; 166 166 167 }} 167 }} 168 168 169 #endif 169 #endif