last-svn-commit-171-ge6852b7 Wrap a subset of complexes' features.

* complex.ixx, complex2.i: New. * Makefile.am (meta_wrappers): Add complex.ixx. (wrappers): Add complex2.i. * python/Makefile.am (pyexec_LTLIBRARIES): Add _complex2.la. (nodist__complex2_la_SOURCES, _complex2_la_LIBADD): New. (CLEANFILES): Add $(nodist__complex2_la_SOURCES) complex2.py complex2.py[co]. (nodist_python_PYTHON): Add complex2.py. (complex_ixx_deps): New. (complex2-wrap.cc): Add dependencies on $(top_srcdir)/swilena/complex.ixx $(complex_ixx_deps). (TESTS): Add complex2-misc.py. * python/complex2-misc.py: New. * python/swilena.py: Import the contents of module complex2. --- swilena/ChangeLog | 19 +++ swilena/Makefile.am | 2 + swilena/complex.ixx | 330 +++++++++++++++++++++++++++++++++++++++ swilena/complex2.i | 111 +++++++++++++ swilena/python/Makefile.am | 17 ++- swilena/python/complex2-misc.py | 100 ++++++++++++ swilena/python/swilena.py | 2 + 7 files changed, 579 insertions(+), 2 deletions(-) create mode 100644 swilena/complex.ixx create mode 100644 swilena/complex2.i create mode 100644 swilena/python/complex2-misc.py diff --git a/swilena/ChangeLog b/swilena/ChangeLog index 9790b3f..7f987ec 100644 --- a/swilena/ChangeLog +++ b/swilena/ChangeLog @@ -1,3 +1,22 @@ +2010-04-08 Roland Levillain <roland@lrde.epita.fr> + + Wrap a subset of complexes' features. + + * complex.ixx, complex2.i: New. + * Makefile.am (meta_wrappers): Add complex.ixx. + (wrappers): Add complex2.i. + * python/Makefile.am (pyexec_LTLIBRARIES): Add _complex2.la. + (nodist__complex2_la_SOURCES, _complex2_la_LIBADD): New. + (CLEANFILES): Add $(nodist__complex2_la_SOURCES) complex2.py + complex2.py[co]. + (nodist_python_PYTHON): Add complex2.py. + (complex_ixx_deps): New. + (complex2-wrap.cc): Add dependencies on + $(top_srcdir)/swilena/complex.ixx $(complex_ixx_deps). + (TESTS): Add complex2-misc.py. + * python/complex2-misc.py: New. + * python/swilena.py: Import the contents of module complex2. + 2010-04-01 Roland Levillain <roland@lrde.epita.fr> Wrap function mln::morpho::tree::max<I, N>. diff --git a/swilena/Makefile.am b/swilena/Makefile.am index 98eb4f6..be32ea6 100644 --- a/swilena/Makefile.am +++ b/swilena/Makefile.am @@ -23,6 +23,7 @@ meta_wrappers = \ box.ixx \ box_piter.ixx \ ch_value.ixx \ + complex.ixx \ concat.ixx \ concrete.ixx \ coord.ixx \ @@ -41,6 +42,7 @@ meta_wrappers = \ wrappers = \ box2d.i \ box2d_piter.i \ + complex2.i \ config.i \ dpoint2d.i \ image2d_int.i \ diff --git a/swilena/complex.ixx b/swilena/complex.ixx new file mode 100644 index 0000000..ec5c196 --- /dev/null +++ b/swilena/complex.ixx @@ -0,0 +1,330 @@ +// -*- C++ -*- +// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +/// \file complex.ixx +/// \brief A wrapper of mln::topo::complex<D>. + +%module complex + +%include "concat.ixx" +%include "python-utils.ixx"; + +%{ +#include "mln/topo/n_face.hh" +#include "mln/topo/n_faces_set.hh" +#include "mln/topo/algebraic_n_face.hh" +#include "mln/topo/complex.hh" +%} + +%include "mln/topo/complex.hh"; + + +/*-------------------------------. +| Operators wrapping shortcuts. | +`-------------------------------*/ + +%define instantiate_boolean_binary_operator(Op, Name, T) +%inline +{ + bool + Name (const T & f1, const T & f2) { return f1 Op f2; } +} + +#if SWIGPYTHON +%extend T +{ + bool + __ ## Name ## __ (const T & rhs) { return *$self Op rhs; } +} +#endif // !SWIGPYTHON +%enddef // !instantiate_boolean_binary_operator + + +/* It seems we cannot use %template nor %rename to wrap (non member) + template operators. Wrap them by hand using %inline. */ + +%define instantiate_n_faces_set_binary_operator(Op, Name, N, D, LType, RType) +%inline +{ + mln::topo::n_faces_set< N, D > + Name (const LType< N, D >& f1, const RType< N, D >& f2) { return f1 Op f2; } +} + +#if SWIGPYTHON +%extend LType< N, D > +{ + mln::topo::n_faces_set< N, D > + __ ## Name ## __ (const RType< N, D >& rhs) { return *$self Op rhs; } +} +#endif // !SWIGPYTHON +%enddef // !instantiate_n_faces_set_binary_operator + +%define instantiate_n_faces_set_binary_operators(Op, Name, N, D) +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::algebraic_n_face, + mln::topo::algebraic_n_face) +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::algebraic_n_face, + mln::topo::n_face) +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::n_face, + mln::topo::algebraic_n_face) +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::n_face, + mln::topo::n_face) + +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::n_faces_set, + mln::topo::algebraic_n_face) +instantiate_n_faces_set_binary_operator(Op, Name, N, D, + mln::topo::n_faces_set, + mln::topo::n_face) +%enddef // !instantiate_n_faces_set_binary_operators + +%define instantiate_algebraic_n_face_unary_operators(N, D) +%inline +{ + mln::topo::algebraic_n_face< N, D > + neg (const mln::topo::n_face< N, D >& f) { return -f; } + + mln::topo::algebraic_n_face< N, D > + neg (const mln::topo::algebraic_n_face< N, D >& f) { return -f; } +} + +#if SWIGPYTHON +%extend mln::topo::algebraic_n_face < N, D > +{ + mln::topo::algebraic_n_face< N, D > __neg__ () { return -*$self; } +} + +%extend mln::topo::n_face < N, D > +{ + mln::topo::algebraic_n_face< N, D > __neg__ () { return -*$self; } +} +#endif // !SWIGPYTHON +%enddef // !instantiate_algebraic_n_face_unary_operators + + +/*-------. +| Face. | +`-------*/ + +%include "mln/topo/face.hh"; + +// Template members (conversions). +%define instantiate_face_data_conversions(N, D) +%extend mln::topo::face< D > +{ + // Construction from n_face<N, D>. + face< D > (const mln::topo::n_face<N, D>& f) + { + return new mln::topo::face< D >(f); + } + + // Conversion to face_data<N>. + %template(data_ ## N) data< N >; +} +%enddef // !instantiate_face_data_conversions + + +/*---------. +| N-face. | +`---------*/ + +%include "mln/topo/n_face.hh"; + +%define instantiate_n_face(N, D) + %ignore mln::topo::n_face<N, D>::lower_dim_adj_faces; + %ignore mln::topo::n_face<N, D>::higher_dim_adj_faces; + %template(n_face_ ## N ## _ ## D) mln::topo::n_face<N, D>; +%enddef // !instantiate_n_face + + +/*-----------------. +| Algebraic face. | + `----------------*/ + +%include "mln/topo/algebraic_face.hh"; + + +/*-------------------. +| Algebraic n-face. | + `-------------------*/ + +%include "mln/topo/algebraic_n_face.hh"; + +%define instantiate_algebraic_n_face(N, D) + %ignore mln::topo::algebraic_n_face<N, D>::lower_dim_adj_faces; + %ignore mln::topo::algebraic_n_face<N, D>::higher_dim_adj_faces; + %template(algebraic_n_face_ ## N ## _ ## D) mln::topo::algebraic_n_face<N, D>; +%enddef // !instantiate_algebraic_n_face + + +/*--------------. +| N-faces set. | +`--------------*/ + +%include "mln/topo/n_faces_set.hh"; + +%define instantiate_n_faces_set(N, D) + %template(n_faces_set_ ## N ## _ ## D) mln::topo::n_faces_set<N, D>; +%enddef // !instantiate_n_faces_set + + +/*------------. +| Face data. | +`------------*/ + +%include "mln/topo/face_data.hh"; + +%define instantiate_face_data(N, D) + %template(face_data_ ## N ## _ ## D) mln::topo::face_data<N, D>; +%enddef // !instantiate_face_data + + +/*----------------. +| Face Iterator. | +`----------------*/ + +%include "mln/core/concept/iterator.hh"; +%include "mln/topo/internal/complex_iterator_base.hh"; +%include "mln/topo/internal/complex_set_iterator_base.hh"; +%include "mln/topo/face_iter.hh"; + +%{ +#include "mln/topo/face_iter.hh" +%} + +// Generate base classes. +%define instantiate_Iterator(ExactName, E) + %template(Iterator_ ## ExactName) mln::Iterator< E >; +%enddef // !instantiate_Iterator + +%define instantiate_complex_iterator_base(ExactName, F, E) + instantiate_Iterator(ExactName, E) + %template(complex_iterator_base_ ## ExactName) + mln::topo::internal::complex_iterator_base< F, E >; +%enddef // !instantiate_complex_iterator_base + +%define instantiate_complex_set_iterator_base(ExactName, F, E) + instantiate_complex_iterator_base(ExactName, F, E) + %template(complex_set_iterator_base_ ## ExactName) + mln::topo::internal::complex_set_iterator_base< F, E >; +%enddef // !instantiate_complex_set_iterator_base + +// Generate mln::topo::face_fwd_iter< D >. +%define instantiate_face_fwd_iter(Name, D) +instantiate_complex_set_iterator_base(Name, + mln::topo::face< D >, + mln::topo::face_fwd_iter< D >) + +#if SWIGPYTHON +// Handling iterators à la Python. +%extend mln::topo::face_fwd_iter< D > +{ + mln::topo::face_fwd_iter< D >& + __iter__() + { + return *$self; + } +} + +// Raise a Python `StopIteration' exception on `next()' if the +// iterator is invalid. +%exception mln::topo::face_fwd_iter< D >::next +{ + /* FIXME: Is it safe to use `arg1'? It seems to be pretty + low-level, and may not be part of Swig's standard interface. */ + if (!arg1->is_valid()) + { + PyErr_SetString(PyExc_StopIteration, "Invalid iterator"); + return NULL; + } + $action +} + +%extend mln::topo::face_fwd_iter< D > +{ + const mln::topo::face< D > + next() + { + // Keep a copy of the current site before incrementation. + const mln::topo::face< D > current = *$self; + // Delegate incrementation to `Super_Iterator's `next()' method. + $self->next(); + return current; + } +} +#endif // !SWIGPYTHON + +%template(Name) mln::topo::face_fwd_iter< D >; +%enddef // !instantiate_face_fwd_iter + +// Conversion helper for Python. +#if SWIGPYTHON +generate__str__(mln::topo::face_fwd_iter) +#endif // !SWIGPYTHON + + +/*----------. +| Complex. | +`----------*/ + +// Generate an instantiation of mln::topo::complex<D>. +%define instantiate_complex(Name, D) + +#if SWIGPYTHON +// Conversion helper for Python. +generate__str__(mln::topo::complex<D>) + +// Python iterator creation. +%extend mln::topo::complex< D > +{ + mln::topo::face_fwd_iter< D > + __iter__() /* FIXME: No `const' here, to be compatible with + face_fwd_iter's ctor. This is bad. */ + { + mln::topo::face_fwd_iter< D > f(*$self); + f.start(); + return f; + } +} +#endif // !SWIGPYTHON + +%template(Name) mln::topo::complex<D>; +%enddef // !instantiate_complex + +// Generate mln::topo::complex's template members. +%define instantiate_complex_add_face(N, N_Plus_One, D) + %extend mln::topo::complex + { + mln::topo::n_face< N_Plus_One, D > + add_face(const mln::topo::n_faces_set< N, D >& adjacent_faces) + { + return $self->add_face(adjacent_faces); + } + }; +%enddef // !instantiate_complex_add_face diff --git a/swilena/complex2.i b/swilena/complex2.i new file mode 100644 index 0000000..95fa9bd --- /dev/null +++ b/swilena/complex2.i @@ -0,0 +1,111 @@ +// -*- C++ -*- +// Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +// +// This file is part of Olena. +// +// Olena is free software: you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation, version 2 of the License. +// +// Olena is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Olena. If not, see <http://www.gnu.org/licenses/>. +// +// As a special exception, you may use this file as part of a free +// software project without restriction. Specifically, if other files +// instantiate templates or use macros or inline functions from this +// file, or you compile this file and link it with other files to produce +// an executable, this file does not by itself cause the resulting +// executable to be covered by the GNU General Public License. This +// exception does not however invalidate any other reasons why the +// executable file might be covered by the GNU General Public License. + +/// \file complex2.i +/// \brief A wrapper of mln::topo::complex<2>. + +%module complex2 + +%include "complex.ixx" + +instantiate_n_faces_set_binary_operators(+, add, 0, 2) +instantiate_n_faces_set_binary_operators(+, add, 1, 2) + +instantiate_n_faces_set_binary_operators(-, sub, 0, 2) +instantiate_n_faces_set_binary_operators(-, sub, 1, 2) + +instantiate_algebraic_n_face_unary_operators(0, 2) +instantiate_algebraic_n_face_unary_operators(1, 2) + + +/*-------. +| Face. | +`-------*/ + +%template(face_2) mln::topo::face<2>; + +instantiate_face_data_conversions(0, 2) +instantiate_face_data_conversions(1, 2) +instantiate_face_data_conversions(2, 2) + +instantiate_boolean_binary_operator(==, eq, mln::topo::face<2>) + +// Conversion helper for Python. +#if SWIGPYTHON +generate__str__(mln::topo::face< 2 >) +#endif // !SWIGPYTHON + +/*---------. +| N-face. | +`---------*/ + +instantiate_n_face(0, 2) +instantiate_n_face(1, 2) +instantiate_n_face(2, 2) + +/*-----------------. +| Algebraic face. | + `----------------*/ + +%template(algebraic_face_2) mln::topo::algebraic_face<2>; + +/*-------------------. +| Algebraic n-face. | + `-------------------*/ + +instantiate_algebraic_n_face(0, 2) +instantiate_algebraic_n_face(1, 2) +instantiate_algebraic_n_face(2, 2) + +/*--------------. +| N-faces set. | +`--------------*/ + +instantiate_n_faces_set(0, 2) +instantiate_n_faces_set(1, 2) + +/*------------. +| Face data. | +`------------*/ + +instantiate_face_data(0, 2) +instantiate_face_data(1, 2) +instantiate_face_data(2, 2) + +/*----------------. +| Face iterator. | +`----------------*/ + +instantiate_face_fwd_iter(face_iter_2, 2) + +/*----------. +| Complex. | +`----------*/ + +instantiate_complex_add_face(0, 1, 2) +instantiate_complex_add_face(1, 2, 2) + +instantiate_complex(complex2, 2) diff --git a/swilena/python/Makefile.am b/swilena/python/Makefile.am index ea4b25d..3e5937d 100644 --- a/swilena/python/Makefile.am +++ b/swilena/python/Makefile.am @@ -74,6 +74,16 @@ CLEANFILES += $(nodist__config_la_SOURCES) config.py config.py[co] @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_config-wrap.Pcc@am__quote@ nodist_python_PYTHON += config.py +## complex2. +pyexec_LTLIBRARIES += _complex2.la +nodist__complex2_la_SOURCES = complex2-wrap.cc +_complex2_la_LIBADD = $(AM_LIBADD) +CLEANFILES += $(nodist__complex2_la_SOURCES) complex2.py complex2.py[co] +## Include the dependency files. Copied from Automake's generated +## case for C++. +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_complex2-wrap.Pcc@am__quote@ +nodist_python_PYTHON += complex2.py + ## point2d. pyexec_LTLIBRARIES += _point2d.la nodist__point2d_la_SOURCES = point2d-wrap.cc @@ -231,6 +241,8 @@ rgb_ixx_deps = $(top_srcdir)/swilena/python-utils.ixx box_ixx_deps = $(top_srcdir)/swilena/coord.ixx +complex_ixx_deps = $(top_srcdir)/swilena/python-utils.ixx + morpho_ixx_deps = \ $(top_srcdir)/swilena/concrete.ixx \ $(top_srcdir)/swilena/ch_value.ixx @@ -243,6 +255,8 @@ rgb8-wrap.cc: $(top_srcdir)/swilena/rgb.ixx $(rgb_ixx_deps) box2d-wrap.cc: $(top_srcdir)/swilena/box.ixx $(box_ixx_deps) box2d_piter-wrap.cc: $(top_srcdir)/swilena/box_piter.ixx +complex2-wrap.cc: $(top_srcdir)/swilena/complex.ixx $(complex_ixx_deps) + point2d-wrap.cc: $(top_srcdir)/swilena/concat.ixx point2d-wrap.cc: $(top_srcdir)/swilena/python-utils.ixx @@ -316,7 +330,6 @@ CLEANFILES += $(bin_SCRIPTS) $(noinst_SCRIPTS) include $(top_srcdir)/swilena/run.mk -## FIXME: Do we really need to pass top_srcdir and top_builddir to run? TESTS_ENVIRONMENT = \ top_srcdir="$(top_srcdir)" top_builddir="$(top_builddir)" $(RUN) # Ensure `run' is rebuilt before the tests are run. @@ -338,7 +351,7 @@ $(srcdir)/run.stamp: $(RUN_IN) # extension as argument. We could improve this by adding options such # as `--python' to `run'. TESTS = \ - box2d-misc.py \ + box2d-misc.py complex2-misc.py \ image2d-misc.py morpho-fun.py morpho-segm.py max-tree.py \ dynamic-image2d-misc.py diff --git a/swilena/python/complex2-misc.py b/swilena/python/complex2-misc.py new file mode 100644 index 0000000..87fb27a --- /dev/null +++ b/swilena/python/complex2-misc.py @@ -0,0 +1,100 @@ +#! /usr/bin/env python +# -*- coding: latin-1 -*- + +# Copyright (C) 2010 EPITA Research and Development Laboratory (LRDE) +# +# This file is part of Olena. +# +# Olena is free software: you can redistribute it and/or modify it under +# the terms of the GNU General Public License as published by the Free +# Software Foundation, version 2 of the License. +# +# Olena is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with Olena. If not, see <http://www.gnu.org/licenses/>. + +# \file python/mesh-complex-segm.py +# \brief Test complex2. +# +# See also Milena's tests/topo/complex.cc. + +import data +from swilena import * + +# A 2-d (simplicial) complex and its adjacency graph. +# +# v0 e3 v3 +# o-----------o v0----e3----v3 +# / \ ,-----. / / \ | / +# / . \ \ t1/ / / \ t1 / +# e0 / / \ e1\ / / e4 e0. ,e1Ž `e4 +# / /t0 \ \ ' / / t0 \ / +# / `-----' \ / / | \ / +# o-----------o v1----e2----v2 +# v1 e2 v2 +# +# v = vertex (0-face) +# e = edge (1-face) +# t = triangle (2-face) + +## ---------------------- ## +## Complex construction. ## +## ---------------------- ## + +c = complex2() + +# 0-faces (points). +v0 = c.add_face() +v1 = c.add_face() +v2 = c.add_face() +v3 = c.add_face() + +# 1-faces (segments). +e0 = c.add_face(-v1 + v0) +e1 = c.add_face(-v0 + v2) +e2 = c.add_face(-v2 + v1) +e3 = c.add_face(-v0 + v3) +e4 = c.add_face(-v3 + v2) + +# 2-faces (triangles). +t0 = c.add_face( e0 + e1 + e2) +t1 = c.add_face(-e1 + e3 + e4) + +print c + + +## ------------------ ## +## Handles and data. ## +## ------------------ ## + +# Get the face data from (``static'') face handle E0. +face1 = e0.data() + +# Face handle. +f = face_2(e0) +print f +print + +# Get the face data from (``dynamic'') face handle AF. +face2 = f.data_1() + + +## ----------- ## +## Iteration. ## +## ----------- ## + +# --------------- # +# Iterator on C. # +# --------------- # + +# (Forward) Iterator on a complex (not complex_image), or more +# precisely on (all) the faces of complex C. +for f in c: + print f + + +# FIXME: Test more iterators. diff --git a/swilena/python/swilena.py b/swilena/python/swilena.py index 6c4dc89..6538046 100644 --- a/swilena/python/swilena.py +++ b/swilena/python/swilena.py @@ -24,6 +24,8 @@ import ltihooks import config +from complex2 import * + from box2d import * from point2d import * from dpoint2d import * -- 1.5.6.5
participants (1)
-
Roland Levillain