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 #ifndef MLN_TOPO_IS_SIMPLE_CELL_HH
00027 # define MLN_TOPO_IS_SIMPLE_CELL_HH
00028 
00032 
00033 # include <mln/core/concept/function.hh>
00034 # include <mln/core/concept/image.hh>
00035 
00036 # include <mln/core/site_set/p_set.hh>
00037 # include <mln/core/site_set/complex_psite.hh>
00038 # include <mln/core/site_set/p_complex_piter.hh>
00039 # include <mln/core/image/complex_neighborhoods.hh>
00040 # include <mln/core/image/complex_neighborhood_piter.hh>
00041 
00042 # include <mln/make/attachment.hh>
00043 
00044 
00045 namespace mln
00046 {
00047 
00048   namespace topo
00049   {
00050 
00056     template <typename I>
00057     class is_simple_cell : public mln::Function_v2b< is_simple_cell<I> >
00058     {
00059     public:
00061       static const unsigned D = I::dim;
00063       typedef mln_geom(I) G;
00065       typedef mln::complex_psite<D, G> psite;
00066 
00068       typedef bool result;
00069 
00070       is_simple_cell();
00071       is_simple_cell(const mln::Image<I>& ima);
00072 
00073       
00074 
00076       void set_image(const mln::Image<I>& ima);
00077 
00079       bool operator()(const mln::complex_psite<I::dim,mln_geom(I)>& p) const;
00080       
00081 
00082     private:
00083       const I* ima_;
00084     };
00085 
00086 
00087 
00088 # ifndef MLN_INCLUDE_ONLY
00089 
00090     template <typename I>
00091     inline
00092     is_simple_cell<I>::is_simple_cell()
00093       : ima_(0)
00094     {
00095     }
00096 
00097     template <typename I>
00098     inline
00099     is_simple_cell<I>::is_simple_cell(const mln::Image<I>& ima)
00100       : ima_(mln::exact(&ima))
00101     {
00102     }
00103 
00104     template <typename I>
00105     inline
00106     void
00107     is_simple_cell<I>::set_image(const mln::Image<I>& ima)
00108     {
00109       ima_ = mln::exact(&ima);
00110     }
00111 
00112     template <typename I>
00113     inline
00114     bool
00115     is_simple_cell<I>::operator()(const mln::complex_psite<I::dim,mln_geom(I)>& p) const
00116     
00117     {
00118       mln_precondition(ima_);
00119 
00120       typedef p_set<psite> faces_t;
00121 
00122       
00123       
00124       faces_t att = make::attachment(p, *ima_);
00125 
00126       
00127       
00128       if (att.nsites() == 0)
00129         return false;
00130 
00131       
00132 
00133 
00134 
00135       
00136       {
00137         typedef complex_lower_neighborhood<D, G> lower_adj_nbh_t;
00138         typedef complex_higher_neighborhood<D, G> higher_adj_nbh_t;
00139         lower_adj_nbh_t lower_adj_nbh;
00140         higher_adj_nbh_t higher_adj_nbh;
00141         while (att.nsites() > 1)
00142           {
00143 
00144             bool simple_pair_collapsed = false;
00145             
00146 
00147 
00148             mln_piter(faces_t) g(att);
00149             for_all(g)
00150               
00151 
00152               if (static_cast<psite>(g).n() > 0)
00153                 {
00154                   
00155                   bool g_is_facet = true;
00156                   mln_niter(higher_adj_nbh_t) f(higher_adj_nbh, g);
00157                   for_all(f)
00158                     if (att.has(f))
00159                       {
00160                         g_is_facet = false;
00161                         break;
00162                       }
00163                   if (!g_is_facet)
00164                     break;
00165 
00166                   
00167                   bool gh_is_simple_pair = false;
00168                   mln_niter(lower_adj_nbh_t) h(lower_adj_nbh, g);
00169                   for_all(h)
00170                   {
00171                     bool h_strictly_in_g = true;
00172                     if (att.has(h))
00173                       {
00174                         mln_niter(higher_adj_nbh_t) i(higher_adj_nbh, h);
00175                         for_all(i)
00176                           if (i != g && att.has(i))
00177                             {
00178                               h_strictly_in_g = false;
00179                               break;
00180                             }
00181                       }
00182                     if (h_strictly_in_g)
00183                       {
00184                         gh_is_simple_pair = true;
00185                         att.remove(g);
00186                         att.remove(h);
00187                         mln_invariant(att.nsites() > 0);
00188                         break;
00189                       }
00190                   } 
00191 
00192                   
00193                   
00194                   if (gh_is_simple_pair)
00195                     {
00196                       simple_pair_collapsed = true;
00197                       break;
00198                     }
00199                 } 
00200 
00201             if (!simple_pair_collapsed)
00202               
00203               
00204               return false;
00205 
00206           } 
00207 
00208         mln_postcondition(att.nsites() == 1);
00209         mln_postcondition(att[0].n() == 0);
00210         
00211         
00212         return true;
00213       }
00214     }
00215 
00216 # endif // MLN_INCLUDE_ONLY
00217 
00218   } 
00219 
00220 } 
00221 
00222 #endif // ! MLN_TOPO_IS_SIMPLE_CELL_HH