BWAPI
|
00001 // Copyright (c) 1997-2002 Max-Planck-Institute Saarbruecken (Germany). 00002 // All rights reserved. 00003 // 00004 // This file is part of CGAL (www.cgal.org); you may redistribute it under 00005 // the terms of the Q Public License version 1.0. 00006 // See the file LICENSE.QPL distributed with CGAL. 00007 // 00008 // Licensees holding a valid commercial license may use this file in 00009 // accordance with the commercial license agreement provided with the software. 00010 // 00011 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE 00012 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 00013 // 00014 // $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal/branches/CGAL-3.5-branch/Nef_S2/include/CGAL/Nef_S2/SM_io_parser.h $ 00015 // $Id: SM_io_parser.h 41659 2008-01-17 15:34:18Z hachenb $ 00016 // 00017 // 00018 // Author(s) : Michael Seel <seel@mpi-sb.mpg.de> 00019 // Peter Hachenberger <hachenberger@mpi-sb.mpg.de> 00020 00021 #ifndef CGAL_SM_IO_PARSER_H 00022 #define CGAL_SM_IO_PARSER_H 00023 00024 #include <CGAL/Nef_S2/SM_decorator.h> 00025 #include <CGAL/Nef_2/Object_index.h> 00026 #include <CGAL/Nef_S2/SM_decorator_traits.h> 00027 #include <vector> 00028 #include <iostream> 00029 00030 #if defined(BOOST_MSVC) 00031 # pragma warning(push) 00032 # pragma warning(disable:4355) // complaint about using 'this' to 00033 #endif // initialize a member 00034 00035 CGAL_BEGIN_NAMESPACE 00036 00037 /*{\Moptions outfile=SM_io_parser.man }*/ 00038 /*{\Manpage {SM_io_parser}{Decorator_}{IO of embedded maps}{IO}}*/ 00039 00040 /*{\Mdefinition An instance |\Mvar| of the data type |\Mname| is a 00041 decorator to provide input and output of a embedded map. |\Mtype| is 00042 generic with respect to the |Decorator_| parameter. |Decorator_| has 00043 to be a decorator model of our |SM_decorator| concept.}*/ 00044 00045 /*{\Mgeneralization SM_decorator}*/ 00046 00047 template <typename Decorator_> 00048 class SM_io_parser : public Decorator_ 00049 { 00050 typedef Decorator_ Base; 00051 typedef typename Decorator_::Sphere_point Sphere_point; 00052 typedef typename Decorator_::Sphere_circle Sphere_circle; 00053 typedef typename Decorator_::Mark Mark; 00054 00055 typedef typename Decorator_::Decorator_traits Decorator_traits; 00056 00057 typedef typename Decorator_traits::SVertex_iterator SVertex_iterator; 00058 typedef typename Decorator_traits::SHalfedge_iterator SHalfedge_iterator; 00059 typedef typename Decorator_traits::SFace_iterator SFace_iterator; 00060 typedef typename Decorator_traits::SVertex_handle SVertex_handle; 00061 typedef typename Decorator_traits::SVertex_const_handle SVertex_const_handle; 00062 typedef typename Decorator_traits::SHalfedge_handle SHalfedge_handle; 00063 typedef typename Decorator_traits::SHalfedge_const_handle SHalfedge_const_handle; 00064 typedef typename Decorator_traits::SFace_const_handle SFace_const_handle; 00065 typedef typename Decorator_traits::SFace_handle SFace_handle; 00066 typedef typename Decorator_traits::SHalfloop_handle SHalfloop_handle; 00067 typedef typename Decorator_traits::SHalfloop_const_handle SHalfloop_const_handle; 00068 typedef typename Decorator_traits::SFace_cycle_iterator SFace_cycle_iterator; 00069 typedef typename Decorator_traits::SHalfedge_around_svertex_circulator 00070 SHalfedge_around_svertex_circulator; 00071 00072 std::istream& in; std::ostream& out; 00073 bool verbose; 00074 // a reference to the IO object 00075 CGAL::Object_index<SVertex_const_handle> VI; 00076 CGAL::Object_index<SHalfedge_const_handle> EI; 00077 CGAL::Object_index<SFace_const_handle> FI; 00078 std::vector<SVertex_handle> SVertex_of; 00079 std::vector<SHalfedge_handle> Edge_of; 00080 std::vector<SFace_handle> SFace_of; 00081 SHalfloop_handle Loop_of[2]; 00082 // object mapping for input 00083 int vn,en,ln,fn,i; 00084 // the number of objects 00085 00086 bool check_sep(const char* sep); 00087 void print_vertex(SVertex_handle) const; 00088 void print_edge(SHalfedge_handle) const; 00089 void print_loop(SHalfloop_const_handle) const; 00090 void print_face(SFace_handle) const; 00091 00092 bool read_vertex(SVertex_handle); 00093 bool read_edge(SHalfedge_handle); 00094 bool read_loop(SHalfloop_handle); 00095 bool read_face(SFace_handle); 00096 00097 void debug_vertex(SVertex_handle) const; 00098 void debug_edge(SHalfedge_handle) const; 00099 void debug_loop(SHalfloop_const_handle) const; 00100 00101 public: 00102 /*{\Mcreation 3}*/ 00103 SM_io_parser(std::istream& is, const Base& D); 00104 /*{\Mcreate creates an instance |\Mvar| of type |\Mname| 00105 to input |H| from |is|.}*/ 00106 00107 SM_io_parser(std::ostream& os, const Base& D); 00108 /*{\Mcreate creates an instance |\Mvar| of type |\Mname| 00109 to output |H| to |os|.}*/ 00110 00111 /*{\Moperations 2 3}*/ 00112 void print() const; 00113 /*{\Mop prints |H| to |os|.}*/ 00114 void read(); 00115 /*{\Mop reads |H| from |is|.}*/ 00116 void debug() const; 00117 void print_faces() const; 00118 00119 std::string index(SVertex_const_handle v) const 00120 { return VI(v,verbose); } 00121 std::string index(SHalfedge_const_handle e) const 00122 { return EI(e,verbose); } 00123 std::string index(SHalfloop_const_handle l) const 00124 { if (verbose) return (l==this->shalfloop()? "l0" : "l1"); 00125 else return (l==this->shalfloop()? "0" : "1"); 00126 } 00127 std::string index(SFace_const_handle f) const 00128 { return FI(f,verbose); } 00129 00130 static void dump(const Decorator_& D, std::ostream& os = std::cerr); 00131 /*{\Mstatic prints the plane map decorated by |D| to |os|.}*/ 00132 00133 }; // SM_io_parser<Decorator_> 00134 00135 00136 template <typename Decorator_> 00137 SM_io_parser<Decorator_>:: 00138 SM_io_parser(std::istream& iin, const Base& H) : 00139 Base(H), in(iin), out(std::cout), verbose(0), 00140 vn(0), en(0), ln(0), fn(0) 00141 { this->clear(); } 00142 00143 template <typename Decorator_> 00144 SM_io_parser<Decorator_>:: 00145 SM_io_parser(std::ostream& iout, const Base& D) 00146 : Base(D), in(std::cin), out(iout), 00147 VI(this->svertices_begin(),this->svertices_end(),'v'), 00148 EI(this->shalfedges_begin(),this->shalfedges_end(),'e'), 00149 FI(this->sfaces_begin(),this->sfaces_end(),'f'), 00150 vn(this->number_of_svertices()), 00151 en(this->number_of_shalfedges()), 00152 ln(this->number_of_shalfloops()), 00153 fn(this->number_of_sfaces()) 00154 { verbose = (out.iword(CGAL::IO::mode) != CGAL::IO::ASCII && 00155 out.iword(CGAL::IO::mode) != CGAL::IO::BINARY); 00156 } 00157 00158 00159 //----------------------------------------------------------------------------- 00160 // OUTPUT AND INPUT: 00161 //----------------------------------------------------------------------------- 00162 00163 template <typename Decorator_> 00164 bool SM_io_parser<Decorator_>::check_sep(const char* sep) 00165 { 00166 char c; 00167 do in.get(c); while (isspace(c)); 00168 while (*sep != '\0') { 00169 if (*sep != c) { 00170 in.putback(c); 00171 return false; 00172 } 00173 ++sep; in.get(c); 00174 } 00175 in.putback(c); 00176 return true; 00177 } 00178 00179 template <typename Decorator_> 00180 void SM_io_parser<Decorator_>::print_vertex(SVertex_handle v) const 00181 { 00182 // syntax: index { isolated incident_object, mark, point } 00183 out << index(v) << " { "; 00184 if ( is_isolated(v) ) out << "1 " << index(v->incident_sface()); 00185 else out << "0 " << index(first_out_edge(v)); 00186 out << ", " << v->mark() << ", " << v->point() << "}\n"; 00187 } 00188 00189 template <typename Decorator_> 00190 bool SM_io_parser<Decorator_>::read_vertex(SVertex_handle v) 00191 { 00192 // precondition: nodes exist 00193 // syntax: index { isolated incident_object, mark, point} 00194 int n; bool iso; int f; Mark m; Sphere_point p; 00195 if ( !(in >> n) || 00196 !check_sep("{") || 00197 !(in >> iso) || 00198 !(in >> f) || 00199 !check_sep(",") || 00200 !(in >> m) || 00201 !check_sep(",") || 00202 !(in >> p) || 00203 !check_sep("}") ) return false; 00204 00205 if (iso) set_face(v,SFace_of[f]); 00206 else set_first_out_edge(v,Edge_of[f]); 00207 v->mark() = m; v->point() = p; 00208 return true; 00209 } 00210 00211 template <typename Decorator_> 00212 void SM_io_parser<Decorator_>::print_edge(SHalfedge_handle e) const 00213 { // syntax: index { twin, prev, next, source, face, mark, circle } 00214 00215 Decorator_ D; 00216 out << index(e) << " { " 00217 << index(e->twin()) << ", " 00218 << index(e->sprev()) << ", " << index(e->snext()) << ", " 00219 << index(e->source()) << ", " << index(e->incident_sface()) << ", " 00220 << e->mark() << ", " << e->circle() << " }\n"; 00221 } 00222 00223 template <typename Decorator_> 00224 bool SM_io_parser<Decorator_>::read_edge(SHalfedge_handle e) 00225 { // syntax: index { twin, prev, next, source, face, mark, circle } 00226 int n, eo, epr, ene, v, f; bool m; Sphere_circle k; 00227 if ( !(in >> n) || 00228 !check_sep("{") || 00229 !(in >> eo) || !check_sep(",") || 00230 !(in >> epr) || !check_sep(",") || 00231 !(in >> ene) || !check_sep(",") || 00232 !(in >> v) || !check_sep(",") || 00233 !(in >> f) || !check_sep(",") || 00234 !(in >> m) || !check_sep(",") || 00235 !(in >> k) || !check_sep("}") ) 00236 return false; 00237 CGAL_assertion_msg 00238 (eo >= 0 && eo < en && epr >= 0 && epr < en && ene >= 0 && ene < en && 00239 v >= 0 && v < vn && f >= 0 && f < fn , 00240 "wrong index in read_edge"); 00241 00242 // precond: features exist! 00243 CGAL_assertion(EI[e->twin()]); 00244 set_prev(e,Edge_of[epr]); 00245 set_next(e,Edge_of[ene]); 00246 set_source(e,SVertex_of[v]); 00247 set_face(e,SFace_of[f]); 00248 e->mark() = m; 00249 e->circle() = k; 00250 return true; 00251 } 00252 00253 template <typename Decorator_> 00254 void SM_io_parser<Decorator_>::print_loop(SHalfloop_const_handle l) const 00255 { // syntax: index { twin, face, mark, circle } 00256 out << index(l) << " { " 00257 << index(l->twin()) << ", " 00258 << index(l->incident_sface()) << ", " 00259 << l->mark() << ", " << l->circle() << " }\n"; 00260 } 00261 00262 template <typename Decorator_> 00263 bool SM_io_parser<Decorator_>::read_loop(SHalfloop_handle l) 00264 { // syntax: index { twin, face, mark, circle } 00265 int n, lo, f; bool m; Sphere_circle k; 00266 if ( !(in >> n) || 00267 !check_sep("{") || 00268 !(in >> lo) || !check_sep(",") || 00269 !(in >> f) || !check_sep(",") || 00270 !(in >> m) || !check_sep(",") || 00271 !(in >> k) || !check_sep("}") ) 00272 return false; 00273 CGAL_assertion_msg( 00274 (lo >= 0 && lo < 2 && f >= 0 && f < fn),"wrong index in read_edge"); 00275 00276 set_face(l,SFace_of[f]); 00277 l->mark() = m; 00278 l->circle() = k; 00279 return true; 00280 } 00281 00282 00283 template <typename Decorator_> 00284 void SM_io_parser<Decorator_>::print_face(SFace_handle f) const 00285 { // syntax: index { fclist, ivlist, loop, mark } 00286 out << index(f) << " { "; 00287 SFace_cycle_iterator it; 00288 CGAL_forall_sface_cycles_of(it,f) 00289 if ( it.is_shalfedge() ) out << index(SHalfedge_handle(it)) << ' '; 00290 out << ", "; 00291 CGAL_forall_sface_cycles_of(it,f) 00292 if ( it.is_svertex() ) out << index(SVertex_handle(it)) << ' '; 00293 out << ", "; 00294 CGAL_forall_sface_cycles_of(it,f) 00295 if ( it.is_shalfloop() ) out << index(SHalfloop_handle(it)); 00296 out << ", " << f->mark() << " }\n"; 00297 } 00298 00299 template <typename Decorator_> 00300 bool SM_io_parser<Decorator_>::read_face(SFace_handle f) 00301 { // syntax: index { fclist, ivlist, loop, mark } 00302 int n, ei, vi, li; Mark m; 00303 if ( !(in >> n) || !check_sep("{") ) return false; 00304 while (in >> ei) { 00305 CGAL_assertion_msg(ei >= 0 && ei < en, 00306 "wrong index in face cycle list."); 00307 store_sm_boundary_object(Edge_of[ei],f); 00308 } in.clear(); 00309 if (!check_sep(",")) { return false; } 00310 while (in >> vi) { 00311 CGAL_assertion_msg(vi >= 0 && vi < vn, 00312 "wrong index in iso vertex list."); 00313 store_sm_boundary_object(SVertex_of[vi],f); 00314 } in.clear(); 00315 if (!check_sep(",")) { return false; } 00316 while (in >> li) { 00317 CGAL_assertion_msg(li >= 0 && li < 2, 00318 "wrong index in iso vertex list."); 00319 store_sm_boundary_object(Loop_of[li],f); 00320 } in.clear(); 00321 if (!check_sep(",") || !(in >> m) || !check_sep("}") ) 00322 return false; 00323 f->mark() = m; 00324 return true; 00325 } 00326 00327 template <typename Decorator_> 00328 void SM_io_parser<Decorator_>::print() const 00329 { 00330 out << "Sphere_map_2" << std::endl; 00331 out << "vertices " << vn << std::endl; 00332 out << "edges " << en << std::endl; 00333 out << "loops " << ln << std::endl; 00334 out << "faces " << fn << std::endl; 00335 if (verbose) 00336 out << "/* index { isolated ? face : edge, mark, point } */" << std::endl; 00337 SVertex_iterator vit; 00338 CGAL_forall_svertices(vit,*this) print_vertex(vit); 00339 if (verbose) 00340 out << "/* index { twin, prev, next, source, face, mark, circle } */" 00341 << std::endl; 00342 SHalfedge_iterator eit; 00343 CGAL_forall_shalfedges(eit,*this) print_edge(eit); 00344 if (verbose) 00345 out << "/* index { twin, face, mark, circle } */" << std::endl; 00346 if ( this->has_shalfloop() ) 00347 { print_loop(this->shalfloop()); print_loop(this->shalfloop()->twin()); } 00348 if (verbose) 00349 out << "/* index { fclist, ivlist, loop, mark } */" << std::endl; 00350 SFace_iterator fit; 00351 CGAL_forall_sfaces(fit,*this) print_face(fit); 00352 out.flush(); 00353 if (verbose) debug(); 00354 } 00355 00356 template <typename Decorator_> 00357 void SM_io_parser<Decorator_>::read() 00358 { 00359 if ( !check_sep("Sphere_map_2") ) 00360 CGAL_error_msg("SM_io_parser::read: no embedded_PM header."); 00361 if ( !(check_sep("vertices") && (in >> vn)) ) 00362 CGAL_error_msg("SM_io_parser::read: wrong vertex line."); 00363 if ( !(check_sep("edges") && (in >> en) && (en%2==0)) ) 00364 CGAL_error_msg("SM_io_parser::read: wrong edge line."); 00365 if ( !(check_sep("loops") && (in >> ln)) ) 00366 CGAL_error_msg("SM_io_parser::read: wrong loop line."); 00367 if ( !(check_sep("faces") && (in >> fn)) ) 00368 CGAL_error_msg("SM_io_parser::read: wrong face line."); 00369 00370 SVertex_of.resize(vn); 00371 Edge_of.resize(en); 00372 SFace_of.resize(fn); 00373 for(i=0; i<vn; i++) SVertex_of[i] = this->new_svertex(); 00374 for(i=0; i<en; i++) 00375 if (i%2==0) Edge_of[i] = this->new_shalfedge_pair(); 00376 else Edge_of[i] = Edge_of[i-1]->twin(); 00377 for(i=0; i<fn; i++) SFace_of[i] = this->new_sface(); 00378 if ( ln == 2 ) { 00379 Loop_of[0] = this->new_shalfloop_pair(); 00380 Loop_of[1] = this->shalfloop()->twin(); 00381 } 00382 00383 for(i=0; i<vn; i++) { 00384 if (!read_vertex(SVertex_of[i])) 00385 CGAL_error_msg("SM_io_parser::read: error in node line"); 00386 } 00387 for(i=0; i<en; i++) { 00388 if (!read_edge(Edge_of[i])) 00389 CGAL_error_msg("SM_io_parser::read: error in edge line"); 00390 } 00391 if ( ln == 2 ) { 00392 read_loop(Loop_of[0]); read_loop(Loop_of[1]); 00393 } 00394 for(i=0; i<fn; i++) { 00395 if (!read_face(SFace_of[i])) 00396 CGAL_error_msg("SM_io_parser::read: error in face line"); 00397 } 00398 } 00399 00400 //----------------------------------------------------------------------------- 00401 // VERBOSE OUTPUT: 00402 // note that we output the index of the objects which is stored in them 00403 // this is NOT the member index as produced by the forall loops 00404 //----------------------------------------------------------------------------- 00405 00406 template <typename Decorator_> 00407 void SM_io_parser<Decorator_>::debug_vertex(SVertex_handle v) const 00408 { 00409 out << index(v) << "[" << v->mark() << "," << v->point() << "]" << std::endl; 00410 } 00411 00412 template <typename Decorator_> 00413 void SM_io_parser<Decorator_>::debug_edge(SHalfedge_handle e) const 00414 { 00415 out << index(e) 00416 << "(" << index(e->source()) << "," << index(e->target()) << ") " 00417 << index(e->twin()) << " " << index(e->incident_sface()) 00418 << " ["<< e->mark() << "," << e->circle() << "] " << std::endl; 00419 } 00420 00421 template <typename Decorator_> 00422 void SM_io_parser<Decorator_>::debug_loop(SHalfloop_const_handle l) const 00423 { 00424 out << index(l) << " " 00425 << index(l->twin()) << " " << index(l->incident_sface()) 00426 << " ["<< l->mark() << "] " << l->circle() << std::endl; 00427 } 00428 00429 00430 template <typename Decorator_> 00431 void SM_io_parser<Decorator_>::debug() const 00432 { 00433 out << "\nDEBUG Plane_map\n"; 00434 out << "Vertices: " << this->number_of_svertices() << "\n"; 00435 out << "SHalfedges: " << this->number_of_shalfedges() << "\n"; 00436 out << "Loop: " << this->number_of_shalfloops() << "\n"; 00437 SVertex_iterator vit; 00438 CGAL_forall_svertices(vit,*this) { 00439 if ( is_isolated(vit) ) continue; 00440 SHalfedge_around_svertex_circulator hcirc(out_edges(vit)), hend(hcirc); 00441 debug_vertex(vit); 00442 CGAL_For_all(hcirc,hend) { out << " "; debug_edge(hcirc); } 00443 } 00444 if ( this->has_shalfloop() ) 00445 { debug_loop(this->shalfloop()); debug_loop(this->shalfloop()->twin()); } 00446 out << std::endl; 00447 } 00448 00449 template <typename Decorator_> 00450 void SM_io_parser<Decorator_>::print_faces() const 00451 { 00452 out << "\nFACES\n"; 00453 out << "Vertices: " << this->number_of_svertices() << "\n"; 00454 out << "SHalfedges: " << this->number_of_shalfedges() << "\n"; 00455 out << "Loop: " << this->number_of_shalfloops() << "\n"; 00456 SHalfedge_iterator e; 00457 Unique_hash_map<SHalfedge_iterator,bool> Done(false); 00458 CGAL_forall_shalfedges(e,*this) { 00459 if ( Done[e] ) continue; 00460 typename Base::SHalfedge_around_sface_circulator c(e), ce = c; 00461 out << "face cycle\n"; 00462 CGAL_For_all(c,ce) 00463 { Done[c]=true; out << " "; debug_vertex(c->source()); } 00464 } 00465 if ( this->has_shalfloop() ) 00466 { debug_loop(this->shalfloop()); debug_loop(this->shalfloop()->twin()); } 00467 out << std::endl; 00468 } 00469 00470 template <typename Decorator_> 00471 void SM_io_parser<Decorator_>::dump(const Decorator_& D, std::ostream& os) 00472 { SM_io_parser<Decorator_> Out(os,D); 00473 Out.print(); 00474 Out.print_faces(); 00475 } 00476 00477 00478 00479 CGAL_END_NAMESPACE 00480 00481 00482 #if defined(BOOST_MSVC) 00483 # pragma warning(pop) 00484 #endif 00485 00486 #endif //CGAL_SM_IO_PARSER_H 00487