Milena (Olena)  User documentation 2.0a Id
volume.hh
00001 // Copyright (C) 2007, 2008, 2009, 2011 EPITA Research and Development
00002 // Laboratory (LRDE)
00003 //
00004 // This file is part of Olena.
00005 //
00006 // Olena is free software: you can redistribute it and/or modify it under
00007 // the terms of the GNU General Public License as published by the Free
00008 // Software Foundation, version 2 of the License.
00009 //
00010 // Olena is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software project without restriction.  Specifically, if other files
00020 // instantiate templates or use macros or inline functions from this
00021 // file, or you compile this file and link it with other files to produce
00022 // an executable, this file does not by itself cause the resulting
00023 // executable to be covered by the GNU General Public License.  This
00024 // exception does not however invalidate any other reasons why the
00025 // executable file might be covered by the GNU General Public License.
00026 
00027 #ifndef MLN_MORPHO_ATTRIBUTE_VOLUME_HH
00028 # define MLN_MORPHO_ATTRIBUTE_VOLUME_HH
00029 
00034 
00035 # include <mln/accu/internal/base.hh>
00036 # include <mln/math/diff_abs.hh>
00037 # include <mln/util/pix.hh>
00038 
00039 
00040 namespace mln
00041 {
00042 
00043   // Forward declaration.
00044   namespace morpho {
00045     namespace attribute {
00046       template <typename I> struct volume;
00047     }
00048   }
00049 
00050 
00051   // Traits.
00052 
00053   namespace trait
00054   {
00055 
00056     template <typename I>
00057     struct accumulator_< morpho::attribute::volume<I> >
00058     {
00059       typedef accumulator::has_untake::no    has_untake;
00060       typedef accumulator::has_set_value::no has_set_value;
00061       typedef accumulator::has_stop::no      has_stop;
00062       typedef accumulator::when_pix::use_v   when_pix;
00063     };
00064 
00065   } // end of namespace mln::trait
00066 
00067 
00068   namespace morpho
00069   {
00070 
00071     namespace attribute
00072     {
00073 
00078       template <typename I>
00079       struct volume
00080         : public mln::accu::internal::base< unsigned , volume<I> >
00081       {
00082         typedef mln_value(I) argument;
00083 
00084         volume();
00085 
00088         void init();
00089 
00090         void take(const mln_value(I)& v);
00091         void take(const util::pix<I>& px);
00092         void take(const volume<I>& other);
00093 
00094         void take_as_init_(const mln_value(I)& v);
00095         void take_as_init_(const util::pix<I>& px);
00097 
00099         unsigned to_result() const;
00100 
00103         bool is_valid() const;
00104 
00106         unsigned area() const;
00107 
00108       protected:
00110         mln_value(I) cur_level_;
00112         unsigned area_;
00114         unsigned volume_;
00115       };
00116 
00117 
00118 
00119 # ifndef MLN_INCLUDE_ONLY
00120 
00121       template <typename I>
00122       inline
00123       volume<I>::volume()
00124       {
00125         init();
00126       }
00127 
00128       template <typename I>
00129       inline
00130       void
00131       volume<I>::init()
00132       {
00133         volume_ = 0;
00134       }
00135 
00136       template <typename I>
00137       inline
00138       void
00139       volume<I>::take(const mln_value(I)& v)
00140       {
00141         mln_invariant(volume_ != mln_max(unsigned));
00142         if (! is_valid())
00143           {
00144             take_as_init_(v);
00145             return;
00146           }
00147         ++area_;
00148         volume_ += 1 + math::diff_abs(v, cur_level_);
00149         cur_level_ = v;
00150       }
00151 
00152       template <typename I>
00153       inline
00154       void
00155       volume<I>::take(const util::pix<I>& px)
00156       {
00157         mln_invariant(volume_ != mln_max(unsigned));
00158         take(px.v());
00159       }
00160 
00161       template <typename I>
00162       inline
00163       void
00164       volume<I>::take(const volume<I>& other)
00165       {
00166         mln_invariant(volume_ != mln_max(unsigned));
00167         area_ += other.area_;
00168         volume_ +=
00169           other.volume_  +
00170           other.area_ * math::diff_abs(other.cur_level_, cur_level_);
00171         // cur_level_ do not change.
00172       }
00173 
00174       template <typename I>
00175       inline
00176       void
00177       volume<I>::take_as_init_(const mln_value(I)& v)
00178       {
00179         cur_level_ = v;
00180         area_ = 1;
00181         volume_ = 1;
00182       }
00183 
00184       template <typename I>
00185       inline
00186       void
00187       volume<I>::take_as_init_(const util::pix<I>& px)
00188       {
00189         take_as_init_(px.v());
00190       }
00191 
00192       template <typename I>
00193       inline
00194       unsigned
00195       volume<I>::to_result() const
00196       {
00197         return volume_;
00198       }
00199 
00200       template <typename I>
00201       inline
00202       unsigned
00203       volume<I>::area() const
00204       {
00205         return area_;
00206       }
00207 
00208       template <typename I>
00209       inline
00210       bool
00211       volume<I>::is_valid() const
00212       {
00213         return volume_ != 0;
00214       }
00215 
00216 # endif // ! MLN_INCLUDE_ONLY
00217 
00218     } // end of namespace mln::morpho::attribute
00219 
00220   } // end of namespace mln::morpho
00221 
00222 } // end of namespace mln
00223 
00224 
00225 #endif // ! MLN_MORPHO_ATTRIBUTE_VOLUME_HH
 All Classes Namespaces Functions Variables Typedefs Enumerator