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/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 8be384f8662..2e4a16f73d1 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -535,6 +535,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); } @@ -610,6 +631,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, @@ -1196,9 +1243,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; @@ -1216,7 +1267,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 { 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 8502b451ee2..4adf1e7915f 100644 --- a/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h +++ b/Combinatorial_map/include/CGAL/internal/Combinatorial_map_internal_functors.h @@ -55,6 +55,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. * @@ -212,6 +216,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; @@ -235,6 +243,11 @@ 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 @@ -246,14 +259,24 @@ struct Test_is_valid_attribute_functor std::cout<<"ERROR: an attribute of the "<(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<(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); @@ -460,6 +483,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 d1cba3c3678..56c07a73e8d 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex.h @@ -34,6 +34,822 @@ namespace CGAL { */ #if !defined(CGAL_NO_DEPRECATED_CODE) + /** Linear_cell_complex class. + * The Linear_cell_complex a nD object with linear geometry, ie + * an nD combinatorial map with point associated to each vertex. + */ + template < unsigned int d_, unsigned int ambient_dim, + class Traits_, + class Items_, + class Alloc_, + template + class CMap, + class Refs, + class Storage_> + class Linear_cell_complex_base: + public CMap + { + public: + typedef Linear_cell_complex_base Self; + typedef CMap Base; + + typedef Traits_ Traits; + typedef Items_ Items; + typedef Alloc_ Alloc; + typedef Storage_ Storage; + + static const unsigned int ambient_dimension = ambient_dim; + static const unsigned int dimension = Base::dimension; + + typedef typename Storage::Dart_handle Dart_handle; + typedef typename Storage::Dart_const_handle Dart_const_handle; + typedef typename Storage::Helper Helper; + + typedef typename Storage::Point Point; + typedef typename Storage::Vector Vector; + typedef typename Storage::FT FT; + + typedef typename Base::Dart_range Dart_range; + + /// Typedef for attributes + template + struct Attribute_type: public Base::template Attribute_type + {}; + template + struct Attribute_handle: public Base::template Attribute_handle + {}; + template + struct Attribute_const_handle: + public Base::template Attribute_const_handle + {}; + template + struct Attribute_range: public Base::template Attribute_range + {}; + template + struct Attribute_const_range: + public Base::template Attribute_const_range + {}; + + typedef typename Base::template Attribute_type<0>::type Vertex_attribute; + typedef typename Base::template Attribute_handle<0>::type + Vertex_attribute_handle; + typedef typename Base::template Attribute_const_handle<0>::type + Vertex_attribute_const_handle; + + typedef typename Base::template Attribute_range<0>::type + Vertex_attribute_range; + typedef typename Base::template Attribute_const_range<0>::type + Vertex_attribute_const_range; + + typedef typename Base::size_type size_type; + typedef typename Base::Use_index Use_index; + typedef typename Base::Exception_no_more_available_mark + Exception_no_more_available_mark; + + /// To use previous definition of create_dart methods. + using Base::create_dart; + using Base::beta; + using Base::is_free; + using Base::attribute; + using Base::null_handle; + using Base::point_of_vertex_attribute; + + using Base::are_attributes_automatically_managed; + using Base::mark; + using Base::unmark; + using Base::free_mark; + using Base::get_new_mark; + + Linear_cell_complex_base() : Base() + {} + + /** Copy the given linear cell complex into *this. + * Note that both LCC can have different dimensions and/or non void attributes. + * @param alcc the linear cell complex to copy. + * @post *this is valid. + */ + Linear_cell_complex_base(const Self & alcc) + { Base::template copy(alcc); } + + template < class LCC2 > + Linear_cell_complex_base(const LCC2& alcc) + { Base::template copy(alcc);} + + template < class LCC2, typename Converters > + Linear_cell_complex_base(const LCC2& alcc, Converters& converters) + { Base::template copy(alcc, converters);} + + template < class LCC2, typename Converters, typename Pointconverter > + Linear_cell_complex_base(const LCC2& alcc, Converters& converters, + const Pointconverter& pointconverter) + { Base::template copy + (alcc, converters, pointconverter);} + + /** Create a vertex attribute. + * @return an handle on the new attribute. + */ +#ifndef CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + template + Vertex_attribute_handle create_vertex_attribute(const Args&... args) + { return Base::template create_attribute<0>(args...); } +#else + Vertex_attribute_handle create_vertex_attribute() + { return Base::template create_attribute<0>(); } + + template + Vertex_attribute_handle create_vertex_attribute(const T1& t1) + { return Base::template create_attribute<0>(t1); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2) + { return Base::template create_attribute<0>(t1, t2); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3) + { return Base::template create_attribute<0>(t1, t2, t3); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4) + { return Base::template create_attribute<0>(t1, t2, t3, t4); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5) + { return Base::template create_attribute<0>(t1, t2, t3, t4, t5); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6) + { return Base::template create_attribute<0>(t1, t2, t3, t4, t5, t6); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6, const T7 &t7) + { return Base::template create_attribute<0>(t1, t2, t3, t4, t5, t6, t7); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8) + { return Base::template create_attribute<0>(t1, t2, t3, t4, t5, t6, t7, + t8); } + + template + Vertex_attribute_handle create_vertex_attribute + (const T1& t1, const T2 &t2, const T3 &t3, const T4 &t4, + const T5 &t5, const T6 &t6, const T7 &t7, const T8 &t8, const T9 &t9) + { return Base::template create_attribute<0>(t1, t2, t3, t4, t5, t6, t7, + t8, t9); } +#endif // CGAL_CFG_NO_CPP0X_VARIADIC_TEMPLATES + + /** + * Create a new dart associated with an handle through an attribute. + * @param ahandle the point handle to associated with the dart. + * @return a Dart_handle on the new dart. + */ + Dart_handle create_dart(Vertex_attribute_handle ahandle) + { + Dart_handle res = create_dart(); + set_vertex_attribute_of_dart(res,ahandle); + return res; + } + + /** Create a new dart associated with a point. + * @param apoint the point to associated with the dart. + * @return a Dart_handle on the new dart. + */ + Dart_handle create_dart(const Point& apoint) + { return create_dart(create_vertex_attribute(apoint)); } + + /** Erase a given vertex attribute. + * @param ahandle the handle to the vertex attribute to erase. + */ + void erase_vertex_attribute(Vertex_attribute_handle ahandle) + { Base::template erase_attribute<0>(ahandle); } + + /** Set the vertex attribute of the given dart. + * @param adart a dart. + * @param ah the attribute to set. + */ + void set_vertex_attribute_of_dart(Dart_handle adart, + Vertex_attribute_handle ah) + { + return CGAL::internal::Set_i_attribute_of_dart_functor:: + run(this, adart,ah); + } + + /** Set the vertex attribute of all the darts of the vertex. + * @param adart a dart of the vertex. + * @param ah the attribute to set. + */ + void set_vertex_attribute(Dart_handle adart, + Vertex_attribute_handle ah) + { return CGAL::Set_i_attribute_functor::run(this, adart,ah); } + + /// @return the Vertex_attribute_range for all vertex_attributes. + Vertex_attribute_range& vertex_attributes() + { return this->template attributes<0>(); } + + /// @return the Vertex_attribute_const_range for all vertex_attributes. + Vertex_attribute_const_range& vertex_attributes() const + { return this->template attributes<0>(); } + + /// @return the size of the vertex_attribute container. + typename Base::size_type number_of_vertex_attributes() const + { return Base::template number_of_attributes<0>(); } + +#ifdef CGAL_CMAP_DEPRECATED + static Vertex_attribute_handle vertex_attribute(Dart_handle adart) + { + CGAL_assertion(adart!=NULL); + return adart->template attribute<0>(); + } + static Vertex_attribute_const_handle vertex_attribute(Dart_const_handle + adart) + { + CGAL_assertion(adart!=NULL); + return adart->template attribute<0>(); + } + static Point& point(Dart_handle adart) + { + CGAL_assertion(adart!=NULL && adart->template attribute<0>()!=NULL ); + return adart->template attribute<0>()->point(); + } + static const Point& point(Dart_const_handle adart) + { + CGAL_assertion(adart!=NULL && adart->template attribute<0>()!=NULL ); + return adart->template attribute<0>()->point(); + } +#else + /// Get the vertex_attribute associated with a dart. + /// @param a dart + /// @return the vertex_attribute. + Vertex_attribute_handle vertex_attribute(Dart_handle adart) + { return this->template attribute<0>(adart); } + + /// Get the vertex_attribute associated with a const dart. + /// @param a dart + /// @return the vertex_const_attribute. + Vertex_attribute_const_handle + vertex_attribute(Dart_const_handle adart) const + { return this->template attribute<0>(adart); } + + /// Get the point associated with a dart. + /// @param a dart + /// @return the point. + Point& point(Dart_handle adart) + { + CGAL_assertion(this->template attribute<0>(adart)!=null_handle ); + return point_of_vertex_attribute(this->template attribute<0>(adart)); + } + + /// Get the point associated with a const dart. + /// @param a dart + /// @return the point. + const Point& point(Dart_const_handle adart) const + { + CGAL_assertion(this->template attribute<0>(adart)!=null_handle ); + return point_of_vertex_attribute(this->template attribute<0>(adart)); + } +#endif // CGAL_CMAP_DEPRECATED + + // Temporary methods to allow to write lcc->temp_vertex_attribute + // even with the old method. Depending if CGAL_CMAP_DEPRECATED is defined or not + // call the static method or the new method. To remove when we remove the + // old code. + Vertex_attribute_handle temp_vertex_attribute(Dart_handle adart) + {return vertex_attribute(adart); } + Vertex_attribute_const_handle + temp_vertex_attribute(Dart_const_handle adart) const + {return vertex_attribute(adart); } + + /** 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(bool reverseextremity=false) const + { + bool valid = Base::is_valid(reverseextremity); + for (typename Dart_range::const_iterator it(this->darts().begin()), + itend(this->darts().end()); valid && it != itend; ++it) + { + if ( vertex_attribute(it)==null_handle ) + { + std::cerr << "Map not valid: dart "<<&(*it) + <<" does not have a vertex."<< std::endl; + valid = false; + } + } + return valid; + } + + /** validate the lcc + */ + void correct_invalid_attributes() + { + // Copy of the code in CMap::correct_invalid_attributes() to avoid + // 2 iterations through the darts of the map. + + std::vector marks(dimension+1); + for ( unsigned int i=0; i<=dimension; ++i) + marks[i] = Base::INVALID_MARK; + + Helper::template + Foreach_enabled_attributes >:: + run(this,&marks); + + for ( typename Dart_range::iterator it(this->darts().begin()), + itend(this->darts().end()); it!=itend; ++it) + { + Helper::template Foreach_enabled_attributes + >:: + run(this,it,&marks); + + if ( vertex_attribute(it)==null_handle ) + { + // If a dart don't have a 0-attribute, we create a Point at the origin + set_vertex_attribute(it, create_vertex_attribute(CGAL::ORIGIN)); + } + } + + for ( unsigned int i=0; i<=dimension; ++i) + if ( marks[i]!=Base::INVALID_MARK ) + { + CGAL_assertion( this->is_whole_map_marked(marks[i]) ); + free_mark(marks[i]); + } + } + + /** test if the two given facets have the same geometry + * @return true iff the two facets have the same geometry. + */ + bool are_facets_same_geometry(Dart_const_handle d1, + Dart_const_handle d2) const + { + typename Base::template Dart_of_orbit_range<1>::const_iterator + it1(*this,d1); + typename Base::template Dart_of_orbit_range<0>::const_iterator + it2(*this,d2); + bool samegeometry = true; + for ( ; samegeometry && it1.cont() && it2.cont(); ++it1, ++it2) + { + if ( this->other_extremity(it2)!=null_handle && + point(it1)!=point(this->other_extremity(it2)) ) + samegeometry = false; + } + if ( it1.cont() != it2.cont() ) samegeometry = false; + return samegeometry; + } + + /// Sew3 the marked facets having same geometry + /// (a facet is considered marked if one of its dart is marked). + unsigned int sew3_same_facets(size_type AMark) + { + unsigned int res = 0; + + std::map > one_dart_per_facet; + size_type mymark = get_new_mark(); + + // First we fill the std::map by one dart per facet, and by using + // the minimal point as index. + for (typename Dart_range::iterator it(this->darts().begin()), + itend(this->darts().end()); it!=itend; ++it ) + { + if ( !this->is_marked(it, mymark) && this->is_marked(it, AMark) ) + { + Point min_point=point(it); + Dart_handle min_dart = it; + this->mark(it, mymark); + typename Base::template + Dart_of_orbit_range<1>::iterator it2(*this,it); + ++it2; + for ( ; it2.cont(); ++it2 ) + { + Point cur_point=point(it2); + this->mark(it2, mymark); + if ( cur_point < min_point ) + { + min_point = cur_point; + min_dart = it2; + } + } + one_dart_per_facet[min_point].push_back(min_dart); + } + else + this->mark(it, mymark); + } + + // Second we run through the map: candidates for sew3 have necessary the + // same minimal point. + typename std::map >::iterator + itmap=one_dart_per_facet.begin(), + itmapend=one_dart_per_facet.end(); + + for ( ; itmap!=itmapend; ++itmap ) + { + for ( typename std::vector::iterator + it1=(itmap->second).begin(), + it1end=(itmap->second).end(); it1!=it1end; ++it1 ) + { + typename std::vector::iterator it2=it1; + for ( ++it2; it2!= it1end; ++it2 ) + { + if ( *it1!=*it2 && is_free(*it1, 3) && + is_free(*it2, 3) && + are_facets_same_geometry(*it1,beta(*it2, 0)) ) + { + ++res; + this->template sew<3>(*it1,beta(*it2, 0)); + } + } + } + } + + CGAL_assertion( this->is_whole_map_marked(mymark) ); + this->free_mark(mymark); + return res; + } + + /// Sew3 the facets having same geometry + /// (all the facets of the map are considered) + unsigned int sew3_same_facets() + { + size_type mark = this->get_new_mark(); + this->negate_mark(mark); + unsigned int res=sew3_same_facets(mark); + this->free_mark(mark); + return res; + } + + /** Create an edge given 2 Vertex_attribute_handle. + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @return the dart of the new edge incident to h0. + */ + Dart_handle make_segment(Vertex_attribute_handle h0, + Vertex_attribute_handle h1) + { + Dart_handle d1 = make_edge(*this); + set_vertex_attribute_of_dart(d1,h0); + set_vertex_attribute_of_dart(beta(d1, 2),h1); + + return d1; + } + + /** Create a segment given 2 points. + * @param p0 the first point. + * @param p1 the second point. + * @return the dart of the new segment incident to p0. + */ + Dart_handle make_segment(const Point& p0,const Point& p1) + { + return make_segment(create_vertex_attribute(p0), + create_vertex_attribute(p1)); + } + + /** Create a triangle given 3 Vertex_attribute_handle. + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @return the dart of the new triangle incident to h0. + */ + Dart_handle make_triangle(Vertex_attribute_handle h0, + Vertex_attribute_handle h1, + Vertex_attribute_handle h2) + { + Dart_handle d1 = make_combinatorial_polygon(*this,3); + + set_vertex_attribute_of_dart(d1,h0); + set_vertex_attribute_of_dart(beta(d1, 1),h1); + set_vertex_attribute_of_dart(beta(d1, 0),h2); + + return d1; + } + + /** Create a triangle given 3 points. + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @return the dart of the new triangle incident to p0. + */ + Dart_handle make_triangle(const Point& p0, + const Point& p1, + const Point& p2) + { + return make_triangle(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2)); + } + + /** Create a quadrangle given 4 Vertex_attribute_handle. + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @return the dart of the new quadrilateral incident to h0. + */ + Dart_handle make_quadrangle(Vertex_attribute_handle h0, + Vertex_attribute_handle h1, + Vertex_attribute_handle h2, + Vertex_attribute_handle h3) + { + Dart_handle d1 = make_combinatorial_polygon(*this,4); + + set_vertex_attribute_of_dart(d1,h0); + set_vertex_attribute_of_dart(beta(d1, 1),h1); + set_vertex_attribute_of_dart(beta(d1, 1, 1),h2); + set_vertex_attribute_of_dart(beta(d1, 0),h3); + + return d1; + } + + /** Create a quadrangle given 4 points. + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @return the dart of the new quadrangle incident to p0. + */ + Dart_handle make_quadrangle(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3) + { + return make_quadrangle(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3)); + } + + + /** Create a tetrahedron given 4 Vertex_attribute_handle. + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @return the dart of the new tetrahedron incident to h0 and to + * facet h0,h1,h2. + */ + Dart_handle make_tetrahedron(Vertex_attribute_handle h0, + Vertex_attribute_handle h1, + Vertex_attribute_handle h2, + Vertex_attribute_handle h3) + { + Dart_handle d1 = make_triangle(h0, h1, h2); + Dart_handle d2 = make_triangle(h1, h0, h3); + Dart_handle d3 = make_triangle(h1, h3, h2); + Dart_handle d4 = make_triangle(h3, h0, h2); + + return make_combinatorial_tetrahedron(*this, d1, d2, d3, d4); + } + + /** Create a tetrahedron given 4 points. + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @return the dart of the new tetrahedron incident to p0 and to + * facet p0,p1,p2. + */ + Dart_handle make_tetrahedron(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3) + { + return make_tetrahedron(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3)); + } + + /** Create an hexahedron given 8 Vertex_attribute_handle. + * (8 vertices, 12 edges and 6 facets) + * \verbatim + * 4----7 + * /| /| + * 5----6 | + * | 3--|-2 + * |/ |/ + * 0----1 + * \endverbatim + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @param h4 the fifth vertex handle. + * @param h5 the sixth vertex handle. + * @param h6 the seventh vertex handle. + * @param h7 the height vertex handle. + * @return the dart of the new hexahedron incident to h0 and to + * the facet (h0,h5,h6,h1). + */ + Dart_handle make_hexahedron(Vertex_attribute_handle h0, + Vertex_attribute_handle h1, + Vertex_attribute_handle h2, + Vertex_attribute_handle h3, + Vertex_attribute_handle h4, + Vertex_attribute_handle h5, + Vertex_attribute_handle h6, + Vertex_attribute_handle h7) + { + Dart_handle d1 = make_quadrangle(h0, h5, h6, h1); + Dart_handle d2 = make_quadrangle(h1, h6, h7, h2); + Dart_handle d3 = make_quadrangle(h2, h7, h4, h3); + Dart_handle d4 = make_quadrangle(h3, h4, h5, h0); + Dart_handle d5 = make_quadrangle(h0, h1, h2, h3); + Dart_handle d6 = make_quadrangle(h5, h4, h7, h6); + + return make_combinatorial_hexahedron(*this, d1, d2, d3, d4, d5, d6); + } + + /** Create an hexahedron given 8 points. + * \verbatim + * 4----7 + * /| /| + * 5----6 | + * | 3--|-2 + * |/ |/ + * 0----1 + * \endverbatim + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @param p4 the fifth point. + * @param p5 the sixth point. + * @param p6 the seventh point. + * @param p7 the height point. + * @return the dart of the new hexahedron incident to p0 + * and to the facet (p0,p5,p6,p1). + */ + Dart_handle make_hexahedron(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4, + const Point& p5, + const Point& p6, + const Point& p7) + { + return make_hexahedron(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3), + create_vertex_attribute(p4), + create_vertex_attribute(p5), + create_vertex_attribute(p6), + create_vertex_attribute(p7)); + } + + /** Compute the barycenter of a given cell. + * @param adart a dart incident to the cell. + * @param adim the dimension of the cell. + * @return the barycenter of the cell. + */ + template + Point barycenter(Dart_const_handle adart) const + { + return CGAL::Barycenter_functor::run(*this, adart); + } + + /** Insert a point in a given 1-cell. + * @param dh a dart handle to the 1-cell + * @param p the point to insert + * @param update_attributes a boolean to update the enabled attributes + * @return a dart handle to the new vertex containing p. + */ + Dart_handle insert_point_in_cell_1(Dart_handle dh, const Point& p, bool update_attributes) + { + return CGAL::insert_cell_0_in_cell_1(*this, dh, + create_vertex_attribute(p), + update_attributes); + } + + /** Insert a point in a given 2-cell. + * @param dh a dart handle to the 2-cell + * @param p the point to insert + * @param update_attributes a boolean to update the enabled attributes + * @return a dart handle to the new vertex containing p. + */ + Dart_handle insert_point_in_cell_2(Dart_handle dh, const Point& p, bool update_attributes) + { + Vertex_attribute_handle v = create_vertex_attribute(p); + + Dart_handle first = CGAL::insert_cell_0_in_cell_2(*this, dh, v, update_attributes); + + if ( first==null_handle ) // If the triangulated facet was made of one dart + erase_vertex_attribute(v); + +#ifdef CGAL_CMAP_TEST_VALID_INSERTIONS + CGAL_assertion( is_valid() ); +#endif + + return first; + } + + /** Insert a point in a given i-cell. + * @param dh a dart handle to the i-cell + * @param p the point to insert + * @param update_attributes a boolean to update the enabled attributes + * @return a dart handle to the new vertex containing p. + */ + template + Dart_handle insert_point_in_cell(Dart_handle dh, const Point& p, bool update_attributes = true) + { + CGAL_static_assertion(1<=i && i<=2); + if (i==1) return insert_point_in_cell_1(dh, p, update_attributes); + return insert_point_in_cell_2(dh, p, update_attributes); + } + + /** Insert a dangling edge in a given facet. + * @param dh a dart of the facet (!=NULL). + * @param p the coordinates of the new vertex. + * @param update_attributes a boolean to update the enabled attributes + * @return a dart of the new edge, incident to the new vertex. + */ + Dart_handle insert_dangling_cell_1_in_cell_2(Dart_handle dh, + const Point& p, + bool update_attributes = true) + { + return CGAL::insert_dangling_cell_1_in_cell_2 + (*this, dh, create_vertex_attribute(p), update_attributes); + } + + /** Insert a point in a given i-cell. + * @param dh a dart handle to the i-cell + * @param p the point to insert + * @param update_attributes a boolean to update the enabled attributes + * @return a dart handle to the new vertex containing p. + */ + template + Dart_handle insert_barycenter_in_cell(Dart_handle dh, bool update_attributes = true) + { return insert_point_in_cell(dh, barycenter(dh), update_attributes); } + + /** Compute the dual of a Linear_cell_complex. + * @param alcc the lcc in which we build the dual of this lcc. + * @param adart a dart of the initial lcc, NULL by default. + * @return adart of the dual lcc, the dual of adart if adart!=NULL, + * any dart otherwise. + * As soon as we don't modify this lcc and alcc lcc, we can iterate + * simultaneously through all the darts of the two lcc and we have + * each time of the iteration two "dual" darts. + */ + Dart_handle dual_points_at_barycenter(Self & alcc, Dart_handle adart=null_handle) + { + Dart_handle res = Base::dual(alcc, adart); + + // Now the lcc alcc is topologically correct, we just need to add + // its geometry to each vertex (the barycenter of the corresponding + // dim-cell in the initial map). + typename Dart_range::iterator it2 = alcc.darts().begin(); + for (typename Dart_range::iterator it(this->darts().begin()); + it!=this->darts().end(); ++it, ++it2) + { + if (vertex_attribute(it2)==null_handle) + { + alcc.set_vertex_attribute(it2, alcc.create_vertex_attribute + (barycenter(it))); + } + } + + return res; + } + + /** Set the status of the managment of the attributes of the CMap + */ + void set_update_attributes(bool newval) + { + if (this->automatic_attributes_management == false && newval == true) + { + // We need to recode this function because correct_invalid_attributes + // is not a virtual function. + correct_invalid_attributes(); + } + + this->automatic_attributes_management = newval; + } + }; + + // Linear_cell_complex using compact container with handle. + // No difference with class Linear_cell_complex_base except the default + // template parameters for Refs class. template < unsigned int d_, unsigned int ambient_dim = d_, class Traits_ = Linear_cell_complex_traits, #if defined(CGAL_CMAP_DART_DEPRECATED) 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;