diff --git a/BGL/include/CGAL/boost/graph/graph_traits_Linear_cell_complex.h b/BGL/include/CGAL/boost/graph/graph_traits_Linear_cell_complex.h index 388c8424613..854e24b73c6 100644 --- a/BGL/include/CGAL/boost/graph/graph_traits_Linear_cell_complex.h +++ b/BGL/include/CGAL/boost/graph/graph_traits_Linear_cell_complex.h @@ -203,9 +203,9 @@ typename boost::graph_traits::vertex_descriptor source(typename boost::graph_traits::edge_descriptor e, const CGAL_LCC_TYPE& amap) { - return e->template attribute<0>(); - /* return const_cast(amap).template beta<2>(e)-> - template attribute<0>(); */ + // return e->template attribute<0>(); + return const_cast(amap).template beta<2>(e)-> + template attribute<0>(); } CGAL_LCC_TEMPLATE_ARGS @@ -213,9 +213,9 @@ typename boost::graph_traits::vertex_descriptor target(typename boost::graph_traits::edge_descriptor e, const CGAL_LCC_TYPE& amap) { - // return e->template attribute<0>(); - return const_cast(amap).template beta<2>(e)-> - template attribute<0>(); + return e->template attribute<0>(); + /*return const_cast(amap).template beta<2>(e)-> + template attribute<0>();*/ } CGAL_LCC_TEMPLATE_ARGS @@ -271,8 +271,8 @@ degree(typename boost::graph_traits::vertex_descriptor v, typename boost::graph_traits::degree_size_type degree=0; for (typename CGAL_LCC_TYPE::template Dart_of_cell_range<0>::const_iterator - it=cm.template darts_of_cell<0>(halfedge(v, cm)).begin(), - itend=cm.template darts_of_cell<0>(halfedge(v, cm)).end(); + it=cm.template darts_of_cell<0>(const_cast(cm).template beta<2>(v->dart())).begin(), + itend=cm.template darts_of_cell<0>(const_cast(cm).template beta<2>(v->dart())).end(); it!=itend; ++it) { ++degree; @@ -361,8 +361,8 @@ void remove_edge(typename boost::graph_traits::vertex_descriptor if ( e.second ) { assert ( !cm.template is_free<2>(e.first.first_halfedge()) ); - cm.erase_dart(cm.template beta<2>(e.first.first_halfedge())); - cm.erase_dart(e.first.first_halfedge()); + cm.restricted_erase_dart(cm.template beta<2>(e.first.first_halfedge())); + cm.restricted_erase_dart(e.first.first_halfedge()); } } @@ -372,8 +372,8 @@ remove_edge(typename boost::graph_traits::edge_descriptor e, CGAL_LCC_TYPE& cm) { assert ( !cm.template is_free<2>(e.first_halfedge()) ); - cm.erase_dart(cm.template beta<2>(e.first_halfedge())); - cm.erase_dart(e); + cm.restricted_erase_dart(cm.template beta<2>(e.first_halfedge())); + cm.restricted_erase_dart(e); } CGAL_LCC_TEMPLATE_ARGS @@ -396,7 +396,7 @@ void remove_vertex(typename boost::graph_traits::vertex_descriptor v, CGAL_LCC_TYPE& cm) { - // cm.template erase_attribute<0>(v); + cm.template erase_attribute<0>(v); // Useled because in CMap, attributes are automatically deleted thanks // to ref counting } @@ -433,11 +433,13 @@ halfedge(typename boost::graph_traits::vertex_descriptor u, const CGAL_LCC_TYPE& g) { for (typename CGAL_LCC_TYPE::template Dart_of_cell_range<0>::iterator - it=const_cast(g).template darts_of_cell<0>(u->dart()).begin(), - itend=const_cast(g).template darts_of_cell<0>(u->dart()).end(); + it=const_cast(g).template + darts_of_cell<0>(const_cast(g).template beta<2>(u->dart())).begin(), + itend=const_cast(g).template + darts_of_cell<0>(const_cast(g).template beta<2>(u->dart())).end(); it!=itend; ++it) { - if (g.template beta<2>(it)->template attribute<0>()==v) + if (it->template attribute<0>()==v) { return std::make_pair(it, true); // return std::make_pair(const_cast(g).template beta<2>(it), true); @@ -495,8 +497,11 @@ add_face(InputIterator begin, InputIterator end, CGAL_LCC_TYPE& cm) CGAL_LCC_TEMPLATE_ARGS bool is_valid(const CGAL_LCC_TYPE& cm, bool = false) -{ return cm.is_valid(); } - +{ + // cm.display_darts(std::cout,true); + return cm.is_valid(true); // true to inverse the convention between darts and 0-attributes +} + CGAL_LCC_TEMPLATE_ARGS Iterator_range::halfedge_iterator> halfedges(const CGAL_LCC_TYPE& cm) @@ -525,7 +530,8 @@ void set_target(typename boost::graph_traits::halfedge_descriptor typename boost::graph_traits::vertex_descriptor v, CGAL_LCC_TYPE& cm) { - cm.template set_dart_attribute<0>(cm.template beta<2>(h1), v); + // cm.template set_dart_attribute<0>(cm.template beta<2>(h1), v); + cm.template restricted_set_dart_attribute<0>(h1, v); // cm.template set_dart_attribute<0>(h1, v); } @@ -540,8 +546,8 @@ void set_halfedge(typename boost::graph_traits::vertex_descriptor typename boost::graph_traits::halfedge_descriptor h, CGAL_LCC_TYPE& cm) { - v->set_dart(cm.template beta<2>(h)); - // v->set_dart(h); + // v->set_dart(cm.template beta<2>(h)); + v->set_dart(h); } CGAL_LCC_TEMPLATE_ARGS @@ -553,7 +559,7 @@ CGAL_LCC_TEMPLATE_ARGS void remove_face(typename boost::graph_traits::face_descriptor f, CGAL_LCC_TYPE& cm) { - // cm.template erase_attribute<2>(f); + cm.template erase_attribute<2>(f); // Useled because in CMap, attributes are automatically deleted thanks // to ref counting } @@ -562,7 +568,10 @@ CGAL_LCC_TEMPLATE_ARGS void set_face(typename boost::graph_traits::halfedge_descriptor h, typename boost::graph_traits::face_descriptor f, CGAL_LCC_TYPE& cm) -{ cm.template set_dart_attribute<2>(h, f); } +{ + cm.template restricted_set_dart_attribute<2>(h, f); + // cm.template set_dart_attribute<2>(h, f); +} CGAL_LCC_TEMPLATE_ARGS void set_halfedge(typename boost::graph_traits::face_descriptor f, diff --git a/Combinatorial_map/include/CGAL/Cell_attribute.h b/Combinatorial_map/include/CGAL/Cell_attribute.h index 245e9a07d09..17ee349e1f2 100644 --- a/Combinatorial_map/include/CGAL/Cell_attribute.h +++ b/Combinatorial_map/include/CGAL/Cell_attribute.h @@ -85,6 +85,9 @@ namespace CGAL { template friend struct internal::Decrease_attribute_functor_run; + template + friend struct internal::Restricted_decrease_attribute_functor_run; + template friend struct internal::Reverse_orientation_of_map_functor; @@ -197,6 +200,9 @@ namespace CGAL { template friend struct internal::Decrease_attribute_functor_run; + template + friend struct internal::Restricted_decrease_attribute_functor_run; + template friend struct internal::Reverse_orientation_of_map_functor; diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 2c428d342af..121ea6d35e9 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -490,6 +490,27 @@ namespace CGAL { mdarts.erase(adart); } + /** Erase a dart from the list of darts. Restricted version + * which do not delete attribute having no more dart associated. + * @param adart the dart to erase. + */ + void restricted_erase_dart(Dart_handle adart) + { + // 1) We update the number of marked darts. + for ( size_type i = 0; i < mnb_used_marks; ++i) + { + if (is_marked(adart, mused_marks_stack[i])) + --mnb_marked_darts[mused_marks_stack[i]]; + } + + // 2) We update the attribute_ref_counting. + Helper::template Foreach_enabled_attributes + >::run(this,adart); + + // 3) We erase the dart. + mdarts.erase(adart); + } + /// @return true if dh points to a used dart (i.e. valid). bool is_dart_used(Dart_const_handle dh) const { return mdarts.is_used(dh); } @@ -565,6 +586,32 @@ namespace CGAL { return null_handle; } + // Set the handle on the i th attribute + // Restricted version which do not use delete attributes when their ref + // counting become null, nor that update the dart of attribute. + template + void restricted_set_dart_attribute(Dart_handle dh, + typename Attribute_handle::type ah) + { + CGAL_static_assertion_msg(Helper::template Dimension_index::value>=0, + "set_dart_attribute called but i-attributes are disabled."); + + if ( this->template attribute(dh)==ah ) return; + + if ( this->template attribute(dh)!=null_handle ) + { + this->template get_attribute(this->template attribute(dh)). + dec_nb_refs(); + } + + Base::template basic_set_dart_attribute(dh, ah); + + if ( ah!=null_handle ) + { + this->template get_attribute(ah).inc_nb_refs(); + } + } + // Set the handle on the i th attribute template void set_dart_attribute(Dart_handle dh, @@ -1093,9 +1140,13 @@ namespace CGAL { } /** Test if the map is valid. + * @param reverseextremity to inverse the convention between source and + * target of a dart. With false (default), a dart is associated with + * a 0-attribute for its source (origin); + * with true this is for its target (as in hds or surface mesh). * @return true iff the map is valid. */ - bool is_valid() const + bool is_valid(bool reverseextremity=false) const { bool valid = true; unsigned int i = 0, j = 0; @@ -1113,7 +1164,10 @@ namespace CGAL { if ( !valid ) { // We continue the traversal to mark all the darts. for ( i=0; i<=dimension; ++i) - if (marks[i]!=INVALID_MARK) mark(it,marks[i]); + if (marks[i]!=INVALID_MARK) + { + mark(it,marks[i]); + } } else { @@ -1182,7 +1236,7 @@ namespace CGAL { } Helper::template Foreach_enabled_attributes >:: - run(this,it,&marks,&valid); + run(this,it,&marks,&valid, reverseextremity); } } for ( i=0; i<=dimension; ++i) @@ -1247,7 +1301,7 @@ namespace CGAL { for ( unsigned int i=0; i<=dimension; ++i) { os << &(*it->beta(i)) << ",\t"; - if (it->is_free(i)) os << "\t"; + if (is_free(it, i)) os << "\t"; } if ( attribs ) { diff --git a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h index a399f0e75d6..6b18569529f 100644 --- a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h @@ -52,6 +52,10 @@ * internal::Decrease_attribute_functor to decrease by one the ref * counting of a given i-attribute. * + * internal::Restricted_decrease_attribute_functor to decrease by one the + * ref counting of a given i-attribute, but without deleting attribute + * having nomore dart associated with. + * * internal::Beta_functor to call several beta on the given dart. * Indices are given as parameter of the run function. * @@ -184,6 +188,10 @@ struct Test_is_valid_attribute_functor * ie all the darts belonging to a i-cell are linked to the same attribute. * @param adart a dart. * @param amark a mark used to mark darts of the i-cell. + * @param reverseextremity to inverse the convention between source and + * target of a dart. With false (default), a dart is associated with + * a 0-attribute for its source (origin); + * with true this is for its target (as in hds or surface mesh). * @return true iff all the darts of the i-cell link to the same attribute. */ typedef typename CMap::size_type size_type; @@ -191,7 +199,8 @@ struct Test_is_valid_attribute_functor template static void run(const CMap* amap, typename CMap::Dart_const_handle adart, - std::vector* marks, bool *ares) + std::vector* marks, bool *ares, + bool reverseextremity=false) { CGAL_static_assertion_msg(CMap::Helper::template Dimension_index::value>=0, @@ -207,25 +216,42 @@ struct Test_is_valid_attribute_functor typename CMap::template Attribute_const_handle::type a=amap->template attribute(adart); + if (i==0 && reverseextremity) + { + a=amap->template attribute(amap->template beta<2>(adart)); + } + unsigned int nb = 0; for ( typename CMap::template Dart_of_cell_basic_const_range::const_iterator it=amap->template darts_of_cell_basic(adart, amark).begin(); it.cont(); ++it ) { - if ( amap->template attribute(it) != a ) + if ( (i==0 && reverseextremity && + amap->template attribute(amap->template beta<2>(it))!= a) || + ((i>0 || !reverseextremity) && amap->template attribute(it) != a) ) { std::cout<<"ERROR: an attribute of the "<template display_attribute(a); std::cout<<" != first:"; - amap->template display_attribute(amap->template attribute(it)); + if (i==0 && reverseextremity) + amap->template display_attribute(amap->template attribute(amap->template beta<2>(it))); + else + amap->template display_attribute(amap->template attribute(it)); std::cout<<" for dart "; - amap->display_dart(it); + + if (i==0 && reverseextremity) + amap->display_dart(amap->template beta<2>(it)); + else + amap->display_dart(it); + std::cout<null_handle && it==amap->template dart_of_attribute(a) ) + if ( a!=amap->null_handle ) + if ( (i==0 && reverseextremity && amap->template beta<2>(it)==amap->template dart_of_attribute(a) ) || + ((i>0 || !reverseextremity) && it==amap->template dart_of_attribute(a) ) ) found_dart=true; amap->mark(it, amark); @@ -414,6 +440,38 @@ struct Decrease_attribute_functor { CGAL::internal::Decrease_attribute_functor_run::run(amap, adart); } }; // **************************************************************************** +template::type> +struct Restricted_decrease_attribute_functor_run +{ + static void run(CMap* amap, typename CMap::Dart_handle adart) + { + if ( amap->template attribute(adart)!=CMap::null_handle ) + { + amap->template get_attribute(amap->template attribute(adart)). + dec_nb_refs(); + } + } +}; +/// Specialization for void attributes. +template +struct Restricted_decrease_attribute_functor_run +{ + static void run(CMap*, typename CMap::Dart_handle) + {} +}; +// **************************************************************************** +/// Functor used to call restricted_decrease_attribute_ref_counting +/// on each i-cell attribute enabled +template +struct Restricted_decrease_attribute_functor +{ + template + static void run(CMap* amap, typename CMap::Dart_handle adart) + { CGAL::internal::Restricted_decrease_attribute_functor_run:: + run(amap, adart); } +}; +// **************************************************************************** /// Functor used to initialize all attributes to NULL. template struct Init_attribute_functor diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex.h index 01ad03d704f..d0d4c7ab25c 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex.h @@ -338,11 +338,15 @@ namespace CGAL { /** Test if the lcc is valid. * A Linear_cell_complex is valid if it is a valid Combinatorial_map with * an attribute associated to each dart. + * @param reverseextremity to inverse the convention between source and + * target of a dart. With false (default), a dart is associated with + * a 0-attribute for its source (origin); + * with true this is for its target (as in hds or surface mesh). * @return true iff the map is valid. */ - bool is_valid() const + bool is_valid(bool reverseextremity=false) const { - bool valid = Base::is_valid(); + bool valid = Base::is_valid(reverseextremity); for (typename Dart_range::const_iterator it(this->darts().begin()), itend(this->darts().end()); valid && it != itend; ++it) { diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_v2.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_v2.h index f2b07afef1d..7d1f1457d9a 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_v2.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_incremental_builder_v2.h @@ -74,8 +74,8 @@ namespace CGAL { if (cur==lcc.null_handle) { - cur = lcc.create_dart(vertex_map[prev_vertex]); - Dart_handle opposite=lcc.create_dart(vertex_map[i]); + cur = lcc.create_dart(vertex_map[i]); + Dart_handle opposite=lcc.create_dart(vertex_map[prev_vertex]); lcc.template basic_link_beta_for_involution<2>(cur, opposite); add_dart_in_vertex_to_dart_map( opposite, i ); } @@ -126,7 +126,6 @@ namespace CGAL { // End of the surface. Return one dart of the created surface. Dart_handle end_surface() { - std::cout<<"******************";lcc.display_characteristics(std::cout)<(lcc.template beta<2>(other))!=NULL); assert(lcc.template is_free<0>(lcc.template beta<2>(other))); lcc.basic_link_beta_1(it, lcc.template beta<2>(other)); + + // For BGL halfedge graph, darts of border vertices must be border darts. + lcc.template set_dart_of_attribute<0>(lcc.vertex_attribute(it), it); ++nb; } } - std::cout<<"****************** nb sew="<(*it))==vh ) + if ( lcc.temp_vertex_attribute(*it)==vh ) return (*it); } return lcc.null_handle;