26 #ifndef MLN_IO_VTK_LOAD_HH
27 # define MLN_IO_VTK_LOAD_HH
44 # include <mln/core/alias/complex_image.hh>
61 void load(bin_2complex_image3df& ima,
const std::string&
filename);
65 # ifndef MLN_INCLUDE_ONLY
74 error(
const std::string& caller,
const std::string&
filename,
75 const std::string& message)
77 std::cerr << caller <<
": `" << filename <<
"': "
78 << message << std::endl;
84 accept(
const std::string& token,
const std::string& expected,
85 const std::string& caller,
const std::string&
filename,
86 const std::string& message)
88 if (token != expected)
89 error(caller, filename, message);
95 accept(
const std::string& token,
const std::string& expected,
96 const std::string& caller,
const std::string& filename)
98 accept(token, expected, caller, filename,
99 std::string(
"parse error (`") + expected +
"' expected, "
100 +
"got `" + token +
"').");
105 template <
typename T>
119 load(bin_2complex_image3df& ima,
const std::string& filename)
121 typedef bin_2complex_image3df I;
123 const std::string me =
"mln::io::off::load";
125 std::ifstream istr(filename.c_str());
128 std::cerr << me <<
": `" << filename <<
"' not found."
156 std::getline(istr, version);
165 std::getline(istr, header);
173 if (format ==
"BINARY")
174 internal::error(me, filename,
175 "`BINARY' VTK format is not supported "
176 "(only `ASCII' is supported yet).");
177 else if (format !=
"ASCII")
178 internal::error(me, filename,
179 std::string(
"invalid file format: `")
201 std::string dataset_keyword, dataset_type;
202 istr >> dataset_keyword >> dataset_type;
203 internal::accept(dataset_keyword,
"DATASET", me, filename);
204 internal::accept(dataset_type,
"POLYDATA", me, filename,
205 "unsupported dataset structure "
206 "(only `POLYDATA' is supported yet).");
212 const unsigned D = 2;
230 std::string points_keyword;
232 std::string points_datatype;
233 istr >> points_keyword >> npoints >> points_datatype;
234 internal::accept(points_keyword,
"POINTS", me, filename);
235 internal::accept(points_datatype,
"float", me, filename,
236 "unsupported points data type "
237 "(only `float' is supported yet).");
240 typedef mln_coord_(P) C;
241 typedef mln_geom_(I) G;
243 geom.reserve(npoints);
244 for (
unsigned i = 0; i < npoints; ++i)
252 geom.add_location(P(x, y, z));
289 std::string vertices_keyword;
290 unsigned nvertices, vertices_size;
291 istr >> vertices_keyword >> nvertices >> vertices_size;
292 internal::accept(vertices_keyword,
"VERTICES", me, filename);
301 if (vertices_size != nvertices * 2)
302 internal::error(me, filename,
"ill-formed `VERTICES' section.");
305 std::vector<unsigned> vertices;
306 vertices.reserve(npoints);
307 for (
unsigned i = 0; i < nvertices; ++i)
309 unsigned numpoints,
p;
310 istr >> numpoints >>
p;
312 internal::error(me, filename,
"ill-formed vertex item.");
314 internal::error(me, filename,
315 "point id out of bounds in vertex item.");
316 vertices.push_back(p);
323 std::string lines_keyword;
324 unsigned nedges, edges_size;
325 istr >> lines_keyword >> nedges >> edges_size;
326 internal::accept(lines_keyword,
"LINES", me, filename);
335 if (edges_size != nedges * 3)
336 internal::error(me, filename,
"ill-formed `LINES' section.");
339 typedef std::vector< std::vector<bool> > complex_edges_t;
340 complex_edges_t complex_edges (npoints,
341 std::vector<bool>(npoints,
false));
344 for (
unsigned i = 0; i < nedges; ++i)
347 unsigned numpoints, p1, p2;
348 istr >> numpoints >> p1 >> p2;
350 internal::error(me, filename,
"ill-formed line item.");
351 if (p1 > npoints || p2 > npoints)
352 internal::error(me, filename,
353 "point id out of bounds in line item.");
354 topo::n_face<0, D> v1(c, p1);
355 topo::n_face<0, D> v2(c, p2);
358 complex_edges[p1][p2] =
true;
359 complex_edges[p2][p1] =
true;
366 std::string polygons_keyword;
367 unsigned npolygons, polygons_size;
368 istr >> polygons_keyword >> npolygons >> polygons_size;
369 internal::accept(polygons_keyword,
"POLYGONS", me, filename);
372 unsigned npolygons_values = 0;
374 for (
unsigned i = 0; i < npolygons; ++i)
381 internal::error(me, filename,
382 std::string(
"ill-formed face (having ")
383 + internal::str(numpoints)
384 + (numpoints < 2 ?
"vertex" :
"vertices")
393 topo::n_faces_set<1, D> face_edges_set;
394 face_edges_set.reserve(numpoints);
397 unsigned first_point_id;
398 istr >> first_point_id;
401 unsigned point_id = first_point_id;
402 if (point_id >= npoints)
403 internal::error(me, filename,
404 std::string(
"invalid point id: `")
405 + internal::str(point_id) +
"'.");
406 for (
unsigned p = 0; p < numpoints; ++
p)
411 unsigned next_point_id;
415 if (p == numpoints - 1)
416 next_point_id = first_point_id;
419 istr >> next_point_id;
421 if (next_point_id >= npoints)
422 internal::error(me, filename,
423 std::string(
"invalid point id: `")
425 + internal::str(next_point_id) +
"'.");
428 topo::n_face<0, D> vertex(c, point_id);
429 topo::n_face<0, D> next_vertex(c, next_point_id);
431 topo::algebraic_n_face<1, D>
edge;
437 if (!complex_edges[point_id][next_point_id])
438 internal::error(me, filename,
439 "ill-formed polygon, having a side "
440 "(edge) not part of the list of LINES.");
442 mln_assertion(edge.is_valid());
444 face_edges_set += edge;
446 point_id = next_point_id;
450 c.add_face(face_edges_set);
455 if (polygons_size != npolygons_values)
456 internal::error(me, filename,
"ill-formed `LINES' section.");
471 std::string dataset_kind;
472 istr >> dataset_kind;
473 if (dataset_kind ==
"POINT_DATA")
474 internal::error(me, filename,
475 "`POINT_DATA' datasets are not supported "
476 "(only `CELL_DATA' datasets are supported yet).");
477 else if (dataset_kind !=
"CELL_DATA")
478 internal::error(me, filename,
479 std::string(
"invalid dataset kind: `")
480 + dataset_kind +
"'.");
481 unsigned nfaces = nvertices + nedges + npolygons;
484 if (ncell_data != nfaces)
485 internal::error(me, filename,
486 std::string(
"wrong number of dataset attributes ")
487 +
"(expected " + internal::str(nfaces)
488 +
", got " + internal::str(ncell_data) +
").");
532 std::string scalars_keyword, data_name, data_type;
533 istr >> scalars_keyword >> data_name >> data_type;
534 internal::accept(scalars_keyword,
"SCALARS", me, filename);
537 if (data_type !=
"bit")
538 internal::error(me, filename,
539 std::string(
"unsupported data (value) type : `")
540 + data_type +
"' (only `bit' is supported yet).");
542 std::string lookup_table_keyword, lookup_table_name;
543 istr >> lookup_table_keyword >> lookup_table_name;
544 internal::accept(lookup_table_keyword,
"LOOKUP_TABLE", me, filename);
547 typedef mln_value_(I) V;
548 typedef metal::vec<D + 1, std::vector<V> > values;
558 for (std::vector<
unsigned>::const_iterator v = vertices.begin();
559 v != vertices.end(); ++ v)
569 for(
unsigned e = 0; e < nedges; ++e)
573 vs[1].push_back(value);
577 for(
unsigned f = 0; f < npolygons; ++f)
581 vs[2].push_back(value);
589 typedef mln_domain_(I) domain;
605 # endif // ! MLN_INCLUDE_ONLY
615 #endif // ! MLN_IO_VTK_LOAD_HH