diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 30da142e923..0742133b735 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -56,10 +56,11 @@ public: { push_back(it->begin, false); if (it->length>0) - { extend_straight_positive(it->length-1, false); } + { extend_straight_positive(it->length, false); } else if (it->length<0) - { extend_straight_negative(-(it->length)-1, false); } + { extend_straight_negative(-(it->length), false); } } + CGAL_assertion(is_valid()); } void swap(Self& p2) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Path_on_surface_with_rle.h index ac2a3432bd2..5aa0efd7253 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface_with_rle.h @@ -39,12 +39,13 @@ class Path_on_surface; // In this version, each flat (even those with length 0) have begin and end darts template -struct CFlat +class CFlat { typedef Map_ Map; typedef typename Map::Dart_const_handle Dart_const_handle; typedef CFlat Self; +public: CFlat(Dart_const_handle dh) : begin(dh), end(dh), length(0) {} @@ -315,6 +316,21 @@ public: m_length=0; } + /// @return true if the given flat is valid + bool is_flat_valid(const List_iterator& flat) const + { + Dart_const_handle dhend=flat->begin; + int nb=0; + while(nb!=flat->length) + { + if (flat->length>0) + { dhend=m_map.template beta<1, 2, 1>(dhend); ++nb; } + else + { dhend=m_map.template beta<2, 0, 2, 0, 2>(dhend); --nb; } + } + return dhend==flat->end; + } + /// @return true iff the path is valid; i.e. a sequence of flats two by /// two adjacent. bool is_valid() @@ -335,54 +351,33 @@ public: return false; } - Dart_const_handle dhend=begin_of_flat(it); - int nb=0; - while(nb!=flat_length(it)) - { - if (flat_length(it)>0) - { dhend=m_map.template beta<1, 2, 1>(dhend); ++nb; } - else - { dhend=m_map.template beta<2, 0, 2, 0, 2>(dhend); --nb; } - ++nbdarts; - } - - if (dhend!=end_of_flat(it)) + if (!is_flat_valid(it)) { + display(); std::cout<<"ERROR: The path is not valid: flat at position "<=0 && next_positive_turn(it)==2 && - flat_length(next_iterator(it))>=0) + /*if (can_merge_with_next_flat(it)) { - /* display(); - Path_on_surface(*this).display_pos_and_neg_turns(); std::cout<(*this).display_pos_and_neg_turns(); std::cout<second; */ - std::cout<<"ERROR: The path is not valid: flat at position "<length>0) { --(it->length); } - else { ++(it->length); } + if (flat_length(it)>0) { --(it->length); } + else { ++(it->length); } } void increase_flat_length(const List_iterator& it) { CGAL_assertion(is_valid_iterator(it)); - if (it->length>0) { ++(it->length); } - else { --(it->length); } + if (flat_length(it)>0) { ++(it->length); } + else { --(it->length); } } void set_begin_of_flat(const List_iterator& it, Dart_const_handle dh) @@ -794,50 +791,51 @@ public: if (!m_path.empty()) { retreat_iterator(it); } // this is why we move it backward here return true; } + // else set_end_of_flat(it, before_last_dart_of_a_flat(it)); decrease_flat_length(it); return false; } - /// Merge, if possible, the flat starting at iterator 'it' with its next - /// flat. return true if a merging was done. - bool merge_adjacent_flats_if_possible(const List_iterator& it) + /// @return true iff the flat 'it' can be merged with its next flat. + bool can_merge_with_next_flat(const List_iterator& it, + bool& positive2, bool& negative2) { + if (m_path.size()<=1) { return false; } + CGAL_assertion(is_valid_iterator(it)); - bool positive1=false, negative1=false; - bool positive2=false, negative2=false; - bool positive3=false, negative3=false; + if (!next_flat_exist(it)) { return false; } List_iterator it2=next_iterator(it); - + CGAL_assertion(m_path.size()>1 || it==it2); if (it==it2) { return false; } // only one flat in the path - if (next_positive_turn(it)==2) { positive2=true; } - if (next_negative_turn(it)==2) { negative2=true; } + positive2=(next_positive_turn(it)==2); + negative2=(next_negative_turn(it)==2); CGAL_assertion(!(positive2 && negative2)); - if (!positive2 && !negative2) { return false; } // the middle turn is not a flat + bool positive1=false, negative1=false; + bool positive3=false, negative3=false; + if (flat_length(it)>0) positive1=true; else if (flat_length(it)<0) negative1=true; - if (flat_length(it)>0) positive3=true; - else if (flat_length(it)<0) negative3=true; + if (flat_length(it2)>0) positive3=true; + else if (flat_length(it2)<0) negative3=true; if (!positive1 && !negative1) { // First flat is empty (length 0) if (!positive3 && !negative3) { // and second flat too - set_flat_length(it, positive2?+1:-1); + return true; } else { // here second flat is not empty if ((positive3 && !positive2) || (negative3 && !negative2)) { return false; } // the two flats cannot be merged - - set_flat_length(it, flat_length(it2)+(positive3?1:-1)); } } else @@ -846,25 +844,42 @@ public: { // and second flat is empty if ((positive1 && !positive2) || (negative1 && !negative2)) { return false; } // the two flats cannot be merged - - set_flat_length(it, flat_length(it)+(positive1?1:-1)); } else { - // Second flat is not empty => we have 4 darts (2 for first flat, 2 for second flat) + // Second flat is not empty if ((positive1!=positive3) || (negative1!=negative3) || (positive1 && !positive2) || (negative1 && !negative2)) { return false; } // the two flats cannot be merged - - set_flat_length(it, flat_length(it)+flat_length(it2)+ - (positive1?1:-1)); } } + return true; + } + /// @return true iff the flat 'it' can be merged with its next flat. + bool can_merge_with_next_flat(const List_iterator& it) + { + bool dummy1, dummy2; + return can_merge_with_next_flat(it, dummy1, dummy2); + } + + /// Merge flat 'it' with its next flat if it is possible. + /// @return true if a merging was done. + bool merge_with_next_flat_if_possible(const List_iterator& it) + { + CGAL_assertion(is_valid_iterator(it)); + + bool positive2=false, negative2=false; + if (!can_merge_with_next_flat(it, positive2, negative2)) + { return false; } + + List_iterator it2=next_iterator(it); + set_flat_length(it, flat_length(it)+flat_length(it2)+ + (positive2?1:-1)); set_end_of_flat(it, end_of_flat(it2)); m_path.erase(it2); - // CGAL_assertion(is_valid()); + // CGAL_assertion(is_flat_valid(it)); return true; } @@ -877,8 +892,7 @@ public: begin_of_flat(next_iterator(it)); } - /// Remove the spur given by 'it', which is either the beginning of a null - /// length flat, or the end of a non null flat. + /// Remove the spur given by 'it'. /// After the operation, either 'it' stay on the same element (if the flat /// still exist), or 'it' move to the previous element if the flat containing /// the spur is removed. @@ -886,29 +900,31 @@ public: void remove_spur(List_iterator& it) { CGAL_assertion(is_spur(it)); - // 'it' is the end of its flat /* static int TOTO=0; + std::cout<<"*********************************** "; + std::cout<<"remove_spur "<(*this).display_pos_and_neg_turns(); std::cout<