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 APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH 00027 # define APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH 00028 00029 /*--------------------------------------------------------------------. 00030 | FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, | 00031 | because fixing image_if + complex_image was much too long. Sorry. | 00032 `--------------------------------------------------------------------*/ 00033 00034 # include <cstdlib> 00035 00036 # include <iostream> 00037 # include <fstream> 00038 # include <sstream> 00039 00040 # include <string> 00041 00042 # include <mln/core/alias/complex_image.hh> 00043 # include <mln/core/image/complex_neighborhoods.hh> 00044 # include <mln/core/image/complex_neighborhood_piter.hh> 00045 00046 namespace mln 00047 { 00048 00049 namespace io 00050 { 00051 00052 namespace off 00053 { 00054 00058 template <typename I> 00059 void save_bin_alt(const I& ima, 00060 const std::string& filename) 00061 { 00062 const std::string me = "mln::io::off::save"; 00063 00064 std::ofstream ostr(filename.c_str()); 00065 if (!ostr) 00066 { 00067 std::cerr << me << ": `" << filename << "' invalid file." 00068 << std::endl; 00069 /* FIXME: Too violent. We should allow the use of 00070 exceptions, at least to have Milena's code behave 00071 correctly in interpreted environments (std::exit() or 00072 std::abort() causes the termination of a Python 00073 interpreter, for instance!). */ 00074 std::exit(1); 00075 } 00076 00077 /*---------. 00078 | Header. | 00079 `---------*/ 00080 00081 static const unsigned D = I::dim; 00082 typedef mln_geom(I) G; 00083 00084 /* ``The .off files in the Princeton Shape Benchmark conform 00085 to the following standard.'' */ 00086 00087 /* ``OFF files are all ASCII files beginning with the 00088 keyword OFF. '' */ 00089 ostr << "OFF" << std::endl; 00090 00091 // A comment. 00092 ostr << "# Generated by Milena 1.0 http://olena.lrde.epita.fr\n" 00093 << "# EPITA Research and Development Laboratory (LRDE)" 00094 << std::endl; 00095 00096 // Count the number of 2-faces set to `true'. 00097 unsigned n2faces = 0; 00098 p_n_faces_fwd_piter<D, G> f(ima.domain(), 2); 00099 for_all(f) 00100 if (ima(f)) 00101 ++n2faces; 00102 00103 /* ``The next line states the number of vertices, the number 00104 of faces, and the number of edges. The number of edges can 00105 be safely ignored.'' */ 00106 /* FIXME: This is too long. We shall be able to write 00107 00108 ima.domain().template nfaces_of_static_dim<0>() 00109 00110 or even 00111 00112 ima.template nfaces_of_static_dim<0>(). 00113 */ 00114 ostr << ima.domain().cplx().template nfaces_of_static_dim<0>() << ' ' 00115 << n2faces << ' ' 00116 << ima.domain().cplx().template nfaces_of_static_dim<1>() 00117 << std::endl; 00118 00119 /*-------. 00120 | Data. | 00121 `-------*/ 00122 00123 // ------------------------------------------ // 00124 // Vertices & geometry (vertices locations). // 00125 // ------------------------------------------ // 00126 00127 /* ``The vertices are listed with x, y, z coordinates, written 00128 one per line.'' */ 00129 00130 // Traverse the 0-faces (vertices). 00131 p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); 00132 for_all(v) 00133 { 00134 mln_invariant(v.to_site().size() == 1); 00135 ostr << v.to_site().front()[0] << ' ' 00136 << v.to_site().front()[1] << ' ' 00137 << v.to_site().front()[2] << std::endl; 00138 } 00139 00140 // --------------- // 00141 // Faces & edges. // 00142 // --------------- // 00143 00144 /* ``After the list of vertices, the faces are listed, with one 00145 face per line. For each face, the number of vertices is 00146 specified, followed by indices into the list of 00147 vertices.'' */ 00148 00149 // Traverse the 2-faces (polygons). 00150 typedef complex_m_face_neighborhood<D, G> nbh_t; 00151 // A neighborhood where neighbors are the set of 0-faces 00152 // transitively adjacent to the reference point. 00153 nbh_t nbh; 00154 mln_fwd_niter(nbh_t) u(nbh, f); 00155 /* FIXME: We should be able to pas this value (m) either at 00156 the construction of the neighborhood or at the construction 00157 of the iterator. */ 00158 u.iter().set_m(0); 00159 00160 // For each (2-)face, iterate on (transitively) ajacent 00161 // vertices (0-faces). 00162 for_all(f) 00163 if (ima(f)) 00164 { 00165 unsigned nvertices = 0; 00166 std::ostringstream vertices; 00167 for_all(u) 00168 { 00169 // FIXME: Likewise, this is a bit too long... 00170 vertices << ' ' << u.unproxy_().face().face_id(); 00171 ++nvertices; 00172 } 00173 ostr << nvertices << vertices.str(); 00174 ostr << std::endl; 00175 } 00176 00177 ostr.close(); 00178 } 00179 00180 } // end of namespace mln::io::off 00181 00182 } // end of namespace mln::io 00183 00184 } // end of namespace mln 00185 00186 00187 #endif // ! APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH