diff --git a/configure.in b/configure.in index a1235303ab97dc00ea7f72d64736bdf7db892904..06953337206aa6f812aa588d74f88fef287a836a 100644 --- a/configure.in +++ b/configure.in @@ -99,20 +99,37 @@ AC_ARG_ENABLE([static-linkage], [AC_HELP_STRING([--enable-static-linkage], [AC_MSG_RESULT(no)] ) AM_CONDITIONAL(STATIC, test $STATIC = yes) -AC_MSG_CHECKING(whether to enable graph filtering...) - AC_ARG_ENABLE([filtering], [AC_HELP_STRING([--disable-filtering], - [disable graph filtering (range and python only) [default=no] ])], +AC_MSG_CHECKING(whether to enable graph python filtering...) +AC_ARG_ENABLE([python-filtering], [AC_HELP_STRING([--enable-python-filtering], + [enable python graph filtering [default=no] ])], if test $enableval = no; then [AC_MSG_RESULT(no)] - [AC_DEFINE([NO_FILTERING], 1, [disable graph filtering])] - NO_FILTERING=yes + [AC_DEFINE([NO_PYTHON_FILTERING], 1, [disable graph filtering])] + NO_PYTHON_FILTERING=yes + else + [AC_MSG_RESULT(yes)] + fi + , + [AC_MSG_RESULT(no)] + [AC_DEFINE([NO_PYTHON_FILTERING], 1, [disable graph filtering])] + NO_PYTHON_FILTERING=yes + ) + +AC_MSG_CHECKING(whether to enable graph range filtering...) +AC_ARG_ENABLE([range-filtering], [AC_HELP_STRING([--disable-range-filtering], + [disable range filtering [default=no] ])], + if test $enableval = no; then + [AC_MSG_RESULT(no)] + [AC_DEFINE([NO_RANGE_FILTERING], 1, [disable range filtering])] + NO_RANGE_FILTERING=yes else [AC_MSG_RESULT(yes)] fi , [AC_MSG_RESULT(yes)] - NO_FILTERING=no + NO_RANGE_FILTERING=no ) + dnl Checks for programs. diff --git a/src/graph-tool b/src/graph-tool index b4a834fb58aa46ee0c37ba3e0c7d4bc4111208e8..5fca9e263458fe8852543aa73e71e38e7ac0d49a 100755 --- a/src/graph-tool +++ b/src/graph-tool @@ -767,8 +767,12 @@ def parse_option(opt, just_file=False): if just_file: return None edit_vars = dict() - def edit_function(): - return (eval(values[1],edit_vars)) + if "file:" in values[1]: + exec open(values[1].replace("file:","").strip()).read() in edit_vars + edit_function = edit_vars["edit_function"] + else: + def edit_function(): + return (eval(values[1],edit_vars)) if opt.name == "edit-vertex-property": graph.EditVertexProperty(values[0],(edit_function,edit_vars)) else: diff --git a/src/graph/graph.cc b/src/graph/graph.cc index 88bb34ffe975b78d25ca5c7ca82d3d19d091ce55..b1e27cf3b16066f1065852c72051ba274af90d80 100644 --- a/src/graph/graph.cc +++ b/src/graph/graph.cc @@ -91,7 +91,7 @@ GraphInterface::~GraphInterface() void GraphInterface::SetVertexFilterProperty(string property) { -#ifndef NO_FILTERING +#ifndef NO_RANGE_FILTERING _vertex_filter_property = property; if (property != "") @@ -119,7 +119,7 @@ void GraphInterface::SetVertexFilterProperty(string property) } } #else - throw GraphException("support for graph filtering was not enabled during compilation."); + throw GraphException("support for graph range filtering was not enabled during compilation."); #endif } @@ -127,7 +127,7 @@ bool GraphInterface::IsVertexFilterActive() const { return _vertex_filter_proper void GraphInterface::SetEdgeFilterProperty(string property) { -#ifndef NO_FILTERING +#ifndef NO_RANGE_FILTERING _edge_filter_property = property; if (property != "") @@ -156,7 +156,7 @@ void GraphInterface::SetEdgeFilterProperty(string property) } #else - throw GraphException("support for graph filtering was not enabled during compilation."); + throw GraphException("support for graph range filtering was not enabled during compilation."); #endif } @@ -164,29 +164,29 @@ bool GraphInterface::IsEdgeFilterActive() const {return _edge_filter_property != void GraphInterface::SetVertexFilterRange(std::pair allowed_range) { -#ifndef NO_FILTERING +#ifndef NO_RANGE_FILTERING _vertex_range = allowed_range; #else - throw GraphException("support for graph filtering was not enabled during compilation."); + throw GraphException("support for graph range filtering was not enabled during compilation."); #endif } void GraphInterface::SetGenericVertexFilter(boost::python::object filter) { -#ifndef NO_FILTERING +#ifndef NO_PYTHON_FILTERING _vertex_python_filter = filter; #else - throw GraphException("support for graph filtering was not enabled during compilation."); + throw GraphException("support for graph python filtering was not enabled during compilation."); #endif } void GraphInterface::SetGenericEdgeFilter(boost::python::object filter) { -#ifndef NO_FILTERING +#ifndef NO_PYTHON_FILTERING _edge_python_filter = filter; #else - throw GraphException("support for graph filtering was not enabled during compilation."); + throw GraphException("support for graph python filtering was not enabled during compilation."); #endif } diff --git a/src/graph/graph_filtering.hh b/src/graph/graph_filtering.hh index bc5d0f7e28e2e2366740fba13cb8201245de477e..9904279449a8c4d8ad23a827ed3c9cfbebc6a0ad 100644 --- a/src/graph/graph_filtering.hh +++ b/src/graph/graph_filtering.hh @@ -244,13 +244,14 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck { bool found = false; -#ifndef NO_FILTERING - typedef RangeFilter vertex_filter_t; typedef RangeFilter edge_filter_t; - + +#ifndef NO_PYTHON_FILTERING if (g._edge_python_filter == python::object() && g._vertex_python_filter == python::object()) { +#endif +#ifndef NO_RANGE_FILTERING if (g._vertex_filter_property != "" && g._edge_filter_property != "") { typedef filtered_graph fg_t; @@ -273,16 +274,19 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck { mpl::for_each(check_directed(g._mg, a, g._reversed, g._directed, found)); } +#else + mpl::for_each(check_directed(g._mg, a, g._reversed, g._directed, found)); +#endif +#ifndef NO_PYTHON_FILTERING } else { check_python_filter(g._mg, g, a, found, ReverseCheck(), DirectedCheck()); } - -#else - +#else +#ifdef NO_RANGE_FILTERING mpl::for_each(check_directed(g._mg, a, g._reversed, g._directed, found)); - +#endif #endif if (!found) diff --git a/src/graph/graph_python_filtering.hh b/src/graph/graph_python_filtering.hh index 60f12121fd708ded74bca8afa7acffae6755c75c..4eb76bb628d4b6ee92533980fda3bf821af8be65 100644 --- a/src/graph/graph_python_filtering.hh +++ b/src/graph/graph_python_filtering.hh @@ -66,6 +66,17 @@ struct populate_python_funcs typedef typename mpl::if_ >::type base_degrees; mpl::for_each(put_base_degree_function(g, v, variables, "orig_")); + + for(typeof(dp.begin()) iter = dp.begin(); iter != dp.end(); ++iter) + { + if (iter->second->key() != typeid(typename graph_traits::vertex_descriptor)) // FIXME: graph properties?x + { + variables["in_"+iter->first] = python::make_function(get_in_or_out_values(g, *iter->second, v), + python::default_call_policies(), mpl::vector::type()); + variables["out_"+iter->first] = python::make_function(get_in_or_out_values(g, *iter->second, v), + python::default_call_policies(), mpl::vector::type()); + } + } } template @@ -125,6 +136,62 @@ struct populate_python_funcs python::object _retval; }; + template + struct get_in_or_out_values + { + typedef typename graph_traits::vertex_descriptor vertex_descriptor; + typedef typename graph_traits::edge_descriptor edge_descriptor; + + get_in_or_out_values(const Graph& g, dynamic_property_map& dmap, const vertex_descriptor& v) + : _g(g),_dmap(dmap),_v(v){} + + python::object operator()() + { + if (In) + return get_in_props(_g, _v, typename is_convertible::directed_category, undirected_tag>::type()); + else + return get_out_props(); + } + + python::object get_out_props() + { + python::list props; + typename graph_traits::out_edge_iterator e,e_end; + for (tie(e, e_end) = out_edges(_v, _g); e != e_end; ++e) + { + get_value::edge_descriptor> value(_dmap, *e); + props.append(value()); + } + return props; + } + + template + python::object get_in_props(const G& g, typename graph_traits::vertex_descriptor v, true_type) + { + python::list props; + typename graph_traits::in_edge_iterator e,e_end; + for (tie(e, e_end) = in_edges(v, g); e != e_end; ++e) + { + get_value::edge_descriptor> value(_dmap, *e); + props.append(value()); + } + return props; + } + + + template + python::object get_in_props(const G& g, typename graph_traits::vertex_descriptor v, false_type) + { + python::list props; + return props; + } + + const Graph& _g; + const dynamic_property_map& _dmap; + const vertex_descriptor& _v; + }; + + template struct get_source_or_target_value {