* apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc: New.
* apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in: New.
* apps/mesh-segm-skel/Makefile.am (bin_PROGRAMS): Add
mesh-complex-max-curv-extrema.
(mesh_complex_max_curv_extrema_SOURCES): New.
(TESTS): Add test-mesh-complex-max-curv-segm-extrema.
(CLEANFILES): Add socket-complex-max-curv-segm-extrema.off,
teapot-complex-max-curv-segm-extrema.off and
bunny-holefilled-complex-max-curv-segm-extrema.off.
---
milena/ChangeLog | 14 +++
milena/apps/mesh-segm-skel/Makefile.am | 13 ++-
...ax-curv.cc => mesh-complex-max-curv-extrema.cc} | 105 +++++++++++++-------
.../test-mesh-complex-max-curv-extrema.in | 10 ++
4 files changed, 102 insertions(+), 40 deletions(-)
copy milena/apps/mesh-segm-skel/{mesh-complex-max-curv.cc =>
mesh-complex-max-curv-extrema.cc} (64%)
create mode 100644 milena/apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in
diff --git a/milena/ChangeLog b/milena/ChangeLog
index f112bea..58cd008 100644
--- a/milena/ChangeLog
+++ b/milena/ChangeLog
@@ -1,5 +1,19 @@
2010-05-11 Roland Levillain <roland(a)lrde.epita.fr>
+ New application: mesh-complex-max-curv-extrema.
+
+ * apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc: New.
+ * apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in: New.
+ * apps/mesh-segm-skel/Makefile.am (bin_PROGRAMS): Add
+ mesh-complex-max-curv-extrema.
+ (mesh_complex_max_curv_extrema_SOURCES): New.
+ (TESTS): Add test-mesh-complex-max-curv-segm-extrema.
+ (CLEANFILES): Add socket-complex-max-curv-segm-extrema.off,
+ teapot-complex-max-curv-segm-extrema.off and
+ bunny-holefilled-complex-max-curv-segm-extrema.off.
+
+2010-05-11 Roland Levillain <roland(a)lrde.epita.fr>
+
Revive, fix and update application mesh-segm.
* apps/mesh-segm-skel/mesh-segm.cc: Catch up with the new
diff --git a/milena/apps/mesh-segm-skel/Makefile.am
b/milena/apps/mesh-segm-skel/Makefile.am
index aa71ef3..460e6e9 100644
--- a/milena/apps/mesh-segm-skel/Makefile.am
+++ b/milena/apps/mesh-segm-skel/Makefile.am
@@ -112,9 +112,16 @@ mesh_complex_max_curv_SOURCES = mesh-complex-max-curv.cc
TESTS += test-mesh-complex-max-curv
CLEANFILES += teapot-complex-max-curv.off
-# FIXME: Write a program showing the local minima (and maxima) of
-# scalar-valued complex-based mesh (to see the curvature extrema).
-# ...
+
+# A program computing the max curvature at each (2-)face of the
+# surface of a triangle mesh and displaying its local minima
+# (in blue) and maxima (in red).
+bin_PROGRAMS += mesh-complex-max-curv-extrema
+mesh_complex_max_curv_extrema_SOURCES = mesh-complex-max-curv-extrema.cc
+TESTS += test-mesh-complex-max-curv-extrema
+CLEANFILES += \
+ socket-complex-max-curv-extrema.off \
+ teapot-complex-max-curv-extrema.off
# Segmentation program working on precomputed meshes with curvatures data.
bin_PROGRAMS += mesh-complex-segm
diff --git a/milena/apps/mesh-segm-skel/mesh-complex-max-curv.cc
b/milena/apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc
similarity index 64%
copy from milena/apps/mesh-segm-skel/mesh-complex-max-curv.cc
copy to milena/apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc
index 8d79839..8f68b3d 100644
--- a/milena/apps/mesh-segm-skel/mesh-complex-max-curv.cc
+++ b/milena/apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc
@@ -1,4 +1,5 @@
-// 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 the Milena Library. This library is free
// software; you can redistribute it and/or modify it under the terms
@@ -25,10 +26,11 @@
// reasons why the executable file might be covered by the GNU General
// Public License.
-/// \file apps/mesh-segm-skel/mesh-complex-max-curv.cc
+/// \file apps/mesh-segm-skel/mesh-complex-max-curv-extrema.cc
/// \brief A program computing the max curvature at each (2-)face of
-/// the surface of the (triangle) mesh of a statue, using a
-/// complex-based image.
+/// the surface of the (triangle) mesh of a statue, using
+/// complex-based image, and displaying its local minima (in blue) and
+/// maxima (in red).
#include <cstdlib>
#include <cmath>
@@ -42,13 +44,20 @@
#include <mln/data/fill.hh>
#include <mln/literal/zero.hh>
+#include <mln/labeling/regional_minima.hh>
+#include <mln/labeling/regional_maxima.hh>
+
#include <mln/math/max.hh>
#include <mln/math/sqr.hh>
#include <mln/accu/stat/min_max.hh>
#include <mln/fun/v2v/linear.hh>
#include <mln/data/transform.hh>
+#include <mln/value/label_16.hh>
+
#include <mln/literal/white.hh>
+#include <mln/literal/grays.hh>
+#include <mln/literal/colors.hh>
#include <mln/io/off/load.hh>
#include <mln/io/off/save.hh>
@@ -86,16 +95,6 @@ int main(int argc, char* argv[])
mln::bin_2complex_image3df input;
mln::io::off::load(input, input_filename);
-// // ------------------------------------------------------------
-// // FIXME: TEST.
-// mln::complex_image< 2, mln::space_2complex_geometry, mln::algebra::vec<3,
float> >
-// normal = mesh_normal(input.domain());
-// mln::p_n_faces_fwd_piter<D, G> v_(normal.domain(), 0);
-// for_all(v_)
-// std::cout << normal(v_) << std::endl;
-// std::exit(0);
-// // ------------------------------------------------------------
-
std::pair<ima_t, ima_t> curv = mln::geom::mesh_curvature(input.domain());
// Compute the max curvature at each vertex.
@@ -133,29 +132,61 @@ int main(int argc, char* argv[])
mln_invariant(n <= 3);
}
- // Normalize values between 0 and 1.
- /* Shrink the values of FACE_M into the range 0..1, as these are
- the only values accepted a an RGB floating-point component in the
- OFF file format. */
- ima_t output(max_curv.domain());
- mln::data::fill(output, mln::literal::zero);
- std::pair<float, float> min_max(acc);
- // FIXME: Taken from mln/data/stretch.hh (this should be factored).
- float min = min_max.first;
- float max = min_max.second;
- std::cout << min << std::endl;
- std::cout << max << std::endl;
- // Don't normalize actually if the curvature is constant (i.e.,
- // if min == max).
- if (min != max)
- {
- float m = 0.0f;
- float M = 1.0f;
- float a = (M - m) / (max - min);
- float b = (m * max - M * min) / (max - min);
- mln::fun::v2v::linear<float, float, float> f(a, b);
- output = mln::data::transform(max_curv, f);
- }
+ /*----------------.
+ | Local extrema. |
+ `----------------*/
+
+ /// Adjacent triangles are connected by shared edges.
+ typedef mln::complex_lower_dim_connected_n_face_neighborhood<D, G> nbh_t;
+ nbh_t nbh;
+
+ typedef mln::value::label_16 label_t;
+ typedef mln_ch_value_(ima_t, label_t) label_ima_t;
+
+ /* FIXME: We should use something like `ima_t | p_n_faces(2)' instead
+ of `ima_t' here. Or better: `input' should only associate data
+ to 2-faces. */
+ label_t nminima;
+ label_ima_t minima =
+ mln::labeling::regional_minima(max_curv, nbh, nminima);
+ std::cout << "nminima = " << nminima << std::endl;
+
+ label_t nmaxima;
+ label_ima_t maxima =
+ mln::labeling::regional_maxima(max_curv, nbh, nmaxima);
+ std::cout << "nmaxima = " << nmaxima << std::endl;
+
+ /*-----------------.
+ | Colored output. |
+ `-----------------*/
+
+ typedef mln::rgb8_2complex_image3df output_t;
+ output_t output(max_curv.domain());
+
+ for_all(t)
+ {
+ if (minima(t) != mln::literal::zero)
+ {
+ // Special (unexpected) case: T is both a minimum and a
+ // maximum. Paint it in magenta (blue + red).
+ if (maxima(t) != mln::literal::zero)
+ {
+ std::cerr
+ << "warning: " << t << " is both a minimum and a
maximum."
+ << std::endl;
+ output(t) = mln::literal::magenta;
+ }
+ else
+ // Paint minimum T in blue.
+ output(t) = mln::literal::blue;
+ }
+ else if (maxima(t) != mln::literal::zero)
+ // Paint maximum T in red.
+ output(t) = mln::literal::red;
+ else
+ // Default color.
+ output(t) = mln::literal::medium_gray;
+ }
// Output.
mln::io::off::save(output, output_filename);
diff --git a/milena/apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in
b/milena/apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in
new file mode 100644
index 0000000..c6fa1e8
--- /dev/null
+++ b/milena/apps/mesh-segm-skel/test-mesh-complex-max-curv-extrema.in
@@ -0,0 +1,10 @@
+#! /bin/sh
+
+set -ex
+
+mesh_dir=@top_srcdir@/milena/mesh
+
+time ./mesh-complex-max-curv-extrema $mesh_dir/socket.off
socket-complex-max-curv-extrema.off
+time ./mesh-complex-max-curv-extrema $mesh_dir/teapot.off
teapot-complex-max-curv-extrema.off
+# FIXME: Too long. Should be run with (future) target `check-full'.
+#time ./mesh-complex-max-curv-extrema $mesh_dir/bunny-holefilled.off
bunny-holefilled-complex-max-curv-extrema.off
--
1.5.6.5