Commit 51632e6c authored by Tiago Peixoto's avatar Tiago Peixoto

* make range and python filtering independently optional

* accept external files for property editing routines
* include in_PROP() andd out_PROP() functions to be used in python filtering/property editing routines.


git-svn-id: https://svn.forked.de/graph-tool/trunk@71 d4600afd-f417-0410-95de-beed9576f240
parent 28411b14
...@@ -99,20 +99,37 @@ AC_ARG_ENABLE([static-linkage], [AC_HELP_STRING([--enable-static-linkage], ...@@ -99,20 +99,37 @@ AC_ARG_ENABLE([static-linkage], [AC_HELP_STRING([--enable-static-linkage],
[AC_MSG_RESULT(no)] ) [AC_MSG_RESULT(no)] )
AM_CONDITIONAL(STATIC, test $STATIC = yes) AM_CONDITIONAL(STATIC, test $STATIC = yes)
AC_MSG_CHECKING(whether to enable graph filtering...) AC_MSG_CHECKING(whether to enable graph python filtering...)
AC_ARG_ENABLE([filtering], [AC_HELP_STRING([--disable-filtering], AC_ARG_ENABLE([python-filtering], [AC_HELP_STRING([--enable-python-filtering],
[disable graph filtering (range and python only) [default=no] ])], [enable python graph filtering [default=no] ])],
if test $enableval = no; then if test $enableval = no; then
[AC_MSG_RESULT(no)] [AC_MSG_RESULT(no)]
[AC_DEFINE([NO_FILTERING], 1, [disable graph filtering])] [AC_DEFINE([NO_PYTHON_FILTERING], 1, [disable graph filtering])]
NO_FILTERING=yes 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 else
[AC_MSG_RESULT(yes)] [AC_MSG_RESULT(yes)]
fi fi
, ,
[AC_MSG_RESULT(yes)] [AC_MSG_RESULT(yes)]
NO_FILTERING=no NO_RANGE_FILTERING=no
) )
dnl Checks for programs. dnl Checks for programs.
......
...@@ -767,8 +767,12 @@ def parse_option(opt, just_file=False): ...@@ -767,8 +767,12 @@ def parse_option(opt, just_file=False):
if just_file: if just_file:
return None return None
edit_vars = dict() edit_vars = dict()
def edit_function(): if "file:" in values[1]:
return (eval(values[1],edit_vars)) 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": if opt.name == "edit-vertex-property":
graph.EditVertexProperty(values[0],(edit_function,edit_vars)) graph.EditVertexProperty(values[0],(edit_function,edit_vars))
else: else:
......
...@@ -91,7 +91,7 @@ GraphInterface::~GraphInterface() ...@@ -91,7 +91,7 @@ GraphInterface::~GraphInterface()
void GraphInterface::SetVertexFilterProperty(string property) void GraphInterface::SetVertexFilterProperty(string property)
{ {
#ifndef NO_FILTERING #ifndef NO_RANGE_FILTERING
_vertex_filter_property = property; _vertex_filter_property = property;
if (property != "") if (property != "")
...@@ -119,7 +119,7 @@ void GraphInterface::SetVertexFilterProperty(string property) ...@@ -119,7 +119,7 @@ void GraphInterface::SetVertexFilterProperty(string property)
} }
} }
#else #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 #endif
} }
...@@ -127,7 +127,7 @@ bool GraphInterface::IsVertexFilterActive() const { return _vertex_filter_proper ...@@ -127,7 +127,7 @@ bool GraphInterface::IsVertexFilterActive() const { return _vertex_filter_proper
void GraphInterface::SetEdgeFilterProperty(string property) void GraphInterface::SetEdgeFilterProperty(string property)
{ {
#ifndef NO_FILTERING #ifndef NO_RANGE_FILTERING
_edge_filter_property = property; _edge_filter_property = property;
if (property != "") if (property != "")
...@@ -156,7 +156,7 @@ void GraphInterface::SetEdgeFilterProperty(string property) ...@@ -156,7 +156,7 @@ void GraphInterface::SetEdgeFilterProperty(string property)
} }
#else #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 #endif
} }
...@@ -164,29 +164,29 @@ bool GraphInterface::IsEdgeFilterActive() const {return _edge_filter_property != ...@@ -164,29 +164,29 @@ bool GraphInterface::IsEdgeFilterActive() const {return _edge_filter_property !=
void GraphInterface::SetVertexFilterRange(std::pair<double,double> allowed_range) void GraphInterface::SetVertexFilterRange(std::pair<double,double> allowed_range)
{ {
#ifndef NO_FILTERING #ifndef NO_RANGE_FILTERING
_vertex_range = allowed_range; _vertex_range = allowed_range;
#else #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 #endif
} }
void GraphInterface::SetGenericVertexFilter(boost::python::object filter) void GraphInterface::SetGenericVertexFilter(boost::python::object filter)
{ {
#ifndef NO_FILTERING #ifndef NO_PYTHON_FILTERING
_vertex_python_filter = filter; _vertex_python_filter = filter;
#else #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 #endif
} }
void GraphInterface::SetGenericEdgeFilter(boost::python::object filter) void GraphInterface::SetGenericEdgeFilter(boost::python::object filter)
{ {
#ifndef NO_FILTERING #ifndef NO_PYTHON_FILTERING
_edge_python_filter = filter; _edge_python_filter = filter;
#else #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 #endif
} }
......
...@@ -244,13 +244,14 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck ...@@ -244,13 +244,14 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck
{ {
bool found = false; bool found = false;
#ifndef NO_FILTERING
typedef RangeFilter<GraphInterface::vertex_filter_map_t> vertex_filter_t; typedef RangeFilter<GraphInterface::vertex_filter_map_t> vertex_filter_t;
typedef RangeFilter<GraphInterface::edge_filter_map_t> edge_filter_t; typedef RangeFilter<GraphInterface::edge_filter_map_t> edge_filter_t;
#ifndef NO_PYTHON_FILTERING
if (g._edge_python_filter == python::object() && g._vertex_python_filter == python::object()) 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 != "") if (g._vertex_filter_property != "" && g._edge_filter_property != "")
{ {
typedef filtered_graph<GraphInterface::multigraph_t, edge_filter_t, vertex_filter_t> fg_t; typedef filtered_graph<GraphInterface::multigraph_t, edge_filter_t, vertex_filter_t> fg_t;
...@@ -273,16 +274,19 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck ...@@ -273,16 +274,19 @@ void check_filter(const GraphInterface &g, Action a, ReverseCheck, DirectedCheck
{ {
mpl::for_each<DirectedCheck>(check_directed<GraphInterface::multigraph_t,Action,ReverseCheck>(g._mg, a, g._reversed, g._directed, found)); mpl::for_each<DirectedCheck>(check_directed<GraphInterface::multigraph_t,Action,ReverseCheck>(g._mg, a, g._reversed, g._directed, found));
} }
#else
mpl::for_each<DirectedCheck>(check_directed<GraphInterface::multigraph_t,Action,ReverseCheck>(g._mg, a, g._reversed, g._directed, found));
#endif
#ifndef NO_PYTHON_FILTERING
} }
else else
{ {
check_python_filter(g._mg, g, a, found, ReverseCheck(), DirectedCheck()); check_python_filter(g._mg, g, a, found, ReverseCheck(), DirectedCheck());
} }
#else
#else #ifdef NO_RANGE_FILTERING
mpl::for_each<DirectedCheck>(check_directed<GraphInterface::multigraph_t,Action,ReverseCheck>(g._mg, a, g._reversed, g._directed, found)); mpl::for_each<DirectedCheck>(check_directed<GraphInterface::multigraph_t,Action,ReverseCheck>(g._mg, a, g._reversed, g._directed, found));
#endif
#endif #endif
if (!found) if (!found)
......
...@@ -66,6 +66,17 @@ struct populate_python_funcs ...@@ -66,6 +66,17 @@ struct populate_python_funcs
typedef typename mpl::if_<HasBase, degrees, mpl::vector<> >::type base_degrees; typedef typename mpl::if_<HasBase, degrees, mpl::vector<> >::type base_degrees;
mpl::for_each<base_degrees>(put_base_degree_function<Graph>(g, v, variables, "orig_")); mpl::for_each<base_degrees>(put_base_degree_function<Graph>(g, v, variables, "orig_"));
for(typeof(dp.begin()) iter = dp.begin(); iter != dp.end(); ++iter)
{
if (iter->second->key() != typeid(typename graph_traits<Graph>::vertex_descriptor)) // FIXME: graph properties?x
{
variables["in_"+iter->first] = python::make_function(get_in_or_out_values<Graph,true>(g, *iter->second, v),
python::default_call_policies(), mpl::vector<python::object>::type());
variables["out_"+iter->first] = python::make_function(get_in_or_out_values<Graph,false>(g, *iter->second, v),
python::default_call_policies(), mpl::vector<python::object>::type());
}
}
} }
template <class Graph> template <class Graph>
...@@ -125,6 +136,62 @@ struct populate_python_funcs ...@@ -125,6 +136,62 @@ struct populate_python_funcs
python::object _retval; python::object _retval;
}; };
template <class Graph, bool In>
struct get_in_or_out_values
{
typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
typedef typename graph_traits<Graph>::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<typename graph_traits<Graph>::directed_category, undirected_tag>::type());
else
return get_out_props();
}
python::object get_out_props()
{
python::list props;
typename graph_traits<Graph>::out_edge_iterator e,e_end;
for (tie(e, e_end) = out_edges(_v, _g); e != e_end; ++e)
{
get_value<typename graph_traits<Graph>::edge_descriptor> value(_dmap, *e);
props.append(value());
}
return props;
}
template<class G>
python::object get_in_props(const G& g, typename graph_traits<G>::vertex_descriptor v, true_type)
{
python::list props;
typename graph_traits<G>::in_edge_iterator e,e_end;
for (tie(e, e_end) = in_edges(v, g); e != e_end; ++e)
{
get_value<typename graph_traits<Graph>::edge_descriptor> value(_dmap, *e);
props.append(value());
}
return props;
}
template<class G>
python::object get_in_props(const G& g, typename graph_traits<G>::vertex_descriptor v, false_type)
{
python::list props;
return props;
}
const Graph& _g;
const dynamic_property_map& _dmap;
const vertex_descriptor& _v;
};
template <class Graph, bool Source> template <class Graph, bool Source>
struct get_source_or_target_value struct get_source_or_target_value
{ {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment