00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
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
00044 namespace morpho {
00045 namespace attribute {
00046 template <typename I> struct volume;
00047 }
00048 }
00049
00050
00051
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 }
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
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 }
00219
00220 }
00221
00222 }
00223
00224
00225 #endif // ! MLN_MORPHO_ATTRIBUTE_VOLUME_HH