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
00028 #ifndef OLENA_TOPO_COMBINATORIAL_MAP_CMAP_HH
00029 # define OLENA_TOPO_COMBINATORIAL_MAP_CMAP_HH
00030
00031 # include <oln/topo/tarjan/flat-zone.hh>
00032 # include <oln/topo/inter-pixel/inter-pixel.hh>
00033 # include <oln/topo/combinatorial-map/internal/zeta.hh>
00034 # include <oln/topo/combinatorial-map/internal/allfunc.hh>
00035 # include <oln/topo/combinatorial-map/internal/level.hh>
00036
00037 # include <algorithm>
00038 # include <iterator>
00039
00050 namespace oln {
00051
00052 namespace topo {
00054 namespace combinatorial_map {
00055
00062 template <class I>
00063 class cmap
00064 {
00065 public:
00066 typedef oln_dpoint_type(I) dpoint_type;
00067 typedef oln_point_type(I) point_type;
00068 typedef oln_fwd_dir_iter_type(I) fwd_dir_iter_type;
00069 typedef oln_bkd_dir_iter_type(I) bkd_dir_iter_type;
00070 typedef oln_head_type(I) head_type;
00071 typedef oln_zeta_type(I) zeta_type;
00072
00073 public:
00074 cmap(const I& input,
00075 const inter_pixel::interpixel<I>& ip,
00076 tarjan::obsolete::flat_zone<I>& cc) :
00077 ndarts_(0),
00078 zeta_(input.nrows() + 1, input.ncols() + 1),
00079 cc_(cc),
00080 level_(cc.nlabels()),
00081 beta_(cc.nlabels())
00082 {
00083 build_zeta_(ip);
00084
00085 sigma_.resize(ndarts_);
00086 lambda_.resize(ndarts_);
00087
00088 build_functions_(ip);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 #if 0
00102
00103 void
00104 ext_neighb(const unsigned l, labels_type & n)
00105 {
00106 if (beta_(l) == 0)
00107 return;
00108
00109 unsigned d = beta_(l);
00110
00111 do
00112 {
00113 n.insert(lambda_(alpha_(d)));
00114
00115 d = sigma_(alpha_(d));
00116 }
00117 while (d != beta_(l));
00118 }
00119
00120
00121
00122
00123 void
00124 int_neighb(const unsigned l, labels_type & n)
00125 {
00126 labels_type ext;
00127
00128 labels_type::const_iterator it;
00129 for (it = daugh_(l).begin(); it != daugh_(l).end(); ++it)
00130 {
00131 ext.clear();
00132 ext_neighb(*it, ext);
00133
00134 if (ext.find(l) != ext.end())
00135 n.insert(*it);
00136 }
00137 }
00138
00139
00140
00141 void
00142 neighb(const unsigned l, labels_type & n)
00143 {
00144 ext_neighb(l, n);
00145 int_neighb(l, n);
00146 }
00147
00148 # endif
00149
00151 void
00152 merge(const unsigned l1, const unsigned l2)
00153 {
00154 static std::vector<unsigned> inter;
00155
00156
00157 assertion(beta_(l1) && beta_(l2));
00158
00159 if (level_.father(l2) != l1)
00160 {
00161
00162 assertion(make_inter1_(l1, l2, inter));
00163 }
00164 else
00165 {
00166
00167 assertion(make_inter2_(l1, l2, inter));
00168 }
00169
00170 update_darts_(l1, l2, inter);
00171
00172 level_.merge(l1, l2);
00173
00174 cc_.merge(l1, l2);
00175
00176 inter.clear();
00177 }
00178
00180 std::ostream&
00181 print(std::ostream & ostr) const
00182 {
00183 ostr << sigma_ << std::endl;
00184 ostr << lambda_ << std::endl;
00185 ostr << beta_ << std::endl;
00186
00187 ostr << level_ << std::endl;
00188
00189 return ostr;
00190 }
00191
00192 private:
00193
00195 void
00196 build_zeta_(const inter_pixel::interpixel<I> & ip)
00197 {
00198 unsigned father = 0;
00199
00200 std::list<point_type> acc;
00201 fwd_dir_iter_type i;
00202
00203 for (unsigned l = 2; l <= cc_.nlabels(); ++l)
00204 if (level_.father(l) == 0)
00205 {
00206 acc.clear();
00207
00208 point_type n1 = cc_.get_root(l);
00209
00210 father = cc_.get_label(n1 + dpoint_type(0, -1));
00211
00212 head_type h1 = ip.folw(head_type(n1, oln_dir_traits_type(I)::first()));
00213
00214 acc.push_back(h1.first);
00215
00216 while (!acc.empty())
00217 {
00218 n1 = acc.front();
00219
00220 for_all(i)
00221 if (ip[n1].get(i) && !zeta_[n1][i])
00222 {
00223 unsigned l = cc_.get_label(n1 + ip.neighb_[i]);
00224
00225 if (father != l && !level_.father(l))
00226 level_.insert(father, l);
00227
00228 zeta_[n1][i] = ++ndarts_;
00229 head_type h2 = ip.folw(head_type(n1, i));
00230
00231 if (zeta_[h2.first].empty())
00232 acc.push_back(h2.first);
00233
00234 zeta_[h2.first][h2.second] = ++ndarts_;
00235 }
00236
00237 acc.pop_front();
00238 }
00239 }
00240 }
00241
00242 void
00243 build_functions_(const inter_pixel::interpixel<I> & ip)
00244 {
00245 oln_iter_type(zeta_type) it(zeta_);
00246 fwd_dir_iter_type i;
00247
00248 for_all(it)
00249 {
00250 if (!zeta_[it].empty())
00251 for_all(i)
00252 {
00253 unsigned d = zeta_[it][i];
00254
00255 if (d)
00256 {
00257 fwd_dir_iter_type j(i.next());
00258 for_all(j)
00259 {
00260 unsigned s = zeta_[it][j];
00261
00262 if (s)
00263 {
00264 unsigned l = cc_.get_label(it + ip.neighb_[i]);
00265
00266 sigma_.assign(d, s);
00267 lambda_.assign(d, l);
00268 beta_.assign(l, d);
00269
00270 break;
00271 }
00272 }
00273 }
00274 }
00275 }
00276 }
00277
00278
00280 bool
00281 make_inter1_(const unsigned l1,
00282 const unsigned l2,
00283 std::vector<unsigned> & inter)
00284 {
00285 static std::vector<bool> buff(ndarts_);
00286
00287 unsigned d = beta_(l1);
00288
00289 do
00290 {
00291 buff[d] = true;
00292 d = sigma_(internal::alpha<unsigned>::result(d));
00293 }
00294 while (d != beta_(l1));
00295
00296 d = beta_(l2);
00297
00298 unsigned d_ = 0;
00299
00300 do
00301 {
00302 d_ = internal::alpha<unsigned>::result(d);
00303
00304 if (buff[d_])
00305 inter.push_back(d_);
00306 d = sigma_(d_);
00307 }
00308 while (d != beta_(l2));
00309
00310 buff.clear();
00311
00312 return !inter.empty();
00313 }
00314
00315 bool
00316 make_inter2_(const unsigned l1,
00317 const unsigned l2,
00318 std::vector<unsigned> & inter)
00319 {
00320 unsigned d = beta_(l2);
00321 unsigned d_;
00322
00323 do
00324 {
00325 d_ = internal::alpha<unsigned>::result(d);
00326
00327 if (lambda_(d_) == l1)
00328 inter.push_back(d_);
00329
00330 d = sigma_(d_);
00331 }
00332 while (d != beta_(l2));
00333
00334 return !inter.empty();
00335 }
00336
00337 void
00338 update_darts_(const unsigned l1,
00339 const unsigned l2,
00340 std::vector<unsigned> & inter)
00341 {
00342 std::vector<unsigned>::const_iterator i;
00343 for (i = inter.begin(); i != inter.end(); ++i)
00344 {
00345 unsigned d = *i;
00346
00347 sigma_.erase(d);
00348 lambda_.erase(d);
00349 }
00350
00351
00352 for (unsigned j = 1; j < ndarts_; ++j)
00353 if (lambda_(j) == l2)
00354 lambda_.assign_(j, l1);
00355
00356 beta_.erase(l2);
00357 }
00358
00359 private:
00360 unsigned ndarts_;
00361 zeta_type zeta_;
00362 tarjan::obsolete::flat_zone<I> &cc_;
00363 internal::level<unsigned> level_;
00364
00365 internal::beta<unsigned> beta_;
00366 internal::sigma<unsigned> sigma_;
00367 internal::lambda<unsigned> lambda_;
00368 };
00369
00370 }
00371
00372 }
00373
00374 }
00375
00376 template<class I>
00377 inline std::ostream &
00378 operator<<(std::ostream & ostr,
00379 const oln::topo::combinatorial_map::cmap<I> & cm)
00380 {
00381 return cm.print(ostr);
00382 }
00383
00384 #endif // ! OLENA_TOPO_COMBINATORIAL_MAP_CMAP_HH