// Copyright (C) 2010, Guy Barrand. All rights reserved. // See the file tools.license for terms. // // Helper functions to search node(s) in a scene graph. // #ifndef tools_sg_search #define tools_sg_search #include "search_action" #include "node" namespace tools { namespace sg { template inline NODE* find_first_node_of_class(std::ostream& a_out,node& a_from) { search_action action(a_out); action.reset(); action.set_what(search_action::search_node_of_class); action.set_stop_at_first(true); action.set_class(NODE::s_class()); a_from.search(action); const std::vector& _objs = action.objs(); if(_objs.empty()) return 0; return (NODE*)_objs[0]; } inline node* find_first_node_with_class(std::ostream& a_out,node& a_from,const std::string& a_class) { search_action action(a_out); action.reset(); action.set_what(search_action::search_node_of_class); action.set_stop_at_first(true); action.set_class(a_class); a_from.search(action); const std::vector& _objs = action.objs(); if(_objs.empty()) return 0; return (node*)_objs[0]; } }} #include "path" namespace tools { namespace sg { inline const path_t& find_path(search_action& a_action,node& a_from,node& a_node,bool a_verbose) { a_action.reset(); a_action.set_what(search_action::search_path_to_node); a_action.set_node(&a_node); a_from.search(a_action); if(!a_action.done()) { if(a_verbose) { a_action.out() << "tools::sg::find_path :" << " not found node of class " << a_node.s_cls() << " from head node of class " << a_from.s_cls() << std::endl; } a_action.clear_path(); return a_action.path(); } if(a_verbose) { a_action.out() << "tools::sg::find_path :" << " found node of class " << a_node.s_cls() << " from head node of class " << a_from.s_cls() << std::endl; } const path_t& path = a_action.path(); if(path.empty()) { if(a_verbose) { a_action.out() << "tools::sg::find_path :" << " node has no path !" << std::endl; } return path; } if(&a_node!=path[path.size()-1]) { a_action.out() << "tools::sg::find_path :" << " node / path tail mismatch !" << " node " << a_node.s_cls() << " tail " << path[path.size()-1]->s_cls() << std::endl; a_action.clear_path(); return a_action.path(); } return path; } inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from,const std::string& a_class){ a_action.reset(); a_action.set_what(search_action::search_path_to_node_of_class); a_action.set_class(a_class); a_from.search(a_action); return a_action.paths(); } template inline const search_action::paths_t& find_paths(search_action& a_action,node& a_from){ a_action.reset(); a_action.set_what(search_action::search_path_to_node_of_class); a_action.set_class(NODE::s_class()); a_from.search(a_action); return a_action.paths(); } template inline NODE* find_ancestor(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) { search_action action(a_out); return rfind(find_path(action,a_from,a_node,a_verbose)); } template inline CONTAINER* find_container(std::ostream& a_out,node& a_from,node& a_node,bool a_verbose) { search_action action(a_out); return container(find_path(action,a_from,a_node,a_verbose)); } template inline NODE* search_node(std::ostream& a_out,node& a_from) { search_action sa(a_out); const paths_t& paths = find_paths(sa,a_from); tools_vforcit(path_t,paths,it) { NODE* _node = tail(*it); if(_node) return _node; } return 0; } template inline SELECTABLE* search_selectable(std::ostream& a_out,node& a_from) { search_action sa(a_out); const paths_t& paths = find_paths(sa,a_from); tools_vforcit(path_t,paths,it) { SELECTABLE* _node = tail(*it); if(_node && _node->border_visible.value()) return _node; } return 0; } }} #endif