42 #ifndef VIGRA_PYTHON_GRAPH_HXX 
   43 #define VIGRA_PYTHON_GRAPH_HXX 
   46 #include <boost/python.hpp> 
   47 #include <boost/iterator/transform_iterator.hpp> 
   50 #include <vigra/graphs.hxx> 
   51 #include <vigra/numpy_array.hxx> 
   52 #include <vigra/multi_gridgraph.hxx> 
   53 #include <vigra/graph_generalization.hxx> 
   54 #include <vigra/multi_array.hxx> 
   55 #include <vigra/graphs.hxx> 
   56 #include <vigra/priority_queue.hxx> 
   57 #include <vigra/merge_graph_adaptor.hxx> 
   66 struct GraphMapTypeTraits;
 
   68 template< 
unsigned int DIM,
class T>
 
   69 struct GraphMapTypeTraits<NumpyArray<DIM,T> >{
 
   70     typedef typename NumpyArray<DIM,T>::value_type Value;
 
   71     typedef Value &                                Reference;
 
   72     typedef const Value  &                         ConstReference;
 
   78 struct NodeHolder :  GRAPH::Node
 
   80     typedef typename GRAPH::Node Node;
 
   81     NodeHolder(
const lemon::Invalid &  = lemon::INVALID)
 
   82     : Node(lemon::INVALID),
 
   85     NodeHolder(
const GRAPH & g , 
const Node & item)
 
   90     typename GRAPH::index_type id()
const{
 
   91         return graph_->id(*
this);
 
   94     typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicNodeMapShape
 
   95     intrinsicNodeCoordinate()
const{
 
   96         return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicNodeCoordinate(*graph_,*
this);
 
  104 template<
class GRAPH>
 
  105 struct EdgeHolder : GRAPH::Edge
 
  108     typedef typename GRAPH::Edge Edge;
 
  109     EdgeHolder(
const lemon::Invalid &  = lemon::INVALID)
 
  110     : Edge(lemon::INVALID),
 
  113     EdgeHolder(
const GRAPH & g , 
const Edge & item)
 
  118     typename GRAPH::index_type id()
const{
 
  119         return graph_->id(*
this);
 
  122     NodeHolder<GRAPH> u()
const{
 
  123         return NodeHolder<GRAPH>(*graph_,graph_->u(*
this));
 
  125     NodeHolder<GRAPH> v()
const{
 
  126         return NodeHolder<GRAPH>(*graph_,graph_->v(*
this));
 
  129     typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicEdgeMapShape
 
  130     intrinsicEdgeCoordinate()
const{
 
  131         return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicEdgeCoordinate(*graph_,*
this);
 
  134     const GRAPH * graph_; 
 
  139 template<
class GRAPH>
 
  140 struct ArcHolder: GRAPH::Arc {
 
  141     typedef typename GRAPH::Arc Arc;
 
  142     ArcHolder(
const lemon::Invalid &  = lemon::INVALID)
 
  143     : Arc(lemon::INVALID),
 
  146     ArcHolder(
const GRAPH & g , 
const Arc & item)
 
  151     typename GRAPH::index_type id()
const{
 
  152         return graph_->id(*
this);
 
  155     typename GraphDescriptorToMultiArrayIndex<GRAPH>::IntrinsicArcMapShape
 
  156     intrinsicArcCoordinate()
const{
 
  157         return GraphDescriptorToMultiArrayIndex<GRAPH>::intrinsicArcCoordinate(*graph_,*
this);
 
  161     const GRAPH * graph_;
 
  165 namespace detail_python_graph{
 
  167 template<
class GRAPH>
 
  168 struct ArcToTargetNodeHolder{
 
  169     typedef typename GRAPH::Node Node;
 
  170     typedef typename GRAPH::Arc Arc;
 
  171     ArcToTargetNodeHolder(
const GRAPH & graph)
 
  174     NodeHolder<GRAPH> operator()(
const Arc & arc)
const{
 
  175         return NodeHolder<GRAPH>(*graph_,graph_->target(arc));
 
  177     const GRAPH * graph_;
 
  180 template<
class GRAPH>
 
  181 struct ArcToEdgeHolder{
 
  182     typedef typename GRAPH::Edge Edge;
 
  183     typedef typename GRAPH::Arc Arc;
 
  184     ArcToEdgeHolder(
const GRAPH & graph)
 
  187     EdgeHolder<GRAPH> operator()(
const Arc & arc)
const{
 
  188         const Edge 
edge(arc);
 
  189         return EdgeHolder<GRAPH>(*graph_,
edge);
 
  191     const GRAPH * graph_;
 
  194 template<
class GRAPH>
 
  195 struct ArcToArcHolder{
 
  196     typedef typename GRAPH::Edge Edge;
 
  197     typedef typename GRAPH::Arc Arc;
 
  198     ArcToArcHolder(
const GRAPH & graph)
 
  201     ArcHolder<GRAPH> operator()(
const Arc & arc)
const{
 
  202         return ArcHolder<GRAPH>(*graph_,arc);
 
  204     const GRAPH * graph_;
 
  208 template<
class GRAPH>
 
  209 struct NodeToNodeHolder{
 
  210     typedef typename GRAPH::Node Node;
 
  211     NodeToNodeHolder(
const GRAPH & graph)
 
  214     NodeHolder<GRAPH> operator()(
const Node & node)
const{
 
  215         return NodeHolder<GRAPH>(*graph_,node);
 
  217     const GRAPH * graph_;
 
  220 template<
class GRAPH>
 
  221 struct EdgeToEdgeHolder{
 
  222     typedef typename GRAPH::Edge Edge;
 
  223     EdgeToEdgeHolder(
const GRAPH & graph)
 
  226     EdgeHolder<GRAPH> operator()(
const Edge & 
edge)
const{
 
  227         return EdgeHolder<GRAPH>(*graph_,
edge);
 
  229     const GRAPH * graph_;
 
  236 template<
class GRAPH>
 
  237 struct NodeIteratorHolder{
 
  238     typedef typename GRAPH::Node Node;
 
  239     typedef typename GRAPH::NodeIt Iter;
 
  240     typedef detail_python_graph::NodeToNodeHolder<GRAPH> Transform;
 
  241     typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
 
  242     NodeIteratorHolder(
const GRAPH & graph,
const Node & node = Node(lemon::INVALID) )
 
  246     const_iterator begin()
const{
 
  248         Iter iter = GraphIteratorAccessor<GRAPH>::nodesBegin(*graph_);
 
  249         return const_iterator(iter,Transform(*graph_));
 
  251     const_iterator end()
const{
 
  252         Iter iter = GraphIteratorAccessor<GRAPH>::nodesEnd(*graph_);
 
  253         return const_iterator(iter,Transform(*graph_));
 
  255     const GRAPH * graph_;
 
  259 template<
class GRAPH>
 
  260 struct EdgeIteratorHolder{
 
  261     typedef typename GRAPH::Edge Edge;
 
  262     typedef typename GRAPH::EdgeIt Iter;
 
  263     typedef detail_python_graph::EdgeToEdgeHolder<GRAPH> Transform;
 
  264     typedef boost::transform_iterator<Transform ,Iter ,EdgeHolder<GRAPH>, EdgeHolder<GRAPH> > const_iterator;
 
  265     EdgeIteratorHolder(
const GRAPH & graph,
const Edge & 
edge = Edge(lemon::INVALID) )
 
  269     const_iterator begin()
const{
 
  271         Iter iter = GraphIteratorAccessor<GRAPH>::edgesBegin(*graph_);
 
  272         return const_iterator(iter,Transform(*graph_));
 
  274     const_iterator end()
const{
 
  275         Iter iter = GraphIteratorAccessor<GRAPH>::edgesEnd(*graph_);
 
  276         return const_iterator(iter,Transform(*graph_));
 
  278     const GRAPH * graph_;
 
  283 template<
class GRAPH>
 
  284 struct NeighbourNodeIteratorHolder{
 
  285     typedef typename GRAPH::Node Node;
 
  286     typedef typename GRAPH::OutArcIt Iter;
 
  287     typedef detail_python_graph::ArcToTargetNodeHolder<GRAPH> Transform;
 
  288     typedef boost::transform_iterator<Transform ,Iter ,NodeHolder<GRAPH>, NodeHolder<GRAPH> > const_iterator;
 
  289     NeighbourNodeIteratorHolder(
const GRAPH & graph,
const Node & node)
 
  293     const_iterator begin()
const{
 
  294         Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
 
  295         return const_iterator(iter,Transform(*graph_));
 
  297     const_iterator end()
const{
 
  298         Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
 
  299         return const_iterator(iter,Transform(*graph_));
 
  301     const GRAPH * graph_;
 
  306 template<
class GRAPH>
 
  307 struct IncEdgeIteratorHolder{
 
  308     typedef typename GRAPH::Node Node;
 
  309     typedef typename GRAPH::Edge Edge;
 
  310     typedef typename GRAPH::OutArcIt Iter;
 
  311     typedef detail_python_graph::ArcToArcHolder<GRAPH> Transform;
 
  312     typedef boost::transform_iterator<Transform ,Iter ,ArcHolder<GRAPH>, ArcHolder<GRAPH> > const_iterator;
 
  313     IncEdgeIteratorHolder(
const GRAPH & graph,
const Node & node)
 
  317     const_iterator begin()
const{
 
  318         Iter iter = GraphIteratorAccessor<GRAPH>::outArcBegin(*graph_,node_);
 
  319         return const_iterator(iter,Transform(*graph_));
 
  321     const_iterator end()
const{
 
  322         Iter iter = GraphIteratorAccessor<GRAPH>::outArcEnd(*graph_,node_);
 
  323         return const_iterator(iter,Transform(*graph_));
 
  325     const GRAPH * graph_;
 
  330 template<
class G,
class AV>
 
  331 class NumpyScalarEdgeMap{
 
  335     typedef AV ArrayView;
 
  336     typedef typename  Graph::Edge                Key;
 
  337     typedef typename  ArrayView::value_type      Value;
 
  338     typedef typename  ArrayView::reference       Reference;
 
  339     typedef typename  ArrayView::const_reference ConstReference;
 
  341     typedef typename  Graph::Edge                key_type;
 
  342     typedef typename  ArrayView::value_type      value_type;
 
  343     typedef typename  ArrayView::reference       reference;
 
  344     typedef typename  ArrayView::const_reference const_reference;
 
  351     NumpyScalarEdgeMap(
const Graph & graph,ArrayView array)
 
  356     Reference operator[](
const Key & key){
 
  357         return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
 
  359     ConstReference operator[](
const Key & key)
const{
 
  360         return   array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
 
  366     const Graph * graph_;
 
  367     MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension,Value> array_;
 
  371 template<
class G,
class AV>
 
  372 class NumpyScalarNodeMap{
 
  376     typedef AV ArrayView;
 
  377     typedef typename  Graph::Node                Key;
 
  378     typedef typename  ArrayView::value_type      Value;
 
  379     typedef typename  ArrayView::reference       Reference;
 
  380     typedef typename  ArrayView::const_reference ConstReference;
 
  382     typedef typename  Graph::Node                key_type;
 
  383     typedef typename  ArrayView::value_type      value_type;
 
  384     typedef typename  ArrayView::reference       reference;
 
  385     typedef typename  ArrayView::const_reference const_reference;
 
  394     NumpyScalarNodeMap(
const Graph & graph,ArrayView array)
 
  399     Reference operator[](
const Key & key){
 
  400         return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
 
  402     ConstReference operator[](
const Key & key)
const{
 
  403         return   array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
 
  409     const Graph * graph_;
 
  410     MultiArrayView<IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension,Value> array_;
 
  415 template<
class G,
class AV>
 
  416 class NumpyMultibandNodeMap{
 
  420     typedef AV ArrayView;
 
  421     typedef typename  Graph::Node                Key;
 
  422     typedef typename  Graph::Node                key_type;
 
  428     typedef  MultiArray<1,typename AV::value_type>           Value;
 
  429     typedef  MultiArrayView<1,typename AV::value_type>       Reference;
 
  430     typedef  MultiArrayView<1,typename AV::value_type> ConstReference;
 
  431     typedef  MultiArray<1,typename AV::value_type>           value_type;
 
  432     typedef  MultiArrayView<1,typename AV::value_type>       reference;
 
  433     typedef  MultiArrayView<1,typename AV::value_type> const_reference;
 
  437     NumpyMultibandNodeMap()
 
  442     NumpyMultibandNodeMap(
const Graph & graph,ArrayView array)
 
  447     Reference operator[](
const Key & key){
 
  448         return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
 
  450     ConstReference operator[](
const Key & key)
const{
 
  451         return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicNodeCoordinate(*graph_,key)];
 
  457     const Graph * graph_;
 
  463 template<
class G,
class AV>
 
  464 class NumpyMultibandEdgeMap{
 
  468     typedef AV ArrayView;
 
  469     typedef typename  Graph::Edge                Key;
 
  470     typedef typename  Graph::Edge                key_type;
 
  476     typedef  MultiArray<1,typename AV::value_type>           Value;
 
  477     typedef  MultiArrayView<1,typename AV::value_type>       Reference;
 
  478     typedef  MultiArrayView<1,typename AV::value_type> ConstReference;
 
  479     typedef  MultiArray<1,typename AV::value_type>           value_type;
 
  480     typedef  MultiArrayView<1,typename AV::value_type>       reference;
 
  481     typedef  MultiArrayView<1,typename AV::value_type> const_reference;
 
  485     NumpyMultibandEdgeMap()
 
  490     NumpyMultibandEdgeMap(
const Graph & graph,ArrayView array)
 
  495     Reference operator[](
const Key & key){
 
  496         return array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
 
  498     ConstReference operator[](
const Key & key)
const{
 
  499         return   array_[GraphDescriptorToMultiArrayIndex<Graph>::intrinsicEdgeCoordinate(*graph_,key)];
 
  505     const Graph * graph_;
 
  518 class TaggedGraphShape{
 
  521     const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension;
 
  522     const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension;
 
  523     const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension;
 
  524     static TaggedShape  taggedNodeMapShape(
const Graph & graph){
 
  525         return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),
"n");
 
  527     static TaggedShape  taggedEdgeMapShape(
const Graph & graph){
 
  528         return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),
"e");
 
  530     static TaggedShape  taggedArcMapShape(
const Graph & graph){
 
  531         return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),
"e");
 
  534     static AxisInfo  axistagsNodeMap(
const Graph & ){
 
  535         return AxisInfo(
"n");
 
  537     static AxisInfo  axistagsEdgeMap(
const Graph & ){
 
  538         return AxisInfo(
"e");
 
  540     static AxisTags  axistagsArcMap(
const Graph & ){
 
  541         return AxisInfo(
"e");
 
  547 #define VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(DIM,tn,te,ta) \ 
  548 template<class BOOST_DIRECTED_TAG> \ 
  549 class TaggedGraphShape<GridGraph<DIM,BOOST_DIRECTED_TAG> >{ \ 
  551     typedef GridGraph<DIM,BOOST_DIRECTED_TAG> Graph; \ 
  552     const static unsigned int ND = IntrinsicGraphShape<Graph>::IntrinsicNodeMapDimension; \ 
  553     const static unsigned int ED = IntrinsicGraphShape<Graph>::IntrinsicEdgeMapDimension; \ 
  554     const static unsigned int AD = IntrinsicGraphShape<Graph>::IntrinsicArcMapDimension; \ 
  555     static TaggedShape  taggedNodeMapShape(const Graph & graph){ \ 
  556        return NumpyArray<ND,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicNodeMapShape(graph),tn); \ 
  558     static TaggedShape  taggedEdgeMapShape(const Graph & graph){  \ 
  559        return NumpyArray<ED,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicEdgeMapShape(graph),te);  \ 
  561     static TaggedShape  taggedArcMapShape(const Graph & graph){  \ 
  562        return NumpyArray<AD,int>::ArrayTraits::taggedShape(IntrinsicGraphShape<Graph>::intrinsicArcMapShape(graph),ta);  \ 
  564     static AxisInfo  axistagsNodeMap(const Graph & ){ \ 
  565         return AxisInfo(tn); \ 
  567     static AxisInfo  axistagsEdgeMap(const Graph & ){ \ 
  568         return AxisInfo(te); \ 
  570     static AxisTags  axistagsArcMap(const Graph & ){ \ 
  571         return AxisInfo(ta); \ 
  575 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(1,
"x",
"xe",
"xe");
 
  576 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(2,
"xy",
"xye",
"xye");
 
  577 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(3,
"xyz",
"xyze",
"xyze");
 
  578 VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO(4,
"xyzt",
"xyzte",
"xyzte");
 
  580 #undef VIGRA_MAKE_TAGGED_GRAPH_SHAPE_MACRO 
  620 template<
class G,
class T>
 
  624         IsMultiband<T>::value,
 
  625         NumpyMultibandNodeMap< G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > , 
 
  626         NumpyScalarNodeMap<    G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension  ,T> >
 
  630     typedef typename IfBool<
 
  631         IsMultiband<T>::value,
 
  632         NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> , 
 
  633         NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension  ,T>
 
  634     >::type NumpyArrayType;
 
  637     typedef typename IfBool<
 
  638         IsMultiband<T>::value,
 
  639         NumpyMultibandNodeMap< G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> > , 
 
  640         NumpyScalarNodeMap<    G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension  ,T> >
 
  643     NumpyNodeMap(
const G & g, NumpyArrayType numpyArray)
 
  644     :BaseType(g,numpyArray){
 
  650 template<
class G,
class T>
 
  654         IsMultiband<T>::value,
 
  655         NumpyMultibandEdgeMap< G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > , 
 
  656         NumpyScalarEdgeMap<    G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension  ,T> >
 
  660     typedef typename IfBool<
 
  661         IsMultiband<T>::value,
 
  662         NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> , 
 
  663         NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension  ,T>
 
  664     >::type NumpyArrayType;
 
  667     typedef typename IfBool<
 
  668         IsMultiband<T>::value,
 
  669         NumpyMultibandEdgeMap< G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> > , 
 
  670         NumpyScalarEdgeMap<    G ,  NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension  ,T> >
 
  673     NumpyEdgeMap(
const G & g, NumpyArrayType numpyArray)
 
  674     :BaseType(g,numpyArray){
 
  681 template<
class G,
class T>
 
  682 struct PyEdgeMapTraits{
 
  683     typedef NumpyEdgeMap<G,T> Map;
 
  684     typedef typename IfBool<
 
  685         IsMultiband<T>::value,
 
  686         NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension+1,T> , 
 
  687         NumpyArray<IntrinsicGraphShape<G>::IntrinsicEdgeMapDimension  ,T>
 
  694 template<
class G,
class T>
 
  695 struct PyNodeMapTraits{
 
  696     typedef NumpyNodeMap<G,T> Map;
 
  697     typedef typename IfBool<
 
  698         IsMultiband<T>::value,
 
  699         NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension+1,T> , 
 
  700         NumpyArray<IntrinsicGraphShape<G>::IntrinsicNodeMapDimension  ,T>
 
  705 namespace cluster_operators{
 
  707 template<
class MERGE_GRAPH>
 
  708 class PythonOperator{
 
  710     typedef PythonOperator<MERGE_GRAPH > SelfType;
 
  714     typedef float WeightType;
 
  715     typedef MERGE_GRAPH MergeGraph;
 
  716     typedef typename MergeGraph::Graph Graph;
 
  717     typedef typename Graph::Edge GraphEdge;
 
  718     typedef typename Graph::Node GraphNode;
 
  719     typedef typename MergeGraph::Edge Edge;
 
  720     typedef typename MergeGraph::Node Node;
 
  721     typedef typename MergeGraph::EdgeIt EdgeIt;
 
  722     typedef typename MergeGraph::NodeIt NodeIt;
 
  723     typedef typename MergeGraph::IncEdgeIt IncEdgeIt;
 
  724     typedef typename MergeGraph::index_type index_type;
 
  725     typedef MergeGraphItemHelper<MergeGraph,Edge> EdgeHelper;
 
  726     typedef MergeGraphItemHelper<MergeGraph,Node> NodeHelper;
 
  729     typedef NodeHolder<MERGE_GRAPH> NodeHolderType;
 
  730     typedef EdgeHolder<MERGE_GRAPH> EdgeHolderType;
 
  733         MergeGraph & mergeGraph,
 
  734         boost::python::object 
object,
 
  735         const bool useMergeNodeCallback,
 
  736         const bool useMergeEdgesCallback,
 
  737         const bool useEraseEdgeCallback
 
  739     :   mergeGraph_(mergeGraph),
 
  742         if(useMergeNodeCallback){
 
  743             typedef typename MergeGraph::MergeNodeCallBackType Callback;
 
  744             Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeNodes>(
this));
 
  745             mergeGraph_.registerMergeNodeCallBack(cb);
 
  748         if(useMergeEdgesCallback){
 
  749             typedef typename MergeGraph::MergeEdgeCallBackType Callback;
 
  750             Callback cb(Callback:: template from_method<SelfType,&SelfType::mergeEdges>(
this));
 
  751             mergeGraph_.registerMergeEdgeCallBack(cb);
 
  753         if(useEraseEdgeCallback){
 
  754             typedef typename MergeGraph::EraseEdgeCallBackType Callback;
 
  755             Callback cb(Callback:: template from_method<SelfType,&SelfType::eraseEdge>(
this));
 
  756             mergeGraph_.registerEraseEdgeCallBack(cb);
 
  763             retVal =  boost::python::extract<bool>(object_.attr(
"done")());
 
  765         catch(std::exception & e){
 
  766             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  767             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::done");
 
  771     void mergeEdges(
const Edge & a,
const Edge & b){
 
  773             const EdgeHolderType aa(mergeGraph_,a);
 
  774             const EdgeHolderType bb(mergeGraph_,b);
 
  775             object_.attr(
"mergeEdges")(aa,bb);
 
  777         catch(std::exception & e){
 
  778             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  779             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::mergeEdges");
 
  782     void mergeNodes(
const Node & a,
const Node & b){\
 
  784             const NodeHolderType aa(mergeGraph_,a);
 
  785             const NodeHolderType bb(mergeGraph_,b);
 
  786             object_.attr(
"mergeNodes")(aa,bb);
 
  788         catch(std::exception & e){
 
  789             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  790             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::mergeNodes");
 
  793     void eraseEdge(
const Edge & e){
 
  795             const EdgeHolderType ee(mergeGraph_,e);
 
  796             object_.attr(
"eraseEdge")(ee);
 
  798         catch(std::exception & e){
 
  799             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  800             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::eraseEdge");
 
  803     Edge contractionEdge(){
 
  806             eh = boost::python::extract<EdgeHolderType>(object_.attr(
"contractionEdge")());
 
  808         catch(std::exception & e){
 
  809             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  810             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::contractionEdge");
 
  814     WeightType contractionWeight()
const{
 
  817             w = boost::python::extract<WeightType>(object_.attr(
"contractionWeight")());
 
  819         catch(std::exception & e){
 
  820             std::cout<<
"reason: "<<e.what()<<
"\n";
 
  821             throw std::runtime_error(
"error while calling cluster_operators PythonOperator::contractionWeight");
 
  826     MergeGraph & mergeGraph(){
 
  830     MergeGraph & mergeGraph_;
 
  831     boost::python::object object_;
 
  839 #endif // VIGRA_PYTHON_GRAPH_HXX 
std::pair< typename vigra::GridGraph< N, DirectedTag >::edge_descriptor, bool > edge(typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &u, typename vigra::GridGraph< N, DirectedTag >::vertex_descriptor const &v, vigra::GridGraph< N, DirectedTag > const &g)
Return the pair (edge_descriptor, true) when an edge between vertices u and v exists, or (lemon::INVALID, false) otherwise (API: boost). 
Definition: multi_gridgraph.hxx:2990