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_GEOM_COMPLEX_GEOMETRY_HH
00027 # define MLN_GEOM_COMPLEX_GEOMETRY_HH
00028 
00034 
00035 # include <vector>
00036 # include <set>
00037 
00038 # include <mln/topo/face.hh>
00039 # include <mln/topo/adj_m_face_iter.hh>
00040 
00041 # include <mln/util/multi_site.hh>
00042 # include <mln/util/tracked_ptr.hh>
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 namespace mln
00057 {
00058 
00059   namespace geom
00060   {
00061 
00062     
00063     namespace internal
00064     {
00065       template <typename P> struct complex_geometry_data;
00066     }
00067 
00068 
00087     template <unsigned D, typename P>
00088     class complex_geometry
00089     {
00090     public:
00091       typedef P location;
00092       typedef util::multi_site<P> site;
00093 
00094     public:
00096       complex_geometry();
00097 
00098     public:
00104       unsigned add_location(const P& p);
00105 
00107       site operator()(const mln::topo::face<D>& f) const;
00108 
00109     private:
00110       mln::util::tracked_ptr< internal::complex_geometry_data<P> > data_;
00111     };
00112 
00113 
00114     namespace internal
00115     {
00119       template <typename P>
00120       struct complex_geometry_data
00121       {
00122         std::vector<P> zero_faces_geom;
00123       };
00124     }
00125 
00126 
00127 
00128 # ifndef MLN_INCLUDE_ONLY
00129 
00130     template <unsigned D, typename P>
00131     inline
00132     complex_geometry<D, P>::complex_geometry()
00133       : data_(new internal::complex_geometry_data<P>())
00134     {
00135     }
00136 
00137     template <unsigned D, typename P>
00138     inline
00139     unsigned
00140     complex_geometry<D, P>::add_location(const P& p)
00141     {
00142       mln_precondition(data_);
00143       
00144       data_->zero_faces_geom.push_back(p);
00145       return data_->zero_faces_geom.size();
00146     }
00147 
00148     template <unsigned D, typename P>
00149     inline
00150     util::multi_site<P>
00151     complex_geometry<D, P>::operator()(const mln::topo::face<D>& f) const
00152     {
00153       mln_precondition(data_);
00154       site s;
00155       s.reserve(1);
00156       if (f.n() == 0)
00157         {
00158           
00159           mln_assertion(f.face_id() < data_->zero_faces_geom.size());
00160           s.push_back(data_->zero_faces_geom[f.face_id()]);
00161         }
00162       else
00163         {
00164           
00165 
00166           topo::adj_m_face_fwd_iter<D> g(f, 0);
00167           for_all(g)
00168             s.push_back(data_->zero_faces_geom[g.subject().face_id()]);
00169         }
00170       return s;
00171     }
00172 
00173 # endif // ! MLN_INCLUDE_ONLY
00174 
00175   } 
00176 
00177 } 
00178 
00179 #endif // ! MLN_GEOM_COMPLEX_GEOMETRY_HH