cgal/BGL/doc/BGL/BGL.txt

765 lines
38 KiB
Plaintext

namespace CGAL {
/*!
\mainpage User Manual
\anchor Chapter_CGAL_and_the_Boost_Graph_Library
\anchor chapterBGL
\cgalAutoToc
\authors Andreas Fabri, Fernando Cacciola, Philipp Moeller, and Ron Wein
Many geometric data structures can be interpreted as graphs as they consist of
vertices and edges. This is the case for the halfedge data structure,
for the polyhedral surface, for the arrangement, and for the 2D triangulation classes. With means of
duality one can also interpret faces as vertices and edges between adjacent
faces as edges of the dual graph.
The scope of \cgal is geometry and not graph algorithms. Nevertheless, this package
provides the necessary classes and functions that enable using the
algorithms of the <A HREF="https://www.boost.org/libs/graph/doc/index.html">Boost Graph Library</A> \cgalCite{cgal:sll-bgl-02}
(\sc{Bgl} for short) with \cgal data structures.
Furthermore, this package extends the \sc{Bgl}
by introducing concepts such as `HalfedgeGraph` and `FaceGraph`
allowing to handle *halfedges* and *faces*.
These concepts reflect the design of the halfedge data structure described
in Chapter \ref PkgHalfedgeDS, with opposite halfedges and circular
sequences of halfedges around vertices and around faces.
This chapter is organized as follows:
- The first section, Section \ref BGLA, summarizes the main ideas of the \sc{Bgl}.
- Section \ref BGLHeader then explains where to find header files and the chosen naming conventions, as we blend two
different libraries.
- The four following sections give examples on how to use CGAL graph and mesh data structures
such as
\link PkgSurfaceMesh Surface_mesh \endlink,
\link PkgPolyhedron Polyhedron \endlink,
\link PkgArrangementOnSurface2 Arrangement_2 \endlink, and the
\link PkgTriangulation2 2D triangulation \endlink classes as models of the \sc{Bgl} concepts.
- Starting with Section \ref BGLExtensions, we introduce new graph concepts, classes,
and functions that extend the functionalities of the \sc{Bgl}.
\section BGLA A Short Introduction to the Boost Graph Library
The algorithms of the \sc{Bgl} operate on models of various <I>graph concepts</I>.
The <I>traits class</I> `boost::graph_traits` enable algorithms to determine the types of vertices and edges
(similar to `std::iterator_traits` for iterators).
<I>Free functions</I> that operate on graphs enable algorithms to obtain,
for example, the source vertex of an edge, or all edges incident to a vertex. The algorithms
use <I>property maps</I> to associate information with vertices and edges.
The algorithms enable <I>visitors</I> to register callbacks that are called
later on during the execution of the algorithms. Finally, the graph algorithms use
the <I>named parameter</I> mechanism, which enables passing the arguments in
arbitrary order.
\subsection BGLGraphConcepts Graph Concepts
The \sc{Bgl} introduces several <a href="https://www.boost.org/libs/graph/doc/graph_concepts.html">graph concepts</a>,
which have different sets of characteristics and requirements.
For example, iterating through all vertices or all edges in a graph, obtaining the outgoing
or in-going edges of a vertex, inserting vertices and edges into a graph,
and removing vertices and edges from a graph.
\subsection BGLTheGraphTraitsClass The Graph Traits Class
An algorithm operating on a graph model determines types with the help of the traits class
<a href="https://www.boost.org/libs/graph/doc/graph_traits.html">boost::graph_traits</a>.
Such types are the `vertex_descriptor`,
which is similar to a vertex handle in \cgal data structures, or
the `edge_descriptor`, which is similar to the \link HalfedgeDSHalfedge halfedge handle \endlink in
the halfedge data structure or to the type \link Triangulation_2::Edge Edge \endlink in 2D triangulations.
There are also iterators, such as the `vertex_iterator`, which is similar
to a vertex iterator in \cgal data structures, and the `out_edge_iterator`,
which is similar to the edge circulator; it enables to iterate through the edges
incident to a vertex. The iterators are similar and not equivalent,
because their value type is a `vertex_descriptor`, whereas in
\cgal handles, iterators, and circulators all have the same value
type, namely the vertex or edge types.
Given a graph type `G`, definitions of descriptors and iterators look as follows:
\code {.cpp}
boost::graph_traits<Graph>::vertex_descriptor vd;
boost::graph_traits<Graph>::edge_iterator ei;
...
\endcode
\subsection BGLFreeFunctionsforExploringaGraph Free Functions for Exploring a Graph
Algorithms obtain incidence information in graphs with the help of global
functions such as:
- `std::pair<vertex_iterator,vertex_iterator> vertices(const Graph& g);` to obtain an iterator range providing access to all the vertices, or
- `int num_vertices(const Graph&);` to obtain the number of vertices of a graph, or
- `vertex_descriptor source(edge_descriptor, const Graph&);` to obtain the source vertex of an edge.
Note, that the way we have written the types is a simplification; in reality,
the signature of the first of the above functions is:
\code{.cpp}
typedef boost::graph_traits<Graph>::vertex_iterator vertex_iterator;
std::pair<vertex_iterator,vertex_iterator> vertices(const Graph& g);
\endcode
\subsection BGLPropertyMaps Property Maps
Another feature extensively used in the \sc{Bgl} is the *property map*,
which is offered by the <a href="https://www.boost.org/libs/property_map/doc/property_map.html">Boost Property Map Library</a>. Property maps
are a general purpose interface for mapping key objects to
corresponding value objects.
The \sc{Bgl} uses property maps to associate information with vertices and edges.
This mechanism uses a traits class (`boost::property_traits`) and free
functions to read (`get`) and write (`put`) information in vertices,
edges, and also in halfedges and faces for models of the \cgal graph concepts.
For example, the \sc{Bgl}
Dijksta's shortest path algorithm writes the predecessor of each vertex, as
well as the distance to the source in such a property map.
Some default property maps are associated with the graph types. They
are called *internal property maps* and can be retrieved using an
overload of the function `get()`. For example,
\code{.cpp}
pm = get(boost::vertex_index, g)
\endcode
returns a property map that associates an index
in the range `[0, num_vertices(g))` with each vertex of the graph.
This reduces the number of parameters to pass.
The data itself may be stored in the vertex or the edge, or it may
be stored in an external data structure, or it may be computed on
the fly. This is an implementation detail of a particular property map.
See also Chapter \ref PkgPropertyMap.
\subsection BGLVisitors Visitors
Visitors are objects that provide functions to be called at
specified event points by the algorithm that they visit.
The functions as well as the event points are algorithm-specific.
Examples of such event points in graph algorithms are when a vertex is traversed the first time,
or when all outgoing edges of a vertex have been traversed.<BR>
See also Section <A HREF="https://www.boost.org/libs/graph/doc/visitor_concepts.html">Visitor Concepts</A>
in the \sc{Bgl} manual.
\subsection BGLNamedParameters Named Parameters
The notion of <I>named parameters</I> was introduced in the \sc{Bgl},
and allow the user to specify only those parameters which are really needed, by name, making the parameter ordering unimportant.
See also <a href="https://www.boost.org/libs/graph/doc/bgl_named_params.html">this page</a>
in the manual of the \sc{Bgl} for more information.
Say there is a function `f()` that takes 3 parameters called name, age and gender,
and you have variables `n`, `a` and `g` to pass as parameters to that function.
Without named parameters, you would call it like this: `f(n,a,g)`,
whereas with named parameters, you call it like this: `f(name(n).age(a).gender(g))`.
That is, you give each parameter a name by wrapping it into a function whose name
matches that of the parameter. The entire list of named parameters is really
a composition of function calls separated by a dot ("."). Thus, if the function
takes a mix of mandatory and named parameters, you use a comma to separate
the last non-named parameter from the first named parameters, like this:
\code{.cpp}
f(non_named_par0, non_named_par1, name(n).age(a).gender(g))
\endcode
When you use named parameters, the ordering is irrelevant, so `f(name(n).age(a).gender(g))`
is equivalent to `f(age(a).gender(g).name(n))`, and you can just omit any named parameter that has a default value.
The sequence of named parameters should start with `CGAL::parameters::`.
\subsubsection BGLNamedParametersExample Example
Below is a sample call of a function that uses the optional BGL named parameters.
\code
// pmesh : polygon mesh with patches to be refined
// faces : the range of faces defining the patches to refine
// faces_out : output iterator into which descriptors of new faces are put
// vertices_out : output iterator into which descriptors of new vertices are put
// vertex_point_map : the property map with the points associated to the vertices of `pmesh`
// density_control_factor : factor to control density of the output mesh
refine(pmesh,
faces,
faces_out,
vertices_out,
CGAL::parameters::vertex_point_map(vpmap)
.density_control_factor(d));
\endcode
\section BGLHeader Header Files, Namespaces, and Naming Conventions
This package provides the necessary classes and functions that enable using
\cgal data structures as models of the \sc{Bgl} graph concepts.
To this end, we offer partial specializations of the `boost::graph_traits<Graph>` for various \cgal packages.
For each such package, denoted `PACKAGE`, the partial specializations live in
the namespace `boost` and are located in the header file `CGAL/boost/graph/graph_traits_PACKAGE.h`.
Free functions are in the namespace `CGAL`, and the compiler uses argument-dependent lookup to find them.
%Euler operations, described in Section \ref BGLEulerOperations, are in the namespace `CGAL::Euler`, as the function `remove_face()` is at
the same time a low-level and an %Euler operation.
Concerning the naming conventions, we have to use those of the \sc{Bgl},
as to fulfill the requirements of the concepts defined in the \sc{Bgl}.
Note that these partial specializations are often providing more than
is required, making these classes not only models of the graph concepts
of the \sc{Bgl}, but also models of the CGAL graph concepts, that will be
described in detail in Section \ref BGLExtensions. Correspondence tables
between the types of a \cgal data structure and their \sc{Bgl} equivalents
can be found in the \ref PkgBGLTraits documentation page.
We present in the following sections some examples of utilization of some
\cgal data structures as \sc{Bgl} graphs.
\section BGLSurface_mesh The Class Surface_mesh as Model of the Boost Graph Concept
The class `Surface_mesh` is a model of most of the graph concepts of the \sc{Bgl}
as well as the concepts provided by \cgal. A complete list can
be found in the documentation of \link BGLSMGT boost::graph_traits \endlink.
The examples show how to use some of the \sc{Bgl} algorithms with `Surface_mesh` and show how to use
the concepts provided by \cgal to implement a simple algorithm.
\subsection BGLExampleMinimumSpanningTreeofaSurfaceMesh Example: Minimum Spanning Tree of a Surface_mesh
The following example program computes the minimum spanning tree on a surface mesh.
More examples can be found in Chapters
\ref PkgSurfaceMeshSimplification, \ref PkgSurfaceMeshSegmentation, and \ref PkgSurfaceMeshDeformation.
The surface mesh class uses integer indices to address vertices and edges,
and it comes with a built-in property mechanism that maps nicely on the \sc{Bgl}.
\cgalExample{BGL_surface_mesh/prim.cpp}
\section BGLPolyhedral The Class Polyhedron_3 as Model of the Boost Graph Concept
The class `Polyhedron_3` is a model of most of the graph concepts of the \sc{Bgl}
as well as the concepts provided by \cgal. A complete list can
be found in the documentation of \link BGLPolyGT boost::graph_traits \endlink.
The examples show how to use some of the \sc{Bgl} algorithms with `Polyhedron_3` and show how to use
the concepts provided by \cgal to implement a simple algorithm.
\subsection BGLExampleMinimumSpanningTreeofaPolyhedral Example: Minimum Spanning Tree of a Polyhedral Surface
The following example program computes the minimum spanning tree on a polyhedral surface.
More examples can be found in the Chapter
\ref PkgSurfaceMeshSimplification.
\cgalExample{BGL_polyhedron_3/kruskal.cpp}
\subsection BGLExampleUsingVerticesandEdgeswithanID Example: Using Vertices, and Edges with an ID
The following example program shows a call to the \sc{Bgl}
Kruskal's minimum spanning tree algorithm accessing the `id()`
field stored in a polyhedron vertex.
The main function illustrates the access to the `id()` field.
\cgalExample{BGL_polyhedron_3/kruskal_with_stored_id.cpp}
\section BGLTriangulations Triangulations as Models of the Boost Graph Concept
Triangulations have vertices and faces, allowing for a direct translation
as a graph. A halfedge is defined as a pair of a face handle and the
index of the edge. A complete list can be found in the documentation
of \link BGLT2GT boost::graph_traits \endlink.
A classical example for an algorithm that is a combination of
computational geometry and graph theory is the <I>Euclidean Minimum
Spanning Tree</I> for a point set in the plane. It can be computed by
running the minimum spanning tree algorithm on a Delaunay
triangulation of the point set.
\subsection BGLExampleEuclideanMinimumSpanningTree Example: Euclidean Minimum Spanning Tree
In the following example we create a Delaunay triangulation and run Kruskal's minimum
spanning tree algorithm on it. Because the vertex handles of the triangulation are not indices
in an array, we have to provide a property map that maps vertex handles to
integers in the range `[0, t.number_of_vertices())`.
\cgalExample{BGL_triangulation_2/emst.cpp}
\subsection BGLExampleStoringtheVertexIDintheVertex Example: Storing the Vertex ID in the Vertex
The algorithms of the \sc{Bgl} extensively use of the indices of
vertices. In the previous example we stored the indices in a `std::map`
and turned that map in a property map. This property map was then
passed as argument to the shortest path function.
If the user does not pass explicitly a property map, the graph algorithms
use the property map returned by the call `get(boost::vertex_index,ft)`.
This property map assumes that the vertex has a
member function `id()` that returns a reference to an int.
Therefore \cgal offers a class `Triangulation_vertex_base_with_id_2`.
It is in the user's responsibility to set the indices properly.
The example further illustrates that the graph traits also works
for the Delaunay triangulation.
\cgalExample{BGL_triangulation_2/dijkstra_with_internal_properties.cpp}
\section BGLArrangements Arrangements as Models of the Boost Graph Concept
\cgal offers a partial specialization of the boost graph traits for its arrangement
class as well as for its dual graph.
\subsection arr_sssecbgl_primal Example for the Arrangement as Graph
Arrangement instances are adapted to <I>boost</I> graphs by specializing the
`boost:graph_traits` template for `Arrangement_2` instances. The
graph-traits states the graph concepts that the arrangement class models
(see below) and defines the types required by these concepts.
In this specialization the `Arrangement_2` vertices correspond to the
graph vertices, where two vertices are adjacent if there is at least one
halfedge connecting them. More precisely, `Arrangement_2::Vertex_handle`
is the graph-vertex type, while `Arrangement_2::Halfedge_handle` is the
graph-edge type. As halfedges are directed, we consider the graph to be
directed as well. Moreover, as several interior-disjoint \f$ x\f$-monotone curves
(say circular arcs) may share two common endpoints, inducing an arrangement
with two vertices that are connected with several edges, we allow parallel
edges in our <I>boost</I> graph.
Given an `Arrangement_2` instance, we can efficiently traverse its
vertices and halfedges. Thus, the arrangement graph is a model of the concepts
`VertexListGraph` and `EdgeListGraph` introduced by the \sc{Bgl}.
At the same time, we use an iterator adapter of the circulator over the
halfedges incident to a vertex (`Halfedge_around_target_circulator` - see
Section \ref arr_sssectr_vertex "Traversal Methods for an Arrangement Vertex"
of the chapter on arrangements), so it is possible to go over the ingoing
and outgoing edges of a vertex in linear time. Thus, our arrangement graph
is a model of the concept `BidirectionalGraph` (this concept refines
`IncidenceGraph`, which requires only the traversal of outgoing edges).
It is important to notice that the vertex descriptors we use are
`Vertex_handle` objects and <I>not</I> vertex indices. However, in order
to gain more efficiency in most \sc{Bgl} algorithm, it is better to have them
indexed \f$ 0, 1, \ldots, (n-1)\f$, where \f$ n\f$ is the number of vertices. We
therefore introduce the `Arr_vertex_index_map<Arrangement>` class-template,
which maintains a mapping of vertex handles to indices, as required by the
\sc{Bgl}. An instance of this class must be attached to a valid arrangement
vertex when it is created. It uses the notification mechanism (see
Section \ref arr_secnotif) to automatically maintain the mapping of vertices
to indices, even when new vertices are inserted into the arrangement or
existing vertices are removed.
A complete description of the types correspondences
can be found in the documentation of \link BGLArgtGT boost::graph_traits \endlink.
In most algorithm provided by the \sc{Bgl}, the output is given by
<I>property maps</I>, such that each map entry corresponds to a vertex.
For example, when we compute the shortest paths from a given source vertex
\f$ s\f$ to all other vertices we can obtain a map of distances and a map of
predecessors - namely for each \f$ v\f$ vertex we have its distance from \f$ s\f$
and a descriptor of the vertex that precedes \f$ v\f$ in the shortest path from \f$ s\f$.
If the vertex descriptors are simply indices, one can use vectors to
efficiently represent the property maps. As this is not the case with the
arrangement graph, we offer the `Arr_vertex_property_map<Arrangement,Type>`
template allows for an efficient mapping of `Vertex_handle` objects to
properties of type `Type`. Note however that unlike the
`Arr_vertex_index_map` class, the vertex property-map class is not
kept synchronized with the number of vertices in the arrangement, so it
should not be reused in calls to the \sc{Bgl} functions in case the arrangement
is modified in between these calls.
\cgalFigureBegin{figex_bgl,ex_bgl.png}
An arrangement of 7 line segments, as constructed by `ex_bgl_primal_adapter.cpp` and `ex_bgl_dual_adapter.cpp`. The breadth-first visit times for the arrangement faces, starting from the unbounded face \f$ f_0\f$, are shown in brackets.
\cgalFigureEnd
In the following example we construct an arrangement of 7 line segments,
as shown in \cgalFigureRef{figex_bgl},
then use the \sc{Bgl} Dijkstra's shortest-paths algorithm to compute
the graph distance of all vertices from the leftmost vertex in the
arrangement \f$ v_0\f$. Note the usage of the `Arr_vertex_index_map` and
the `Arr_vertex_property_map` classes. The latter one, instantiated by
the type `double` is used to map vertices to their distances from \f$ v_0\f$.
\cgalExample{BGL_arrangement_2/primal.cpp}
\subsection arr_sssecbgl_dual Example for the Dual of an Arrangement as Graph
It is possible to give a dual graph representation for an arrangement instance,
such that each arrangement face corresponds to a graph vertex and two vertices
are adjacent iff the corresponding faces share a common edge on their
boundaries. This is done by specializing the
`boost:graph_traits` template for `Dual<Arrangement_2>` instances,
where `Dual<Arrangement_2>` is a template specialization that gives a
dual interpretation to an arrangement instance.
In dual representation, `Arrangement_2::Face_handle`
is the graph-vertex type, while `Arrangement_2::Halfedge_handle` is the
graph-edge type. We treat the graph edges as directed, such that a halfedge
`e` is directed from \f$ f_1\f$, which is its incident face, to \f$ f_2\f$, which
is the incident face of its twin halfedge. As two arrangement faces may
share more than a single edge on their boundary, we allow parallel
edges in our <I>boost</I> graph. As is the case in the primal graph, the dual
arrangement graph is also a model of the concepts `VertexListGraph`,
`EdgeListGraph` and `BidirectionalGraph` (thus also of
`IncidenceGraph`).
Since we use `Face_handle` objects as the vertex descriptors, we define
the `Arr_face_index_map<Arrangement>` class-template, which maintains an
efficient mapping of face handles to indices. We also provide the template
`Arr_face_property_map<Arrangement,Type>` for associating arbitrary
data with the arrangement faces.
In the following example we construct the same arrangement as in
example `ex_bgl_primal_adapter.cpp` (see \cgalFigureRef{arr_figex_bgl}),
and perform breadth-first search on the graph faces, starting from the
unbounded face. We extend the \sc{Dcel} faces
with an unsigned integer, marking the discover time of the face and use a
breadth-first-search visitor to obtain these times and update the faces
accordingly:
\cgalExample{BGL_arrangement_2/arrangement_dual.cpp}
\section BGLExtensions Extensions of the BGL
The previous sections introduced partial specializations
and free functions so that several \cgal data structures are adapted as models of some
of the \sc{Bgl} graph concepts.
In this section, we introduce new concepts, iterators, and property maps inspired
by the functionalities of the \sc{Bgl}.
\subsection BGLExtensionsGraphConcepts Graph concepts
In order to match \ref PkgHalfedgeDS more closely and to enable writing generic algorithms
which operate on data structures that have faces and halfedges, we define
a set of new concepts to extend the <a href="https://www.boost.org/libs/graph/doc/graph_concepts.html">graph concepts of the BGL</a>:
- `HalfedgeGraph` refines <a href="https://www.boost.org/libs/graph/doc/Graph.html">`Graph`</a>
with operations to accommodate halfedge data structures:
given a halfedge, say `h`, the concept `HalfedgeGraph` requires the provision
of the halfedge opposite to `h`, the halfedge that succeeds `h`,
and the halfedge that precedes `h`.
- `HalfedgeListGraph` adds the requirement for efficient traversal of
the halfedges of the graph.
- `MutableHalfedgeGraph` adds the requirement for operations to
change next/previous relations and to adjust the target of a halfedge.
- `FaceGraph` adds the requirements to explicitly handle faces in
a graph, to provide quick access to the incident halfedges of a face, and to
enable access from every halfedge to an adjacent face.
- `FaceListGraph` adds the requirement for efficient traversal of
the faces of a graph.
- `MutableFaceGraph` adds requirements to change adjacency of
faces and halfedges, and to remove and add faces.
A summary of the expressions and types associated with each of these concepts
as well as a refinement relation graph can be found in the
\ref PkgBGLConcepts documentation page.
\subsection BGLIteratorsAndCirculators Iterators and Circulators
By combining basic operations on graphs, we create various useful
\link devman_iterators_and_circulators iterators and circulators\endlink
to traverse specific types of elements. For example:
- Starting at a halfedge `h` of a halfedge graph `g`, applying several times `next(h,g)` brings us back
to the halfedge where we started. All halfedges traversed on the way are incident to the same face.
- Using the composition of the functions `next(h,g)` and `opposite(h,g)` results
in another cycle, namely the cycle of halfedges which are incident to
the same vertex.
A complete list of these traversal tools can be found in \link PkgBGLIterators the reference manual\endlink.
For convenience, two iterator and circulator types enable the traversal of all halfedges
incident to a given face, and all halfedges having a given vertex as target.
These types are not part of the concept `HalfedgeGraph`, but they
are class templates that work for any model of this concept.
\subsubsection BGLExampleIncidentVertices Example: Finding Incident Vertices in a HalfedgeGraph
The following example shows several functions to navigate in a `HalfedgeGraph`.
We have two implementations of the operation that finds the vertices adjacent to a vertex `v`.
Let us have a look at the first version. Given a vertex descriptor `vd`,
we first call `halfedge(vd,g)` to obtain the halfedge with `vd` as target.
Applying `source()` then gives us an adjacent vertex. We then get to the next halfedge
with `vd` as target, by first going to the next halfedge around the face, and then
going to the opposite halfedge.
The second version does the `%next()` and `%opposite()` jumping with an iterator.
Note that when calling `source()` we have to dereference `hi`, as the function
expects a halfedge descriptor and not a halfedge iterator.
Also observe that `halfedges_around_target()` expects a halfedge, and not a vertex.
This provides the user with the ability to start the traversal at a specific
halfedge incident to the input vertex (and not the arbitrary incident halfedge
stored in the vertex record.)
\cgalExample{BGL_polyhedron_3/incident_vertices.cpp}
\subsubsection BGLExampleNormalHalfedgeGraph Example: Calculating Facet Normals using HalfedgeGraph
The following example program shows a simple algorithm for calculating
facet normals for a polyhedron using the \sc{Bgl} API. A
<a href="https://www.boost.org/libs/property_map/doc/vector_property_map.html">boost::vector_property_map</a>
is used to to store the calculated normals instead of changing the Polyhedron items class.
\cgalExample{BGL_polyhedron_3/normals.cpp}
\subsection BGLProperties Properties and Dynamic Properties
As the concepts `HalfedgeGraph` and `FaceGraph` add the notion of halfedges and faces,
as well as a geometric embedding of the vertices, we have to add
property tags such as `face_index_t` and `vertex_point_t`.
We further add <em>dynamic properties</em> that enable the user
to add properties to vertices, halfedges, edges, and faces on the fly.
The lifetime of a dynamic property is bound to the lifetime
of the property map: reference counting is used to delete the property
when no map refers to it.
Dynamic property tags, such as `dynamic_vertex_property_t`, are a generalization of
`boost::vertex_index_t`, as they have a template parameter for the
value type of the dynamic property map, and a default value.
`boost::property_map<G,T>::%type` is used to obtain the
type of the dynamic property map for a graph of type `G`, for a
dynamic property tag `T`. This type must be default constructible and assignable.
As for ordinary properties, the function `%get()` is overloaded and
serves for retrieving a property map for a given graph and dynamic
property tag, as well as for retrieving a value for a given key and
property map.
The following example shows how to attach a `string` property to vertices and
a `double` value to the halfedges of a graph.
\cgalExample{Property_map/dynamic_properties.cpp}
\subsection BGLGraphIO Graph I/O
Using a common graph concept enables having common input/output functions for all the models
of this concept. The following file formats are supported for models of `FaceGraph`:
- \ref IOStreamOFF (`.off`)
- \ref IOStreamOBJ (`.obj`)
- \ref IOStreamSTL (`.stl`)
- \ref IOStreamPLY (`.ply`)
- \ref IOStreamGocad (`.ts`)
- \ref IOStreamVTK (`.vtp`)
See the page \ref PkgBGLIOFct for an exhaustive description of the I/O functions of this package.
\section BGLEulerOperations Euler Operations
There are two categories of mutating operations. The first category comprises
low level operations that change incidences such as the target vertex of a
halfedge.
A halfedge graph might turn invalid by the application of inconsistent
low lever operations. The second category of operations
are called <em>%Euler Operations</em>. These are high level operations such
as adding a center vertex to a face, which means also adding halfedges
and faces, and updating incidence information. The %Euler operations
enable manipulating models of `MutableFaceGraph`.
The complete list of Euler operations provided by this package can be found in
\link PkgBGLEulerOperations the reference manual\endlink.
\section BGLGraphAdaptors Graph Adaptors
Graph adaptors are classes that build an interface over an existing graph to provide
new functionalities. By operating almost entirely on the input graph, adaptors
can avoid potentially expensive operations, both in term of time and memory.
\subsection BGLDual The Dual Graph
The <em>dual graph</em> of a `FaceGraph` `G` is a graph that has a vertex for each
face of `G`. The dual graph has an edge whenever two faces of `G` are
separated from each other by an edge. Thus, each edge `e` of `G` has a
corresponding dual edge, the edge that connects the two faces on
either side of `e`.
Computing the dual graph of a graph has many uses, for example when one wishes
to compute the connected components of a mesh.
The class template `Dual` is an adaptor that creates the dual view of
a `FaceGraph`. Faces of the original graph correspond to vertices in
the `Dual` and vice versa.
Note that border edges in a `Dual` have the `null_face` of the
original graph as either source or target. This is unusual and might
break other algorithms since edges are always assumed to have non-null
vertices as a source and target. It is nevertheless possible to filter border edges
using <a href="https://www.boost.org/libs/graph/doc/filtered_graph.html">boost::filtered_graph</a>,
as shown in the following example.
\cgalExample{BGL_surface_mesh/surface_mesh_dual.cpp}
\subsection BGLSeamMesh The Seam Mesh
The class `Seam_mesh` allows to mark edges of a mesh as <em>seam edges</em>
so that they <em>virtually</em> become border edges when exploring a seam mesh with the \sc{Bgl} API.
The input mesh is referred to as <em>underlying</em> mesh of the seam mesh.
We denote `tm` and `sm` the underlying mesh and the seam mesh respectively.
Figure \cgalFigureRef{fig_Seam_mesh_1} shows an example of mesh on which two
edges, defined by the halfedge pairs `h2-h3` and `h6-h7`, are marked as seams.
The introduction of virtual borders modifies the elementary \sc{Bgl} graph traversal
operations: when we circulate around the target of `h7` in the underlying mesh,
we traverse `h7`, `h1`, `h3`, `h5`, before arriving at `h7` again.
However, when we circulate in the seam mesh, we traverse `h7`, `h1`, `h3*`,
before arriving at `h7` again.
Similarly, if we start at `h3`, we traverse `h3`, `h5`, `h7*`, and `h3` again.
\cgalFigureBegin{fig_Seam_mesh_1, seam_mesh_1.svg}
A seam mesh with two seam edges `(h2, h3)` and `(h6, h7)`.
\cgalFigureEnd
A vertex of the underlying mesh may correspond to multiple vertices in the seam mesh.
For example in Figure \cgalFigureRef{fig_Seam_mesh_1}, the target of `h7` corresponds to two
vertices in the seam mesh, on either side of the virtual border created by the seam edges.
For this reason, a vertex `v` of the seam mesh is internally represented as a halfedge `h`
of the seam mesh. To obtain a canonical definition, the halfedge `h` is defined as the halfedge
that has `v` as target, that lies on the seam, and that is not a border
halfedge. The function `target(hd, sm)` will return this halfedge.
For vertices `v` in the underlying mesh that are not on a seam edge, we choose
`halfedge(v, tm)` as its canonical halfedge.
\subsubsection BGLSeamMeshTraversal Seam Mesh Traversal
Using the function `next(halfedge_descriptor, FaceGraph)`, we can walk around a face but also around
a border of a mesh. For the seam mesh `sm` from Figure \cgalFigureRef{fig_Seam_mesh_1},
we have `opposite(h2, sm) == h3*`, and it holds that `face(h3*, sm) == null_face()`.
We can walk along this virtual border: starting at `h3*` and repeatedly calling `next(..,sm)`,
we will traverse `h6*`, `h7*`, `h2*`, before reaching `h3*` again.
All other traversal functions, iterators, and circulators (see \ref PkgBGLIterators) can
be used on a seam mesh, but their behavior is similarly modified by the (virtual and real)
border edges of the seam mesh.
\subsubsection BGLSeamMeshNature Seams
A collection of seam edges, or simply a <em>seam</em>, is not necessarily a simple polyline
as we can see in the next figure:
<UL>
<LI>In <em>(a)</em>, the seam forms a tree. Consequently, we pass at a vertex as often as
there are incident seam edges.
<LI>In <em>(b)</em>, the seam has a vertex `v` on the border of the underlying mesh.
While walking along the border of the seam mesh, we leave the border of the underlying mesh
when we reach `v` and walk on a virtual border until we reach `v` again, from the other side
of the seam.
<LI>In <em>(c)</em>, the seam forms a closed polyline. While the first two define a single border,
a cycle defines two borders and splits the set of faces in two connected components.
Something similar happens when the seam touches the same border more than once.
A seam can also connect different borders, potentially changing the genus of the mesh.
Finally, a seam may have more than one connected component.
</UL>
\cgalFigureBegin{fig_Seam_mesh_2, seam_mesh_2.svg}
Walking around a seam <em>(a)</em> with no seam vertex on the real border,
<em>(b)</em> with a seam vertex on the real border, <em>(c)</em> with a closed polyline.
Vertices of the seam mesh that are linked by a green dashed segment correspond
to the same vertex in the underlying mesh.
\cgalFigureEnd
Seam meshes are for example used in Chapter \ref PkgSurfaceMeshParameterization
to parameterize a topological sphere by first virtually cutting it into a topological
disk.
\section BGLPartitioning Graph Partitioning
For algorithms that operate locally, partitioning is often an easy way to parallelize
the algorithm at little cost.
The functions `CGAL::METIS::partition_graph()` and `CGAL::METIS::partition_dual_graph()`
provide wrappers to the graph partitioning library METIS \cgalCite{karypis1998fast},
allowing to split triangular meshes that are models of the concept `FaceListGraph`
into a given number of subdomains.
The following example shows how to read, partition, and write a mesh using
`partition_dual_graph()`. The class template `CGAL::Face_filtered_graph`
and the free function `copy_face_graph()` are used to create an independent mesh from one
of the subdomains of the partition. Note that the copy is optional as writing
can be done directly using `Face_filtered_graph`.
\cgalExample{BGL_surface_mesh/surface_mesh_partition.cpp}
Using \ref BGLNamedParameters some of the many options of METIS can be customized,
as shown in \ref BGL_polyhedron_3/polyhedron_partition.cpp "this example".
\section BGLGraphcut Graph Cut
An optimal partition from a set of labels can be computed through a
graph cut approach called alpha expansion
\cgalCite{Boykov2001FastApproximate}. \cgal provides
`CGAL::alpha_expansion_graphcut()` which, for a graph \f$(V,E)\f$,
computes the partition `f` that minimizes the following cost function:
\f[
\mathrm{C}(f) = \sum_{\{v0,v1\} \in E} C_E(v0,v1) + \sum_{v \in V} C_V(f_v)
\f]
where \f$C_E(v0,v1)\f$ is the edge cost of assigning a different label
to \f$v0\f$ and \f$v1\f$, and \f$C_V(f_v)\f$ is the vertex cost of
assigning the label \f$f\f$ to the vertex \f$v\f$.
Three different implementations are provided and can be selected by
using one of the following tags:
- `CGAL::Alpha_expansion_boost_adjacency_list_tag` (default)
- `CGAL::Alpha_expansion_boost_compressed_sparse_raw_tag`
- `CGAL::Alpha_expansion_MaxFlow_tag`, released under GPL
license and provided by the \ref PkgSurfaceMeshSegmentationRef
package
All these implementations produce the exact same result but behave
differently in terms of timing and memory (see
\cgalFigureRef{alpha_exp}). The _MaxFlow_ implementation is the
fastest, but it grows rapidly in memory when increasing the complexity
of the input graph and labeling; the _compressed sparse raw_ (CSR) is very
efficient from a memory point of view but becomes very slow as the
complexity of the input graph and labeling increases; the _adjacency
list_ version provides a good compromise and is therefore the default
implementation.
\cgalFigureBegin{alpha_exp, alpha_expansion.png}
Comparison of time and memory consumed by the different alpha
expansion implementations.
\cgalFigureEnd
\subsection BGLGraphcutExample Example
The following example shows how to apply the alpha expansion algorithm
to a `boost::adjacency_list` describing a 2D array with 3 labels "X",
" " and "O":
\cgalExample{BGL_graphcut/alpha_expansion_example.cpp}
The output of this program shows how the initial 2D array is
regularized spatially:
```
Input:
XOX
XX X O
OX OO
X OOX
OXOO
Alpha expansion...
Output:
XXX
XX O
XX OO
X OOO
OOOO
```
\subsection BGLGraphcutRegularizeSelection Application to Regularization of the Borders of a Face Selection
Manually selecting faces on a triangle mesh may create irregular
borders (sawtooth) because of the shape of the triangles. Such borders
can be regularized using the alpha expansion algorithm.
\cgal provides a function `CGAL::regularize_face_selection_borders()`
to apply this algorithm to the borders of a face selection on a
`FaceGraph`. \cgalFigureRef{regularization_fig} shows how this
function affects a selection depending on the parameters.
\cgalFigureBegin{regularization_fig, regularize_selection.png}
Regularization of the borders of a face selection using alpha
expansion. Different outputs are shown for different weight
parameters, with and without preventing unselection.
\cgalFigureEnd
The following example shows how to apply this alpha expansion
regularization to the borders of a face selection of a
`CGAL::Surface_mesh` object:
\cgalExample{BGL_graphcut/face_selection_borders_regularization_example.cpp}
*/
} /* namespace CGAL */