00001 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE) 00002 // 00003 // This file is part of the Milena Library. This library is free 00004 // software; you can redistribute it and/or modify it under the terms 00005 // of the GNU General Public License version 2 as published by the 00006 // Free Software Foundation. 00007 // 00008 // This library is distributed in the hope that it will be useful, 00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00011 // General Public License for more details. 00012 // 00013 // You should have received a copy of the GNU General Public License 00014 // along with this library; see the file COPYING. If not, write to 00015 // the Free Software Foundation, 51 Franklin Street, Fifth Floor, 00016 // Boston, MA 02111-1307, USA. 00017 // 00018 // As a special exception, you may use this file as part of a free 00019 // software library without restriction. Specifically, if other files 00020 // instantiate templates or use macros or inline functions from this 00021 // file, or you compile this file and link it with other files to 00022 // produce an executable, this file does not by itself cause the 00023 // resulting executable to be covered by the GNU General Public 00024 // License. This exception does not however invalidate any other 00025 // reasons why the executable file might be covered by the GNU General 00026 // Public License. 00027 00028 #ifndef APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH 00029 # define APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH 00030 00031 /*--------------------------------------------------------------------. 00032 | FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, | 00033 | because fixing image_if + complex_image was much too long. Sorry. | 00034 `--------------------------------------------------------------------*/ 00035 00036 # include <cstdlib> 00037 00038 # include <iostream> 00039 # include <fstream> 00040 # include <sstream> 00041 00042 # include <string> 00043 00044 # include <mln/core/alias/complex_image.hh> 00045 # include <mln/core/image/complex_neighborhoods.hh> 00046 # include <mln/core/image/complex_neighborhood_piter.hh> 00047 00048 namespace mln 00049 { 00050 00051 namespace io 00052 { 00053 00054 namespace off 00055 { 00056 00060 template <typename I> 00061 void save_bin_alt(const I& ima, 00062 const std::string& filename) 00063 { 00064 const std::string me = "mln::io::off::save"; 00065 00066 std::ofstream ostr(filename.c_str()); 00067 if (!ostr) 00068 { 00069 std::cerr << me << ": `" << filename << "' invalid file." 00070 << std::endl; 00071 /* FIXME: Too violent. We should allow the use of 00072 exceptions, at least to have Milena's code behave 00073 correctly in interpreted environments (std::exit() or 00074 std::abort() causes the termination of a Python 00075 interpreter, for instance!). */ 00076 std::exit(1); 00077 } 00078 00079 /*---------. 00080 | Header. | 00081 `---------*/ 00082 00083 static const unsigned D = I::dim; 00084 typedef mln_geom(I) G; 00085 00086 /* ``The .off files in the Princeton Shape Benchmark conform 00087 to the following standard.'' */ 00088 00089 /* ``OFF files are all ASCII files beginning with the 00090 keyword OFF. '' */ 00091 ostr << "OFF" << std::endl; 00092 00093 // A comment. 00094 ostr << "# Generated by Milena 1.0 http://olena.lrde.epita.fr\n" 00095 << "# EPITA Research and Development Laboratory (LRDE)" 00096 << std::endl; 00097 00098 // Count the number of 2-faces set to `true'. 00099 unsigned n2faces = 0; 00100 p_n_faces_fwd_piter<D, G> f(ima.domain(), 2); 00101 for_all(f) 00102 if (ima(f)) 00103 ++n2faces; 00104 00105 /* ``The next line states the number of vertices, the number 00106 of faces, and the number of edges. The number of edges can 00107 be safely ignored.'' */ 00108 /* FIXME: This is too long. We shall be able to write 00109 00110 ima.domain().template nfaces_of_static_dim<0>() 00111 00112 or even 00113 00114 ima.template nfaces_of_static_dim<0>(). 00115 */ 00116 ostr << ima.domain().cplx().template nfaces_of_static_dim<0>() << ' ' 00117 << n2faces << ' ' 00118 << ima.domain().cplx().template nfaces_of_static_dim<1>() 00119 << std::endl; 00120 00121 /*-------. 00122 | Data. | 00123 `-------*/ 00124 00125 // ------------------------------------------ // 00126 // Vertices & geometry (vertices locations). // 00127 // ------------------------------------------ // 00128 00129 /* ``The vertices are listed with x, y, z coordinates, written 00130 one per line.'' */ 00131 00132 // Traverse the 0-faces (vertices). 00133 p_n_faces_fwd_piter<D, G> v(ima.domain(), 0); 00134 for_all(v) 00135 { 00136 mln_invariant(v.to_site().size() == 1); 00137 ostr << v.to_site().front()[0] << ' ' 00138 << v.to_site().front()[1] << ' ' 00139 << v.to_site().front()[2] << std::endl; 00140 } 00141 00142 // --------------- // 00143 // Faces & edges. // 00144 // --------------- // 00145 00146 /* ``After the list of vertices, the faces are listed, with one 00147 face per line. For each face, the number of vertices is 00148 specified, followed by indices into the list of 00149 vertices.'' */ 00150 00151 // Traverse the 2-faces (polygons). 00152 typedef complex_m_face_neighborhood<D, G> nbh_t; 00153 // A neighborhood where neighbors are the set of 0-faces 00154 // transitively adjacent to the reference point. 00155 nbh_t nbh; 00156 mln_fwd_niter(nbh_t) u(nbh, f); 00157 /* FIXME: We should be able to pas this value (m) either at 00158 the construction of the neighborhood or at the construction 00159 of the iterator. */ 00160 u.iter().set_m(0); 00161 00162 // For each (2-)face, iterate on (transitively) ajacent 00163 // vertices (0-faces). 00164 for_all(f) 00165 if (ima(f)) 00166 { 00167 unsigned nvertices = 0; 00168 std::ostringstream vertices; 00169 for_all(u) 00170 { 00171 // FIXME: Likewise, this is a bit too long... 00172 vertices << ' ' << u.unproxy_().face().face_id(); 00173 ++nvertices; 00174 } 00175 ostr << nvertices << vertices.str(); 00176 ostr << std::endl; 00177 } 00178 00179 ostr.close(); 00180 } 00181 00182 } // end of namespace mln::io::off 00183 00184 } // end of namespace mln::io 00185 00186 } // end of namespace mln 00187 00188 00189 #endif // ! APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH