bindings/python/simplex.cpp
author Dmitriy Morozov <dmitriy@mrzv.org>
Fri, 10 Apr 2009 14:35:43 -0700
branchdev
changeset 123 c50e7020a1e4
parent 112 f209958b5c17
child 127 406c6cc00b9c
permissions -rw-r--r--
Added intrusive containers issue and issue filters

#include <topology/simplex.h>
#include <utilities/indirect.h>
#include <iostream>

#include <boost/python.hpp>
#include <boost/python/stl_iterator.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/functional/hash.hpp>
using namespace boost::python;

/* Various wrappers for exposing Simplex to Python */
// `data` property
template<class V, class T>
typename Simplex<V,T>::Data         get_data(const Simplex<V,T>& s)             { return s.data(); }
template<class V, class T>
void                                set_data(Simplex<V,T>& s, 
                                             typename Simplex<V,T>::Data d)     { s.data() = d; }
// `vertices` property
template<class V, class T>
typename Simplex<V,T>::VertexContainer::const_iterator
                                    vertices_begin(const Simplex<V,T>& s)       { return s.vertices().begin(); }
template<class V, class T>
typename Simplex<V,T>::VertexContainer::const_iterator
                                    vertices_end(const Simplex<V,T>& s)         { return s.vertices().end(); }

// Constructor from iterator
template<class V, class T>
boost::shared_ptr<Simplex<V,T> >    init_from_iterator(object iter)                      
{ 
    boost::shared_ptr<Simplex<V,T> > p(new Simplex<V,T>(stl_input_iterator<V>(iter), stl_input_iterator<V>()));
    return p;
}

// Constructor from iterator and data
template<class V, class T>
boost::shared_ptr<Simplex<V,T> >    init_from_iterator_data(object iter, T data)                      
{ 
    boost::shared_ptr<Simplex<V,T> > p(new Simplex<V,T>(stl_input_iterator<V>(iter), stl_input_iterator<V>(), data));
    return p;
}

// Simplex hash
template<class V, class T>
size_t                              hash_simplex(const Simplex<V,T>& s)
{
    return boost::hash_range(s.vertices().begin(), s.vertices().end());
}

template<class V, class T>
size_t                              eq_simplex(const Simplex<V,T>& a, const Simplex<V,T>& b)
{
    return vertex_comparison(a,b) == 0;
}


/* Comparisons */
// VertexComparison
template<class V, class T>
int                                 vertex_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
{
    return ThreeOutcomeCompare<typename Simplex<V,T>::VertexComparison>().compare(a,b);
}

// DataComparison
template<class V, class T>
int                                 data_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
{
    return ThreeOutcomeCompare<typename Simplex<V,T>::DataComparison>().compare(a,b);
}

// DataDimensionComparison
template<class V, class T>
int                                 data_dimension_comparison(const Simplex<V,T>& a, const Simplex<V,T>& b)
{
    return ThreeOutcomeCompare<DataDimensionComparison<Simplex<V,T> > >().compare(a,b);
}

#include "python-simplex.h"         // defines SimplexVD, Vertex, and Data

void export_simplex()
{
    class_<SimplexVD>("Simplex")
        .def("__init__",            make_constructor(&init_from_iterator<Vertex, Data>))
        .def("__init__",            make_constructor(&init_from_iterator_data<Vertex, Data>))

        .def("add",                 &SimplexVD::add)
        .add_property("boundary",   range(&SimplexVD::boundary_begin, &SimplexVD::boundary_end))
        .def("contains",            &SimplexVD::contains)
        .def("join",                (void (SimplexVD::*)(const SimplexVD&)) &SimplexVD::join)
        .def("dimension",           &SimplexVD::dimension)
        .add_property("data",       &get_data<Vertex,Data>, &set_data<Vertex,Data>)
        
        .add_property("vertices",   range(&vertices_begin<Vertex,Data>, &vertices_end<Vertex,Data>))
        .def(repr(self))

        .def("__hash__",            &hash_simplex<Vertex, Data>)
        .def("__eq__",              &eq_simplex<Vertex, Data>)
    ;

    def("vertex_cmp",               &vertex_comparison<Vertex, Data>);
    def("data_cmp",                 &data_comparison<Vertex, Data>);
    def("data_dim_cmp",             &data_dimension_comparison<Vertex, Data>);
}