660: Add a slice morpher.

https://svn.lrde.epita.fr/svn/oln/trunk/olena Index: ChangeLog from Roland Levillain <roland@lrde.epita.fr> Add a slice morpher. * oln/morpher/tags.hh (oln::morpher::tag::slice): New tag. * oln/morpher/slice.hh: New file (new morpher). * oln/core/type_fun/slice.hh: New. * oln/core/iterator_vtypes.hh: Include it. (oln::single_vtype<morpher::slice<Image>, typedef_::fwd_piter_type>) (oln::single_vtype<morpher::slice<Image>, typedef_::bkd_piter_type>): New. * oln/core/1d/topo1d.hh, oln/core/2d/topo2d.hh, * oln/core/3d/topo3d.hh: New (shortcuts). * oln/core/gen/topo_lbbox.hh (oln::vtypes< topo_lbbox_<point> >: Reduce the explanation to a reference to the virtual types of oln::topo_bbox_. (topo_lbbox::topo_lbbox_(const point&, const point&, unsigned)): New ctor. (topo_lbbox::border): New method. * oln/core/gen/topo_bbox.hh (topo_bbox::topo_bbox_(const point&, const point&)): New ctor. * oln/Makefile.am (nobase_oln_HEADERS): Add core/1d/topo1d.hh, core/2d/topo2d.hh, core/3d/topo3d.hh, core/gen/piter_isubset.hh, core/type_fun/slice_piter.hh and morpher/slice.hh. * tests/morphers/slice_morpher.cc: New test. * tests/morphers/Makefile.am (check_PROGRAMS): Add slice_morpher. (slice_morpher_SOURCES): New. * oln/core/gen/bbox_fwd_piter.hh, oln/core/gen/bbox_bkd_piter.hh, * tests/morphers/add_neighborhood_morpher.cc: Fix a comment. oln/Makefile.am | 7 oln/core/1d/topo1d.hh | 38 +++ oln/core/2d/topo2d.hh | 38 +++ oln/core/3d/topo3d.hh | 38 +++ oln/core/gen/bbox_bkd_piter.hh | 2 oln/core/gen/bbox_fwd_piter.hh | 2 oln/core/gen/topo_bbox.hh | 10 - oln/core/gen/topo_lbbox.hh | 76 ++----- oln/core/iterator_vtypes.hh | 43 ++++ oln/core/type_fun/slice.hh | 280 +++++++++++++++++++++++++++++ oln/morpher/slice.hh | 206 +++++++++++++++++++++ oln/morpher/tags.hh | 2 tests/morphers/Makefile.am | 4 tests/morphers/add_neighborhood_morpher.cc | 6 tests/morphers/slice_morpher.cc | 92 +++++++++ 15 files changed, 780 insertions(+), 64 deletions(-) Index: tests/morphers/add_neighborhood_morpher.cc --- tests/morphers/add_neighborhood_morpher.cc (revision 659) +++ tests/morphers/add_neighborhood_morpher.cc (working copy) @@ -50,9 +50,9 @@ image_t ima(42, 51); - /*------------------------------------. - | add_neighborhood< image2d<char> >. | - `------------------------------------*/ + /*---------------------------------------------------. + | add_neighborhood< image2d<char>, oln::neighb2d >. | + `---------------------------------------------------*/ typedef oln::neighb2d neighb_t; typedef oln::morpher::add_neighborhood<image_t, neighb_t> image_with_nbh_t; Index: tests/morphers/slice_morpher.cc --- tests/morphers/slice_morpher.cc (revision 0) +++ tests/morphers/slice_morpher.cc (revision 0) @@ -0,0 +1,92 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +/// Test the identity morpher. + +#include <cassert> + +#include <mlc/assert.hh> +#include <mlc/is_a.hh> + +// FIXME: We should not include oln/basics2d.hh and oln/basics3d.hh, +// but only oln/core/2d/image2d.hh and oln/core/3d/image3d.hh. +#include <oln/basics2d.hh> +#include <oln/basics3d.hh> +#include <oln/morpher/slice.hh> + +#include <oln/level/fill.hh> + + +int +main() +{ + /*---------------. + | image2d<int>. | + `---------------*/ + + typedef oln::image3d<int> image_t; + + // Sanity check: interfaces realized by oln::image2d. + mlc::assert_< mlc_is_a_(image_t, oln::abstract::image3d) >::check(); + + image_t ima(3, 4, 5); + oln::level::fill (ima, 42); + + + /*----------------------------. + | add_slice< image2d<int> >. | + `----------------------------*/ + + typedef oln::morpher::slice<image_t> slice_t; + + // Check that the instantiated slice morpher realizes the suited + // interfaces. + mlc::assert_< mlc::eq_<oln_type_of_(slice_t, grid), oln::grid2d> >::check(); + mlc::assert_< mlc_is_a_(slice_t, oln::abstract::image2d) >::check(); + mlc::assert_< mlc_is_a_(slice_t, oln::abstract::mutable_image) >::check(); + + // Create a slice of \a ima along the 2nd axis (which the ``row'' + // axis, numbered 1), and check its peoperties. + int slice_row = 2; + slice_t ima_with_nbh(ima, 1, slice_row); + assert(ima_with_nbh.bbox().nrows() == 3); + assert(ima_with_nbh.bbox().ncols() == 5); + // Fill a slice of \a ima by filling \a ima_with_nbh. + oln::level::fill (ima_with_nbh, 51); + + // Check that \a ima has been altered, by comapring it to a similar + // 3D image. + image_t ref(3, 4, 5); + oln::level::fill (ref, 42); + for (unsigned s = 0; s < ima.bbox().nslices(); ++s) + for (unsigned c = 0; c < ima.bbox().ncols(); ++c) + ref.at(s, slice_row, c) = 51; + // FIXME: Implement equality on images. + oln_type_of_(image_t, piter) p (ima.topo()); + for_all (p) + assert(ima(p) == ref(p)); +} Index: tests/morphers/Makefile.am --- tests/morphers/Makefile.am (revision 659) +++ tests/morphers/Makefile.am (working copy) @@ -21,13 +21,17 @@ check_PROGRAMS = \ identity_morpher \ add_neighborhood_morpher \ + slice_morpher \ value_cast \ + \ morphers # Morphers. identity_morpher_SOURCES = identity_morpher.cc add_neighborhood_morpher_SOURCES = add_neighborhood_morpher.cc +slice_morpher_SOURCES = slice_morpher.cc value_cast_SOURCES = value_cast.cc + morphers_SOURCES = morphers.cc Index: oln/core/type_fun/slice.hh --- oln/core/type_fun/slice.hh (revision 0) +++ oln/core/type_fun/slice.hh (revision 0) @@ -0,0 +1,280 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +#ifndef OLN_CORE_TYPE_FUN_SLICE_HH +# define OLN_CORE_TYPE_FUN_SLICE_HH + +# include <mlc/flags.hh> + +# include <oln/core/1d/point1d.hh> +# include <oln/core/1d/topo1d.hh> + +# include <oln/core/2d/point2d.hh> +# include <oln/core/2d/topo2d.hh> + +# include <oln/core/3d/point3d.hh> +# include <oln/core/3d/topo3d.hh> + + +namespace oln +{ + + /*-----------------------------------. + | Point translation during slicing. | + `-----------------------------------*/ + + // FIXME: To be moved elsewhere (these are function on values, not + // on types). + + // FIXME: Can't we rewrite this in a more generic way? + + // --------- // + // Slicing. // + // --------- // + + /// Translate an image point to a slice point. + /// \{ + + /// 2D to 1D version. + point1d slice_point(const point2d& p, unsigned slice_dim) + { + switch (slice_dim) + { + case 0: + return point1d(p.col()); + break; + case 1: + return point1d(p.row()); + break; + default: + abort(); + } + } + + /// 3D to 2D version. + point2d slice_point(const point3d& p, unsigned slice_dim) + { + switch (slice_dim) + { + case 0: + return point2d(p.row(), p.col()); + break; + case 1: + return point2d(p.slice(), p.col()); + break; + case 2: + return point2d(p.slice(), p.row()); + break; + default: + abort(); + } + } + + /// \} + + + // ----------- // + // Unslicing. // + // ----------- // + + /// Translate a slice point to an image point. + /// \{ + + /// 1D to 2D version. + point2d unslice_point(const point1d& p, unsigned slice_dim, int slice_coord) + { + switch (slice_dim) + { + case 0: + return point2d(slice_coord, p.index()); + break; + case 1: + return point2d(p.index(), slice_coord); + break; + default: + abort(); + } + } + + /// 2D to 3D version. + point3d unslice_point(const point2d& p, unsigned slice_dim, int slice_coord) + { + switch (slice_dim) + { + case 0: + return point3d(slice_coord, p.row(), p.col()); + break; + case 1: + return point3d(p.row(), slice_coord, p.col()); + break; + case 2: + return point3d(p.row(), p.col(), slice_coord); + break; + default: + abort(); + } + } + + /// \} + + + /// Error messages raised by static assertions/abortions. + namespace ERROR + { + struct TYPE_FUNCTION_slice_piter_NOT_DEFINED_FOR_THIS_PARAMETER; + struct TYPE_FUNCTION_slice_topo_NOT_DEFINED_FOR_THIS_PARAMETER; + } + + + namespace type_fun + { + + /*------------------------. + | type_fun::slice_piter. | + `------------------------*/ + + /// Type function returning the ``sliced'' piter corresponding to + /// \a Piter + /// \{ + + /// Default version, undefined. + template <typename Piter> + struct slice_piter : + public mlc::abort_< + Piter, + oln::ERROR::TYPE_FUNCTION_slice_piter_NOT_DEFINED_FOR_THIS_PARAMETER + > + { + typedef mlc::undefined ret; + }; + + + // --------- // + // image2d. // + // --------- // + + template <> + struct slice_piter<fwd_piter2d> + { + typedef fwd_piter1d ret; + }; + + template <> + struct slice_piter<bkd_piter2d> + { + typedef bkd_piter1d ret; + }; + + + // --------- // + // image3d. // + // --------- // + + template <> + struct slice_piter<fwd_piter3d> + { + typedef fwd_piter2d ret; + }; + + template <> + struct slice_piter<bkd_piter3d> + { + typedef bkd_piter2d ret; + }; + + /// \} + + + /// Type function returning the ``sliced'' topo corresponding to + /// \a Topo + /// \{ + + /// Default version, undefined. + template <typename Topo> + struct slice_topo : + public mlc::abort_< + Topo, + oln::ERROR::TYPE_FUNCTION_slice_topo_NOT_DEFINED_FOR_THIS_PARAMETER + > + { + typedef mlc::undefined ret; + }; + + + // --------- // + // image2d. // + // --------- // + + // FIXME: slice_topo<topo2d> is more than a function on type, + // because of convert(). (Where should me move this?) + + template <> + struct slice_topo<topo2d> + { + typedef topo1d ret; + + /// Convert a topo2d to a topo1d. + static topo1d convert (const topo2d& topo, unsigned slice_dim) + { + return topo1d(slice_point(topo.bbox().pmin(), slice_dim), + slice_point(topo.bbox().pmax(), slice_dim), + topo.border()); + } + }; + + + // --------- // + // image3d. // + // --------- // + + // FIXME: slice_topo<topo3d> is more than a function on type, + // because of convert(). (Where should me move this?) + + template <> + struct slice_topo<topo3d> + { + + typedef topo2d ret; + + /* FIXME: slice_topo<topo3d>::convert() is almost the same as + slice_topo<topo2d>::convert(). */ + + /// Convert a topo2d to a topo1d. + static topo2d convert (const topo3d& topo, unsigned slice_dim) + { + return topo2d(slice_point(topo.bbox().pmin(), slice_dim), + slice_point(topo.bbox().pmax(), slice_dim), + topo.border()); + } + }; + + } // end of namespace oln::type_fun + +} // end of namespace oln + + +#endif // ! OLN_CORE_TYPE_FUN_SLICE_HH Index: oln/core/iterator_vtypes.hh --- oln/core/iterator_vtypes.hh (revision 659) +++ oln/core/iterator_vtypes.hh (working copy) @@ -33,6 +33,7 @@ # include <oln/core/1d/aliases.hh> # include <oln/core/2d/aliases.hh> # include <oln/core/3d/aliases.hh> +# include <oln/core/type_fun/slice.hh> namespace oln @@ -169,7 +170,8 @@ `--------------------------------------------*/ // Forward declarations. - namespace morpher { + namespace morpher + { template <typename Image, typename Isubset> struct add_isubset; } template <typename piter_t, typename isubset_t> class piter_isubset_; @@ -237,7 +239,8 @@ `-------------------------------------------------*/ // Forward declarations. - namespace morpher { + namespace morpher + { template <typename Image, typename Neighb> struct add_neighborhood; } template <typename point_t> class fwd_niter_neighb_; @@ -269,6 +272,42 @@ }; + /*-----------------------------. + | oln::morpher::slice<Image>. | + `-----------------------------*/ + + // Forward declarations. + namespace morpher + { + template <typename Image> struct slice; + } + template <typename Piter, typename Topo> class piter_slice_; + + + /// fwd_piter vtype of morpher::slice. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::fwd_piter_type > + { + private: + typedef oln_type_of(Image, fwd_piter) orig_fwd_piter; + public: + typedef typename type_fun::slice_piter<orig_fwd_piter>::ret ret; + }; + + /// bkd_piter vtype of morpher::slice. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::bkd_piter_type > + { + private: + typedef oln_type_of(Image, bkd_piter) orig_bkd_piter; + public: + typedef typename type_fun::slice_piter<orig_bkd_piter>::ret ret; + }; + + + // FIXME: What about niters and qiter? + + } // end of namespace oln Index: oln/core/1d/topo1d.hh --- oln/core/1d/topo1d.hh (revision 0) +++ oln/core/1d/topo1d.hh (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +#ifndef OLN_CORE_1D_TOPO1D_HH +# define OLN_CORE_1D_TOPO1D_HH + +// Headers required for the complete definition of oln::topo1d +// (i.e., oln::topo_lbbox_<point1d>). +# include <oln/core/1d/aliases.hh> +# include <oln/core/1d/point1d.hh> +# include <oln/core/1d/dpoint1d.hh> +# include <oln/core/gen/topo_lbbox.hh> + +#endif // ! OLN_CORE_1D_TOPO1D_HH Index: oln/core/2d/topo2d.hh --- oln/core/2d/topo2d.hh (revision 0) +++ oln/core/2d/topo2d.hh (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +#ifndef OLN_CORE_2D_TOPO2D_HH +# define OLN_CORE_2D_TOPO2D_HH + +// Headers required for the complete definition of oln::topo2d +// (i.e., oln::topo_lbbox_<point2d>). +# include <oln/core/2d/aliases.hh> +# include <oln/core/2d/point2d.hh> +# include <oln/core/2d/dpoint2d.hh> +# include <oln/core/gen/topo_lbbox.hh> + +#endif // ! OLN_CORE_2D_TOPO2D_HH Index: oln/core/3d/topo3d.hh --- oln/core/3d/topo3d.hh (revision 0) +++ oln/core/3d/topo3d.hh (revision 0) @@ -0,0 +1,38 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +#ifndef OLN_CORE_3D_TOPO3D_HH +# define OLN_CORE_3D_TOPO3D_HH + +// Headers required for the complete definition of oln::topo3d +// (i.e., oln::topo_lbbox_<point3d>). +# include <oln/core/3d/aliases.hh> +# include <oln/core/3d/point3d.hh> +# include <oln/core/3d/dpoint3d.hh> +# include <oln/core/gen/topo_lbbox.hh> + +#endif // ! OLN_CORE_3D_TOPO3D_HH Index: oln/core/gen/topo_bbox.hh --- oln/core/gen/topo_bbox.hh (revision 659) +++ oln/core/gen/topo_bbox.hh (working copy) @@ -123,17 +123,15 @@ public: topo_bbox_(); - topo_bbox_(const bbox_t& bb); + topo_bbox_(const point& pmin, const point& pmax); const bbox_t& impl_bbox() const; - bbox_t& impl_bbox(); bbox_t& impl_lbbox(); bool impl_has(const point& p) const; - bool impl_has_large(const point& p) const; protected: @@ -158,6 +156,12 @@ } template <typename point> + topo_bbox_<point>::topo_bbox_(const point& pmin, const point& pmax) + : bb_(pmin, pmax) + { + } + + template <typename point> const typename topo_bbox_<point>::bbox_t& topo_bbox_<point>::impl_bbox() const { Index: oln/core/gen/bbox_fwd_piter.hh --- oln/core/gen/bbox_fwd_piter.hh (revision 659) +++ oln/core/gen/bbox_fwd_piter.hh (working copy) @@ -59,7 +59,7 @@ - /// Abstract forward point iterator class. + /// Generic forward point iterator class. template <typename point> class bbox_fwd_piter_ : public internal::bbox_fwd_piter< bbox_fwd_piter_<point> >, private mlc::assert_< mlc_is_a(point, abstract::point) > Index: oln/core/gen/topo_lbbox.hh --- oln/core/gen/topo_lbbox.hh (revision 659) +++ oln/core/gen/topo_lbbox.hh (working copy) @@ -54,58 +54,8 @@ template <typename point> struct vtypes< topo_lbbox_<point> > { - /* Trick to force the instantiation of bbox_<point>. - - As bbox_<point> is a template type used to define the `bbox' - virtual type of topo_lbbox_<point>, it requires some attention - regarding its instantiation. - - - Metalic's mlc_is_a is used by the static hierarchy mechanism of - Static. mlc_is_a performs a static typedef introspection, - taking advantage of the SFINAE rule. However, there two - phenomena seem to happen here (probably due to the very nature - of SFINAE): - - 1. the statement `mlc_is_a(B, A)' requires the knowledge of the - entire declaration of the inspected class to answer - positively if a `B' actually *is a* `A'. If B is a template - class, this implies that B must have been instantiated for - mlc_is_a to be able to inspect it; - - 2. mlc_is_a does *not* trigger the instantiation of the - inspected type (probably to prevent any error, in accordance - to the SFINAE rule). - - When a template type is used to define a virtual type, it - *must* have been instantiated, because it might be used during - the construction of the base classes of the class it belongs - to. That is the case of bbox_<point> here. - - So, how one can trigger such an instantiation? We used to - address this problem by using explicit template instantiations - placed before the definition of the class holding the template - type used a virtual type : - - template class bbox_<point1d>; - template class bbox_<point2d>; - template class bbox_<point3d>; - - And so on. But this is not good w.r.t. software engineering: - one must take care of the correct explicit instantiations at - the right place, which is error-prone --and the C++ compiler - won't produces easily understandable messages!-- and requires a - manual addition for each instantiation of the template type - potentially used as a definition of a virtual type. - - A better solution is to force the compiler to instantiate the - type at the definition site of the virtual type (here, as for - bbox_<point>). Such an instantiation can be triggered by - requesting the use of a typedef contained within this type. As - many template types define a typedef `self_t' to refer to - themselves, we use this typename to both trigger the - instantiation of bbox_<point>, and to define - `vtypes< topo_lbbox_<point> >::bbox_type'. */ + /* Same trick as in the virtual types of oln::topo_bbox_ to force + the compiler to instantiate bbox_<point>. */ typedef typename bbox_<point>::self_type bbox_type; typedef point point_type; typedef mlc::true_ is_random_accessible_type; @@ -124,16 +74,16 @@ public: topo_lbbox_(); - topo_lbbox_(const bbox_t& bb, unsigned border); + topo_lbbox_(const point& pmin, const point& pmax, unsigned border); const bbox_t& impl_bbox() const; bool impl_has(const point& p) const; - bool impl_has_large(const point& p) const; const bbox_t& lbbox() const; + unsigned border () const; protected: @@ -163,6 +113,17 @@ } template <typename point> + topo_lbbox_<point>::topo_lbbox_(const point& pmin, const point& pmax, + unsigned border) + : bb_(pmin, pmax), border_(border) + { + typedef oln_type_of(point, dpoint) dpoint_t; + dpoint_t dp; + dp.set_all(border); + lbb_ = bbox_<point>(bb_.pmin() - dp, bb_.pmax() + dp); + } + + template <typename point> const typename topo_lbbox_<point>::bbox_t& topo_lbbox_<point>::impl_bbox() const { @@ -190,6 +151,13 @@ return lbb_; } + template <typename point> + unsigned + topo_lbbox_<point>::border () const + { + return border_; + } + # endif } // end of namespace oln Index: oln/core/gen/bbox_bkd_piter.hh --- oln/core/gen/bbox_bkd_piter.hh (revision 659) +++ oln/core/gen/bbox_bkd_piter.hh (working copy) @@ -59,7 +59,7 @@ - /// Abstract forward point iterator class. + /// Generic backward point iterator class. template <typename point> class bbox_bkd_piter_ : public internal::bbox_bkd_piter< bbox_bkd_piter_<point> >, private mlc::assert_< mlc_is_a(point, abstract::point) > Index: oln/Makefile.am --- oln/Makefile.am (revision 659) +++ oln/Makefile.am (working copy) @@ -12,6 +12,7 @@ core/1d/image1d.hh \ core/1d/neighb1d.hh \ core/1d/point1d.hh \ + core/1d/topo1d.hh \ \ core/2d/aliases.hh \ core/2d/array2d.hh \ @@ -20,6 +21,7 @@ core/2d/image2d.hh \ core/2d/neighb2d.hh \ core/2d/point2d.hh \ + core/2d/topo2d.hh \ \ core/3d/aliases.hh \ core/3d/array3d.hh \ @@ -28,6 +30,7 @@ core/3d/image3d.hh \ core/3d/neighb3d.hh \ core/3d/point3d.hh \ + core/3d/topo3d.hh \ \ core/abstract/image/accessibility/hierarchy.hh \ \ @@ -111,12 +114,14 @@ core/gen/fwd_niter_neighb.hh \ core/gen/fwd_piter_bbox.hh \ core/gen/fwd_qiter_win.hh \ + core/gen/piter_isubset.hh \ core/gen/grid.hh \ core/gen/mapimage.hh \ core/gen/neighb.hh \ core/gen/topo_add_nbh.hh \ core/gen/topo_bbox.hh \ core/gen/topo_lbbox.hh \ + core/gen/topo_slice.hh \ core/gen/window.hh \ \ core/spe/col.hh \ @@ -125,6 +130,7 @@ \ core/type_fun/ch_value.hh \ core/type_fun/plain.hh \ + core/type_fun/slice_piter.hh \ \ core/internal/bbox_bkd_piter.hh \ core/internal/bbox_fwd_piter.hh \ @@ -161,6 +167,7 @@ morpher/fwd_decls.hh \ morpher/identity.hh \ morpher/tags.hh \ + morpher/slice.hh \ morpher/thru_fun.hh \ morpher/value_cast.hh \ \ Index: oln/morpher/tags.hh --- oln/morpher/tags.hh (revision 659) +++ oln/morpher/tags.hh (working copy) @@ -37,6 +37,8 @@ { /// Tag associated to oln::morpher::image_extension. struct identity; + /// Tag associated to oln::morpher::slice. + struct slice; } // end of namespace oln::morpher::tag Index: oln/morpher/slice.hh --- oln/morpher/slice.hh (revision 0) +++ oln/morpher/slice.hh (revision 0) @@ -0,0 +1,206 @@ +// Copyright (C) 2006 EPITA Research and Development Laboratory +// +// 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. + +#ifndef OLN_MORPHER_SLICE_HH +# define OLN_MORPHER_SLICE_HH + +# include <cstdlib> + +# include <mlc/int.hh> +# include <mlc/abort.hh> + +# include <oln/core/image_entry.hh> +# include <oln/core/gen/bbox.hh> +# include <oln/core/type_fun/slice.hh> + + +namespace oln +{ + + /*---------------. + | slice<Image>. | + `---------------*/ + + namespace morpher + { + // Forward declaration. + template <typename Image> struct slice; + + } // end of namespace oln::morpher + + + /// Super type. + template <typename Image> + struct set_super_type< morpher::slice<Image> > + { + typedef image_entry< morpher::slice<Image> > ret; + }; + + + /// Virtual types associated to oln::morpher::slice<Image> + /// \{ + template <typename Image> + struct vtypes< morpher::slice<Image> > + { + private: + typedef oln_deduce_type_of(Image, grid, dimvalue) orig_dimvalue_type; + typedef mlc::uint_< mlc_value(orig_dimvalue_type) - 1 > dimvalue_type; + + public: + typedef typename + type_fun::slice_topo< oln_type_of(Image, topo) >::ret topo_type; + + typedef grid_<mlc_value(orig_dimvalue_type) - 1> grid_type; + + // psite_type: see below. + typedef typename + point_< mlc_value(dimvalue_type), + oln_deduce_type_of(Image, point, coord) >::ret + point_type; + + // piter_type: see below. + + typedef oln_type_of(Image, value) value_type; + // rvalue_type: see below. + + // fwd_piter_type: see oln/core/iterator_vtypes.hh. + // bkd_piter_type: see oln/core/iterator_vtypes.hh. + + // FIXME: fwd_qiter_type? + // FIXME: bkd_qiter_type? + + typedef oln::morpher::tag::slice morpher_type; + + }; + + // Coord. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::coord_type > + { + typedef oln_deduce_type_of(Image, point, coord) ret; + }; + + // Psite. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::psite_type > + { + private: + typedef morpher::slice<Image> self_t; + public: + typedef oln_type_of(self_t, point) ret; + }; + + /* FIXME: Should we keep the `piter' vtype, knowing that the macro + `oln_piter' gives the `fwd_piter' vtype (and not the `piter' + vtype)? */ + // Piter. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::piter_type > + { + typedef oln_type_of(Image, fwd_piter) ret; + }; + + // Rvalue. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::rvalue_type > + { + typedef oln_type_of(Image, rvalue) ret; + }; + + // Lvalue. + template <typename Image> + struct single_vtype< morpher::slice<Image>, typedef_::lvalue_type > + { + typedef oln_type_of(Image, lvalue) ret; + }; + /// \} + + + namespace morpher + { + + template <typename Image> + class slice : public stc_get_supers(slice<Image>) + { + typedef slice<Image> self_t; + + typedef oln_type_of(self_t, topo) topo_t; + typedef oln_type_of(self_t, rvalue) rvalue_t; + typedef oln_type_of(self_t, lvalue) lvalue_t; + typedef oln_type_of(self_t, point) point_t; + + typedef oln_type_of(Image, topo) orig_topo_t; + typedef oln_type_of(Image, point) orig_point_t; + + typedef oln_deduce_type_of(Image, point, coord) coord_t; + + + public: + // FIXME: Handle the constness. + slice(const abstract::image_having_bbox<Image>& image, + unsigned slice_dim, coord_t slice_coord) : + image_(image.exact()), + slice_dim_(slice_dim), + slice_coord_(slice_coord), + topo_(type_fun::slice_topo<orig_topo_t>::convert(image.topo(), + slice_dim)) + { + } + + const topo_t& impl_topo() const + { + return topo_; + } + + rvalue_t impl_op_read(const point_t& p) const + { + precondition(topo_.has_large(p)); + orig_point_t q = unslice_point(p, slice_dim_, slice_coord_); + return image_(q); + } + + lvalue_t impl_op_readwrite(const point_t& p) + { + precondition(topo_.has_large(p)); + orig_point_t q = unslice_point(p, slice_dim_, slice_coord_); + return image_(q); + } + + protected: + Image image_; + unsigned slice_dim_; + coord_t slice_coord_; + + private: + topo_t topo_; + }; + + } // end of namespace oln::morpher + +} // end of namespace oln + +#endif // ! OLN_MORPHER_SLICE_HH
participants (1)
-
Roland Levillain