mirror of https://github.com/CGAL/cgal
Merge branch 'CMap-path_isotopy-gdamiand' of github.com:CGAL/CNRS into CMap-path_isotopy-gdamiand
This commit is contained in:
commit
3f6cb9ef42
|
|
@ -11,8 +11,7 @@ namespace CGAL {
|
||||||
class Path_on_surface
|
class Path_on_surface
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/*! Constructor. Creates a Surface_mesh_curve_topology object using amap as input.
|
/// Constructor. Creates an empty path object which should lie on amap.
|
||||||
*/
|
|
||||||
Path_on_surface(const Map& amap);
|
Path_on_surface(const Map& amap);
|
||||||
|
|
||||||
/// @return true iff the path is empty
|
/// @return true iff the path is empty
|
||||||
|
|
@ -33,18 +32,31 @@ namespace CGAL {
|
||||||
|
|
||||||
/// Add the given dart at the end of this path.
|
/// Add the given dart at the end of this path.
|
||||||
/// @pre can_be_pushed(dh)
|
/// @pre can_be_pushed(dh)
|
||||||
void push_back(Dart_const_handle dh, bool update_isclosed=true);
|
void push_back(Dart_const_handle dh);
|
||||||
|
|
||||||
/*!
|
/// Add the dart with given index i at the end of this path.
|
||||||
*/
|
/// @pre can_be_pushed_by_index(i)
|
||||||
|
void push_back_by_index(std::size_t i);
|
||||||
|
|
||||||
|
/// @return true iff the dart with index i can be added at the end of the path.
|
||||||
|
bool can_be_pushed_by_index(std::size_t i) const;
|
||||||
|
|
||||||
|
/// Add the dart obtained by turning nb times around the target vertex of the last dart in this path, in the positive circular order.
|
||||||
|
/// @pre !is_empty()
|
||||||
|
void extend_positive_turn(std::size_t nb);
|
||||||
|
|
||||||
|
/// Add the dart obtained by turning nb times around the target vertex of the last dart in this path, in the negative circular order.
|
||||||
|
/// @pre !is_empty()
|
||||||
|
void extend_negative_turn(std::size_t nb);
|
||||||
|
|
||||||
|
/// Concatenation operator. Concatenates other to this path.
|
||||||
|
/// @pre the last vertex of this path should coincide with the first vertex of other.
|
||||||
Self& operator+=(const Self& other);
|
Self& operator+=(const Self& other);
|
||||||
|
|
||||||
/*!
|
/// Creates a random open path with lenght darts.
|
||||||
*/
|
void generate_random_path(std::size_t lenght, CGAL::Random& random=CGAL::get_default_random());
|
||||||
void generate_random_path(std::size_t length, CGAL::Random& random=CGAL::get_default_random());
|
|
||||||
|
|
||||||
/*!
|
/// Creates a random closed path with at least lenght darts.
|
||||||
*/
|
|
||||||
void generate_random_closed_path(std::size_t length, CGAL::Random& random=CGAL::get_default_random());
|
void generate_random_closed_path(std::size_t length, CGAL::Random& random=CGAL::get_default_random());
|
||||||
|
|
||||||
/// Reverse the path (i.e. negate its orientation).
|
/// Reverse the path (i.e. negate its orientation).
|
||||||
|
|
|
||||||
|
|
@ -27,15 +27,25 @@ The algorithms used are based on a paper by Erickson and Whittlesey \cgalCite{ew
|
||||||
|
|
||||||
\subsection SMTopology_Input Specifying the Input Surface and Curves
|
\subsection SMTopology_Input Specifying the Input Surface and Curves
|
||||||
|
|
||||||
The homotopy tests are performed on a surface represented as a model of combinatorial map. The input surface mesh is supposed to be a connected closed orientable surface. This input surface is provided to conctruct a `Surface_mesh_curve_topology`. This class computes an internal representation of the surface as described below.
|
The homotopy tests are performed on a surface represented as a model of \ref ChapterCombinatorialMap "combinatorial map" or `HalfedgeGraph`. The input surface mesh is supposed to be a connected closed orientable surface. This input surface is provided to conctruct a `Surface_mesh_curve_topology`. This class computes an internal representation of the surface as described below.
|
||||||
|
|
||||||
Each curve on this surface is contained in an instance of the class `Path_on_surface`. An object in this class should be constructed with the same input surface as the `Surface_mesh_curve_topology` container. A `Path_on_surface` behaves as a list. This list is initially empty and the darts corresponding to the sequence of oriented edges of an input curve should be pushed back in order in this list.
|
Each curve on this surface is contained in an instance of the class `Path_on_surface`. An object in this class should be constructed with the same input surface as the `Surface_mesh_curve_topology` container.
|
||||||
|
|
||||||
|
A `Path_on_surface` behaves as a list. This list is initially empty and the darts or halfedges corresponding to the sequence of consecutive oriented edges of an input curve should be pushed back in this list. The class provides three ways for extending a nonempty path.
|
||||||
|
- Simply push the next dart or halfedge using the \ref Path_on_surface::push_back "push_back()" member function.
|
||||||
|
- When the surface is represented by a combinatorial map or a `Surface_mesh` the user may push the index of the next dart/halfedge instead of the dart/halfedge itself with the member function \ref Path_on_surface::push_back_by_index "push_back_by_index()". This may however be at the cost of an overhead computation mapping the index to the actual dart/halfedge.
|
||||||
|
- The path may be extended with the member function \ref Path_on_surface::extend_positive_turn "extend_positive_turn()" by specifying the next dart/halfedge thanks to a number of positive turns with respect to the previous dart/halfedge in the path.
|
||||||
|
|
||||||
|
In the two first cases, the source vertex of the added dart/halfedge should coincide with the target vertex of the last dart/halfedge in the path. The user is responsible for ensuring this condition. The member functions \ref Path_on_surface::can_be_pushed "can_be_pushed" and \ref Path_on_surface::can_be_pushed_by_index "can_be_pushed_by_index()" return true if and only if the condition is satisfied.
|
||||||
|
|
||||||
|
In addition to these functionalities, we provide an intuitive mesh builder `Combinatorial_map_2_incremental_builder`. The user can add facets to the mesh one at a time. Each facet is specified by the sequence of its oriented edge labels given as a string where the labels are words separated by blank spaces. The label of the opposite of an oriented edge is preceded by a minus. For example, the opposite of 'a1' is '-a1'. See \ref SMTopology_Example_II "examples below". Note that all the facets should be oriented the same way to form an oriented surface. This builder includes a path creator where the sequence of darts of the path is given as a string of oriented edge labels, similarly to the facets.
|
||||||
|
|
||||||
\subsection SMTopology_DS Data Structure Presentation
|
\subsection SMTopology_DS Data Structure Presentation
|
||||||
|
|
||||||
\subsubsection SMTopology_Build Building the Internal Surface Representation
|
\subsubsection SMTopology_Build Building the Internal Surface Representation
|
||||||
|
|
||||||
A common first step in the homotopy test algorithms is to transform the input surface mesh into a simplified mesh. This preprocessing step is done once for all for a given mesh. The simplified surface is a quadrangulation, every face of which is a quadrilateral, stored in a `Surface_mesh_curve_topology`. The user should not modify the input surface as long as homotopy tests should be performed with this `Surface_mesh_curve_topology`.
|
A common first step in the homotopy test algorithms is to transform the input surface mesh into a simplified mesh. This preprocessing step is done once for all for a given mesh. The simplified surface is a quadrangulation, every face of which is a quadrilateral, stored in a `Surface_mesh_curve_topology`.
|
||||||
|
\note The user should not modify the input surface as long as homotopy tests should be performed with this `Surface_mesh_curve_topology`.
|
||||||
|
|
||||||
Each time a `Path_on_surface` is provided for a homotopy test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_curve_topology`. This transformation is transparent to the user who has never access to the quadrangulation.
|
Each time a `Path_on_surface` is provided for a homotopy test, it is first transformed to an equivalent path in the quadrangulation stored by the `Surface_mesh_curve_topology`. This transformation is transparent to the user who has never access to the quadrangulation.
|
||||||
|
|
||||||
|
|
@ -47,11 +57,27 @@ Given two `Path_on_surface` \f$p_1\f$ and \f$p_2\f$, the class `Surface_mesh_cur
|
||||||
|
|
||||||
- `are_freely_homotopic`(\f$p_1\f$, \f$p_2\f$) returns true if the closed curves \f$p_1\f$ and \f$p_2\f$ are freely homotopic.
|
- `are_freely_homotopic`(\f$p_1\f$, \f$p_2\f$) returns true if the closed curves \f$p_1\f$ and \f$p_2\f$ are freely homotopic.
|
||||||
|
|
||||||
- `are_base_point_homotopic`(\f$p_1\f$, \f$p_2\f$) returns true if the paths \f$p_1\f$ and \f$p_2\f$ are homotopic with fixed endpoints. This call is equivalent to `is_contractible`(\f$p_1\cdot \bar{p_2}\f$), where \f$p_1\cdot \bar{p_2}\f$ is the concatenation of \f$p_1\f$ and the reverse of \f$p_2\f$.
|
- `are_base_point_homotopic`(\f$p_1\f$, \f$p_2\f$) returns true if the paths \f$p_1\f$ and \f$p_2\f$ are homotopic with fixed endpoints. This call is equivalent to `is_contractible`(\f$p_1\cdot \overline{p_2}\f$), where \f$p_1\cdot \overline{p_2}\f$ is the concatenation of \f$p_1\f$ and the reverse of \f$p_2\f$.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
\section SMTopology_Examples Examples
|
\section SMTopology_Examples Examples
|
||||||
|
\subsection SMTopology_Example_I Simple Example
|
||||||
|
The following example shows how to load an off file and how to create three closed paths on this surface. Contractibility and free homotopy tests are then performed. The example also shows how to use the CGAL viewer if CGAL was compiled with Qt5.
|
||||||
|
\cgalExample{Surface_mesh_topology/basic_example_surface_mesh_topology.cpp}
|
||||||
|
|
||||||
|
\subsection SMTopology_Example_II Mesh Builder Examples
|
||||||
|
Here, we show with two examples how to create a surface from a list of faces specified by edge label sequences.
|
||||||
|
In this first example, we build a genus two torus surface from a single face, also called a polygonal schema. Two closed paths are then created. The paths are freely homotopic but not homotopic with fixed endpoint.
|
||||||
|
\cgalExample{Surface_mesh_topology/path_homotopy_with_symbols.cpp}
|
||||||
|
|
||||||
|
In this second example, we build a genus two torus surface from a set of three squares. The first two faces are added each with a single call to the member function add_facet(). The third face is build incrementally by adding its edge labels one at a time. We then create a contractible closed path.
|
||||||
|
\cgalExample{Surface_mesh_topology/path_homotopy_with_symbols_2.cpp}
|
||||||
|
|
||||||
|
\subsection SMTopology_Example_III Open Path Example
|
||||||
|
|
||||||
|
In this third example, we create non closed paths on the same mesh as in the first example and perform homotopy tests with fixed endpoints.
|
||||||
|
\cgalExample{Surface_mesh_topology/open_path_homotopy.cpp}
|
||||||
|
|
||||||
\section SMTopology_Benchmarks Benchmarks
|
\section SMTopology_Benchmarks Benchmarks
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
Combinatorial_map
|
Combinatorial_map
|
||||||
Linear_cell_complex
|
Linear_cell_complex
|
||||||
|
BGL
|
||||||
|
|
@ -1,3 +1,7 @@
|
||||||
/*!
|
/*!
|
||||||
\example Surface_mesh_topology/path_homotopy.cpp
|
\example Surface_mesh_topology/path_homotopy.cpp
|
||||||
|
\example Surface_mesh_topology/basic_example_surface_mesh_topology.cpp
|
||||||
|
\example Surface_mesh_topology/path_homotopy_with_symbols.cpp
|
||||||
|
\example Surface_mesh_topology/path_homotopy_with_symbols_2.cpp
|
||||||
|
\example Surface_mesh_topology/open_path_homotopy.cpp
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ int main()
|
||||||
{ p1.extend_positive_turn(2); } // Extend the path
|
{ p1.extend_positive_turn(2); } // Extend the path
|
||||||
|
|
||||||
CGAL::Path_on_surface<LCC_3_cmap> p2(lcc); // A second path
|
CGAL::Path_on_surface<LCC_3_cmap> p2(lcc); // A second path
|
||||||
p2.push_back_by_index(202); // 408); // Its starting dart
|
p2.push_back_by_index(202); // Its starting dart
|
||||||
for (int i=0; i<3; ++i)
|
for (int i=0; i<3; ++i)
|
||||||
{ p2.extend_negative_turn(2); } // Extend the path
|
{ p2.extend_negative_turn(2); } // Extend the path
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue