• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • File List

is_simple_cell.hh

00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
00002 //
00003 // This file is part of Olena.
00004 //
00005 // Olena is free software: you can redistribute it and/or modify it under
00006 // the terms of the GNU General Public License as published by the Free
00007 // Software Foundation, version 2 of the License.
00008 //
00009 // Olena is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with Olena.  If not, see <http://www.gnu.org/licenses/>.
00016 //
00017 // As a special exception, you may use this file as part of a free
00018 // software project without restriction.  Specifically, if other files
00019 // instantiate templates or use macros or inline functions from this
00020 // file, or you compile this file and link it with other files to produce
00021 // an executable, this file does not by itself cause the resulting
00022 // executable to be covered by the GNU General Public License.  This
00023 // exception does not however invalidate any other reasons why the
00024 // executable file might be covered by the GNU General Public License.
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       /* FIXME: Rename as init() or something like this?  See how other
00074          functors are written.  */
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       // Tech note: The argument type above is explicit to help g++-3.3.
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     // Tech note: The argument type above is explicit to help g++-3.3.
00117     {
00118       mln_precondition(ima_);
00119 
00120       typedef p_set<psite> faces_t;
00121 
00122       // Compute the attachment of the cell corresponding to P to he
00123       // domain of *IMA_.
00124       faces_t att = make::attachment(p, *ima_);
00125 
00126       // A cell with an empty attachment is not simple.
00127       /* FIXME: Why does p_set not provide an empty() predicate?  */
00128       if (att.nsites() == 0)
00129         return false;
00130 
00131       /* FIXME: This part could be moved to its own function/method
00132          (`is_collapsible').  Moreover, the code could be split: looking
00133          up for a free pair (g, h) could be performed in another
00134          routine.  */
00135       // Try to collapse the attachment (to a single point).
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             /* FIXME: The selection of G and H is probably suboptimal
00146                (i.e., selecting G has a face of highest avalaible
00147                dimension in CELL is probably smarter).  */
00148             mln_piter(faces_t) g(att);
00149             for_all(g)
00150               /* G cannot have dimension 0, since we later look for an
00151                  adjacent face H of lower dimension.  */
00152               if (static_cast<psite>(g).n() > 0)
00153                 {
00154                   // Check whether G is a facet within ATT.
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                   // Look for a face H stricly included in G.
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                   } // for_all(h)
00191 
00192                   // If a free pair (G, H) has been found and removed,
00193                   // restart the free pair look up from the beginning.
00194                   if (gh_is_simple_pair)
00195                     {
00196                       simple_pair_collapsed = true;
00197                       break;
00198                     }
00199                 } // for_all(g)
00200 
00201             if (!simple_pair_collapsed)
00202               // If no free pair (G, H) was found, then the attachment is
00203               // not collapsible.
00204               return false;
00205 
00206           } // while (att.nsites() > 1)
00207 
00208         mln_postcondition(att.nsites() == 1);
00209         mln_postcondition(att[0].n() == 0);
00210         // If the attachment is collapsible to a 0-face, then the cell
00211         // corresponding to the (face) P is simple.
00212         return true;
00213       }
00214     }
00215 
00216 # endif // MLN_INCLUDE_ONLY
00217 
00218   } // end of namespace mln::topo
00219 
00220 } // end of namespace mln
00221 
00222 #endif // ! MLN_TOPO_IS_SIMPLE_CELL_HH

Generated on Tue Oct 4 2011 15:24:00 for Milena (Olena) by  doxygen 1.7.1