#129: Reintegrate oln.m4 (full or a part of it) into Olena 1.0
-----------------------------------+----------------------------------------
Reporter: levill_r | Owner: levill_r
Type: enhancement | Status: new
Priority: minor | Milestone: Olena 1.0ß
Component: Olena | Version: 1.0
Keywords: configure autoconf M4 |
-----------------------------------+----------------------------------------
In Olena 0.11, `oln.m4` (which might be renamed to `olena.m4`) provided
useful services to both the Olena package (search for libraries, set up
flags for tests, etc.) and autoconfiscated packages using Olena, by
providing a `--with-oln` (to be renamed to `--with-olena`) flag.
We should reintegrate a part of these features, possibly in two M4 macro
packages:
* one for Olena,
* one for Olena-based projects.
--
Ticket URL: <https://trac.lrde.org/olena/ticket/129>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image library.
#212: Convert Olena's Subversion repository to Git
----------------------+-----------------------------------------------------
Reporter: levill_r | Owner: levill_r
Type: task | Status: new
Priority: blocker | Milestone: Olena 1.1
Component: Milena | Version: 1.0
Keywords: |
----------------------+-----------------------------------------------------
I (Roland) will take care of it ASAP (following the release of Olena 1.0).
A few remarks:
* Use a script to do this, of course (reuse the one I wrote to convert
`share/`).
* Don't forget to use a real list of authors (as in the conversion of
other LRDE repositories). Compile a list of all contributors to ensure we
forgot nobody.
* Keep Subversion revision numbers in Git: they will be useful to match
information from Trac and the mailing lists.
* Actually merge branches in the Git repository, by rewriting the
history. The best is probably to create a map of Subversion merges, then
extend the script to handle this.
* Don't forget branches in source:prototypes (grrr...).
* See also #201 and #203.
* Later: Teach Git to Git beginners.
* Even later: reintegrate the PRCS repository (see #3).
--
Ticket URL: <https://trac.lrde.org/olena/ticket/212>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
#206: Add the sources of the images of the ISMM 2009 paper to the Olena
repository
-----------------------------------+----------------------------------------
Reporter: levill_r | Owner: levill_r
Type: enhancement | Status: new
Priority: minor | Milestone: Olena 1.1
Component: other | Version: 1.0
Keywords: reproducible research |
-----------------------------------+----------------------------------------
Most of the work is already done, since the repository of the ISMM 2009
paper contains the material to automatically generate the images (needs
some clean up though).
Once moved to the Olena repository, remove the generators from the ISMM
2009 repository and only keep the end products (and possibly add Make
rules to automate the update (copy) of the images from the Olena
repository).
--
Ticket URL: <https://trac.lrde.org/olena/ticket/206>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
#173: Complete the graph fusion example started with Géraud Béguin
----------------------+-----------------------------------------------------
Reporter: levill_r | Owner: Olena Team
Type: task | Status: new
Priority: minor | Milestone:
Component: other | Version: 1.0
Keywords: IGR |
----------------------+-----------------------------------------------------
See:
* source:branches/cleanup-2008/milena/sandbox/beguin/irm.cc
* source:branches/cleanup-2008/milena/sandbox/beguin/fusion_graph.hh
--
Ticket URL: <https://trac.lrde.org/olena/ticket/173>
Olena <http://olena.lrde.epita.fr>
Olena, a generic and efficient C++ image processing library.
* apps/papers/,
* apps/papers/levillain.09.ismm/:
New directories.
* apps/papers/levillain.09.ismm/chain.hh,
* apps/papers/levillain.09.ismm/complex.cc,
* apps/papers/levillain.09.ismm/graph.cc,
* apps/papers/levillain.09.ismm/image2d.cc:
New (imported from ISMM 2009).
Adjust.
* apps/Makefile.am (SUBDIRS): Add papers.
* apps/papers/Makefile.am,
* apps/papers/levillain.09.ismm/Makefile.am:
New.
---
milena/ChangeLog | 18 +
milena/apps/Makefile.am | 6 +-
milena/apps/{ => papers}/Makefile.am | 5 +-
.../{ => papers/levillain.09.ismm}/Makefile.am | 16 +-
milena/apps/papers/levillain.09.ismm/chain.hh | 42 ++
milena/apps/papers/levillain.09.ismm/complex.cc | 130 +++++
milena/apps/papers/levillain.09.ismm/graph.cc | 497 ++++++++++++++++++++
milena/apps/papers/levillain.09.ismm/image2d.cc | 103 ++++
8 files changed, 809 insertions(+), 8 deletions(-)
copy milena/apps/{ => papers}/Makefile.am (84%)
copy milena/apps/{ => papers/levillain.09.ismm}/Makefile.am (65%)
create mode 100644 milena/apps/papers/levillain.09.ismm/chain.hh
create mode 100644 milena/apps/papers/levillain.09.ismm/complex.cc
create mode 100644 milena/apps/papers/levillain.09.ismm/graph.cc
create mode 100644 milena/apps/papers/levillain.09.ismm/image2d.cc
diff --git a/milena/ChangeLog b/milena/ChangeLog
index 6d1aa08..3cb555a 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,3 +1,21 @@
+2009-10-02 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Import the code of the illustrations of the ISMM 2009 paper.
+
+ * apps/papers/,
+ * apps/papers/levillain.09.ismm/:
+ New directories.
+ * apps/papers/levillain.09.ismm/chain.hh,
+ * apps/papers/levillain.09.ismm/complex.cc,
+ * apps/papers/levillain.09.ismm/graph.cc,
+ * apps/papers/levillain.09.ismm/image2d.cc:
+ New (imported from ISMM 2009).
+ Adjust.
+ * apps/Makefile.am (SUBDIRS): Add papers.
+ * apps/papers/Makefile.am,
+ * apps/papers/levillain.09.ismm/Makefile.am:
+ New.
+
2009-10-28 Guillaume Lazzara <z(a)lrde.epita.fr>
Small fixes.
diff --git a/milena/apps/Makefile.am b/milena/apps/Makefile.am
index dc39cff..c42ffd7 100644
--- a/milena/apps/Makefile.am
+++ b/milena/apps/Makefile.am
@@ -15,6 +15,8 @@
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
#
-## Process this file through Automake to produce Makefile.in.
-
+# Applied examples of Milena.
SUBDIRS = mesh-segm-skel graph-morpho constrained-connectivity
+
+# Examples from papers.
+SUBDIRS += papers
diff --git a/milena/apps/Makefile.am b/milena/apps/papers/Makefile.am
similarity index 84%
copy from milena/apps/Makefile.am
copy to milena/apps/papers/Makefile.am
index dc39cff..d2ae9bc 100644
--- a/milena/apps/Makefile.am
+++ b/milena/apps/papers/Makefile.am
@@ -13,8 +13,7 @@
#
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-#
-## Process this file through Automake to produce Makefile.in.
+# Examples from papers.
-SUBDIRS = mesh-segm-skel graph-morpho constrained-connectivity
+SUBDIRS = levillain.09.ismm
diff --git a/milena/apps/Makefile.am b/milena/apps/papers/levillain.09.ismm/Makefile.am
similarity index 65%
copy from milena/apps/Makefile.am
copy to milena/apps/papers/levillain.09.ismm/Makefile.am
index dc39cff..5bcacd3 100644
--- a/milena/apps/Makefile.am
+++ b/milena/apps/papers/levillain.09.ismm/Makefile.am
@@ -13,8 +13,18 @@
#
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-#
-## Process this file through Automake to produce Makefile.in.
+# Illustrations from the ISMM 2009 paper.
+
+# Find Milena headers.
+AM_CPPFLAGS = -I$(top_srcdir)/milena -I$(top_builddir)/milena
+# Produce fast code.
+APPS_CXXFLAGS = @APPS_CXXFLAGS@
+AM_CXXFLAGS = $(APPS_CXXFLAGS)
+
+noinst_HEADERS = chain.hh
-SUBDIRS = mesh-segm-skel graph-morpho constrained-connectivity
+noinst_PROGRAMS = image2d graph complex
+image2d_SOURCES = image2d.cc
+graph_SOURCES = graph.cc
+complex_SOURCES = complex.cc
diff --git a/milena/apps/papers/levillain.09.ismm/chain.hh b/milena/apps/papers/levillain.09.ismm/chain.hh
new file mode 100644
index 0000000..d7ee28c
--- /dev/null
+++ b/milena/apps/papers/levillain.09.ismm/chain.hh
@@ -0,0 +1,42 @@
+// Copyright (C) 2009 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.
+
+#ifndef CHAIN_HH
+# define CHAIN_HH
+
+#include <mln/morpho/closing/area.hh>
+#include <mln/morpho/watershed/flooding.hh>
+
+template <typename I, typename N, typename L>
+mln_ch_value(I, L)
+chain(const mln::Image<I>& ima, const mln::Neighborhood<N>& nbh,
+ unsigned lambda, L& nbasins)
+{
+ mln_concrete(I) c = mln::morpho::closing::area(ima, nbh, lambda);
+ mln_ch_value(I, L) s = mln::morpho::watershed::flooding(c, nbh, nbasins);
+ return s;
+}
+
+#endif // ! CHAIN_HH
diff --git a/milena/apps/papers/levillain.09.ismm/complex.cc b/milena/apps/papers/levillain.09.ismm/complex.cc
new file mode 100644
index 0000000..22bd139
--- /dev/null
+++ b/milena/apps/papers/levillain.09.ismm/complex.cc
@@ -0,0 +1,130 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+#include <cstdlib>
+
+#include <string>
+
+#include <mln/core/image/complex_image.hh>
+#include <mln/core/image/complex_neighborhoods.hh>
+#include <mln/core/image/complex_windows.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_16.hh>
+
+#include <mln/data/fill.hh>
+#include <mln/math/diff_abs.hh>
+#include <mln/literal/zero.hh>
+
+#include <mln/io/off/load.hh>
+#include <mln/io/off/save.hh>
+#include <mln/labeling/colorize.hh>
+
+#include "chain.hh"
+
+
+// FIXME: Should be rewritten using a diff_abs-based accumulator
+// taking values from triangles (and checking that exactly two values
+// where taken, of course).
+template <unsigned D, typename G, typename V>
+inline
+mln::complex_image<D, G, V>
+gradient_on_edges(const mln::complex_image<D, G, V>& input)
+{
+ typedef mln::complex_image<D, G, V> ima_t;
+ ima_t output (input.domain());
+ mln::data::fill(output, mln::literal::zero);
+
+ // Values on edges.
+ mln::p_n_faces_fwd_piter<D, G> e(input.domain(), 1);
+ // Edge-to-triangle adjacency.
+ typedef mln::complex_higher_neighborhood<D, G> e2t_t;
+ e2t_t e2t;
+ mln_niter(e2t_t) t(e2t, e);
+ // Iterate on edges (1-faces).
+ for_all(e)
+ {
+ t.start();
+ // An edge should be adjacent to at least one triangle.
+ if (!t.is_valid())
+ abort();
+ V v1 = input(t);
+ t.next();
+ // If E is adjacent to two triangles, compute the absolute
+ // difference between their values.
+ if (t.is_valid())
+ {
+ V v2 = input(t);
+ output(e) = mln::math::diff_abs(v1, v2);
+ // There should be no more adjacent triangles.
+ t.next();
+ mln_assertion(!t.is_valid());
+ }
+ }
+ return output;
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "usage: " << argv[0] << " input.off lambda output.off"
+ << std::endl;
+ std::exit(1);
+ }
+ std::string input_filename = argv[1];
+ unsigned lambda = atoi(argv[2]);
+ std::string output_filename = argv[3];
+
+ using namespace mln;
+
+ typedef float val;
+ typedef value::label_16 label;
+ // Input and output types.
+ typedef mln::float_2complex_image3df input;
+ typedef mln_ch_value_(input, label) output;
+ static const unsigned dim = input::dim;
+ typedef mln_geom_(input) geom;
+ complex_lower_dim_connected_n_face_neighborhood<dim, geom> nbh;
+ complex_lower_dim_connected_n_face_window_p<dim, geom> win;
+ label nbasins;
+
+ // Load, process, save.
+ /* FIXME: The domain of IMA should be limited to 2-faces. Alas, we
+ do not have (yet) an mln::pcomplex_subset site set type. Anyway,
+ this should not alter the results, only slow the computation
+ down. */
+ input ima;
+ io::off::load(ima, input_filename);
+
+ // Gradient on edges.
+ input g = gradient_on_edges(ima);
+ output s = chain(ima, nbh, lambda, nbasins);
+ io::off::save(labeling::colorize(value::rgb8(), s, nbasins),
+ output_filename);
+}
diff --git a/milena/apps/papers/levillain.09.ismm/graph.cc b/milena/apps/papers/levillain.09.ismm/graph.cc
new file mode 100644
index 0000000..bd6f983
--- /dev/null
+++ b/milena/apps/papers/levillain.09.ismm/graph.cc
@@ -0,0 +1,497 @@
+// Copyright (C) 2008, 2009 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.
+
+#include <iostream>
+#include <iomanip>
+
+#include <vector>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/routine/duplicate.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/site_set/p_queue_fast.hh>
+#include <mln/labeling/blobs.hh>
+#include <mln/io/pgm/load.hh>
+#include <mln/debug/println.hh>
+#include <mln/draw/line.hh>
+#include <mln/pw/all.hh>
+#include <mln/binarization/threshold.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_8.hh>
+#include <mln/core/alias/point2d.hh>
+
+#include <mln/core/site_set/p_faces.hh>
+#include <mln/core/image/complex_image.hh>
+#include <mln/core/alias/complex_geometry.hh>
+#include <mln/core/alias/complex_image.hh>
+
+// FIXME: Include these elsewhere? (In complex_image.hh?)
+#include <mln/core/image/complex_neighborhoods.hh>
+#include <mln/core/image/complex_neighborhood_piter.hh>
+#include <mln/core/image/complex_windows.hh>
+
+#include <mln/data/fill.hh>
+#include <mln/morpho/gradient.hh>
+#include <mln/labeling/colorize.hh>
+
+#include "chain.hh"
+
+
+// FIXME: Copied and adjusted from pics/graph.cc; factor.
+
+namespace mln
+{
+
+ template <typename I, typename N>
+ mln_concrete(I)
+ influence_zones(const I& input, const N& nbh)
+ {
+ mln_concrete(I) output = duplicate(input);
+
+ p_queue_fast<mln_site(I)> q;
+
+ {
+ // Initialization.
+ mln_piter(I) p(input.domain());
+ mln_niter(N) n(nbh, p);
+ for_all(p)
+ if (input(p) != 0)
+ for_all(n) if (input.has(n))
+ if (input(n) == 0)
+ {
+ q.push(p);
+ break;
+ }
+ }
+ {
+ // Body.
+ mln_site(I) p;
+ mln_niter(N) n(nbh, p);
+ while (! q.is_empty())
+ {
+ p = q.pop_front();
+ mln_invariant(output(p) != 0);
+ for_all(n) if (input.has(n))
+ if (output(n) == 0)
+ {
+ output(n) = output(p);
+ q.push(n);
+ }
+ }
+ }
+
+ return output;
+
+ }
+
+
+ namespace io
+ {
+
+ namespace neato
+ {
+
+ /* FIXME: This is just the gray-level version. Handle other value
+ types as well. */
+ void
+ save(const complex_image<1, discrete_plane_1complex_geometry,
+ value::int_u8>& ima,
+ const std::string& filename,
+ const std::string& bgcolor = "#0000C0",
+ const std::string& fontcolor = "#0000C0",
+ bool empty_vertex_label = true)
+ {
+ typedef value::int_u8 V;
+ typedef complex_image<1, discrete_plane_1complex_geometry, V> I;
+ const unsigned D = 1;
+ typedef discrete_plane_1complex_geometry G;
+
+ std::ofstream g(filename.c_str());
+ g << "graph wst" << std::endl
+ << "{" << std::endl
+ << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl
+ << " edge [color = \"#FFFFFF\"]" << std::endl
+ << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\","
+ << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]"
+ << std::endl;
+
+ // Vertices.
+ p_n_faces_fwd_piter<D, G> v(ima.domain(), 0);
+ typedef complex_higher_neighborhood<D, G> e_nbh_t;
+ e_nbh_t e_nbh;
+ for_all(v)
+ {
+ V vertex_color = ima(v);
+ std::ostringstream vertex_color_str;
+ // FIXME: Only valid for gray-level images.
+ vertex_color_str << '#'
+ << std::hex
+ << std::setfill('0')
+ << std::setw(2) << vertex_color
+ << std::setw(2) << vertex_color
+ << std::setw(2) << vertex_color
+ << std::dec;
+
+ g << " v" << v.unproxy_().face_id()
+ << " [pos = \""
+ << std::fixed << std::setprecision(1)
+ << (float)v.to_site().front()[1] << ", "
+ << -(float)v.to_site().front()[0]
+ << "\", color = \"" << vertex_color_str.str()
+ << "\", fillcolor = \"" << vertex_color_str.str()
+ << "\", pin = \"true\", style=\"filled,setlinewidth(3)\"";
+ if (empty_vertex_label)
+ g << ", label = \"\"";
+ g << "];"
+ << std::endl;
+ }
+
+ // Edges.
+ p_n_faces_fwd_piter<D, G> e(ima.domain(), 1);
+ typedef complex_lower_neighborhood<D, G> v_nbh_t;
+ v_nbh_t v_nbh;
+ mln_niter_(v_nbh_t) adj_v(v_nbh, e);
+ for_all(e)
+ {
+ V edge_color = ima(e);
+ std::ostringstream edge_color_str;
+ edge_color_str << '#'
+ << std::hex
+ << std::setfill('0')
+ << std::setw(2) << edge_color
+ << std::setw(2) << edge_color
+ << std::setw(2) << edge_color
+ << std::dec;
+
+ // Adjacent vertices.
+ adj_v.start();
+ topo::face<1> v1 = adj_v.unproxy_().face();
+ point2d p1 = adj_v.to_site().front();
+ adj_v.next();
+ topo::face<1> v2 = adj_v.unproxy_().face();
+ point2d p2 = adj_v.to_site().front();
+ adj_v.next();
+ mln_invariant(!adj_v.is_valid());
+
+ g << " v" << v1.face_id() << " -- v" << v2.face_id() << " ";
+ g << "[color = \"" << edge_color_str.str()
+ << "\", style=\"setlinewidth(10)\"];" << std::endl;
+ }
+
+ g << "}" << std::endl;
+ g.close();
+ }
+
+ // FIXME: Factor with the previous version.
+ void
+ save(const complex_image<1, discrete_plane_1complex_geometry,
+ value::rgb8>& ima,
+ const std::string& filename,
+ const std::string& bgcolor = "#0000C0",
+ const std::string& fontcolor = "#0000C0",
+ bool empty_vertex_label = true)
+ {
+ typedef value::rgb8 V;
+ typedef complex_image<1, discrete_plane_1complex_geometry, V> I;
+ const unsigned D = 1;
+ typedef discrete_plane_1complex_geometry G;
+
+ std::ofstream g(filename.c_str());
+ g << "graph wst" << std::endl
+ << "{" << std::endl
+ << " graph [bgcolor = \"" << bgcolor << "\"]" << std::endl
+ << " edge [color = \"#FFFFFF\"]" << std::endl
+ << " node [color = \"#FFFFFF\", height=\"5\", width=\"5\","
+ << " fontsize=\"100\", fontcolor = \"" << fontcolor << "\"]"
+ << std::endl;
+
+ // Vertices.
+ p_n_faces_fwd_piter<D, G> v(ima.domain(), 0);
+ typedef complex_higher_neighborhood<D, G> e_nbh_t;
+ e_nbh_t e_nbh;
+ for_all(v)
+ {
+ V vertex_color = ima(v);
+ std::ostringstream vertex_color_str;
+ // FIXME: Only valid for gray-level images.
+ vertex_color_str << '#'
+ << std::hex
+ << std::setfill('0')
+ << std::setw(2) << vertex_color.red()
+ << std::setw(2) << vertex_color.green()
+ << std::setw(2) << vertex_color.blue()
+ << std::dec;
+
+ g << " v" << v.unproxy_().face_id()
+ << " [pos = \""
+ << std::fixed << std::setprecision(1)
+ << (float)v.to_site().front()[1] << ", "
+ << -(float)v.to_site().front()[0]
+ << "\", color = \"" << vertex_color_str.str()
+ << "\", fillcolor = \"" << vertex_color_str.str()
+ << "\", pin = \"true\", style=\"filled,setlinewidth(3)\"";
+ if (empty_vertex_label)
+ g << ", label = \"\"";
+ g << "];"
+ << std::endl;
+ }
+
+ // Edges.
+ p_n_faces_fwd_piter<D, G> e(ima.domain(), 1);
+ typedef complex_lower_neighborhood<D, G> v_nbh_t;
+ v_nbh_t v_nbh;
+ mln_niter_(v_nbh_t) adj_v(v_nbh, e);
+ for_all(e)
+ {
+ V edge_color = ima(e);
+ std::ostringstream edge_color_str;
+ edge_color_str << '#'
+ << std::hex
+ << std::setfill('0')
+ << std::setw(2) << edge_color.red()
+ << std::setw(2) << edge_color.green()
+ << std::setw(2) << edge_color.blue()
+ << std::dec;
+
+ // Adjacent vertices.
+ adj_v.start();
+ topo::face<1> v1 = adj_v.unproxy_().face();
+ point2d p1 = adj_v.to_site().front();
+ adj_v.next();
+ topo::face<1> v2 = adj_v.unproxy_().face();
+ point2d p2 = adj_v.to_site().front();
+ adj_v.next();
+ mln_invariant(!adj_v.is_valid());
+
+ g << " v" << v1.face_id() << " -- v" << v2.face_id() << " ";
+ g << "[color = \"" << edge_color_str.str()
+ << "\", style=\"setlinewidth(10)\"];" << std::endl;
+ }
+
+ g << "}" << std::endl;
+ g.close();
+ }
+
+ } // end of namespace mln::io::neato
+
+ } // end of namespace mln::io
+
+} // end of namespace mln
+
+
+// FIXME: Clean up and move into Milena?
+mln::int_u8_1complex_image2d
+make_complex_image(const mln::image2d<mln::value::int_u8>& input)
+{
+ using namespace mln;
+ using mln::value::int_u8;
+
+ /*----------------------------------------.
+ | Complex + complex geometry (location). |
+ `----------------------------------------*/
+
+ border::thickness = 0;
+
+ unsigned nlabels;
+ image2d<unsigned> label =
+ labeling::blobs(mln::binarization::threshold(input, 1), c4(), nlabels);
+
+ std::cout << "n seeds = " << nlabels << std::endl;
+ {
+ image2d<int_u8> lab(label.domain());
+ data::paste(label, lab);
+ }
+
+ image2d<unsigned> iz = influence_zones(label, c4());
+ {
+ image2d<int_u8> IZ(iz.domain());
+ data::paste(iz, IZ);
+ }
+
+
+ // Make graph/complex.
+
+ std::vector< std::vector<bool> > adj(nlabels + 1);
+ for (unsigned l = 1; l <= nlabels; ++l)
+ adj[l].resize(nlabels + 1, false);
+
+ {
+ box2d::piter p(iz.domain());
+ for_all(p)
+ {
+ point2d r = p + right, b = p + down;
+ if (iz.has(r) && iz(p) != iz(r))
+ {
+ if (iz(p) <= iz(r))
+ adj[iz(p)][iz(r)] = true;
+ else
+ adj[iz(r)][iz(p)] = true;
+ }
+ if (iz.has(b) && iz(p) != iz(b))
+ {
+ if (iz(p) <= iz(b))
+ adj[iz(p)][iz(b)] = true;
+ else
+ adj[iz(b)][iz(p)] = true;
+ }
+ }
+ }
+
+ // end of mk_graph
+
+
+ const unsigned D = 1;
+
+ topo::complex<D> c;
+
+ typedef point2d P;
+ typedef geom::complex_geometry<D, P> G;
+ G geom;
+
+ // Convenience typedefs.
+ typedef topo::n_face<0, D> vertex;
+ typedef topo::n_face<1, D> edge;
+
+ {
+
+ // 0-faces (vertices).
+ std::vector<vertex> v;
+ {
+ box2d::piter p(label.domain());
+ for_all(p)
+ if (label(p) != 0)
+ {
+ geom.add_location(p);
+ v.push_back(c.add_face());
+ }
+ }
+
+ std::cout << "v size = " << v.size() << std::endl;
+
+ // 1-faces (edges).
+ std::vector<edge> e;
+ {
+ for (unsigned l = 1; l <= nlabels; ++l)
+ for (unsigned ll = l + 1; ll <= nlabels; ++ll)
+ if (adj[l][ll])
+ e.push_back( c.add_face(-v[l-1] + v[ll-1]) );
+ }
+
+ std::cout << "e size = " << e.size() << std::endl;
+
+ }
+
+
+ /*---------------------.
+ | Complex-based pset. |
+ `---------------------*/
+
+ p_complex<D, G> pc(c, geom);
+
+ /*----------------------.
+ | Complex-based image. |
+ `----------------------*/
+
+ // An image type built on a 1-complex with unsigned values on each
+ // face (both vertices and edges).
+ typedef complex_image<D, G, int_u8> output_t;
+
+ // Create and initialize an image based on PC.
+ output_t output(pc);
+
+ // Color OUTPUT's vertices with INPUT's values.
+ p_n_faces_fwd_piter<D, G> v(output.domain(), 0);
+ for_all(v)
+ output(v) = input(v.to_site().front());
+
+ // Use a medium gray to color edges.
+ p_n_faces_fwd_piter<D, G> e(output.domain(), 1);
+ for_all(e)
+ output(e) = 128;
+
+ return output;
+}
+
+
+// FIXME: Move to Milena?
+template <unsigned D, typename G, typename V>
+mln::complex_higher_dim_connected_n_face_window_p<D, G>
+make_elt_win(const mln::complex_image<D, G, V>& /* ima */)
+{
+ return mln::complex_higher_dim_connected_n_face_window_p<D, G>();
+}
+
+// FIXME: Move to Milena?
+template <unsigned D, typename G, typename V>
+mln::complex_higher_dim_connected_n_face_neighborhood<D, G>
+make_elt_nbh(const mln::complex_image<D, G, V>& /* ima */)
+{
+ return mln::complex_higher_dim_connected_n_face_neighborhood<D, G>();
+}
+
+
+int main(int argc, char* argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "usage: " << argv[0] << " seeds.pgm lambda output.neato"
+ << std::endl;
+ std::exit(1);
+ }
+ std::string input_filename = argv[1];
+ unsigned lambda = atoi(argv[2]);
+ std::string output_filename = argv[3];
+
+ using namespace mln;
+ using mln::value::int_u8;
+ // Use clearer names.
+ typedef int_u8_1complex_image2d int_u8_graph_image2d;
+
+ typedef int_u8_graph_image2d input;
+ typedef value::label_8 label;
+ typedef mln_ch_value_(input, label) output;
+ label nbasins;
+
+ // Seeds.
+ image2d<int_u8> seeds = io::pgm::load<int_u8>(input_filename);
+ // Input image computed from the graph of influence zones (IZ) of seeds.
+ typedef int_u8_graph_image2d ima_t;
+ ima_t ima = make_complex_image(seeds);
+ io::neato::save(ima, "apps/graph.neato");
+
+ // Gradient.
+ input g = morpho::gradient(ima, make_elt_win(ima));
+
+#if 0
+ // FIXME: get the name as argument.
+ io::neato::save(g, "apps/graph-g.neato");
+#endif
+
+ // Chain.
+ output s = chain(g, make_elt_nbh(g), lambda, nbasins);
+ io::neato::save(labeling::colorize(value::rgb8(), s, nbasins),
+ output_filename);
+}
diff --git a/milena/apps/papers/levillain.09.ismm/image2d.cc b/milena/apps/papers/levillain.09.ismm/image2d.cc
new file mode 100644
index 0000000..c1a7d3c
--- /dev/null
+++ b/milena/apps/papers/levillain.09.ismm/image2d.cc
@@ -0,0 +1,103 @@
+// Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
+//
+// This file is part of the Olena Library. This library is free
+// software; you can redistribute it and/or modify it under the terms
+// of the GNU General Public License version 2 as published by the
+// Free Software Foundation.
+//
+// This library 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 this library; see the file COPYING. If not, write to
+// the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+// Boston, MA 02111-1307, USA.
+//
+// As a special exception, you may use this file as part of a free
+// software library 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.
+
+#include <cstdlib>
+
+#include <string>
+
+#include <mln/core/image/image2d.hh>
+#include <mln/core/alias/neighb2d.hh>
+#include <mln/core/alias/window2d.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/value/label_8.hh>
+
+#include <mln/morpho/gradient.hh>
+
+#include <mln/io/pgm/load.hh>
+#include <mln/io/pgm/save.hh>
+#include <mln/io/ppm/save.hh>
+#include <mln/labeling/colorize.hh>
+
+#include "chain.hh"
+
+int main(int argc, char* argv[])
+{
+ if (argc != 4)
+ {
+ std::cerr << "usage: " << argv[0] << " input.pgm lambda output.ppm"
+ << std::endl;
+ std::exit(1);
+ }
+ std::string input_filename = argv[1];
+ unsigned lambda = atoi(argv[2]);
+ std::string output_filename = argv[3];
+
+ using namespace mln;
+
+ typedef value::int_u8 val;
+ typedef value::label_8 label;
+ // Input and output types.
+ typedef image2d<val> input;
+ typedef mln_ch_value_(input, label) output;
+ neighb2d nbh = c4();
+ window2d win = win_c4p();
+ label nbasins;
+
+ std::cout << c4() << std::endl;
+ std::cout << win_c4p() << std::endl;
+
+ // Load, process, save.
+ input ima = io::pgm::load<val>(input_filename);
+ // Gradient.
+ /* FIXME: Unfortunately, we cannot write
+
+ morpho::gradient(ima, win)
+
+ here, since MM only uses windows (yet?), not neighborhoods. And
+ we cannot either write
+
+ morpho::gradient(ima, nbh.win()),
+
+ since that window would not contain the center site...
+ Therefore, this function asks for a window WIN matching the
+ neighborhood NBH, plus the center site.
+
+ A neighborhood `n' should provide a method `win_p()' returning a
+ window corresponding to `n' plus the center site. */
+ input g = morpho::gradient(ima, win);
+
+#if 0
+ // FIXME: get the name as argument.
+ io::pgm::save(g, "apps/lena-g.pgm");
+#endif
+
+ // Chain.
+ output s = chain(g, nbh, lambda, nbasins);
+ io::ppm::save(labeling::colorize(value::rgb8(), s, nbasins),
+ output_filename);
+}
--
1.6.5
* configure.ac (DARWIN): New conditional.
* src/libiberty-fix.c: New.
* src/Makefile.am (libdyn_la_SOURCES) [DARWIN]: Add
libiberty-fix.c.
---
dynamic-use-of-static-c++/ChangeLog | 9 +++++
dynamic-use-of-static-c++/configure.ac | 4 ++
dynamic-use-of-static-c++/src/Makefile.am | 7 ++++
dynamic-use-of-static-c++/src/libiberty-fix.c | 46 +++++++++++++++++++++++++
4 files changed, 66 insertions(+), 0 deletions(-)
create mode 100644 dynamic-use-of-static-c++/src/libiberty-fix.c
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index fef105e..ce53b40 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,5 +1,14 @@
2009-10-29 Roland Levillain <roland(a)lrde.epita.fr>
+ Fix issues w.r.t. MacPorts' libiberty to have Python bindings work.
+
+ * configure.ac (DARWIN): New conditional.
+ * src/libiberty-fix.c: New.
+ * src/Makefile.am (libdyn_la_SOURCES) [DARWIN]: Add
+ libiberty-fix.c.
+
+2009-10-29 Roland Levillain <roland(a)lrde.epita.fr>
+
Provide some Python bindings over dyn using SWIG.
* Makefile.am (SUBDIRS): Add swig.
diff --git a/dynamic-use-of-static-c++/configure.ac b/dynamic-use-of-static-c++/configure.ac
index 2bbb19c..e6ff54b 100644
--- a/dynamic-use-of-static-c++/configure.ac
+++ b/dynamic-use-of-static-c++/configure.ac
@@ -95,6 +95,10 @@ AC_SUBST(LIBLTDL)
DYN_LIBIBERTY
+# Are we running on Darwin (Mac OS X)? If so, we'll have to deal with
+# MacPorts' libiberty's issues w.r.t `environ'.
+AM_CONDITIONAL([DARWIN], [echo "$host_os" | grep '^darwin'])
+
## ------ ##
## Boost. ##
## ------ ##
diff --git a/dynamic-use-of-static-c++/src/Makefile.am b/dynamic-use-of-static-c++/src/Makefile.am
index da9a4cf..ea01751 100644
--- a/dynamic-use-of-static-c++/src/Makefile.am
+++ b/dynamic-use-of-static-c++/src/Makefile.am
@@ -61,6 +61,13 @@ libdyn_la_SOURCES = \
ruby_stream.hh ruby_stream.cc \
ansidecl.h demangle.h config.hh
+# Provide a dummy `environ' symbol expected by libiberty (from the
+# MacPorts), but missing on Mac OS X. This is just a workaround. We
+# should file a problem report to the MacPorts about this.
+if DARWIN
+ libdyn_la_SOURCES += libiberty-fix.c
+endif DARWIN
+
libdyn_la_LIBADD = @RUBY_LIBRUBYARG_SHARED@ $(LIBLTDL) \
$(top_builddir)/libmd5/libmd5.la $(BOOST_FILESYSTEM_LIBS)
libdyn_la_DEPENDENCIES = $(LTDLDEPS)
diff --git a/dynamic-use-of-static-c++/src/libiberty-fix.c b/dynamic-use-of-static-c++/src/libiberty-fix.c
new file mode 100644
index 0000000..6010944
--- /dev/null
+++ b/dynamic-use-of-static-c++/src/libiberty-fix.c
@@ -0,0 +1,46 @@
+/* Copyright (C) 2009 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
+ \brief An ugly workaround to have libiberty (glued into libdyn)
+ find the \c environ symbol.
+
+ Everything should run well as long as we do not use it, nor any
+ function depending on it.
+
+ The recommended solution (see
+ http://www.gnu.org/software/gnulib/manual/gnulib.html#environ) is
+ to patch the guilty source by prepending these lines:
+
+ \code
+ #include <crt_externs.h>
+ #define environ (*_NSGetEnviron())
+ \endcode
+
+ Alas, we depend on a <em>compiled</em> libiberty, so we cheat by
+ providing a dummy \c environ. */
+
+char** environ = 0;
--
1.6.5
* Makefile.am (SUBDIRS): Add swig.
* config/pypath.m4: New symlink to ../../m4/pypath.m4.
* config/swig.m4: New symlink to ../../m4/swig.m4.
* configure.ac: Re-enable and update the configuration of SWIG and
Python.
* swig/,
* swig/python/:
New directories.
* swig/dyn.i,
* swig/run.mk,
* swig/Makefile.am,
* swig/python/config.py,
* swig/python/milena.py,
* swig/python/Makefile.am:
New.
* swig/run.in: New symlink to ../../swilena/run.in.
* swig/python/ltihooks.py: New symlink to
../../../swilena/python/ltihooks.py.
---
dynamic-use-of-static-c++/ChangeLog | 23 ++++
dynamic-use-of-static-c++/Makefile.am | 2 +-
dynamic-use-of-static-c++/config/pypath.m4 | 1 +
dynamic-use-of-static-c++/config/swig.m4 | 1 +
dynamic-use-of-static-c++/configure.ac | 86 ++++++++++-----
dynamic-use-of-static-c++/src/data.hh | 3 +
dynamic-use-of-static-c++/{ => swig}/Makefile.am | 8 +-
dynamic-use-of-static-c++/swig/dyn.i | 81 ++++++++++++++
dynamic-use-of-static-c++/swig/python/Makefile.am | 116 ++++++++++++++++++++
.../{Makefile.am => swig/python/config.py} | 15 ++-
dynamic-use-of-static-c++/swig/python/ltihooks.py | 1 +
dynamic-use-of-static-c++/swig/python/milena.py | 51 +++++++++
dynamic-use-of-static-c++/swig/run.in | 1 +
.../{Makefile.am => swig/run.mk} | 11 +-
14 files changed, 358 insertions(+), 42 deletions(-)
create mode 120000 dynamic-use-of-static-c++/config/pypath.m4
create mode 120000 dynamic-use-of-static-c++/config/swig.m4
copy dynamic-use-of-static-c++/{ => swig}/Makefile.am (76%)
create mode 100644 dynamic-use-of-static-c++/swig/dyn.i
create mode 100644 dynamic-use-of-static-c++/swig/python/Makefile.am
copy dynamic-use-of-static-c++/{Makefile.am => swig/python/config.py} (60%)
create mode 120000 dynamic-use-of-static-c++/swig/python/ltihooks.py
create mode 100644 dynamic-use-of-static-c++/swig/python/milena.py
create mode 120000 dynamic-use-of-static-c++/swig/run.in
copy dynamic-use-of-static-c++/{Makefile.am => swig/run.mk} (72%)
diff --git a/dynamic-use-of-static-c++/ChangeLog b/dynamic-use-of-static-c++/ChangeLog
index baa9f2f..fef105e 100644
--- a/dynamic-use-of-static-c++/ChangeLog
+++ b/dynamic-use-of-static-c++/ChangeLog
@@ -1,3 +1,26 @@
+2009-10-29 Roland Levillain <roland(a)lrde.epita.fr>
+
+ Provide some Python bindings over dyn using SWIG.
+
+ * Makefile.am (SUBDIRS): Add swig.
+ * config/pypath.m4: New symlink to ../../m4/pypath.m4.
+ * config/swig.m4: New symlink to ../../m4/swig.m4.
+ * configure.ac: Re-enable and update the configuration of SWIG and
+ Python.
+ * swig/,
+ * swig/python/:
+ New directories.
+ * swig/dyn.i,
+ * swig/run.mk,
+ * swig/Makefile.am,
+ * swig/python/config.py,
+ * swig/python/milena.py,
+ * swig/python/Makefile.am:
+ New.
+ * swig/run.in: New symlink to ../../swilena/run.in.
+ * swig/python/ltihooks.py: New symlink to
+ ../../../swilena/python/ltihooks.py.
+
2009-10-27 Roland Levillain <roland(a)lrde.epita.fr>
Have configure find libiberty and stop depending on compiled libaries.
diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/Makefile.am
index a769c69..737a9f9 100644
--- a/dynamic-use-of-static-c++/Makefile.am
+++ b/dynamic-use-of-static-c++/Makefile.am
@@ -14,7 +14,7 @@
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-SUBDIRS = libltdl libmd5 bin src config data test
+SUBDIRS = libltdl libmd5 bin src config data test swig
ACLOCAL_AMFLAGS = -I config -I libltdl
diff --git a/dynamic-use-of-static-c++/config/pypath.m4 b/dynamic-use-of-static-c++/config/pypath.m4
new file mode 120000
index 0000000..6e4faa9
--- /dev/null
+++ b/dynamic-use-of-static-c++/config/pypath.m4
@@ -0,0 +1 @@
+../../m4/pypath.m4
\ No newline at end of file
diff --git a/dynamic-use-of-static-c++/config/swig.m4 b/dynamic-use-of-static-c++/config/swig.m4
new file mode 120000
index 0000000..c45fb81
--- /dev/null
+++ b/dynamic-use-of-static-c++/config/swig.m4
@@ -0,0 +1 @@
+../../m4/swig.m4
\ No newline at end of file
diff --git a/dynamic-use-of-static-c++/configure.ac b/dynamic-use-of-static-c++/configure.ac
index 09e97a3..2bbb19c 100644
--- a/dynamic-use-of-static-c++/configure.ac
+++ b/dynamic-use-of-static-c++/configure.ac
@@ -102,34 +102,64 @@ DYN_LIBIBERTY
BOOST_FILESYSTEM
BOOST_STRING_ALGO
-dnl ## ------ ##
-dnl ## Swig. ##
-dnl ## ------ ##
-
-dnl AC_ARG_WITH([swig],
- dnl [AC_HELP_STRING([--with-swig],
- dnl [require Swig modules (defaults to auto)])],
- dnl [],
- dnl [with_swig=auto])
-
-dnl if test x$with_swig != xno; then
- dnl has_swig=yes
-
- dnl # Check for python and swig
-
- dnl AC_PROG_SWIG([1.3.24])
- dnl if (eval "$SWIG -version") >/dev/null 2>&1; then :; else
- dnl has_swig=no
- dnl fi
-
- dnl case $with_swig:$has_swig in
- dnl yes:no)
- dnl AC_MSG_ERROR([SWIG 1.3.24 is required.
- dnl Use `--without-swig' to disable SWIG modules.]);;
- dnl esac
-dnl fi
-
-dnl AC_MSG_RESULT([$has_swig])
+## ------ ##
+## Swig. ##
+## ------ ##
+
+# FIXME: Unify the Autoconf machinery w.r.t. SWIG and Python with Olena's.
+
+AC_ARG_WITH([swig],
+ [AC_HELP_STRING([--with-swig],
+ [require Swig modules (defaults to auto)])],
+ [],
+ [with_swig=auto])
+
+if test x$with_swig != xno; then
+ has_swig=yes
+
+ # Check for Python.
+ AM_PATH_PYTHON([2.5])
+ adl_CHECK_PYTHON
+
+ # Check for Python and SWIG.
+ save_CPPFLAGS=$CPPFLAGS
+ CPPFLAGS="$CPPFLAGS -I$PYTHONINC"
+ AC_CHECK_HEADERS([Python.h],
+ [python_headers=yes],
+ [python_headers=no])
+
+ if test x$python_headers = xno; then
+ oln_has_swig=no
+ if test x$with_swig = xyes; then
+ AC_MSG_ERROR(
+ [Python.h is required to build SWIG modules.
+ Add `-I python_include_path' to `CPPFLAGS'
+ or `--without-swig' to disable SWIG modules.])
+ fi
+ fi
+
+ CPPFLAGS=$save_CPPFLAGS
+
+ AC_PROG_SWIG([1.3.36])
+ if (eval "$SWIG -version") >/dev/null 2>&1; then :; else
+ has_swig=no
+ fi
+
+ case $with_swig:$has_swig in
+ yes:no)
+ AC_MSG_ERROR([SWIG 1.3.36 is required.
+ Use `--without-swig' to disable SWIG modules.]);;
+ esac
+fi
+
+AC_MSG_RESULT([$has_swig])
+
+AC_CONFIG_FILES([swig/Makefile
+ swig/python/Makefile])
+
+AC_CONFIG_FILES([swig/run], [chmod +x swig/run])
+
+
# FIXME: Doesn't Autoconf provide something like abs_top_srcdir?
my_abs_srcdir=`cd $srcdir && pwd`
diff --git a/dynamic-use-of-static-c++/src/data.hh b/dynamic-use-of-static-c++/src/data.hh
index f0e1812..812c3cd 100644
--- a/dynamic-use-of-static-c++/src/data.hh
+++ b/dynamic-use-of-static-c++/src/data.hh
@@ -338,6 +338,9 @@ namespace dyn {
data() : proxy_(nil_proxy) {}
+ /* FIXME: What's the purpose of the second argument? I (Roland)
+ presume it serve as a desambiguition mechanism w.r.t to ctors
+ `data<T>(T&)' and `data<T>(const T&)'. If so, document it. */
data(abstract_data* proxy, proxy_tag*) : all_methods(), proxy_(proxy) {}
template <class T>
diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/Makefile.am
similarity index 76%
copy from dynamic-use-of-static-c++/Makefile.am
copy to dynamic-use-of-static-c++/swig/Makefile.am
index a769c69..2d894af 100644
--- a/dynamic-use-of-static-c++/Makefile.am
+++ b/dynamic-use-of-static-c++/swig/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -14,8 +14,8 @@
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-SUBDIRS = libltdl libmd5 bin src config data test
+SUBDIRS = python
-ACLOCAL_AMFLAGS = -I config -I libltdl
+EXTRA_DIST = dyn.i
-EXTRA_DIST = bootstrap
+check_SCRIPTS = run
diff --git a/dynamic-use-of-static-c++/swig/dyn.i b/dynamic-use-of-static-c++/swig/dyn.i
new file mode 100644
index 0000000..eaeacdf
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/dyn.i
@@ -0,0 +1,81 @@
+// -*- C++ -*-
+// Copyright (C) 2009 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
+/// \brief A wrapper of libdyn.
+
+%module dyn
+
+%include std_string.i
+
+%{
+#include "dyn-all.hh"
+%}
+
+// Ignore global objects causing trouble.
+%ignore dyn::logger;
+%ignore dyn::internal::operator_push;
+%ignore dyn::internal::operator_pop;
+%ignore dyn::internal::operator_incr;
+%ignore dyn::internal::operator_decr;
+%ignore dyn::internal::operator_plus;
+%ignore dyn::internal::operator_star;
+%ignore dyn::internal::operator_equal;
+%ignore dyn::internal::operator_not_equal;
+%ignore dyn::internal::operator_square_brackets;
+
+%include "dyn-all.hh";
+
+%inline %{
+ /* The natural, single-argument ctors of dyn::data manipulate the
+ encapulsated by reference, which is wrong when these data are of
+ builtin types of the target language (e.g., Pythons' `int's),
+ because we have no control on them and they can vanish at any
+ moment.
+
+ To prevent this, provide construction helpers creating dyn::data
+ objects manipulating data by value (copy). */
+ template <typename T>
+ dyn::data make_data_by_cpy(T i)
+ {
+ dyn::proxy_tag* dummy = 0;
+ // This dummy pointer passed as second argument is required to
+ // call the right ctor.
+ dyn::data d(new dyn::data_proxy_by_cpy<T>(i), dummy);
+ return d;
+ }
+%}
+
+// Instantiate make_data_by_cpy ctors for some types.
+%template(integer) make_data_by_cpy<int>;
+%template(string) make_data_by_cpy<std::string>;
+
+// Instantiate dyn::data explicit conversion routines for some types.
+%extend dyn::data
+{
+ %template(convert_to_int) convert_to<int>;
+ %template(convert_to_string) convert_to<std::string>;
+}
diff --git a/dynamic-use-of-static-c++/swig/python/Makefile.am b/dynamic-use-of-static-c++/swig/python/Makefile.am
new file mode 100644
index 0000000..81455f7
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/python/Makefile.am
@@ -0,0 +1,116 @@
+# Copyright (C) 2009 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/>.
+
+
+## ------------------ ##
+## Generic material. ##
+## ------------------ ##
+
+## FIXME: Factor as much as possible. See how we handled this in TC.
+
+## FIXME: Adjust.
+
+CLEANFILES =
+AM_CPPFLAGS = -I$(PYTHONINC) -I$(top_builddir)/src -I$(top_srcdir)/src
+## FIXME: Define an equivalent to Olena's TOOLS_CXXFLAGS?
+## TOOLS_CXXFLAGS = @TOOLS_CXXFLAGS@
+## AM_CXXFLAGS = $(TOOLS_CXXFLAGS)
+AM_SWIGFLAGS = -Wall -c++ -python -I$(top_builddir)/src -I$(top_srcdir)/src
+# We build modules, not plain libs.
+AM_LDFLAGS = -avoid-version -module -shared
+AM_LIBADD = $(top_builddir)/src/libdyn.la # $(LIBLTDL)
+
+# Run Swig to create the C++ wrapper files, the Python interface
+# files, and the dependency Makefile snippets.
+# FIXME: `%'-style patterns rules are not portable.
+%-wrap.cc %.py: $(top_srcdir)/swig/%.i
+ if $(SWIG) $(AM_SWIGFLAGS) $(SWIGFLAGS) -MD -MF "$(DEPDIR)/$*-wrap.Tcc" -o $@ $<; then \
+ mv -f "$(DEPDIR)/$*-wrap.Tcc" "$(DEPDIR)/$*-wrap.Pcc";\
+ else \
+ rm -f "$(DEPDIR)/$*-wrap.Tcc"; exit 1;\
+ fi
+
+
+# ltihooks.py: Python import hooks that understand Libtool libraries.
+python_PYTHON = ltihooks.py
+
+# config.py: Configuration values of the package.
+EXTRA_DIST = config.py
+
+
+## ----------------- ##
+## Wrapped modules. ##
+## ----------------- ##
+
+## FIXME: All of this should be generated.
+## Don't forget to add a `deps-reset' target as in TC.
+
+## FIXME: Dependencies do not work as expected, e.g., touching
+## mln/core/point.hh will not void point-wrap.cc, and Swig will not
+## regen it (it will merely recompile _point2d.la). See how other
+## projects people handle this.
+
+nodist_python_PYTHON =
+pyexec_LTLIBRARIES =
+
+## dyn.
+pyexec_LTLIBRARIES += _dyn.la
+nodist__dyn_la_SOURCES = dyn-wrap.cc
+_dyn_la_LIBADD = $(AM_LIBADD)
+CLEANFILES += $(nodist__dyn_la_SOURCES) dyn.py dyn.py[co]
+## Include the dependency files. Copied from Automake's generated
+## case for C++.
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/_dyn-wrap.Pcc@am__quote@
+nodist_python_PYTHON += dyn.py
+
+
+## ------- ##
+## Tests. ##
+## ------- ##
+
+include $(top_srcdir)/swig/run.mk
+
+TESTS_ENVIRONMENT = \
+ abs_top_srcdir="$(abs_top_srcdir)" \
+ abs_top_builddir="$(abs_top_builddir)" \
+ $(RUN)
+# Ensure `run' is rebuilt before the tests are run.
+$(TESTS): $(srcdir)/run.stamp
+# The dependency is on `run.in' and not `run', since `run' is
+# regenerated at distribution time, and voids the time stamps (which
+# we don't want!).
+EXTRA_DIST += $(srcdir)/run.stamp
+$(srcdir)/run.stamp: $(RUN_IN)
+ @rm -f $@
+ @rm -f $@.tmp
+ @touch $@.tmp
+ $(MAKE) $(AM_MAKEFLAGS) $(RUN)
+ @mv -f $@.tmp $@
+
+# FIXME: We should not use the `.py' extension: it is not needed, and
+# it prevents us from using the same name for both a module (wrapper)
+# and a test. Alas, the script `run' expects a file name with an
+# extension as argument. We could improve this by adding options such
+# as `--python' to `run'.
+TESTS = milena.py
+
+# FIXME: Is this really needed?
+EXTRA_DIST += $(TESTS)
+
+clean-local: clean-repository
+.PHONY: clean-repository
+clean-repository:
+ -rm -rf repository
diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/python/config.py
similarity index 60%
copy from dynamic-use-of-static-c++/Makefile.am
copy to dynamic-use-of-static-c++/swig/python/config.py
index a769c69..1594f5e 100644
--- a/dynamic-use-of-static-c++/Makefile.am
+++ b/dynamic-use-of-static-c++/swig/python/config.py
@@ -1,4 +1,6 @@
-# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+#! /usr/bin/env python
+
+# Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
#
# This file is part of Olena.
#
@@ -14,8 +16,13 @@
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-SUBDIRS = libltdl libmd5 bin src config data test
+# \file
+# \brief Configuration values of the package.
+
+# FIXME: We might want to turn this into a config.py.in file and
+# generate it instead of getting variables from the environment.
-ACLOCAL_AMFLAGS = -I config -I libltdl
+import os
-EXTRA_DIST = bootstrap
+abs_top_srcdir = os.environ["abs_top_srcdir"]
+abs_milena_dir = os.path.join(abs_top_srcdir, "..", "milena")
diff --git a/dynamic-use-of-static-c++/swig/python/ltihooks.py b/dynamic-use-of-static-c++/swig/python/ltihooks.py
new file mode 120000
index 0000000..11249fa
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/python/ltihooks.py
@@ -0,0 +1 @@
+../../../swilena/python/ltihooks.py
\ No newline at end of file
diff --git a/dynamic-use-of-static-c++/swig/python/milena.py b/dynamic-use-of-static-c++/swig/python/milena.py
new file mode 100644
index 0000000..85a1cfc
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/python/milena.py
@@ -0,0 +1,51 @@
+#! /usr/bin/env python
+
+# Copyright (C) 2009 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
+# \brief A Python version of test/test_olena.cc.
+
+import ltihooks
+
+import dyn
+import config
+
+dyn.include_dir(config.abs_milena_dir)
+dyn.include("mln/core/image/image2d.hh")
+dyn.include("mln/data/fill.hh")
+dyn.include("mln/debug/iota.hh")
+dyn.include("mln/debug/println.hh")
+
+mk_image2d_int = dyn.ctor("mln::image2d<int>")
+fill = dyn.fun("mln::data::fill")
+iota = dyn.fun("mln::debug::iota")
+println = dyn.fun("mln::debug::println")
+
+# We'd like to be able to write this:
+#
+# ima = mk_image2d_int(3, 3)
+#
+# but we just can't. `mk_image2d_int' only accept `dyn.data' as
+# arguments, so we have to encapsulate integers in `dyn.data' objects
+# using `dyn.integer' (likewise for strings with `dyn.string').
+
+ima = mk_image2d_int(dyn.integer(3), dyn.integer(3))
+
+fill(ima, dyn.integer(0))
+println(dyn.string("ima (before) ="), ima)
+iota(ima)
+println(dyn.string("ima (after) ="), ima)
diff --git a/dynamic-use-of-static-c++/swig/run.in b/dynamic-use-of-static-c++/swig/run.in
new file mode 120000
index 0000000..585aed6
--- /dev/null
+++ b/dynamic-use-of-static-c++/swig/run.in
@@ -0,0 +1 @@
+../../swilena/run.in
\ No newline at end of file
diff --git a/dynamic-use-of-static-c++/Makefile.am b/dynamic-use-of-static-c++/swig/run.mk
similarity index 72%
copy from dynamic-use-of-static-c++/Makefile.am
copy to dynamic-use-of-static-c++/swig/run.mk
index a769c69..24aaa09 100644
--- a/dynamic-use-of-static-c++/Makefile.am
+++ b/dynamic-use-of-static-c++/swig/run.mk
@@ -1,4 +1,4 @@
-# Copyright (C) 2005, 2009 EPITA Research and Development Laboratory (LRDE).
+# Copyright (C) 2008, 2009 EPITA Research and Development Laboratory (LRDE).
#
# This file is part of Olena.
#
@@ -14,8 +14,9 @@
# You should have received a copy of the GNU General Public License
# along with Olena. If not, see <http://www.gnu.org/licenses/>.
-SUBDIRS = libltdl libmd5 bin src config data test
+# A test/script wrapper.
-ACLOCAL_AMFLAGS = -I config -I libltdl
-
-EXTRA_DIST = bootstrap
+RUN = $(top_builddir)/swig/run
+RUN_IN = $(top_srcdir)/swig/run.in
+$(RUN): $(RUN_IN)
+ cd $(top_builddir)/swig && $(MAKE) $(AM_MAKEFLAGS) run
--
1.6.5