diff --git a/Combinatorial_map/examples/Combinatorial_map/map_3_constructor.cpp b/Combinatorial_map/examples/Combinatorial_map/map_3_constructor.cpp new file mode 100644 index 00000000000..d34e7b24265 --- /dev/null +++ b/Combinatorial_map/examples/Combinatorial_map/map_3_constructor.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include + +typedef CGAL::Combinatorial_map<2> CMap; + +int main() +{ + CMap cm; + CGAL::Combinatorial_map_incremental_builder b(cm); + + b.begin_surface(0,0,0); + b.add_facet("a b c -a -b"); + b.add_facet("-c d e -d -e"); + b.end_surface(); + + // Display the combinatorial map characteristics. + cm.display_characteristics(std::cout); + std::cout<<", valid="< +// +#ifndef CGAL_COMBINATORIAL_MAP_INCREMENTAL_BUILDER_H +#define CGAL_COMBINATORIAL_MAP_INCREMENTAL_BUILDER_H 1 + +#include +#include +#include + +namespace CGAL { + struct Combinatorial_map_tag; + struct Generalized_map_tag; + + template + struct Add_vertex_to_face + { + static typename CMAP::Dart_handle run(CMAP&, + typename CMAP::Dart_handle) + {} + }; + template + struct Add_vertex_to_face + { + static typename CMAP::Dart_handle run(CMAP& cmap, + typename CMAP::Dart_handle prev_dart) + { + typename CMAP::Dart_handle res=cmap.create_dart(); + if (prev_dart!=cmap.null_handle) + { + cmap.template link_beta<1>(prev_dart, res); + } + return res; + } + static void run_for_last(CMAP&, + typename CMAP::Dart_handle) + { // here nothing to do, all darts were already created. + } + }; + template + struct Add_vertex_to_face + { + static typename CMAP::Dart_handle run(CMAP& cmap, + typename CMAP::Dart_handle prev_dart) + { + typename CMAP::Dart_handle res=cmap.create_dart(); + if (prev_dart!=cmap.null_handle) + { + cmap.template link_alpha<0>(prev_dart, res); + cmap.template link_alpha<1>(res, cmap.create_dart()); + res=cmap.template alpha<1>(res); + } + return res; + } + static void run_for_last(CMAP& cmap, + typename CMAP::Dart_handle prev_dart) + { + // here we need to create a last dart and 0-link it + assert(prev_dart!=cmap.null_handle); + cmap.template link_alpha<0>(prev_dart, cmap.create_dart()); + } + }; + + // Incremental builder + template < class CMap_ > + class Combinatorial_map_incremental_builder + { + public: + typedef CMap_ CMap; + typedef typename CMap::Dart_handle Dart_handle; + typedef typename CMap::size_type size_type; + + Combinatorial_map_incremental_builder(CMap & acmap) : + cmap(acmap), + first_dart(cmap.null_handle), + prev_dart(cmap.null_handle), + used_add_vertex(false), + used_add_edge(false) + {} + + void begin_facet() + { + first_dart = cmap.null_handle; + prev_dart = cmap.null_handle; + // std::cout<<"Begin facet: "<::run(cmap, prev_dart); + + if ( prev_dart!=cmap.null_handle ) + { + Dart_handle opposite=find_dart_between(i, prev_vertex); + if ( opposite!=cmap.null_handle ) + { + CGAL_assertion( cmap.template is_free<2>(opposite) ); + cmap.template set_opposite<2>(prev_dart, opposite); + } + + add_dart_in_vertex_to_dart_map(prev_dart, prev_vertex, i); + } + else + { + first_dart = cur; + first_vertex = i; + } + + prev_dart = cur; + prev_vertex = i; + } + + // Add one edge to the current facet, given by its label (any string, using minus sign for orientation) + void add_edge_to_facet(const std::string& s) + { + if (used_add_vertex) + { + std::cerr<<"Combinatorial_map_incremental_builder ERROR: you cannot mix add_edge_to_facet" + <<" and add_vertex_to_facet for a same builder."<::run(cmap, prev_dart); + auto ite=edge_label_to_dart.find(opposite_label(s)); + + if (ite!=edge_label_to_dart.end()) + { + CGAL_assertion( cmap.template is_free<2>(ite->second) ); + cmap.template set_opposite<2>(cur, ite->second); + } + + edge_label_to_dart[s]=cur; + + if (prev_dart==cmap.null_handle) + { first_dart=cur; } + + prev_dart=cur; + } + + // add one facet, s is a sequence of labels, add all the corresponding edges into the current facet. + void add_facet(const std::string& s) + { + begin_facet(); + + std::istringstream iss(s); + for (std::string token; std::getline(iss, token, ' '); ) + { add_edge_to_facet(token); } + + end_facet(); + } + + // End of the facet. Return the first dart of this facet. + Dart_handle end_facet() + { + CGAL_assertion( first_dart!=cmap.null_handle && prev_dart!=cmap.null_handle ); + + if (used_add_vertex) + { + Add_vertex_to_face::run_for_last(cmap, prev_dart); + cmap.set_next(prev_dart, first_dart); + + Dart_handle opposite=find_dart_between(first_vertex, prev_vertex); + if ( opposite!=cmap.null_handle ) + { + CGAL_assertion( cmap.template is_free<2>(opposite) ); + cmap.template set_opposite<2>(prev_dart, opposite); + } + + add_dart_in_vertex_to_dart_map(prev_dart, prev_vertex, first_vertex); + } + else + { + cmap.set_next(prev_dart, first_dart); + } + + return first_dart; + } + + void begin_surface( std::size_t v, std::size_t /*f*/, std::size_t h) + { + new_vertices = 0; + first_dart = cmap.null_handle; + prev_dart = cmap.null_handle; + + vertex_to_dart_map.clear(); + vertex_to_dart_map.reserve(v); + + edge_label_to_dart.clear(); + edge_label_to_dart.reserve(h/2); + + used_add_vertex=false; + used_add_edge=false; + + // cmap.reserve(v,h); + } + + // End of the surface. Return one dart of the created surface. + Dart_handle end_surface() + { return first_dart; } + + protected: + + Dart_handle find_dart_between(size_type i, size_type j) + { + typename std::vector >::reverse_iterator + it(vertex_to_dart_map[i].rbegin()); + typename std::vector >::reverse_iterator + itend(vertex_to_dart_map[i].rend()); + + for ( ; it!=itend; ++it ) + { + if ( it->second==j ) return (it->first); + } + return cmap.null_handle; + } + + void add_dart_in_vertex_to_dart_map(Dart_handle adart, size_type i, size_type j) + { + CGAL_assertion( adart!=cmap.null_handle ); + vertex_to_dart_map[i].push_back(std::make_pair(adart, j)); + } + + std::string opposite_label(const std::string & s) + { + assert(!s.empty()); + if (s[0]=='-') + { return s.substr(1, std::string::npos); } + + return std::string("-")+s; + } + + private: + // For vertex number i, vector of all vertices linked to i with an edge (dart of the edge and index + // of the second vertex). TODO use a std::unordered_map instead of the second vector + typedef std::vector > > Vertex_to_dart_array; + Vertex_to_dart_array vertex_to_dart_map; + + // For edge label, its corresponding dart. For an edge a -a, stores its two darts in two different entries. + std::unordered_map edge_label_to_dart; + + CMap& cmap; + Dart_handle first_dart; + Dart_handle prev_dart; + size_type first_vertex; + size_type prev_vertex; + size_type new_vertices; + bool used_add_vertex; + bool used_add_edge; + }; + +} //namespace CGAL + +#endif // CGAL_COMBINATORIAL_MAP_INCREMENTAL_BUILDER_H // +// EOF //