Milena (Olena)  User documentation 2.0a Id
 All Classes Namespaces Functions Variables Typedefs Enumerator Groups Pages
save_bin_alt.hh
1 // Copyright (C) 2009 EPITA Research and Development Laboratory (LRDE)
2 //
3 // This file is part of Olena.
4 //
5 // Olena is free software: you can redistribute it and/or modify it under
6 // the terms of the GNU General Public License as published by the Free
7 // Software Foundation, version 2 of the License.
8 //
9 // Olena is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Olena. If not, see <http://www.gnu.org/licenses/>.
16 //
17 // As a special exception, you may use this file as part of a free
18 // software project without restriction. Specifically, if other files
19 // instantiate templates or use macros or inline functions from this
20 // file, or you compile this file and link it with other files to produce
21 // an executable, this file does not by itself cause the resulting
22 // executable to be covered by the GNU General Public License. This
23 // exception does not however invalidate any other reasons why the
24 // executable file might be covered by the GNU General Public License.
25 
26 #ifndef APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH
27 # define APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH
28 
29 /*--------------------------------------------------------------------.
30 | FIXME: Copied and adjusted (in a hurry) from mln/io/off/save.hh, |
31 | because fixing image_if + complex_image was much too long. Sorry. |
32 `--------------------------------------------------------------------*/
33 
34 # include <cstdlib>
35 
36 # include <iostream>
37 # include <fstream>
38 # include <sstream>
39 
40 # include <string>
41 
42 # include <mln/core/alias/complex_image.hh>
43 # include <mln/core/image/complex_neighborhoods.hh>
44 # include <mln/core/image/complex_neighborhood_piter.hh>
45 
46 namespace mln
47 {
48 
49  namespace io
50  {
51 
52  namespace off
53  {
54 
58  template <typename I>
59  void save_bin_alt(const I& ima,
60  const std::string& filename)
61  {
62  const std::string me = "mln::io::off::save";
63 
64  std::ofstream ostr(filename.c_str());
65  if (!ostr)
66  {
67  std::cerr << me << ": `" << filename << "' invalid file."
68  << std::endl;
69  /* FIXME: Too violent. We should allow the use of
70  exceptions, at least to have Milena's code behave
71  correctly in interpreted environments (std::exit() or
72  std::abort() causes the termination of a Python
73  interpreter, for instance!). */
74  std::exit(1);
75  }
76 
77  /*---------.
78  | Header. |
79  `---------*/
80 
81  static const unsigned D = I::dim;
82  typedef mln_geom(I) G;
83 
84  /* ``The .off files in the Princeton Shape Benchmark conform
85  to the following standard.'' */
86 
87  /* ``OFF files are all ASCII files beginning with the
88  keyword OFF. '' */
89  ostr << "OFF" << std::endl;
90 
91  // A comment.
92  ostr << "# Generated by Milena 1.0 http://olena.lrde.epita.fr\n"
93  << "# EPITA Research and Development Laboratory (LRDE)"
94  << std::endl;
95 
96  // Count the number of 2-faces set to `true'.
97  unsigned n2faces = 0;
98  p_n_faces_fwd_piter<D, G> f(ima.domain(), 2);
99  for_all(f)
100  if (ima(f))
101  ++n2faces;
102 
103  /* ``The next line states the number of vertices, the number
104  of faces, and the number of edges. The number of edges can
105  be safely ignored.'' */
106  /* FIXME: This is too long. We shall be able to write
107 
108  ima.domain().template nfaces_of_static_dim<0>()
109 
110  or even
111 
112  ima.template nfaces_of_static_dim<0>().
113  */
114  ostr << ima.domain().cplx().template nfaces_of_static_dim<0>() << ' '
115  << n2faces << ' '
116  << ima.domain().cplx().template nfaces_of_static_dim<1>()
117  << std::endl;
118 
119  /*-------.
120  | Data. |
121  `-------*/
122 
123  // ------------------------------------------ //
124  // Vertices & geometry (vertices locations). //
125  // ------------------------------------------ //
126 
127  /* ``The vertices are listed with x, y, z coordinates, written
128  one per line.'' */
129 
130  // Traverse the 0-faces (vertices).
131  p_n_faces_fwd_piter<D, G> v(ima.domain(), 0);
132  for_all(v)
133  {
134  mln_invariant(v.to_site().size() == 1);
135  ostr << v.to_site().front()[0] << ' '
136  << v.to_site().front()[1] << ' '
137  << v.to_site().front()[2] << std::endl;
138  }
139 
140  // --------------- //
141  // Faces & edges. //
142  // --------------- //
143 
144  /* ``After the list of vertices, the faces are listed, with one
145  face per line. For each face, the number of vertices is
146  specified, followed by indices into the list of
147  vertices.'' */
148 
149  // Traverse the 2-faces (polygons).
150  typedef complex_m_face_neighborhood<D, G> nbh_t;
151  // A neighborhood where neighbors are the set of 0-faces
152  // transitively adjacent to the reference point.
153  nbh_t nbh;
154  mln_fwd_niter(nbh_t) u(nbh, f);
155  /* FIXME: We should be able to pas this value (m) either at
156  the construction of the neighborhood or at the construction
157  of the iterator. */
158  u.iter().set_m(0);
159 
160  // For each (2-)face, iterate on (transitively) ajacent
161  // vertices (0-faces).
162  for_all(f)
163  if (ima(f))
164  {
165  unsigned nvertices = 0;
166  std::ostringstream vertices;
167  for_all(u)
168  {
169  // FIXME: Likewise, this is a bit too long...
170  vertices << ' ' << u.unproxy_().face().face_id();
171  ++nvertices;
172  }
173  ostr << nvertices << vertices.str();
174  ostr << std::endl;
175  }
176 
177  ostr.close();
178  }
179 
180  } // end of namespace mln::io::off
181 
182  } // end of namespace mln::io
183 
184 } // end of namespace mln
185 
186 
187 #endif // ! APPS_MESH_SEGM_SKEL_SAVE_BIN_ALT_HH