Milena (Olena)
User documentation 2.0a Id
|
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 #include <iostream> 00027 00028 #include <mln/value/int_u8.hh> 00029 #include <mln/core/alias/point2d.hh> 00030 00031 #include <mln/core/site_set/p_faces.hh> 00032 #include <mln/core/image/complex_image.hh> 00033 00034 // FIXME: Include these elsewhere? (In complex_image.hh?) 00035 #include <mln/core/image/complex_neighborhoods.hh> 00036 #include <mln/core/image/complex_neighborhood_piter.hh> 00037 00038 /* FIXME: Split this test (and maybe factor common parts, like the 00039 construction of the complex), since it exercises too many features 00040 in a single file. */ 00041 00042 // Forward declaration. 00043 template <typename I, typename N> 00044 void 00045 test_neighborhood(const mln::Image<I>& ima_, const mln::Neighborhood<N> nbh, 00046 const std::string& comment); 00047 00048 00049 int main() 00050 { 00051 using namespace mln; 00052 00053 /*----------. 00054 | Complex. | 00055 `----------*/ 00056 00057 /* A 2-d (simplicial) complex and its adjacency graph. 00058 00059 c 0 1 2 3 00060 r .------------------------ 00061 | v0 e3 v3 00062 0 | o-----------o v0----e3----v3 00063 | / \ ,-----. / / \ | / 00064 | / . \ \ t1/ / / \ t1 / 00065 1 | e0 / / \ e1\ / / e4 e0. ,e1ยด `e4 00066 | / /t0 \ \ ' / / t0 \ / 00067 | / `-----' \ / / | \ / 00068 2 | o-----------o v1----e2----v2 00069 | v1 e2 v2 00070 00071 v = vertex 00072 e = edge 00073 t = triangle 00074 */ 00075 00076 00077 const unsigned D = 2; 00078 00079 topo::complex<D> c; 00080 00081 // 0-faces (points). 00082 topo::n_face<0, D> v0 = c.add_face(); 00083 topo::n_face<0, D> v1 = c.add_face(); 00084 topo::n_face<0, D> v2 = c.add_face(); 00085 topo::n_face<0, D> v3 = c.add_face(); 00086 00087 // 1-faces (segments). 00088 topo::n_face<1, D> e0 = c.add_face(v0 + v1); 00089 topo::n_face<1, D> e1 = c.add_face(v0 + v2); 00090 topo::n_face<1, D> e2 = c.add_face(v1 + v2); 00091 topo::n_face<1, D> e3 = c.add_face(v0 + v3); 00092 topo::n_face<1, D> e4 = c.add_face(v2 + v3); 00093 00094 // 2-faces (triangles). 00095 topo::n_face<2, D> t0 = c.add_face(e0 + e1 + e2); 00096 topo::n_face<2, D> t1 = c.add_face(e1 + e3 + e4); 00097 00098 00099 /*------------------------------. 00100 | Complex geometry (location). | 00101 `------------------------------*/ 00102 00103 typedef point2d P; 00104 typedef geom::complex_geometry<D, P> G; 00105 G geom; 00106 geom.add_location(point2d(0,1)); // 0-face #0. 00107 geom.add_location(point2d(2,0)); // 0-face #1. 00108 geom.add_location(point2d(2,2)); // 0-face #2. 00109 geom.add_location(point2d(0,3)); // 0-face #3. 00110 00111 00112 /*---------------------. 00113 | Complex-based pset. | 00114 `---------------------*/ 00115 00116 // A pset. 00117 p_complex<D, G> pc(c, geom); 00118 topo::face<D> af(e0); 00119 // An associated psite. 00120 complex_psite<D, G> cs(pc, af); 00121 00122 00123 /*--------------------. 00124 | Faces-based psets. | 00125 `--------------------*/ 00126 00127 /* FIXME: Not that p_faces have become less interesting since the 00128 introduction of p_complex_faces_{fwd,bkd}_piter_. Keep this part 00129 of the test? */ 00130 00131 // Pset of 0-faces. 00132 p_faces<0, D, G> pf0(c); 00133 // Pset of 1-faces. 00134 p_faces<1, D, G> pf1(c); 00135 // Pset of 2-faces. 00136 p_faces<2, D, G> pf2(c); 00137 00138 // Some psites on faces. 00139 faces_psite<0, D, G> fs0(pf0, v0); 00140 faces_psite<1, D, G> fs1(pf1, e0); 00141 faces_psite<2, D, G> fs2(pf2, t0); 00142 00143 00144 /*----------------------. 00145 | Complex-based image. | 00146 `----------------------*/ 00147 00148 using mln::value::int_u8; 00149 00150 // An image type built on a 2-complex with mln::int_u8 values on 00151 // each face. 00152 typedef complex_image<D, G, int_u8> ima_t; 00153 00154 // Values. 00155 metal::vec<D + 1, std::vector< int_u8 > > values; 00156 // Assign 0 to 0-faces, 1 to 1-faces and 2 to 2-faces. 00157 for (unsigned d = 0; d <= D; ++d) 00158 for (unsigned n = 0; n < pc.cplx().nfaces_of_dim(d); ++n) 00159 values[d].push_back(d); 00160 00161 // Create and init an image based on PC. 00162 ima_t ima(pc, values); 00163 00164 // Check the value associated to edge E0 (through complex psite CS). 00165 mln_assertion(ima(cs) == 1u); 00166 00167 00168 /*--------------------------------. 00169 | Complex-based image iterators. | 00170 `--------------------------------*/ 00171 00172 // ---------------------------- // 00173 // Iterators on all the faces. // 00174 // ---------------------------- // 00175 00176 mln_fwd_piter_(ima_t) fp(ima.domain()); 00177 for_all(fp) 00178 std::cout << "ima(" << fp << ") = " << ima(fp) << std::endl; 00179 std::cout << std::endl; 00180 00181 mln_bkd_piter_(ima_t) bp(ima.domain()); 00182 for_all(bp) 00183 std::cout << "ima(" << bp << ") = " << ima(bp) << std::endl; 00184 std::cout << std::endl; 00185 00186 00187 // ----------------------------------------------- // 00188 // Iterators on n-faces (with n fixed in [0, D]). // 00189 // ----------------------------------------------- // 00190 00191 // Dynamic version. 00192 for (unsigned n = 0; n <= D; ++n) 00193 { 00194 p_n_faces_fwd_piter<D, G> fwd_np(ima.domain(), n); 00195 p_n_faces_bkd_piter<D, G> bkd_np(ima.domain(), n); 00196 for_all_2(fwd_np, bkd_np) 00197 std::cout << "ima(" << fwd_np << ") = " << ima(fwd_np) << '\t' 00198 << "ima(" << bkd_np << ") = " << ima(bkd_np) 00199 << std::endl; 00200 std::cout << std::endl; 00201 } 00202 00203 // Static version. 00204 // FIXME: Disabled (moved to the attic). 00205 # if 0 00206 // FIXME: Sugar the name of the iterator. 00207 p_complex_faces_fwd_piter_<0, D, G> f0p(ima.domain()); 00208 for_all(f0p) 00209 std::cout << "ima(" << f0p << ") = " << ima(f0p) << std::endl; 00210 #endif 00211 00212 /* FIXME: Implement other psite iterators, for instance: 00213 00214 - iterators on N-faces with N in a subset of [0, D]; 00215 - etc. */ 00216 00217 // ---------------------------- // 00218 // Iterators on neighborhoods. // 00219 // ---------------------------- // 00220 00221 00222 test_neighborhood(ima, complex_lower_neighborhood<D, G>(), 00223 "Lower-dimension faces"); 00224 test_neighborhood(ima, complex_higher_neighborhood<D, G>(), 00225 "Higher-dimension faces"); 00226 test_neighborhood(ima, complex_lower_higher_neighborhood<D, G>(), 00227 "Lower- and higer-dimension faces"); 00228 00229 test_neighborhood(ima, 00230 complex_lower_dim_connected_n_face_neighborhood<D, G>(), 00231 "Lower-dimension connected n-faces"); 00232 test_neighborhood(ima, 00233 complex_higher_dim_connected_n_face_neighborhood<D, G>(), 00234 "Higher-dimension connected n-faces"); 00235 00236 /* FIXME: Implement other neighborhoods (and windows) and 00237 corresponding iterators for complex-based images. 00238 00239 For a given (fixed) dimension N and a psite P on a N-face, 00240 implement windows returning 00241 00242 - the set of N-faces sharing a (N-1)-face with P; 00243 - the set of N-faces sharing a (N-1)-face or (N-2)-face (by 00244 transitivity) with P (is it useful?); 00245 00246 - the set of the ``cell'' including P (named ``P-hat'' in 00247 couprie.08.pami), i.e., the set of all M-faces adjacent to P, 00248 where M is in [0, N-1]. 00249 00250 In that definition, P is said adjacent to an M-face Q if 00251 there is a sequence (M1, M2, ..., Mk) of faces so that 00252 - M1 is an (N-1)-face adjacent to P ; 00253 - M2 is an (N-2)-face adjacent to M1 ; 00254 - and so on; 00255 - Mk is an (M+1)-face adjacent to Q. 00256 00257 - what else? 00258 00259 We might want to look at operators on (simplicial?) complexes 00260 like star, link, etc. and possibly implement them. 00261 00262 See also https://trac.lrde.org/olena/ticket/162. */ 00263 } 00264 00265 00266 template <typename I, typename N> 00267 void 00268 test_neighborhood(const mln::Image<I>& ima_, const mln::Neighborhood<N> nbh, 00269 const std::string& comment) 00270 { 00271 const I& ima = exact(ima_); 00272 mln_fwd_piter(I) fp(ima.domain()); 00273 00274 mln_fwd_niter(N) fn(nbh, fp); 00275 mln_bkd_niter(N) bn(nbh, fp); 00276 for_all(fp) 00277 { 00278 std::cout << comment << " adjacent to " << fp << std::endl; 00279 for_all_2(fn, bn) 00280 { 00281 mln_assertion((fn.center() == static_cast<const mln_psite(I)&>(fp))); 00282 mln_assertion((bn.center() == static_cast<const mln_psite(I)&>(fp))); 00283 std::cout << " " << fn << '\t' << bn << std::endl; 00284 } 00285 } 00286 std::cout << std::endl; 00287 }