27 #ifndef MLN_IO_OFF_LOAD_HH
28 # define MLN_IO_OFF_LOAD_HH
42 # include <mln/literal/black.hh>
43 # include <mln/core/concept/object.hh>
44 # include <mln/core/alias/complex_image.hh>
90 template <
typename I,
typename E>
91 struct off_loader :
public Object<E>
93 typedef off_loader<I, E>
self;
96 static const unsigned D = 2;
98 typedef metal::vec<D + 1, std::vector< mln_value(I) > > values;
100 typedef mln_domain(I) domain;
106 void operator()(I& ima, const std::
string& filename);
110 static std::istream& eat_comment(std::istream& istr);
114 struct bin_off_loader
120 void read_face_data(std::istream& istr);
123 void assign(values& vs,
const domain& s);
128 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
136 struct float_off_loader
137 :
public off_loader< float_2complex_image3df, float_off_loader >
140 void read_face_data(std::istream& istr);
143 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
146 void assign(values& vs,
const domain& s);
149 std::vector<float> face_value;
153 struct rgb8_off_loader
154 :
public off_loader< rgb8_2complex_image3df, rgb8_off_loader >
157 void read_face_data(std::istream& istr);
160 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
163 void assign(values& vs,
const domain& s);
166 std::vector<value::rgb8> face_value;
173 # ifndef MLN_INCLUDE_ONLY
183 trace::entering(
"mln::io::off::load");
184 internal::bin_off_loader()(ima, filename);
185 trace::exiting(
"mln::io::off::load");
192 trace::entering(
"mln::io::off::load");
193 internal::float_off_loader()(ima, filename);
194 trace::exiting(
"mln::io::off::load");
201 trace::entering(
"mln::io::off::load");
202 internal::rgb8_off_loader()(ima, filename);
203 trace::exiting(
"mln::io::off::load");
219 template <
typename I,
typename E>
221 off_loader<I, E>::off_loader()
224 void (E::*m1)(std::istream&) = &E::read_face_data;
226 void (E::*m2)(unsigned, unsigned, unsigned) = &E::reserve;
228 void (E::*m3)(values&,
const domain&) = &E::assign;
233 template <
typename I,
typename E>
236 off_loader<I, E>::operator()(I& ima,
const std::string& filename)
238 const std::string me =
"mln::io::off::load";
240 std::ifstream istr(filename.c_str());
243 std::cerr << me <<
": `" << filename <<
"' not found."
263 istr >> &self::eat_comment >> type;
266 std::cerr << me <<
": `" << filename <<
"': ill-formed header."
274 unsigned nvertices, nfaces, nedges;
275 istr >> &self::eat_comment >> nvertices
276 >> &self::eat_comment >> nfaces
277 >> &self::eat_comment >> nedges;
280 exact(
this)->reserve(nvertices, nedges, nfaces);
293 const unsigned D = 2;
305 for (
unsigned v = 0; v < nvertices; ++v)
309 typedef mln_coord_(P) C;
310 typedef geom::complex_geometry<D, P> G;
312 for (
unsigned v = 0; v < nvertices; ++v)
315 istr >> &self::eat_comment >> x
316 >> &self::eat_comment >> y
317 >> &self::eat_comment >> z;
318 geom.add_location(
point3df(x, y, z));
331 typedef std::vector< std::vector<bool> > complex_edges_t;
332 complex_edges_t complex_edges (nvertices,
333 std::vector<bool>(nvertices,
false));
335 for (
unsigned f = 0; f < nfaces; ++f)
337 unsigned nface_vertices;
338 istr >> &self::eat_comment >> nface_vertices;
339 if (nface_vertices <= 2)
341 std::cerr << me <<
": `" << filename
342 <<
"': ill-formed face (having "
343 << nface_vertices <<
' '
344 << (nface_vertices < 2 ?
"vertex" :
"vertices")
350 topo::n_faces_set<1, D> face_edges_set;
351 face_edges_set.reserve(nface_vertices);
354 unsigned first_vertex_id;
355 istr >> &self::eat_comment >> first_vertex_id;
357 unsigned vertex_id = first_vertex_id;
358 if (first_vertex_id >= nvertices)
360 std::cerr << me <<
": `" << filename
361 <<
"': invalid vertex id " << first_vertex_id
366 for (
unsigned v = 0; v < nface_vertices; ++v)
371 unsigned next_vertex_id;
375 if (v == nface_vertices - 1)
376 next_vertex_id = first_vertex_id;
379 istr >> &self::eat_comment >> next_vertex_id;
380 if (next_vertex_id >= nvertices)
382 std::cerr << me <<
": `" << filename
383 <<
"': invalid vertex id "
384 << next_vertex_id << std::endl;
389 topo::n_face<0, D> vertex(c, vertex_id);
390 topo::n_face<0, D> next_vertex(c, next_vertex_id);
392 topo::algebraic_n_face<1, D>
edge;
395 if (!complex_edges[vertex_id][next_vertex_id])
397 complex_edges[vertex_id][next_vertex_id] =
true;
398 complex_edges[next_vertex_id][vertex_id] =
true;
407 mln_assertion(edge.is_valid());
410 face_edges_set += edge;
412 vertex_id = next_vertex_id;
416 exact(
this)->read_face_data(istr);
419 c.add_face(face_edges_set);
431 exact(
this)->assign(vs, s);
440 istr >> &self::eat_comment;
443 std::cerr << me <<
": `" << filename
444 <<
"': end of file not reached" << std::endl;
504 bin_off_loader::read_face_data(std::istream& )
511 float_off_loader::read_face_data(std::istream& istr)
527 istr >> r >> g >> b >> a;
528 mln_assertion(0.0f <= r); mln_assertion(r <= 1.0f);
529 mln_assertion(0.0f <= g); mln_assertion(g <= 1.0f);
530 mln_assertion(0.0f <= b); mln_assertion(b <= 1.0f);
531 mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
532 face_value.push_back(r);
537 rgb8_off_loader::read_face_data(std::istream& istr)
547 istr >> r >> g >> b >> a;
548 mln_assertion(0.0f <= r); mln_assertion(r <= 1.0f);
549 mln_assertion(0.0f <= g); mln_assertion(g <= 1.0f);
550 mln_assertion(0.0f <= b); mln_assertion(b <= 1.0f);
551 mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
561 bin_off_loader::reserve(
unsigned ,
570 float_off_loader::reserve(
unsigned ,
574 face_value.reserve(nfaces);
580 rgb8_off_loader::reserve(
unsigned ,
584 face_value.reserve(nfaces);
590 bin_off_loader::assign(values& vs,
const domain& s)
593 for (
unsigned i = 0; i <= D; ++i)
594 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i),
true);
599 float_off_loader::assign(values& vs,
const domain& s)
602 for (
unsigned i = 0; i < D; ++i)
603 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i), 0.0f);
610 rgb8_off_loader::assign(values& vs,
const domain& s)
613 for (
unsigned i = 0; i < D; ++i)
614 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i),
625 template <
typename I,
typename E>
628 off_loader<I, E>::eat_comment(std::istream& istr)
632 while (istr.peek() ==
'#')
639 while (c !=
'\n' && c !=
'\r' && !istr.eof());
649 # endif // ! MLN_INCLUDE_ONLY
659 #endif // ! MLN_IO_OFF_LOAD_HH