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>
66 void load(bin_2complex_image3df& ima,
const std::string&
filename);
81 void load(float_2complex_image3df& ima,
const std::string&
filename);
94 void load(rgb8_2complex_image3df& ima,
const std::string&
filename);
100 template <
typename I,
typename E>
101 struct off_loader :
public Object<E>
103 typedef off_loader<I, E>
self;
106 static const unsigned D = 2;
108 typedef metal::vec<D + 1, std::vector< mln_value(I) > > values;
110 typedef mln_domain(I) domain;
116 void operator()(I& ima,
const std::string&
filename);
120 static std::istream& eat_comment(std::istream& istr);
124 struct bin_off_loader
125 :
public off_loader< bin_2complex_image3df, bin_off_loader >
130 void read_face_data(std::istream& istr);
133 void assign(values& vs,
const domain& s);
138 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
146 struct float_off_loader
147 :
public off_loader< float_2complex_image3df, float_off_loader >
150 void read_face_data(std::istream& istr);
153 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
156 void assign(values& vs,
const domain& s);
159 std::vector<float> face_value;
163 struct rgb8_off_loader
164 :
public off_loader< rgb8_2complex_image3df, rgb8_off_loader >
167 void read_face_data(std::istream& istr);
170 void reserve(
unsigned nvertices,
unsigned nedges,
unsigned nfaces);
173 void assign(values& vs,
const domain& s);
176 std::vector<value::rgb8> face_value;
183 # ifndef MLN_INCLUDE_ONLY
193 mln_trace(
"mln::io::off::load");
194 internal::bin_off_loader()(ima,
filename);
201 mln_trace(
"mln::io::off::load");
202 internal::float_off_loader()(ima,
filename);
209 mln_trace(
"mln::io::off::load");
210 internal::rgb8_off_loader()(ima,
filename);
226 template <
typename I,
typename E>
228 off_loader<I, E>::off_loader()
231 void (E::*m1)(std::istream&) = &E::read_face_data;
235 void (E::*m3)(values&,
const domain&) = &E::assign;
240 template <
typename I,
typename E>
243 off_loader<I, E>::operator()(I& ima,
const std::string&
filename)
245 const std::string me =
"mln::io::off::load";
247 std::ifstream istr(filename.c_str());
250 std::cerr << me <<
": `" << filename <<
"' not found."
270 istr >> &self::eat_comment >> type;
273 std::cerr << me <<
": `" << filename <<
"': ill-formed header."
281 unsigned nvertices, nfaces, nedges;
282 istr >> &self::eat_comment >> nvertices
283 >> &self::eat_comment >> nfaces
284 >> &self::eat_comment >> nedges;
287 exact(
this)->reserve(nvertices, nedges, nfaces);
300 const unsigned D = 2;
311 typedef mln_coord_(P) C;
312 typedef geom::complex_geometry<D, P> G;
314 geom.reserve(nvertices);
315 for (
unsigned v = 0; v < nvertices; ++v)
322 istr >> &self::eat_comment >> x
323 >> &self::eat_comment >> y
324 >> &self::eat_comment >> z;
325 geom.add_location(point3df(x, y, z));
338 typedef std::vector< std::vector<bool> > complex_edges_t;
339 complex_edges_t complex_edges (nvertices,
340 std::vector<bool>(nvertices,
false));
342 for (
unsigned f = 0; f < nfaces; ++f)
344 unsigned nface_vertices;
345 istr >> &self::eat_comment >> nface_vertices;
346 if (nface_vertices <= 2)
348 std::cerr << me <<
": `" << filename
349 <<
"': ill-formed face (having "
350 << nface_vertices <<
' '
351 << (nface_vertices < 2 ?
"vertex" :
"vertices")
357 topo::n_faces_set<1, D> face_edges_set;
358 face_edges_set.reserve(nface_vertices);
361 unsigned first_vertex_id;
362 istr >> &self::eat_comment >> first_vertex_id;
364 unsigned vertex_id = first_vertex_id;
365 if (first_vertex_id >= nvertices)
367 std::cerr << me <<
": `" << filename
368 <<
"': invalid vertex id " << first_vertex_id
373 for (
unsigned v = 0; v < nface_vertices; ++v)
378 unsigned next_vertex_id;
382 if (v == nface_vertices - 1)
383 next_vertex_id = first_vertex_id;
386 istr >> &self::eat_comment >> next_vertex_id;
387 if (next_vertex_id >= nvertices)
389 std::cerr << me <<
": `" << filename
390 <<
"': invalid vertex id: "
391 << next_vertex_id << std::endl;
396 topo::n_face<0, D> vertex(c, vertex_id);
397 topo::n_face<0, D> next_vertex(c, next_vertex_id);
399 topo::algebraic_n_face<1, D>
edge;
402 if (!complex_edges[vertex_id][next_vertex_id])
404 complex_edges[vertex_id][next_vertex_id] =
true;
405 complex_edges[next_vertex_id][vertex_id] =
true;
413 mln_assertion(edge.is_valid());
416 face_edges_set += edge;
418 vertex_id = next_vertex_id;
422 exact(
this)->read_face_data(istr);
425 c.add_face(face_edges_set);
437 exact(
this)->assign(vs, s);
446 istr >> &self::eat_comment;
449 std::cerr << me <<
": `" << filename
450 <<
"': end of file not reached" << std::endl;
510 bin_off_loader::read_face_data(std::istream& )
517 float_off_loader::read_face_data(std::istream& istr)
533 istr >> r >> g >> b >> a;
534 mln_assertion(0.0f <= r); mln_assertion(r <= 1.0f);
535 mln_assertion(0.0f <= g); mln_assertion(g <= 1.0f);
536 mln_assertion(0.0f <= b); mln_assertion(b <= 1.0f);
537 mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
538 face_value.push_back(r);
543 rgb8_off_loader::read_face_data(std::istream& istr)
553 istr >> r >> g >> b >> a;
554 mln_assertion(0.0f <= r); mln_assertion(r <= 1.0f);
555 mln_assertion(0.0f <= g); mln_assertion(g <= 1.0f);
556 mln_assertion(0.0f <= b); mln_assertion(b <= 1.0f);
557 mln_assertion(0.0f <= a); mln_assertion(a <= 1.0f);
558 face_value.push_back(value::rgb8(
int(255 * r),
567 bin_off_loader::reserve(
unsigned ,
576 float_off_loader::reserve(
unsigned ,
580 face_value.reserve(nfaces);
586 rgb8_off_loader::reserve(
unsigned ,
590 face_value.reserve(nfaces);
596 bin_off_loader::assign(values& vs,
const domain& s)
599 for (
unsigned i = 0; i <= D; ++i)
600 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i),
true);
605 float_off_loader::assign(values& vs,
const domain& s)
608 for (
unsigned i = 0; i < D; ++i)
609 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i), 0.0f);
616 rgb8_off_loader::assign(values& vs,
const domain& s)
619 for (
unsigned i = 0; i < D; ++i)
620 vs[i].insert(vs[i].begin(), s.cplx().nfaces_of_dim(i),
631 template <
typename I,
typename E>
634 off_loader<I, E>::eat_comment(std::istream& istr)
638 while (istr.peek() ==
'#')
645 while (c !=
'\n' && c !=
'\r' && !istr.eof());
655 # endif // ! MLN_INCLUDE_ONLY
665 #endif // ! MLN_IO_OFF_LOAD_HH