From 05bb25687cd26940b31402f22d3abf3d5f098e5f Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Mon, 3 Dec 2018 09:58:57 +0100 Subject: [PATCH] Operator== linear for path with rle. --- .../include/CGAL/Path_on_surface_with_rle.h | 49 +- .../CGAL/Surface_mesh_curve_topology.h | 443 +----------------- 2 files changed, 47 insertions(+), 445 deletions(-) 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 34ea398b890..a1174420fa5 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 @@ -146,6 +146,24 @@ public: return *this; } + Self& operator+=(const Self& other) + { + // Be careful to the special case when *this==other + // this is the reason of the iend. + for (List_iterator lit=other.begin(), litend=std::prev(other.end()); + lit!=litend; ++lit) + { m_path.push_back(*lit); } + m_path.push_back(other.back()); // Last element + update_is_closed(); + return *this; + } + + Self operator+(const Self& other) const + { + Self res=*this; + res+=other; + return res; + } /// @Return true if this path is equal to other path, identifying dart begin /// of this path with dart 'itother' in other path. bool are_same_paths_from(Self& other, List_iterator itother) @@ -164,8 +182,9 @@ public: } /// @return true if this path is equal to other path. For closed paths, test - /// all possible starting darts. - bool operator==(Self& other) + /// all possible starting darts. Old quadratic version, new version + /// (operator==) use linear version based on Knuth, Morris, Pratt + bool are_paths_equals(const Self& other) { if (is_closed()!=other.is_closed() || length()!=other.length() || @@ -184,6 +203,28 @@ public: return false; } + /// @return true if this path is equal to other path. For closed paths, test + /// all possible starting darts. + bool operator==(Self& other) + { + if (is_closed()!=other.is_closed() || + length()!=other.length() || + size_of_list()!=other.size_of_list()) + return false; + + if (!is_closed()) + { return are_same_paths_from(other, other.m_path.begin()); } + + Self p2(*this); p2+=p2; + // Now we search if other is a sub-motif of p2 <=> *this==other + + return boost::algorithm::knuth_morris_pratt_search(p2.m_path.begin(), + p2.m_path.end(), + other.m_path.begin(), + other.m_path.end()).first + !=p2.m_path.end(); + } + bool operator!=(Self& other) { return !(operator==(other)); } @@ -332,7 +373,7 @@ public: m_path.push_back(dh); if (update_isclosed) { update_is_closed(); } } - + */ // Update m_is_closed to true iff the path is closed (i.e. the second // extremity of the last dart of the path is the same vertex than the one // of the first dart of the path). @@ -347,7 +388,7 @@ public: else { m_is_closed=CGAL::belong_to_same_cell(m_map, m_path[0], pend); } } - } */ + } /// @return true iff there is a dart after it bool next_dart_exist(const List_iterator& it) const diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_curve_topology.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_curve_topology.h index 6258eb150ea..06347016ccc 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_curve_topology.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_curve_topology.h @@ -906,458 +906,19 @@ namespace CGAL { return res; } - std::size_t find_end_of_braket(const Path_on_surface& path, - std::size_t begin, bool positive) const - { - assert((positive && next_positive_turn(path, begin)==1) || - (!positive && next_negative_turn(path, begin)==1)); - std::size_t end=path.next_index(begin); - if (!path.is_closed() && end>=path.length()-1) - { return begin; } // begin is the before last dart - - while ((positive && next_positive_turn(path, end)==2) || - (!positive && next_negative_turn(path, end)==2)) - { end=path.next_index(end); } - - if ((positive && next_positive_turn(path, end)==1) || - (!positive && next_negative_turn(path, end)==1)) // We are on the end of a bracket - { end=path.next_index(end); } - else - { end=begin; } - - return end; - } - - void transform_positive_bracket(Path_on_surface& path, - std::size_t begin, std::size_t end, - Path_on_surface& new_path) const - { - // There is a special case for (1 2^r). In this case, we need to ignore - // the two darts begin and end - Dart_const_handle d1=(path.next_index(begin)!=end? - m_map.template beta<0>(path.get_ith_dart(begin)): - m_map.template beta<1,2,0>(path.get_ith_dart(end))); - Dart_const_handle d2=(path.next_index(begin)!=end? - m_map.template beta<2,0,2>(path.get_ith_dart(end)): - m_map.template beta<0,0,2>(path.get_ith_dart(begin))); - - new_path.push_back(m_map.template beta<2>(d1)); - CGAL::extend_straight_negative_until(new_path, d2); - } - - void transform_negative_bracket(Path_on_surface& path, - std::size_t begin, std::size_t end, - Path_on_surface& new_path) const - { - // There is a special case for (-1 -2^r). In this case, we need to ignore - // the two darts begin and end - Dart_const_handle d1=(path.next_index(begin)!=end? - m_map.template beta<2,1>(path.get_ith_dart(begin)): - m_map.template beta<2,0,2,1>(path.get_ith_dart(end))); - Dart_const_handle d2=(path.next_index(begin)!=end? - m_map.template beta<1>(path.get_ith_dart(end)): - m_map.template beta<2,1,1>(path.get_ith_dart(begin))); - - new_path.push_back(d1); - CGAL::extend_straight_positive_until(new_path, d2); - } - - void transform_bracket(Path_on_surface& path, - std::size_t begin, std::size_t end, - Path_on_surface& new_path, - bool positive) const - { - if (positive) - { transform_positive_bracket(path, begin, end, new_path); } - else - { transform_negative_bracket(path, begin, end, new_path); } - } - - bool bracket_flattening_one_step(Path_on_surface& path) const - { - if (path.is_empty()) return false; - - #ifndef NDEBUG - bool is_even=path.length()%2; - #endif // NDEBUG - - Path_on_surface new_path(m_map); - bool positive=false; - std::size_t begin, end; - std::size_t lastturn=path.length()-(path.is_closed()?0:1); - - for (begin=0; begin& path) const - { - /* // TODO TEMPO POUR TEST - Path_on_surface_with_rle prle(path); - prle.remove_brackets(); - Path_on_surface p2(prle); */ - - bool res=false; - while(bracket_flattening_one_step(path)) - { res=true; } - - // assert(p2==path); // FOR TEST - return res; - } - // Simplify the path by removing all brackets bool bracket_flattening(Path_on_surface_with_rle& path) const { return path.remove_brackets(); // TODO use method with index to compute turns (and add a compilation flat allowing to use either normal version, or version with indices } - bool remove_spurs_one_step(Path_on_surface& path) const - { - if (path.is_empty()) return false; - - bool res=false; - std::size_t i; - std::size_t lastturn=path.length()-(path.is_closed()?0:1); - for (i=0; !res && i(path.get_next_dart(i))) - { res=true; } - } - - if (!res) - { return false; } - - #ifndef NDEBUG - bool is_even=path.length()%2; - #endif // NDEBUG - - --i; // Because we did a ++ before to leave the loop - // Here there is a spur at position i in the path - Path_on_surface new_path(m_map); - - // Special case, the spur is between last dart of the path and the first dart - if (path.is_closed() && i==path.length()-1) - { - path.copy_rest_of_path(1, path.length()-1, new_path); // copy path between 1 and m_path.length()-2 - } - else - { // Otherwise copy darts before the spur - if (i>0) - { path.copy_rest_of_path(0, i, new_path); } // copy path between 0 and i-1 - - // and the darts after - if (i+2& path) const - { - // TODO TEMPO POUR TEST - /* Path_on_surface_with_rle prle(path); - prle.remove_spurs(); - Path_on_surface p2(prle); */ - - bool res=false; - while(remove_spurs_one_step(path)) - { res=true; } - - // assert(p2==path); // TEMPO POUR TESTS - - return res; - } - bool remove_spurs(Path_on_surface_with_rle& path) const { return path.remove_spurs(); } - // Simplify the path by removing all possible brackets and spurs - void simplify(Path_on_surface& path) const - { - bool modified=false; - do - { - modified=bracket_flattening_one_step(path); - if (!modified) - { modified=remove_spurs_one_step(path); } - } - while(modified); - } - - /* bool find_l_shape(const Path_on_surface& path, - std::size_t begin, - std::size_t& middle, - std::size_t& end) const - { - assert(next_negative_turn(begin)==1 || next_negative_turn(begin)==2); - end=begin+1; - if (end==path.length()-1 && !path.is_closed()) - { return false; } // begin is the before last dart - - while (next_negative_turn(end)==2 && end!=begin) - { end=path.next_index(end); } - - if (begin==end) - { // Case of a path having only 2 turns - return true; - } - - if (next_negative_turn(end)==1) - { - middle=end; - end=path.next_index(end); - } - else - { return false; } - - while (next_negative_turn(end)==2 && end!=begin) - { end=path.next_index(end); } - - return true; - } - - void push_l_shape(Path_on_surface& path, - std::size_t begin, - std::size_t middle, - std::size_t end, - Path_on_surface& new_path, - bool case_seven) const - { - Dart_const_handle d1; - - if (!case_seven) - { d1=m_map.template beta<2,1>(path.get_ith_dart(begin)); } - else - { d1=m_map.template beta<2,1,2,0>(path.get_ith_dart(begin)); } - new_path.push_back(d1); - - if (begin!=middle) - { - if (!case_seven) - { CGAL::extend_uturn_positive(new_path, 1); } - - d1=m_map.template beta<2,1,1>(path.get_ith_dart(middle)); - CGAL::extend_straight_positive_until(new_path, d1); - - if (path.next_index(middle)!=end) - { CGAL::extend_uturn_positive(new_path, 3); } - else - { CGAL::extend_straight_positive(new_path, 1); } - } - - if (path.next_index(middle)!=end) - { - d1=m_map.template beta<2,0,2,1>(path.get_ith_dart(end)); - CGAL::extend_straight_positive_until(new_path, d1); - - if (!case_seven) - { CGAL::extend_uturn_positive(new_path, 1); } - else - { CGAL::extend_straight_positive(new_path, 1); } - } - - if (begin==middle && path.next_index(middle)==end) - { // TODO: check if we need to do also something for !case_seven ? - // if (case_seven) - { CGAL::extend_uturn_positive(new_path, 1); } - // else { assert(false); } // We think (?) that this case is not possible - } - - } - - void push_l_shape_cycle_2(Path_on_surface& path) const - { - Dart_const_handle d1= - m_map.template beta<2,1,1>(path.get_ith_dart(0)); - path.clear(); - path.push_back(d1); - CGAL::extend_straight_positive(path, 1); - CGAL::extend_straight_positive_until(path, d1); - } - - bool push_l_shape_2darts(Path_on_surface& path) const - { - Dart_const_handle d1=NULL; - - if (next_negative_turn(path, 0)==1) - d1=m_map.template beta<2,1>(path.get_ith_dart(0)); - else if (next_negative_turn(path, 1)==1) - d1=m_map.template beta<2,1>(path.get_ith_dart(1)); - else return false; - - path.clear(); - path.push_back(d1); - CGAL::extend_uturn_positive(path, 1); - //path.push_back(m_map.template beta<1>(d1)); - return true; - } - - bool right_push_one_step(Path_on_surface& path) const - { - if (path.is_empty()) { return false; } - - if (path.length()==2) - { return push_l_shape_2darts(path); } - - #ifndef NDEBUG - bool is_even=path.length()%2; - #endif // NDEBUG - - std::size_t begin, middle, end; - std::size_t lastturn=path.length()-(path.is_closed()?0:1); - std::size_t next_turn; - std::size_t val_x=0; // value of turn before the beginning of a l-shape - bool prev2=false; - - for (middle=0; middle0) - { val_x=next_negative_turn(path, path.prev_index(begin)); } - - // And here now we can push the path - Path_on_surface new_path(m_map); - if (end& path) const - { - // TODO TEMPO POUR TEST - /* Path_on_surface_with_rle prle(path); - prle.right_push(); - Path_on_surface p2(prle); */ - - bool res=false; - while(right_push_one_step(path)) - { res=true; - - /*std::cout<<"PUSH "; display(); display_pos_and_neg_turns(); - std::cout<& path) const { return path.right_push(); @@ -1370,9 +931,9 @@ namespace CGAL { if (!path.is_closed()) { return; } - #ifdef COMPUTE_TIME +#ifdef COMPUTE_TIME CGAL::Timer t; t.start(); - #endif // COMPUTE_TIME +#endif // COMPUTE_TIME #ifdef CGAL_QUADRATIC_CANONIZE Path_on_surface& path2=path;