Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 // 5 // Helper functions to search node(s) in a scene graph. 6 // 7 8 #ifndef tools_sg_search 9 #define tools_sg_search 10 11 #include "search_action" 12 #include "node" 13 14 namespace tools { 15 namespace sg { 16 17 template <class NODE> 18 inline NODE* find_first_node_of_class(std::ostream& a_out,node& a_from) { 19 search_action action(a_out); 20 action.reset(); 21 action.set_what(search_action::search_node_of_class); 22 action.set_stop_at_first(true); 23 action.set_class(NODE::s_class()); 24 a_from.search(action); 25 const std::vector<void*>& _objs = action.objs(); 26 if(_objs.empty()) return 0; 27 return (NODE*)_objs[0]; 28 } 29 30 inline node* find_first_node_with_class(std::ostream& a_out,node& a_from,const std::string& a_class) { 31 search_action action(a_out); 32 action.reset(); 33 action.set_what(search_action::search_node_of_class); 34 action.set_stop_at_first(true); 35 action.set_class(a_class); 36 a_from.search(action); 37 const std::vector<void*>& _objs = action.objs(); 38 if(_objs.empty()) return 0; 39 return (node*)_objs[0]; 40 } 41 42 }} 43 44 #include "path" 45 46 namespace tools { 47 namespace sg { 48 49 inline const path_t& find_path(search_action& a_action,node& a_from,node& a_node,bool a_verbose) { 50 a_action.reset(); 51 a_action.set_what(search_action::search_path_to_node); 52 a_action.set_node(&a_node); 53 a_from.search(a_action); 54 if(!a_action.done()) { 55 if(a_verbose) { 56 a_action.out() << "tools::sg::find_path :" 57 << " not found node of class " << a_node.s_cls() 58 << " from head node of class " << a_from.s_cls() 59 << std::endl; 60 } 61 a_action.clear_path(); 62 return a_action.path(); 63 } 64 if(a_verbose) { 65 a_action.out() << "tools::sg::find_path :" 66 << " found node of class " << a_node.s_cls() 67 << " from head node of class " << a_from.s_cls() 68 << std::endl; 69 } 70 const path_t& path = a_action.path(); 71 if(path.empty()) { 72 if(a_verbose) { 73 a_action.out() << "tools::sg::find_path :" 74 << " node has no path !" 75 << std::endl; 76 } 77 return path; 78 } 79 if(&a_node!=path[path.size()-1]) { 80 a_action.out() << "tools::sg::find_path :" 81 << " node / path tail mismatch !" 82 << " node " << a_node.s_cls() 83 << " tail " << path[path.size()-1]->s_cls() 84 << std::endl; 85 a_action.clear_path(); 86 return a_action.path(); 87 } 88 return path; 89 } 90 91 inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from,const std::string& a_class){ 92 a_action.reset(); 93 a_action.set_what(search_action::search_path_to_node_of_class); 94 a_action.set_class(a_class); 95 a_from.search(a_action); 96 return a_action.paths(); 97 } 98 99 template <class NODE> 100 inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from){ 101 a_action.reset(); 102 a_action.set_what(search_action::search_path_to_node_of_class); 103 a_action.set_class(NODE::s_class()); 104 a_from.search(a_action); 105 return a_action.paths(); 106 } 107 108 template <class NODE> 109 inline NODE* find_ancestor(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) { 110 search_action action(a_out); 111 return rfind<NODE>(find_path(action,a_from,a_node,a_verbose)); 112 } 113 114 template <class CONTAINER> 115 inline CONTAINER* find_container(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) { 116 search_action action(a_out); 117 return container<CONTAINER>(find_path(action,a_from,a_node,a_verbose)); 118 } 119 120 template <class NODE> 121 inline NODE* search_node(std::ostream& a_out,node& a_from) { 122 search_action sa(a_out); 123 const paths_t& paths = find_paths<NODE>(sa,a_from); 124 tools_vforcit(path_t,paths,it) { 125 NODE* _node = tail<NODE>(*it); 126 if(_node) return _node; 127 } 128 return 0; 129 } 130 131 template <class SELECTABLE> 132 inline SELECTABLE* search_selectable(std::ostream& a_out,node& a_from) { 133 search_action sa(a_out); 134 const paths_t& paths = find_paths<SELECTABLE>(sa,a_from); 135 tools_vforcit(path_t,paths,it) { 136 SELECTABLE* _node = tail<SELECTABLE>(*it); 137 if(_node && _node->border_visible.value()) return _node; 138 } 139 /* 140 tools_vforcit(sg::path_t,paths,it) { 141 SELECTABLE* _node = sg::tail<SELECTABLE>(*it); 142 if(_node) return _node; 143 } 144 */ 145 return 0; 146 } 147 148 }} 149 150 #endif