cmap.hh

Go to the documentation of this file.
00001 // Copyright (C) 2001, 2002, 2003, 2004  EPITA Research and Development Laboratory
00002 //
00003 // This file is part of the Olena Library.  This library is free
00004 // software; you can redistribute it and/or modify it under the terms
00005 // of the GNU General Public License version 2 as published by the
00006 // Free Software Foundation.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU General Public License
00014 // along with this library; see the file COPYING.  If not, write to
00015 // the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
00016 // MA 02111-1307, USA.
00017 //
00018 // As a special exception, you may use this file as part of a free
00019 // software library 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
00022 // produce an executable, this file does not by itself cause the
00023 // resulting executable to be covered by the GNU General Public
00024 // License.  This exception does not however invalidate any other
00025 // reasons why the executable file might be covered by the GNU General
00026 // Public License.
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         | neighborhood |
00093         `-------------*/
00094 
00095         // ext_neighb:
00096         // give a labels' set of connected component of given label which
00097         // are ouside of l.
00098 
00099         // FIXME: why is this code disabled? Should it be removed?
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         // int_neighb:
00121         // give a labels' set of connected component of given label which
00122         // are inside of l.
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         // neighb
00140         // give a label' set of both inside and outside connected component
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           // FIXME: Do not check whether a label is valide on beta function
00157           assertion(beta_(l1) && beta_(l2));
00158 
00159           if (level_.father(l2) != l1)
00160             {
00161               // l1 and l2 are connected
00162               assertion(make_inter1_(l1, l2, inter));
00163             }
00164           else
00165             {
00166               // l2 is included in l1
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           // FIXME: find a way to get this in constant time
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     } // end of namespace combinatorial_map
00371 
00372   } // end of namespace topo
00373 
00374 } // end of namespace oln
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

Generated on Thu Apr 15 20:13:07 2004 for Olena by doxygen 1.3.6-20040222