From e29896a13513f63e1bdce27ba0ee2b0c420739c8 Mon Sep 17 00:00:00 2001 From: Youmu Date: Sat, 6 Jun 2020 19:49:32 -0400 Subject: [PATCH] Add path factorization --- .../include/CGAL/Path_on_surface.h | 35 +++++++++++++++++++ .../internal/Path_on_surface_with_rle.h | 6 ++++ 2 files changed, 41 insertions(+) diff --git a/Surface_mesh_topology/include/CGAL/Path_on_surface.h b/Surface_mesh_topology/include/CGAL/Path_on_surface.h index 96a0c56a029..5dd53b8605d 100644 --- a/Surface_mesh_topology/include/CGAL/Path_on_surface.h +++ b/Surface_mesh_topology/include/CGAL/Path_on_surface.h @@ -1095,6 +1095,41 @@ public: } } + /// @return the primitive root and the power of the path in the sense of string. + /// use the linear Knuth-Morris-Pratt search + Self factorize(int& power) { + CGAL_assertion(is_valid()); + if (!is_closed()) { + // if a path is not closed, it is already primitive + power = 1; + return Path_on_surface(*this); + } + + Self pp1(*this); + pp1.simplify_flips(); + Self pp2(pp1); + /// create a path of (*this)->(*this) + pp2 += pp1; + + /// Match (*this) to (*this)->(*this) with the first dart removed + auto itMatch = boost::algorithm::knuth_morris_pratt_search(pp2.m_path.begin() + 1, + pp2.m_path.end(), + pp1.m_path.begin(), + pp1.m_path.end()) +#if BOOST_VERSION>=106200 + .first +#endif + ; + /// It can be proved that the first match location is the length of match + auto primitiveSize = itMatch - pp2.m_path.begin(); + std::cout << pp1.length() << ' ' << primitiveSize << std::endl; + CGAL_assertion(pp1.length() % primitiveSize == 0); + power = pp1.length() / primitiveSize; + pp1.cut(primitiveSize); + CGAL_assertion(pp1.is_closed()); + return pp1; + } + /// @return the turn between dart number i and dart number i+1. /// (turn is position of the second edge in the cyclic ordering of /// edges starting from the first edge around the second extremity diff --git a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h index 64438208dd6..82dcda953f1 100644 --- a/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h +++ b/Surface_mesh_topology/include/CGAL/Surface_mesh_topology/internal/Path_on_surface_with_rle.h @@ -1499,6 +1499,12 @@ public: CGAL_assertion(is_valid()); } + /// Factorize the path into primitive + Self factorize(int& power) { + Path_on_surface p(*this); + return Self(m_MQ, p.factorize(power), m_use_only_positive, m_use_only_negative); + } + void display_positive_turns() { std::cout<<"+(";