Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/sg/path

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

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