// Copyright (c) 2019 CNRS and LIRIS' Establishments (France). // 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 Lesser 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$ // SPDX-License-Identifier: LGPL-3.0+ // // Author(s) : Guillaume Damiand // #ifndef CGAL_POLYGONAL_SCHEMA_H #define CGAL_POLYGONAL_SCHEMA_H 1 #include #include #include #include //#include #include namespace CGAL { /// @return opposite label of label s /// (i.e. add/remove - depending if s is positive or negative) inline std::string opposite_label(const std::string & s) { CGAL_assertion(!s.empty()); if (s[0]=='-') { return s.substr(1, std::string::npos); } return std::string("-")+s; } struct Combinatorial_map_tag; struct Generalized_map_tag; template struct Map_incremental_builder_tools {}; template struct Map_incremental_builder_tools { typedef typename CMap::Dart_handle Dart_handle; static Dart_handle add_edge_to_face(CMap& cmap, const std::string& s, Dart_handle prev_dart, Dart_handle dart_same_label, Dart_handle dart_opposite_label, std::unordered_map& edge_label_to_dart) { if (dart_same_label!=NULL && dart_opposite_label!=NULL) { std::cerr<<"Polygonal_schema ERROR: "<<"both labels "<(prev_dart, res); } if (dart_opposite_label!=NULL) { cmap.template link_beta<2>(res, dart_opposite_label); } return res; } }; template struct Map_incremental_builder_tools { typedef typename GMap::Dart_handle Dart_handle; static Dart_handle add_edge_to_face(GMap& gmap, const std::string& s, Dart_handle prev_dart, Dart_handle dart_same_label, Dart_handle dart_opposite_label, std::unordered_map& edge_label_to_dart) { if (dart_same_label!=NULL && dart_opposite_label!=NULL) { std::cerr<<"Polygonal_schema ERROR: "<<"both labels "<(res, dh2); if (prev_dart!=gmap.null_handle) { gmap.template link_alpha<1>(res, gmap.template alpha<0>(prev_dart)); } if ((dart_same_label==NULL && dart_opposite_label==NULL) || dart_opposite_label!=NULL) { edge_label_to_dart[s]=res; gmap.info(res).m_label=new char[s.size()+1]; strncpy(gmap.info(res).m_label, s.c_str(), s.size()+1); // +1 to copy also the \0 char if (dart_opposite_label!=NULL) { gmap.template sew<2>(dh2, dart_opposite_label); } } else { // Here dart_same_label!=NULL std::string s2=opposite_label(s); edge_label_to_dart[s2]=dh2; gmap.info(dh2).m_label=new char[s2.size()+1]; strncpy(gmap.info(dh2).m_label, s2.c_str(), s2.size()+1); // +1 to copy also the \0 char gmap.template sew<2>(res, dart_same_label); } return res; } }; template < class BaseModel > class Polygonal_schema_base: public BaseModel { public: typedef BaseModel Base; typedef BaseModel Map; // Either a GMap or a CMap typedef typename Map::Dart_handle Dart_handle; typedef typename Map::Dart_const_handle Dart_const_handle; typedef typename Map::size_type size_type; Polygonal_schema_base() : Base(), first_dart(this->null_handle), prev_dart(this->null_handle), facet_started(false) {} ~Polygonal_schema_base() { for (auto it=this->darts().begin(), itend=this->darts().end(); it!=itend; ++it) { if (this->info(it).m_label!=NULL) { delete []this->info(it).m_label; this->info(it).m_label=NULL; } } } /// Start a new facet. void begin_facet() { if (facet_started) { std::cerr<<"Polygonal_schema ERROR: " <<"you try to start a facet" <<" but the previous facet is not yet ended."<null_handle; prev_dart = this->null_handle; facet_started=true; // std::cout<<"Begin facet: "<:: add_edge_to_face(*this, s, prev_dart, dart_same_label, dart_opposite_label, edge_label_to_dart); if (prev_dart==this->null_handle) { first_dart=cur; } prev_dart=cur; } /// add the given edges to the current facet /// s is a sequence of labels, add all the corresponding edges into the current facet. void add_edges_to_facet(const std::string& s) { if (!facet_started) { std::cerr<<"Polygonal_schema ERROR: " <<"you try to add edges to a facet" <<" but the facet is not yet started."<null_handle && prev_dart!=this->null_handle ); this->set_next(prev_dart, first_dart); facet_started=false; return first_dart; } /// Start a new surface void begin_surface() { if (facet_started) { end_facet(); } first_dart = this->null_handle; prev_dart = this->null_handle; edge_label_to_dart.clear(); } /// End of the surface. Return one dart of the created surface. Dart_handle end_surface() { return first_dart; } /// Start a path on the surface void begin_path() { /* if (path_started) { std::cerr<<"Polygonal_schema ERROR: " <<"you try to start a path" <<" but the previous path is not yet ended."< end_path() { if (!path_started) { std::cerr<<"Polygonal_schema ERROR: " <<"you try to end a path" <<" but the path is not yet started."< create_path(const std::string& s) { begin_path(); std::istringstream iss(s); for (std::string token; std::getline(iss, token, ' '); ) { add_edge_to_path(token); } return end_path(); } */ /// @return dart with the given label, NULL if this dart does not exist. Dart_handle find_dart_with_label(const std::string & s) const { auto ite=edge_label_to_dart.find(s); if (ite==edge_label_to_dart.end()) { return NULL; } return ite->second; } const char* get_label(Dart_handle dh) const { // TODO } protected: // For each edge label, its corresponding dart. Stores both association a -a, to allow // users to start to add either a or -a. std::unordered_map edge_label_to_dart; Dart_handle first_dart; Dart_handle prev_dart; bool facet_started; }; template > class Polygonal_schema_with_combinatorial_map: public Polygonal_schema_base, Items_, Alloc_, Storage_> > { public: typedef Polygonal_schema_with_combinatorial_map Self; typedef Combinatorial_map_base<2, Self, Items_, Alloc_, Storage_> CMap_base; typedef Polygonal_schema_base Base; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Dart_const_handle Dart_const_handle; Polygonal_schema_with_combinatorial_map() : Base() {} Polygonal_schema_with_combinatorial_map(const Self & amap) : Base(amap) {} template Polygonal_schema_with_combinatorial_map(const Combinatorial_map_base& amap) : Base(amap) {} template Polygonal_schema_with_combinatorial_map(const Combinatorial_map_base& amap, const Converters& converters) : Base(amap, converters) {} template Polygonal_schema_with_combinatorial_map(const Combinatorial_map_base& amap, const Converters& converters, const DartInfoConverter& dartinfoconverter) : Base(amap, converters, dartinfoconverter) {} template Polygonal_schema_with_combinatorial_map(const Combinatorial_map_base& amap, const Converters& converters, const DartInfoConverter& dartinfoconverter, const PointConverter& pointconverter) : Base(amap, converters, dartinfoconverter, pointconverter) {} }; template > class Polygonal_schema_with_generalized_map: public Polygonal_schema_base, Items_, Alloc_, Storage_> > { public: typedef Polygonal_schema_with_generalized_map Self; typedef Generalized_map_base<2, Self, Items_, Alloc_, Storage_> GMap_base; typedef Polygonal_schema_base Base; typedef typename Base::Dart_handle Dart_handle; typedef typename Base::Dart_const_handle Dart_const_handle; Polygonal_schema_with_generalized_map() : Base() {} Polygonal_schema_with_generalized_map(const Self & amap) : Base(amap) {} template Polygonal_schema_with_generalized_map(const Generalized_map_base& amap) : Base(amap) {} template Polygonal_schema_with_generalized_map(const Generalized_map_base& amap, const Converters& converters) : Base(amap, converters) {} template Polygonal_schema_with_generalized_map(const Generalized_map_base& amap, const Converters& converters, const DartInfoConverter& dartinfoconverter) : Base(amap, converters, dartinfoconverter) {} template Polygonal_schema_with_generalized_map(const Generalized_map_base& amap, const Converters& converters, const DartInfoConverter& dartinfoconverter, const PointConverter& pointconverter) : Base(amap, converters, dartinfoconverter, pointconverter) {} }; } //namespace CGAL #endif // CGAL_POLYGONAL_SCHEMA_H // // EOF //