00001 // Copyright (C) 2008, 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_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 /* FIXME: Also provide functors where the locations are computed using 00046 a function (useful for a complex on a regular grid/support. */ 00047 00048 /* FIXME: This class could probably be turned into something more 00049 generic, usable for other other purpose, e.g. attaching sites to 00050 graphs. */ 00051 00052 /* FIXME: Also provide another geometry type where everything is 00053 stored even for n-face with n > 0. */ 00054 00055 00056 namespace mln 00057 { 00058 00059 namespace geom 00060 { 00061 00062 // Forward declaration. 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 // FIXME: These two lines are not thread safe. 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 // F is a 0-face. 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 /* F is an n-face, with n > 0. 00165 Compute the set of 0-faces transitively adjacent to F. */ 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 } // end of mln::geom 00176 00177 } // end of mln 00178 00179 #endif // ! MLN_GEOM_COMPLEX_GEOMETRY_HH