// Copyright (c) 1997-2000 Max-Planck-Institute Saarbruecken (Germany). // All rights reserved. // // This file is part of CGAL (www.cgal.org). // You can redistribute it and/or modify it under the terms of the GNU // General Public License as published by the Free Software Foundation, // either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. // // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // // $URL$ // $Id$ // // // Author(s) : Michael Seel #ifndef CGAL_PM_IO_PARSER_H #define CGAL_PM_IO_PARSER_H #include #include #include namespace CGAL { /*{\Moptions outfile=PM_io_parser.man }*/ /*{\Manpage {PM_io_parser}{PMDEC}{IO of plane maps}{IO}}*/ /*{\Mdefinition An instance |\Mvar| of the data type |\Mname| is a decorator to provide input and output of a plane map. |\Mtype| is generic with respect to the |PMDEC| parameter. |PMDEC| has to be a decorator model of our |PM_decorator| concept.}*/ /*{\Mgeneralization PM_decorator}*/ template class PM_io_parser : public PMDEC { typedef PMDEC Base; typedef typename PMDEC::Plane_map Plane_map; typedef typename PMDEC::Point Point; typedef typename PMDEC::Mark Mark; typedef typename PMDEC::Vertex_iterator Vertex_iterator; typedef typename PMDEC::Halfedge_iterator Halfedge_iterator; typedef typename PMDEC::Face_iterator Face_iterator; typedef typename PMDEC::Vertex_handle Vertex_handle; typedef typename PMDEC::Halfedge_handle Halfedge_handle; typedef typename PMDEC::Face_handle Face_handle; using Base::clear; using Base::vertices_begin; using Base::vertices_end; using Base::halfedges_begin; using Base::halfedges_end; using Base::faces_begin; using Base::faces_end; using Base::number_of_vertices; using Base::number_of_halfedges; using Base::number_of_faces; using Base::new_vertex; using Base::new_face; using Base::new_halfedge_pair_without_vertices; using Base::is_isolated; using Base::face; using Base::mark; using Base::point; using Base::twin; using Base::previous; using Base::next; using Base::source; using Base::target; using Base::out_edges; using Base::halfedge; std::istream& in; std::ostream& out; bool verbose; // a reference to the IO object CGAL::Object_index VI; CGAL::Object_index EI; CGAL::Object_index FI; std::vector Vertex_of; std::vector Halfedge_of; std::vector Face_of; // object mapping for input std::size_t vn,en,fn,i; // the number of objects void print_vertex(Vertex_handle) const; void print_hedge(Halfedge_handle) const; void print_face(Face_handle) const; bool read_vertex(Vertex_handle); bool read_hedge(Halfedge_handle); bool read_face(Face_handle); void debug_vertex(Vertex_handle) const; void debug_hedge(Halfedge_handle) const; public: /*{\Mcreation 3}*/ PM_io_parser(std::istream& is, Plane_map& H) /*{\Mcreate creates an instance |\Mvar| of type |\Mname| to input |H| from |is|.}*/ : Base(H), in(is), out(std::cout), verbose(0), vn(0), en(0), fn(0) { this->clear(); } PM_io_parser(std::ostream& os, const Plane_map& H) /*{\Mcreate creates an instance |\Mvar| of type |\Mname| to output |H| to |os|.}*/ : Base(const_cast(H)), in(std::cin), out(os), VI(Base::vertices_begin(), Base::vertices_end(),'v'), EI(Base::halfedges_begin(),Base::halfedges_end(),'e'), FI(Base::faces_begin(),Base::faces_end(),'f'), vn(Base::number_of_vertices()), en(Base::number_of_halfedges()), fn(Base::number_of_faces()) { verbose = (get_mode(out) != CGAL::IO::ASCII && get_mode(out) != CGAL::IO::BINARY); } PM_io_parser(std::ostream& os, const PMDEC& D) : Base(D), in(std::cin), out(os), VI(Base::vertices_begin(),Base::vertices_end(),'v'), EI(Base::halfedges_begin(),Base::halfedges_end(),'e'), FI(Base::faces_begin(),Base::faces_end(),'f'), vn(Base::number_of_vertices()), en(Base::number_of_halfedges()), fn(Base::number_of_faces()) { verbose = (get_mode(out) != CGAL::IO::ASCII && get_mode(out) != CGAL::IO::BINARY); } /*{\Moperations 2 3}*/ bool check_sep(const char* sep); void print() const; /*{\Mop prints |H| to |os|.}*/ void read(); /*{\Mop reads |H| from |is|.}*/ void debug() const; std::string index(Vertex_handle v) const { return VI(v,verbose); } std::string index(Halfedge_handle e) const { return EI(e,verbose); } std::string index(Face_handle f) const { return FI(f,verbose); } static void dump(const PMDEC& D, std::ostream& os = std::cerr); /*{\Mstatic prints the plane map decorated by |D| to |os|.}*/ }; // PM_io_parser //----------------------------------------------------------------------------- // OUTPUT AND INPUT: //----------------------------------------------------------------------------- template bool PM_io_parser::check_sep(const char* sep) { char c; do in.get(c); while (isspace(c)); while (*sep != '\0') { if (*sep != c) { in.putback(c); return false; } ++sep; in.get(c); } in.putback(c); return true; } template void PM_io_parser::print_vertex(Vertex_handle v) const { // syntax: index { isolated incident_object, mark, point } out << index(v) << " { "; if ( is_isolated(v) ) out << "1 " << index(face(v)); else out << "0 " << index(v->halfedge()); out << ", " << mark(v) << ", " << point(v) << "}\n"; } template bool PM_io_parser::read_vertex(Vertex_handle v) { // precondition: nodes exist // syntax: index { mark, point, isolated object } int n; bool iso; int f; Mark m; Point p; if ( !(in >> n) || !check_sep("{") || !(in >> iso) || !(in >> f) || !check_sep(",") || !(in >> m) || !check_sep(",") || !(in >> p) || !check_sep("}") ) return false; if(!(f >= 0 && ((iso && (std::size_t)f < fn) || (!iso && (std::size_t)f < en)))) { in.setstate(std::ios_base::badbit); return false; } if (iso) v->set_face(Face_of[f]); else v->set_halfedge(Halfedge_of[f]); mark(v) = m; point(v) = p; return true; } template void PM_io_parser::print_hedge(Halfedge_handle e) const { // syntax: index { opposite, prev, next, vertex, face, mark } out << index(e) << " { " << index(twin(e)) << ", " << index(previous(e)) << ", " << index(next(e)) << ", " << index(target(e)) << ", " << index(face(e)) << ", " << mark(e) << " }\n"; } template bool PM_io_parser::read_hedge(Halfedge_handle e) { // syntax: index { opposite, prev, next, vertex, face, mark } int n, eo, epr, ene, v, f; bool m; if ( !(in >> n) || !check_sep("{") || !(in >> eo) || !check_sep(",") || !(in >> epr) || !check_sep(",") || !(in >> ene) || !check_sep(",") || !(in >> v) || !check_sep(",") || !(in >> f) || !check_sep(",") || !(in >> m) || !check_sep("}") ) return false; if(!(eo >= 0 && (std::size_t) eo < en && epr >= 0 && (std::size_t) epr < en && ene >= 0 && (std::size_t) ene < en && v >= 0 && (std::size_t) v < vn && f >= 0 && (std::size_t) f < fn )) { in.setstate(std::ios_base::badbit); std::cerr<<"wrong index in read_hedge"<opposite()]); e->set_prev(Halfedge_of[epr]); e->set_next(Halfedge_of[ene]); e->set_vertex(Vertex_of[v]); e->set_face(Face_of[f]); mark(e) = m; return true; } template void PM_io_parser::print_face(Face_handle f) const { // syntax: index { halfedge, fclist, ivlist, mark } out << index(f) << " { " << index(halfedge(f)) << ", "; typedef typename std::list::iterator lhiterator; lhiterator hit, hend = f->fc_end(); for(hit = f->fc_begin(); hit!=hend; ++hit) out << index(*hit) << ' '; out << ", "; typedef typename std::list::iterator lviterator; lviterator vit, vend = f->iv_end(); for(vit = f->iv_begin(); vit!=vend; ++vit) out << index(*vit) << ' '; out << ", " << mark(f) << " }\n"; } template bool PM_io_parser::read_face(Face_handle f) { // syntax: index { halfedge, fclist, ivlist, mark } int n, ei, vi; Mark m; if ( !(in >> n) || !check_sep("{") ) return false; if ( !(in >> ei) || !check_sep(",") ) return false; if (ei >= 0 && (std::size_t) ei < en) { f->set_halfedge(Halfedge_of[ei]); } while (in >> ei) { CGAL_assertion_msg(ei >= 0 && (std::size_t) ei < en, "wrong index in face cycle list."); if (!(ei >= 0 && (std::size_t)ei < en)) { in.setstate(std::ios_base::badbit); return false; } f->store_fc(Halfedge_of[ei]); } in.clear(); if (!check_sep(",")) { return false; } while (in >> vi) { CGAL_assertion_msg(vi >= 0 && (std::size_t) vi < vn, "wrong index in iso vertex list."); if (!(vi >= 0 && (std::size_t)vi < vn)) { in.setstate(std::ios_base::badbit); return false; } f->store_iv(Vertex_of[vi]); } in.clear(); if (!check_sep(",") || !(in >> m) || !check_sep("}") ) return false; mark(f) = m; return true; } template void PM_io_parser::print() const { out << "Plane_map_2" << std::endl; out << "vertices " << vn << std::endl; out << "halfedges " << en << std::endl; out << "faces " << fn << std::endl; if (verbose) out << "/* index { isolated ? face : halfedge, mark, point } */" << std::endl; Vertex_iterator vit, vend = this->vertices_end(); for(vit = this->vertices_begin(); vit!=vend; ++vit) print_vertex(vit); if (verbose) out << "/* index { opposite, prev, next, vertex, face, mark } */" << std::endl; Halfedge_iterator eit, eend = this->halfedges_end(); for(eit = this->halfedges_begin(); eit!=eend; ++eit) print_hedge(eit); if (verbose) out << "/* index { halfedge, fclist, ivlist, mark } */" << std::endl; Face_iterator fit, fend = this->faces_end(); for(fit = this->faces_begin(); fit!=fend; ++fit) print_face(fit); out.flush(); if (verbose) debug(); } template void PM_io_parser::read() { if ( !check_sep("Plane_map_2") ) { CGAL_warning_msg(false, "PM_io_parser::read: no embedded_PM header."); return; } if ( !(check_sep("vertices") && (in >> vn)) ) { CGAL_warning_msg(false, "PM_io_parser::read: wrong node line."); return; } if ( !(check_sep("halfedges") && (in >> en) && (en%2==0)) ) { CGAL_warning_msg(false, "PM_io_parser::read: wrong edge line."); return; } if ( !(check_sep("faces") && (in >> fn)) ) { CGAL_warning_msg(false, "PM_io_parser::read: wrong face line."); return; } Vertex_of.resize(vn); Halfedge_of.resize(en); Face_of.resize(fn); for(i=0; inew_vertex(); for(i=0; inew_halfedge_pair_without_vertices(); else Halfedge_of[i] = twin(Halfedge_of[i-1]); for(i=0; inew_face(); for(i=0; i void PM_io_parser::debug_vertex(Vertex_handle v) const { out << index(v) << "[" << mark(v) << "," << point(v) << "]" << std::endl; } template void PM_io_parser::debug_hedge(Halfedge_handle e) const { out << index(e) << "(" << index(source(e)) << "," << index(target(e)) << ") " << index(face(e)) << " " << index(twin(e)) << " ["<< mark(e) << "]" <<" "<<&*(face(e)) << std::endl; } template void PM_io_parser::debug() const { out << "\nDEBUG Plane_map\n" << "Vertices: " << this->number_of_vertices() << "\n" << "Halfedges: " << this->number_of_halfedges() << "\n"; Vertex_iterator vit,vend = this->vertices_end(); for( vit = this->vertices_begin(); vit != vend; ++vit ) { if ( is_isolated(vit) ) continue; typename Base::Halfedge_around_vertex_circulator hcirc = out_edges(vit), hend = hcirc; debug_vertex(vit); CGAL_For_all(hcirc,hend) { out << " "; debug_hedge(hcirc); } } out << std::endl; } template void PM_io_parser::dump(const PMDEC& D, std::ostream& os) { PM_io_parser Out(os,D); Out.print(); } } //namespace CGAL #endif //CGAL_PM_IO_PARSER_H