mirror of https://github.com/CGAL/cgal
228 lines
11 KiB
Plaintext
228 lines
11 KiB
Plaintext
|
|
namespace CGAL {
|
|
/*!
|
|
|
|
\mainpage User Manual
|
|
\anchor Chapter_Halfedge_Data_Structures
|
|
\anchor chapterHalfedgeDS
|
|
\cgalAutoToc
|
|
\author Lutz Kettner
|
|
|
|
\section HalfedgeDSIntroduction Introduction
|
|
|
|
A halfedge data structure (abbreviated as `HalfedgeDS`, or
|
|
`HDS` for template parameters) is an edge-centered data structure
|
|
capable of maintaining incidence information of vertices, edges and
|
|
faces, for example for planar maps, polyhedra, or other orientable,
|
|
two-dimensional surfaces embedded in arbitrary dimension. Each edge is
|
|
decomposed into two halfedges with opposite orientations. One incident
|
|
face and one incident vertex are stored in each halfedge. For each
|
|
face and each vertex, one incident halfedge is stored. Reduced
|
|
variants of the halfedge data structure can omit some of these
|
|
information, for example the halfedge pointers in faces or the
|
|
storage of faces at all.
|
|
|
|
\image html halfedge_small.png
|
|
\image latex halfedge_small.png
|
|
|
|
The halfedge data structure is a combinatorial data structure,
|
|
geometric interpretation is added by classes built on top of the
|
|
halfedge data structure. These classes might be more convenient to
|
|
use than the halfedge data structure directly, since the halfedge data
|
|
structure is meant as an implementation layer. See for example the
|
|
`Polyhedron_3` class in Chapter \ref chapterPolyhedron "Polyhedral Surface".
|
|
|
|
The data structure provided here is also known as the
|
|
FE-structure \cgalCite{w-ebdss-85}, as
|
|
halfedges \cgalCite{m-ism-88}, \cgalCite{cgal:bfh-mgedm-95} or as the doubly connected edge
|
|
list (DCEL) \cgalCite{bkos-cgaa-97}, although the original reference for
|
|
the DCEL \cgalCite{mp-fitcp-78} describes a different data structure. The
|
|
halfedge data structure can also be seen as one of the variants of the
|
|
quad-edge data structure \cgalCite{gs-pmgsc-85}. In general, the quad-edge
|
|
data can represent non-orientable 2-manifolds, but the variant here is
|
|
restricted to orientable 2-manifolds only. An overview and comparison
|
|
of these different data structures together with a thorough
|
|
description of the design implemented here can be found
|
|
in \cgalCite{k-ugpdd-99}.
|
|
|
|
|
|
|
|
\section HalfedgeDSSoftware Software Design
|
|
|
|
\cgalFigureBegin{figureHalfedgeDSDesign,hds_design_col.png}
|
|
Responsibilities of the different layers in the halfedge data-structure design.
|
|
\cgalFigureEnd
|
|
|
|
|
|
\cgalFigureRef{figureHalfedgeDSDesign}
|
|
illustrates the responsibilities of the three layers of the software
|
|
design, with the `Polyhedron_3` as an example for the top
|
|
layer. The items provide the space for the information that is
|
|
actually stored, i.e., with member variables and access member
|
|
functions in `Vertex`, `Halfedge`, and `Face`
|
|
respectively. Halfedges are required to provide a reference to the
|
|
next halfedge and to the opposite halfedge. Optionally they may
|
|
provide a reference to the previous halfedge, to the incident vertex,
|
|
and to the incident face. Vertices and faces may be empty. Optionally
|
|
they may provide a reference to the incident halfedge. The options
|
|
mentioned are supported in the halfedge data structure and the
|
|
polyhedron, for example, Euler operations update the optional
|
|
references if they are present. Furthermore, the item classes can be
|
|
extended with arbitrary attributes and member functions, which will be
|
|
promoted by inheritance to the actual classes used for the polyhedron.
|
|
|
|
Vertices, halfedges, and faces are passed as local types of the
|
|
`Items` class to the halfedge data structure and polyhedron.
|
|
Implementations for vertices, halfedges and faces are provided that
|
|
fulfill the mandatory part of the requirements. They can be used as
|
|
base classes for extensions by the user. Richer implementations are
|
|
also provided to serve as defaults; for polyhedra they provide all
|
|
optional incidences, a three-dimensional point in the vertex type and
|
|
a plane equation in the face type.
|
|
|
|
The Halfedge data structure concept `HalfedgeDS`, is
|
|
responsible for the storage organization of the items. Currently,
|
|
implementations using internally a bidirectional list or a
|
|
vector are provided. The `HalfedgeDS` defines the handles and iterators
|
|
belonging to the items. These types are promoted to the declaration of
|
|
the items themselves and are used there to provide the references to
|
|
the incident items. This promotion of types is done with a template
|
|
parameter `Refs` of the item types. The halfedge data structure
|
|
provides member functions to insert and delete items, to traverse all
|
|
items, and it gives access to the items.
|
|
|
|
There are two different models for the `HalfedgeDS` concept available,
|
|
`HalfedgeDS_list` and `HalfedgeDS_vector`, and more might come.
|
|
Therefore we have kept their interface small and factored out common
|
|
functionality into separate helper classes, `HalfedgeDS_decorator`,
|
|
`HalfedgeDS_const_decorator`, and `HalfedgeDS_items_decorator`, which
|
|
are not shown in \cgalFigureRef{figureHalfedgeDSDesign}, but would be
|
|
placed at the side of the `HalfedgeDS` since they broaden that
|
|
interface but do not hide it. These helper classes contain operations
|
|
that are useful to implement the operations in the next layer, for
|
|
example, the polyhedron. They add, for example, the Euler operations
|
|
and partial operations from which further Euler operations can be
|
|
built, such as inserting an edge into the ring of edges at a
|
|
vertex. Furthermore, the helper classes contain adaptive
|
|
functionality. For example, if the `HalfedgeDSHalfedge::prev()` member function is not
|
|
provided for halfedges, the `HalfedgeDS_items_decorator::find_prev()` member function of a helper
|
|
class searches in the positive direction along the face for the
|
|
previous halfedge. But if the `HalfedgeDSHalfedge::prev()` member function is provided,
|
|
the `HalfedgeDS_items_decorator::find_prev()` member function simply calls it. This distinction is
|
|
resolved at compile time with a technique called <I>compile-time
|
|
tags</I>, similar to iterator tags in \cgalCite{cgal:sl-stl-95}.
|
|
|
|
The `Polyhedron_3` as an example for the third layer adds the
|
|
geometric interpretation, provides an easy-to-use interface of
|
|
high-level functions, and unifies the access to the flexibility
|
|
provided underneath. It renames face to facet, which is more common
|
|
for three-dimensional surfaces. The interface is designed to protect
|
|
the integrity of the internal representation, the handles stored in
|
|
the items can no longer directly be written by the user. The
|
|
polyhedron adds the convenient and efficient circulators, see
|
|
`Circulator`, for accessing the circular sequence of edges
|
|
around a vertex or around a facet. To achieve this, the
|
|
`Polyhedron_3` derives new vertices, halfedges and facets from those
|
|
provided in `Items`. These new items are those actually used in
|
|
the `HalfedgeDS`, which gives us the coherent type
|
|
structure in this design, especially if compared to our previous
|
|
design.
|
|
|
|
\section HalfedgeDSExample Example Programs
|
|
|
|
\anchor sectionHdsExamples
|
|
|
|
\subsection HalfedgeDSTheDefaultHalfedgeDataStructure The Default Halfedge Data Structure
|
|
|
|
The following example program uses the default halfedge data structure
|
|
and the decorator class. The default halfedge data structure uses a
|
|
list-based representation. All incidences of the items and a point
|
|
type for vertices are defined. The trivial traits class provides the
|
|
type used for the point. The program creates a loop, consisting
|
|
of two halfedges, one vertex and two faces, and checks its validity.
|
|
|
|
\image html loop.png
|
|
\image latex loop.png
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_default.cpp}
|
|
|
|
\subsection HalfedgeDSAMinimalHalfedgeDataStructure A Minimal Halfedge Data Structure
|
|
|
|
The following program defines a minimal halfedge data structure using
|
|
the minimal items class `HalfedgeDS_min_items` and a
|
|
list-based halfedge data structure. The result is a data structure
|
|
maintaining only halfedges with next and opposite pointers. No
|
|
vertices or faces are stored. The data structure represents an <I>undirected graph</I>.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_graph.cpp}
|
|
|
|
\subsection HalfedgeDSTheDefaultwithaVectorInsteadof The Default with a Vector Instead of a List
|
|
|
|
The default halfedge data structure uses a list internally and the
|
|
maximal base classes. We change the list to a vector representation
|
|
here. Again, a trivial traits class provides the type used for the
|
|
point. Note that for the vector storage the size of the halfedge data
|
|
structure should be reserved beforehand, either with the constructor
|
|
as shown in the example or with the `reserve()` member function.
|
|
One can later resize the data structure with further calls to the
|
|
`reserve()` member function, but only if the data structure is
|
|
in a consistent, i.e., <I>valid</I>, state.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_vector.cpp}
|
|
|
|
\subsection HalfedgeDSExampleAddingColortoFaces Example Adding Color to Faces
|
|
|
|
This example re-uses the base class available for faces and adds a
|
|
member variable `color`.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_color.cpp}
|
|
|
|
\subsection HalfedgeDSExampleDefiningaMoreCompactHalfedge Example Defining a More Compact Halfedge
|
|
|
|
The halfedge data structure as presented here is slightly less space
|
|
efficient as, for example, the winged-edge data
|
|
structure \cgalCite{b-prcv-75}, the DCEL \cgalCite{mp-fitcp-78} or variants of
|
|
the quad-edge data structure \cgalCite{gs-pmgsc-85}. On the other hand,
|
|
it does not require any search operations during traversals. A
|
|
comparison can be found in \cgalCite{k-ugpdd-99}.
|
|
|
|
The following example trades traversal time for a compact storage
|
|
representation using traditional C techniques (i.e., type casting and
|
|
the assumption that pointers, especially those from <TT>malloc</TT> or
|
|
<TT>new</TT>, point to even addresses). The idea goes as follows: The
|
|
halfedge data structure allocates halfedges pairwise. Concerning the
|
|
vector-based data structure this implies that the absolute value of
|
|
the difference between a halfedge and its opposite halfedge is always
|
|
one with respect to C pointer arithmetic. We can replace the opposite
|
|
pointer by a single bit encoding the sign of this difference. We will
|
|
store this bit as the least significant bit in the next halfedge
|
|
handle. Furthermore, we do not implement a pointer to the previous
|
|
halfedge. What remains are three pointers per halfedge.
|
|
|
|
We use the static member function `HalfedgeDS::halfedge_handle()` to convert
|
|
from pointers to halfedge handles. The same solution can be applied to
|
|
the list-based halfedge data structure `HalfedgeDS_list`,
|
|
see <TT>examples/HalfedgeDS/hds_prog_compact2.cpp</TT>. Here is the
|
|
example for the vector-based data structure.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_compact.cpp}
|
|
|
|
\subsection HalfedgeDSExampleUsingtheHalfedgeIterator Example Using the Halfedge Iterator
|
|
|
|
Two edges are created in the default halfedge data structure.
|
|
The halfedge iterator is used to count the halfedges.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_halfedge_iterator.cpp}
|
|
|
|
\subsection HalfedgeDSExampleforanAdaptertoBuildanEdge Example for an Adapter to Build an Edge Iterator
|
|
|
|
Three edges are created in the default halfedge data structure.
|
|
The adapter `N_step_adaptor` is used to declare the edge
|
|
iterator used in counting the edges.
|
|
|
|
\cgalExample{HalfedgeDS/hds_prog_edge_iterator.cpp}
|
|
|
|
*/
|
|
} /* namespace CGAL */
|
|
|