[PATCH 1/5] Help Swilena wrap mln::complex<D>.

* mln/topo/complex.hh: Use `0' instead of `0u' as template parameter. --- milena/ChangeLog | 7 +++++++ milena/mln/topo/complex.hh | 38 +++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 19 deletions(-) diff --git a/milena/ChangeLog b/milena/ChangeLog index 0806c6b..80958f0 100644 --- a/milena/ChangeLog +++ b/milena/ChangeLog @@ -1,3 +1,10 @@ +2010-04-08 Roland Levillain <roland@lrde.epita.fr> + + Help Swilena wrap mln::complex<D>. + + * mln/topo/complex.hh: Use `0' instead of `0u' as template + parameter. + 2010-03-30 Roland Levillain <roland@lrde.epita.fr> Do not install low-quality HTML documentation. diff --git a/milena/mln/topo/complex.hh b/milena/mln/topo/complex.hh index 3662396..2ecb551 100644 --- a/milena/mln/topo/complex.hh +++ b/milena/mln/topo/complex.hh @@ -107,7 +107,7 @@ namespace mln complex(); /// Add a 0-face to the complex. - n_face<0u, D> add_face(); + n_face<0, D> add_face(); /// Add a \p (N+1)-face to the complex (with \p N >= 0). /// @@ -369,9 +369,9 @@ namespace mln /// Faces of lowest dimension (0). template <unsigned D> - struct faces_set_mixin<0u, D> : public higher_dim_faces_set_mixin<0u, D> + struct faces_set_mixin<0, D> : public higher_dim_faces_set_mixin<0, D> { - std::vector< face_data<0u, D> > faces_; + std::vector< face_data<0, D> > faces_; /// Pretty-printing. /// \{ @@ -396,9 +396,9 @@ namespace mln /// Faces of a 0-complex. template <> - struct faces_set_mixin<0u, 0u> + struct faces_set_mixin<0, 0> { - std::vector< face_data<0u, 0u> > faces_; + std::vector< face_data<0, 0> > faces_; /// Pretty-printing. /// \{ @@ -475,14 +475,14 @@ namespace mln template <unsigned D> inline - n_face<0u, D> + n_face<0, D> complex<D>::add_face() { /* FIXME: This is not thread-proof (these two lines should form an atomic section). */ - data_->internal::faces_set_mixin<0u, D>::faces_.push_back(face_data<0u, D>()); - unsigned id = nfaces_of_static_dim<0u>() - 1; - return n_face<0u, D>(*this, id); + data_->internal::faces_set_mixin<0, D>::faces_.push_back(face_data<0, D>()); + unsigned id = nfaces_of_static_dim<0>() - 1; + return n_face<0, D>(*this, id); } template <unsigned D> @@ -716,7 +716,7 @@ namespace mln template <unsigned D> inline void - faces_set_mixin<0u, D>::print_rec_asc(std::ostream& ostr) const + faces_set_mixin<0, D>::print_rec_asc(std::ostream& ostr) const { print(ostr); } @@ -732,7 +732,7 @@ namespace mln inline void - faces_set_mixin<0u, 0u>::print_rec_asc(std::ostream& ostr) const + faces_set_mixin<0, 0>::print_rec_asc(std::ostream& ostr) const { print(ostr); } @@ -760,9 +760,9 @@ namespace mln template <unsigned D> inline void - faces_set_mixin<0u, D>::print(std::ostream& ostr) const + faces_set_mixin<0, D>::print(std::ostream& ostr) const { - const unsigned N = 0u; + const unsigned N = 0; ostr << "Faces of dimension " << N << " and their ajacent faces of dimension " << N + 1 << std::endl; @@ -793,9 +793,9 @@ namespace mln inline void - faces_set_mixin<0u, 0u>::print(std::ostream& ostr) const + faces_set_mixin<0, 0>::print(std::ostream& ostr) const { - const unsigned N = 0u; + const unsigned N = 0; ostr << "Faces of dimension " << N << std::endl; for (unsigned f = 0; f < faces_.size(); ++f) ostr << " " << f << std::endl; @@ -873,7 +873,7 @@ namespace mln template <typename BinaryFunction, typename T> inline T - faces_set_mixin<0u, D>::fold_left_(const BinaryFunction& f, + faces_set_mixin<0, D>::fold_left_(const BinaryFunction& f, const T& accu) const { return f(accu, faces_); @@ -882,7 +882,7 @@ namespace mln template <typename BinaryFunction, typename T> inline T - faces_set_mixin<0u, 0u>::fold_left_(const BinaryFunction& f, + faces_set_mixin<0, 0>::fold_left_(const BinaryFunction& f, const T& accu) const { return f(accu, faces_); @@ -943,7 +943,7 @@ namespace mln template <typename UnaryFunction> inline typename UnaryFunction::result_type - faces_set_mixin<0u, D>::apply_if_dim_matches_(unsigned n, + faces_set_mixin<0, D>::apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const { // If we reached this method, then N should be 0. @@ -956,7 +956,7 @@ namespace mln template <typename UnaryFunction> inline typename UnaryFunction::result_type - faces_set_mixin<0u, 0u>::apply_if_dim_matches_(unsigned n, + faces_set_mixin<0, 0>::apply_if_dim_matches_(unsigned n, const UnaryFunction& f) const { // If we reached this method, then N should be 0. -- 1.7.0.4

* 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.7.0.4

* python-utils.ixx (generate__str__): Do not include C++ header `string'. * image2d_int.i, * image2d_int_u8.i, * image2d_rgb8.i: Fix the Swilena documentation headers. * int_u.ixx, * rgb.ixx, * image2d.ixx: More Doxygen documentation. * concat.ixx: Typo in comment. * box_piter.ixx: Remove a blank line. --- swilena/ChangeLog | 17 +++++++++++++++++ swilena/box_piter.ixx | 3 +-- swilena/concat.ixx | 4 ++-- swilena/image2d.ixx | 2 +- swilena/image2d_int.i | 5 +++-- swilena/image2d_int_u8.i | 5 +++-- swilena/image2d_rgb8.i | 2 +- swilena/int_u.ixx | 24 ++++++++++++++---------- swilena/python-utils.ixx | 3 +-- swilena/rgb.ixx | 20 ++++++++++++-------- 10 files changed, 55 insertions(+), 30 deletions(-) diff --git a/swilena/ChangeLog b/swilena/ChangeLog index 7f987ec..e751084 100644 --- a/swilena/ChangeLog +++ b/swilena/ChangeLog @@ -1,5 +1,22 @@ 2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Clean up Swilena a bit. + + * python-utils.ixx (generate__str__): + Do not include C++ header `string'. + * image2d_int.i, + * image2d_int_u8.i, + * image2d_rgb8.i: + Fix the Swilena documentation headers. + * int_u.ixx, + * rgb.ixx, + * image2d.ixx: + More Doxygen documentation. + * concat.ixx: Typo in comment. + * box_piter.ixx: Remove a blank line. + +2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Wrap a subset of complexes' features. * complex.ixx, complex2.i: New. diff --git a/swilena/box_piter.ixx b/swilena/box_piter.ixx index 032ef7d..f1cc79e 100644 --- a/swilena/box_piter.ixx +++ b/swilena/box_piter.ixx @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -30,7 +30,6 @@ %module box_piter %{ - #include "mln/core/site_set/box_piter.hh" %} diff --git a/swilena/concat.ixx b/swilena/concat.ixx index 220a609..18050a9 100644 --- a/swilena/concat.ixx +++ b/swilena/concat.ixx @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -28,7 +28,7 @@ /// \brief Macros concatenating their arguments. /// /// These macros are useful to wrap strings containing commas and -/// passed as arguments other macros. For instance, to pass the +/// passed as arguments to other macros. For instance, to pass the /// argument <tt>Bar<int, float></tt> to a macro /// <tt>instantiate_foo</tt> taking a single argument, use this: /// diff --git a/swilena/image2d.ixx b/swilena/image2d.ixx index 702bc74..a08864b 100644 --- a/swilena/image2d.ixx +++ b/swilena/image2d.ixx @@ -62,7 +62,7 @@ // mln::image2d definition. %include "mln/core/image/image2d.hh" -// FIXME: Doc. +// Generate a wrapper of mln::image2d<T> named I. %define instantiate_image2d(I, T) /* Add a setter, since Python does not seem to allow writings like diff --git a/swilena/image2d_int.i b/swilena/image2d_int.i index ac82fe6..10e1afb 100644 --- a/swilena/image2d_int.i +++ b/swilena/image2d_int.i @@ -1,5 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009, 2010 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -24,7 +25,7 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -/// \file image2d.i +/// \file image2d_int.i /// \brief A simple wrapping of mln::image2d<int> along with some /// algorithms. diff --git a/swilena/image2d_int_u8.i b/swilena/image2d_int_u8.i index 109f8bc..18b4f84 100644 --- a/swilena/image2d_int_u8.i +++ b/swilena/image2d_int_u8.i @@ -1,5 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009, 2010 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -24,7 +25,7 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -/// \file image2d.i +/// \file image2d_int_u8.i /// \brief A simple wrapping of mln::image2d<mln::value::int_u8> along /// with some algorithms. diff --git a/swilena/image2d_rgb8.i b/swilena/image2d_rgb8.i index bda1ff9..6b8b2d8 100644 --- a/swilena/image2d_rgb8.i +++ b/swilena/image2d_rgb8.i @@ -25,7 +25,7 @@ // exception does not however invalidate any other reasons why the // executable file might be covered by the GNU General Public License. -/// \file image2d.i +/// \file image2d_rgb8.i /// \brief A simple wrapping of mln::image2d<mln::value::rgb8> along /// with some algorithms. diff --git a/swilena/int_u.ixx b/swilena/int_u.ixx index b558467..a10b0de 100644 --- a/swilena/int_u.ixx +++ b/swilena/int_u.ixx @@ -1,5 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2008, 2009, 2010 EPITA Research and Development +// Laboratory (LRDE) // // This file is part of Olena. // @@ -91,18 +92,21 @@ namespace mln - /*! \brief Print an unsigned integer \p i into the output stream \p ostr. - * - * \param[in,out] ostr An output stream. - * \param[in] i An unsigned integer. - * - * \return The modified output stream \p ostr. - */ + /// \brief Print an unsigned integer \p i on the output stream \p ostr. + /// + /// \param[in,out] ostr An output stream. + /// \param[in] i An unsigned integer. + /// + /// \return The modified output stream \p ostr. template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const int_u<n>& i); - - // FIXME: Doc! + /// \brief Get an unsigned integer \p i from the input stream \p istr. + /// + /// \param[in,out] istr An input stream. + /// \param[out] i An unsigned integer (destination). + /// + /// \return The modified input stream \p istr. template <unsigned n> std::istream& operator>>(std::istream& istr, int_u<n>& i); diff --git a/swilena/python-utils.ixx b/swilena/python-utils.ixx index 6d18e4a..30160e9 100644 --- a/swilena/python-utils.ixx +++ b/swilena/python-utils.ixx @@ -1,5 +1,5 @@ // -*- C++ -*- -// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) +// Copyright (C) 2009, 2010 EPITA Research and Development Laboratory (LRDE) // // This file is part of Olena. // @@ -39,7 +39,6 @@ %define generate__str__(Type) %{ #include <cstring> -#include <string> #include <sstream> %} diff --git a/swilena/rgb.ixx b/swilena/rgb.ixx index c5607f3..bc9f6d3 100644 --- a/swilena/rgb.ixx +++ b/swilena/rgb.ixx @@ -126,17 +126,21 @@ namespace mln }; - /*! \brief Print an unsigned integer \p i into the output stream \p ostr. - * - * \param[in,out] ostr An output stream. - * \param[in] i An unsigned integer. - * - * \return The modified output stream \p ostr. - */ + /// Print an RGB \p c value on the output stream \p ostr. + /// + /// \param[in,out] ostr An output stream. + /// \param[in] c An RGB value. + /// + /// \return The modified output stream \p ostr. template <unsigned n> std::ostream& operator<<(std::ostream& ostr, const rgb<n>& i); - // FIXME: Doc! + /// Get an RGB value \p c from the input stream \p istr. + /// + /// \param[in,out] istr An input stream. + /// \param[out] c An RGB value (destination). + /// + /// \return The modified input stream \p istr. template <unsigned n> std::istream& operator>>(std::istream& istr, rgb<n>& i); -- 1.7.0.4

* morpho.ixx: Here. * image2d_int_u8.i, * python/morpho-segm.py: Adjust. --- swilena/ChangeLog | 9 +++++++++ swilena/image2d_int_u8.i | 8 ++++---- swilena/morpho.ixx | 11 +++++------ swilena/python/morpho-segm.py | 2 +- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/swilena/ChangeLog b/swilena/ChangeLog index e751084..58577e6 100644 --- a/swilena/ChangeLog +++ b/swilena/ChangeLog @@ -1,5 +1,14 @@ 2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Wrap morpho::watershed::flooding instead of morpho::meyer_wst. + + * morpho.ixx: Here. + * image2d_int_u8.i, + * python/morpho-segm.py: + Adjust. + +2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Clean up Swilena a bit. * python-utils.ixx (generate__str__): diff --git a/swilena/image2d_int_u8.i b/swilena/image2d_int_u8.i index 18b4f84..ae96049 100644 --- a/swilena/image2d_int_u8.i +++ b/swilena/image2d_int_u8.i @@ -78,10 +78,10 @@ instantiate_morpho(mln::image2d< mln::value::int_u<8> >, | image2d<int_u8> and image2d<int_u32>. | `---------------------------------------*/ -instantiate_meyer_wst(meyer_wst32, - mln::value::int_u<32>, - mln::image2d< mln::value::int_u<8> >, - mln::neighb2d) +instantiate_watershed_flooding(watershed_flooding32, + mln::value::int_u<32>, + mln::image2d< mln::value::int_u<8> >, + mln::neighb2d) // FIXME: Rearrange and move this elsewhere. instantiate_image2d(image2d_int_u32, mln::value::int_u<32>) diff --git a/swilena/morpho.ixx b/swilena/morpho.ixx index d917ac0..bf84d2d 100644 --- a/swilena/morpho.ixx +++ b/swilena/morpho.ixx @@ -154,16 +154,15 @@ namespace mln `------------------------------------*/ %{ -#include "mln/morpho/meyer_wst.hh" +#include "mln/morpho/watershed/flooding.hh" %} -%include "mln/morpho/meyer_wst.hh" +%include "mln/morpho/watershed/flooding.hh" -// FIXME: Wrap mln::morpho::watershed::flooding instead. -%define instantiate_meyer_wst(Name, L, I, N) +%define instantiate_watershed_flooding(Name, L, I, N) // Explicit instantiation of this trait for the return type. %template() mln::trait::ch_value< I, L >; - %template(Name) mln::morpho::meyer_wst< L, I, N >; + %template(Name) mln::morpho::watershed::flooding< L, I, N >; %enddef /*-----------. @@ -200,7 +199,7 @@ namespace mln instantiate_closing_area(closing_area, I, N) instantiate_opening_area(opening_area, I, N) - instantiate_meyer_wst(meyer_wst, mln_value(I), I, N) + instantiate_watershed_flooding(watershed_flooding, mln_value(I), I, N) instantiate_max_tree(max_tree, I, N) %enddef diff --git a/swilena/python/morpho-segm.py b/swilena/python/morpho-segm.py index 654aa95..f8176a2 100644 --- a/swilena/python/morpho-segm.py +++ b/swilena/python/morpho-segm.py @@ -34,7 +34,7 @@ image.save(gradient, "gradient.pgm") closed_gradient = image.closing_area(ima, c4(), 50) # Watershed transform. nbasins = int_u8() -ws = image.meyer_wst (closed_gradient, c4(), nbasins) +ws = image.watershed_flooding(closed_gradient, c4(), nbasins) print nbasins image.save(ws, "segm.pgm") -- 1.7.0.4

* python/max-tree.py (values): Use itertools.izip to shorten the parallel iterations on sites and values. --- swilena/ChangeLog | 7 +++++++ swilena/python/max-tree.py | 9 ++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/swilena/ChangeLog b/swilena/ChangeLog index 58577e6..f39ebab 100644 --- a/swilena/ChangeLog +++ b/swilena/ChangeLog @@ -1,5 +1,12 @@ 2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Simplify python/max-tree.py using Python's itertools. + + * python/max-tree.py (values): Use itertools.izip to shorten the + parallel iterations on sites and values. + +2010-04-08 Roland Levillain <roland@lrde.epita.fr> + Wrap morpho::watershed::flooding instead of morpho::meyer_wst. * morpho.ixx: Here. diff --git a/swilena/python/max-tree.py b/swilena/python/max-tree.py index 0c5dd65..7f09eff 100644 --- a/swilena/python/max-tree.py +++ b/swilena/python/max-tree.py @@ -22,21 +22,20 @@ import data from swilena import * +import itertools + # Module aliases. image = image2d_int_u8 par_image = image2d_point2d -ima = image.load(data.lena) ima = image.image2d_int_u8(3, 3) values = [5, 6, 6, 8, 9, 9, 8, 9, 9] -v = values.__iter__() - -for p in ima.domain(): - ima.set(p, int_u8(v.next())) +for p, v in itertools.izip(ima.domain(), values): + ima.set(p, int_u8(v)) image.println("ima =", ima) max_tree_parent = image.max_tree(ima, c4()); -- 1.7.0.4
participants (1)
-
Roland Levillain