Merge branch 'master' into 'sloriot/CGAL-using_c++17_stl'

This commit is contained in:
Sébastien Loriot 2023-08-14 14:19:25 +02:00
commit eada3ee8ca
373 changed files with 22609 additions and 18444 deletions

35
.github/workflows/reuse.yml vendored Normal file
View File

@ -0,0 +1,35 @@
# SPDX-FileCopyrightText: 2020 Free Software Foundation Europe e.V. <https://fsfe.org>
#
# SPDX-License-Identifier: GPL-3.0-or-later
name: REUSE Compliance Check
on: [push, pull_request]
jobs:
reuse:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: REUSE version
uses: fsfe/reuse-action@v2
with:
args: --version
- name: REUSE lint
uses: fsfe/reuse-action@v2
with:
args: --include-submodules lint
- name: REUSE SPDX SBOM
uses: fsfe/reuse-action@v2
with:
args: spdx
- name: install dependencies
run: sudo apt-get install -y cmake
- name: Create CGAL internal release
run: |
mkdir -p ./release
cmake -DDESTINATION=./release -DCGAL_VERSION=9.9 -P ./Scripts/developer_scripts/cgal_create_release_with_cmake.cmake
- name: REUSE lint release tarball
uses: fsfe/reuse-action@v2
with:
args: --root ./release/CGAL-9.9 --include-submodules lint

12
.reuse/dep5 Normal file
View File

@ -0,0 +1,12 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: CGAL
Upstream-Contact: CGAL Editorial Board <info@cgal.org>
Source: https://github.com/CGAL/cgal
Files: .* *.cmake *.md .github/* Maintenance/* */TODO */doc/* */deb/* */applications/* */doc_html/* */scripts/* */developer_scripts/* */demo/* */examples/* */src/* */test/* */benchmarks/* */benchmark/* */package_info/* */data/* */cmake/*
Copyright: 1995-2023 The CGAL Project
License: CC0-1.0
Files: CMakeLists.txt GraphicsView/include/CGAL/Qt/ImageInterface.ui GraphicsView/include/CGAL/Qt/resources/qglviewer-icon.xpm Installation/AUTHORS Installation/CMakeLists.txt Installation/README Installation/auxiliary/cgal_create_cmake_script.1 Installation/auxiliary/gmp/README Installation/include/CGAL/license/gpl_package_list.txt MacOSX/auxiliary/cgal_app.icns copyright
Copyright: 1995-2023 The CGAL Project
License: CC0-1.0

View File

@ -33,7 +33,7 @@ namespace CGAL {
/*! /*!
* \ingroup PkgAABBTreeRef * \ingroup PkgAABBTreeRef
* Primitive type for a edge of a polyhedral surface. * Primitive type for an edge of a polyhedral surface.
* It wraps an `edge_descriptor` into a 3D segment. * It wraps an `edge_descriptor` into a 3D segment.
* The class model of `HalfedgeGraph` from which the primitive is built should not be deleted * The class model of `HalfedgeGraph` from which the primitive is built should not be deleted
* while the AABB tree holding the primitive is in use. * while the AABB tree holding the primitive is in use.

View File

@ -142,7 +142,7 @@ namespace CGAL {
/// An explicit call to `build()` must be made to ensure that the next call to /// An explicit call to `build()` must be made to ensure that the next call to
/// a query function will not trigger the construction of the data structure. /// a query function will not trigger the construction of the data structure.
/// A call to `AABBTraits::set_shared_data(t...)` is made using the internally stored traits. /// A call to `AABBTraits::set_shared_data(t...)` is made using the internally stored traits.
/// This procedure has a complexity of \f$O(n log(n))\f$, where \f$n\f$ is the number of /// This procedure has a complexity of \cgalBigO{n log(n)}, where \f$n\f$ is the number of
/// primitives of the tree. /// primitives of the tree.
template<typename ... T> template<typename ... T>
void build(T&& ...); void build(T&& ...);

View File

@ -3,7 +3,7 @@
\ingroup PkgAlgebraicFoundationsAlgebraicStructuresConcepts \ingroup PkgAlgebraicFoundationsAlgebraicStructuresConcepts
\cgalConcept \cgalConcept
A model of `EuclideanRing` represents an euclidean ring (or Euclidean domain). A model of `EuclideanRing` represents a Euclidean ring (or Euclidean domain).
It is an `UniqueFactorizationDomain` that affords a suitable notion of minimality of remainders It is an `UniqueFactorizationDomain` that affords a suitable notion of minimality of remainders
such that given \f$ x\f$ and \f$ y \neq 0\f$ we obtain an (almost) unique solution to such that given \f$ x\f$ and \f$ y \neq 0\f$ we obtain an (almost) unique solution to
\f$ x = qy + r \f$ by demanding that a solution \f$ (q,r)\f$ is chosen to minimize \f$ r\f$. \f$ x = qy + r \f$ by demanding that a solution \f$ (q,r)\f$ is chosen to minimize \f$ r\f$.

View File

@ -613,7 +613,7 @@ public:
/* /*
* \brief returns the indices of the <tt>i</tt>th event value * \brief returns the indices of the <tt>i</tt>th event value
* *
* Returns a Event_indices <tt>(fg,ffy,ggy)</tt> such that * Returns an `Event_indices` <tt>(fg,ffy,ggy)</tt> such that
* the <tt>i</tt>th event root is the <tt>fg</tt>th root of the * the <tt>i</tt>th event root is the <tt>fg</tt>th root of the
* resultant of \c f and \c g, the <tt>ffy</tt>th root of the * resultant of \c f and \c g, the <tt>ffy</tt>th root of the
* discriminant of \c f, and the <tt>ggy</tt>th root of the * discriminant of \c f, and the <tt>ggy</tt>th root of the

View File

@ -254,7 +254,7 @@ public:
/*! /*!
* \brief y-coordinate of this point * \brief y-coordinate of this point
* *
* Note: In general, this method results in a extremely large polynomial * Note: In general, this method results in an extremely large polynomial
* for the y-coordinate. It is recommended to use it carefully, * for the y-coordinate. It is recommended to use it carefully,
* and using get_approximation_y() instead whenever approximations suffice. * and using get_approximation_y() instead whenever approximations suffice.
*/ */

View File

@ -80,7 +80,7 @@ use binary search.
`Alpha_shape_2::number_of_solid_components()` performs a graph traversal and takes time `Alpha_shape_2::number_of_solid_components()` performs a graph traversal and takes time
linear in the number of faces of the underlying triangulation. linear in the number of faces of the underlying triangulation.
`Alpha_shape_2::find_optimal_alpha()` uses binary search and takes time `Alpha_shape_2::find_optimal_alpha()` uses binary search and takes time
\f$ O(n \log n)\f$, where \f$ n\f$ is the number of points. \cgalBigO{n \log n}, where \f$ n\f$ is the number of points.
*/ */
template< typename Dt, typename ExactAlphaComparisonTag > template< typename Dt, typename ExactAlphaComparisonTag >

View File

@ -77,7 +77,7 @@ use binary search.
`Alpha_shape_3::number_of_solid_components()` performs a graph traversal and takes time `Alpha_shape_3::number_of_solid_components()` performs a graph traversal and takes time
linear in the number of cells of the underlying triangulation. linear in the number of cells of the underlying triangulation.
`Alpha_shape_3::find_optimal_alpha()` uses binary search and takes time `Alpha_shape_3::find_optimal_alpha()` uses binary search and takes time
\f$ O(n \log n)\f$, where \f$ n\f$ is the number of points. \cgalBigO{n \log n}, where \f$ n\f$ is the number of points.
*/ */
template< typename Dt, typename ExactAlphaComparisonTag > template< typename Dt, typename ExactAlphaComparisonTag >

View File

@ -173,7 +173,7 @@ class Alpha_wrap_3
using Alpha_PQ = Modifiable_priority_queue<Gate, Less_gate, Gate_ID_PM<Dt>, CGAL_BOOST_PAIRING_HEAP>; using Alpha_PQ = Modifiable_priority_queue<Gate, Less_gate, Gate_ID_PM<Dt>, CGAL_BOOST_PAIRING_HEAP>;
protected: protected:
const Oracle& m_oracle; const Oracle m_oracle;
SC_Iso_cuboid_3 m_bbox; SC_Iso_cuboid_3 m_bbox;
FT m_alpha, m_sq_alpha; FT m_alpha, m_sq_alpha;
@ -1343,6 +1343,7 @@ private:
return true; return true;
} }
public:
// Not the best complexity, but it's very cheap compared to the rest of the algorithm. // Not the best complexity, but it's very cheap compared to the rest of the algorithm.
void make_manifold() void make_manifold()
{ {

View File

@ -608,24 +608,22 @@ Vertex_handle nearest_neighbor(const Point_2& p, Vertex_handle vnear) const;
/*! /*!
Returns the Returns the
dual corresponding to the face handle `f`. The returned object can dual corresponding to the face handle `f`. The returned object can
be assignable to one of the following: `Site_2`, `Gt::Line_2`. be assigned to one of the following: `Site_2`, `Gt::Line_2`.
*/ */
Gt::Object_2 dual(Face_handle f) const; Gt::Object_2 dual(Face_handle f) const;
/*! /*!
Returns the Returns the
dual of the face to which `it` points to. The returned object can dual of the face to which `it` points to. The returned object can
be assignable to one of the following: `Site_2`, `Gt::Line_2`. be assigned to one of the following: `Site_2`, `Gt::Line_2`.
*/ */
Gt::Object_2 dual(All_faces_iterator it) const; Gt::Object_2 dual(All_faces_iterator it) const;
/*! /*!
Returns Returns
the dual of the face to which `it` points to. The returned the dual of the face to which `it` points to.
object can be assignable to one of the following: `Site_2`,
`Gt::Line_2`.
*/ */
Gt::Object_2 dual(Finite_faces_iterator it) const; Site dual(Finite_faces_iterator it) const;
/// @} /// @}

View File

@ -7,9 +7,12 @@ namespace CGAL {
The class `Apollonius_graph_vertex_base_2` provides a model for the The class `Apollonius_graph_vertex_base_2` provides a model for the
`ApolloniusGraphVertexBase_2` concept which is the vertex base `ApolloniusGraphVertexBase_2` concept which is the vertex base
required by the `ApolloniusGraphDataStructure_2` concept. The required by the `ApolloniusGraphDataStructure_2` concept. The
class `Apollonius_graph_vertex_base_2` has two template arguments, the first being the class `Apollonius_graph_vertex_base_2` has three template arguments.
geometric traits of the Apollonius graph and should be a model of the
concept `ApolloniusGraphTraits_2`. The second is a Boolean which \tparam Gt is the geometric traits of the Apollonius graph and must be a model of the
concept `ApolloniusGraphTraits_2`.
\tparam StoreHidden is a Boolean which
controls whether hidden sites are actually stored. Such a controls whether hidden sites are actually stored. Such a
control is important if the user is not interested in hidden sites control is important if the user is not interested in hidden sites
and/or if only insertions are made, in which case no hidden and/or if only insertions are made, in which case no hidden
@ -17,13 +20,17 @@ site can become visible. If `StoreHidden` is set to
`true`, hidden sites are stored, otherwise they are `true`, hidden sites are stored, otherwise they are
discarded. By default `StoreHidden` is set to `true`. discarded. By default `StoreHidden` is set to `true`.
\tparam Vb must be a model of the concept `TriangulationDSVertexBase_2`
By default this parameter is
instantiated by `Triangulation_ds_vertex_base_2<>`.
\cgalModels `ApolloniusGraphVertexBase_2` \cgalModels `ApolloniusGraphVertexBase_2`
\sa `CGAL::Triangulation_data_structure_2<Vb,Fb>` \sa `CGAL::Triangulation_data_structure_2<Vb,Fb>`
\sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2<Gt>` \sa `CGAL::Apollonius_graph_hierarchy_vertex_base_2<Gt>`
*/ */
template< typename Gt, typename StoreHidden > template< typename Gt, typename StoreHidden, typename Vb >
class Apollonius_graph_vertex_base_2 { class Apollonius_graph_vertex_base_2 : public Vb {
public: public:
/// \name Creation /// \name Creation

View File

@ -39,6 +39,7 @@ if(GMP_FOUND)
create_single_source_cgal_program("Arithmetic_kernel.cpp") create_single_source_cgal_program("Arithmetic_kernel.cpp")
create_single_source_cgal_program("LEDA_arithmetic_kernel.cpp") create_single_source_cgal_program("LEDA_arithmetic_kernel.cpp")
create_single_source_cgal_program("CORE_arithmetic_kernel.cpp") create_single_source_cgal_program("CORE_arithmetic_kernel.cpp")
create_single_source_cgal_program("GMPXX_arithmetic_kernel.cpp")
create_single_source_cgal_program("Get_arithmetic_kernel.cpp") create_single_source_cgal_program("Get_arithmetic_kernel.cpp")
else() else()

View File

@ -12,7 +12,7 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// SPDX-License-Identifier: GPL-3.0+ // SPDX-License-Identifier: GPL-3.0-or-later
// //
// Author(s): Saurabh Singh <ssingh@cs.iitr.ac.in> // Author(s): Saurabh Singh <ssingh@cs.iitr.ac.in>
// Ahmed Essam <theartful.ae@gmail.com> // Ahmed Essam <theartful.ae@gmail.com>

View File

@ -12,7 +12,7 @@
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
// //
// SPDX-License-Identifier: GPL-3.0+ // SPDX-License-Identifier: GPL-3.0-or-later
// //
// Author(s): Saurabh Singh <ssingh@cs.iitr.ac.in> // Author(s): Saurabh Singh <ssingh@cs.iitr.ac.in>
// Ahmed Essam <theartful.ae@gmail.com> // Ahmed Essam <theartful.ae@gmail.com>

View File

@ -1223,10 +1223,10 @@ halfedge \f$e_{\mathrm{pred}}\f$ directed toward \f$v\f$, such that
\f$c\f$ is located between the curves associated with \f$c\f$ is located between the curves associated with
\f$e_{\mathrm{pred}}\f$ and the next halfedge in the clockwise order \f$e_{\mathrm{pred}}\f$ and the next halfedge in the clockwise order
in the circular list of halfedges around \f$v\f$; see in the circular list of halfedges around \f$v\f$; see
\cgalFigureRef{aos_fig-insert}. This search may take \f$O(d)\f$ time, \cgalFigureRef{aos_fig-insert}. This search may take \cgalBigO{d} time,
where \f$d\f$ is the degree of the vertex \f$v\f$. \cgalFootnote{We where \f$d\f$ is the degree of the vertex \f$v\f$. \cgalFootnote{We
can store the handles to the halfedges incident to \f$v\f$ in an efficient can store the handles to the halfedges incident to \f$v\f$ in an efficient
search structure to obtain \f$O(\log d)\f$ access time. However, as search structure to obtain \cgalBigO{\log d} access time. However, as
\f$d\f$ is usually very small, this may lead to a waste of storage \f$d\f$ is usually very small, this may lead to a waste of storage
space without a meaningful improvement in running time in practice.} space without a meaningful improvement in running time in practice.}
However, if the halfedge \f$e_{\mathrm{pred}}\f$ is known in advance, However, if the halfedge \f$e_{\mathrm{pred}}\f$ is known in advance,
@ -1488,9 +1488,9 @@ keep up-to-date as this arrangement changes.
As mentioned above, the triangulation strategy is provided only for As mentioned above, the triangulation strategy is provided only for
educational purposes, and thus we do not elaborate on this strategy. educational purposes, and thus we do not elaborate on this strategy.
The data structure needed by the landmark and the trapezoidal map RIC The data structure needed by the landmark and the trapezoidal map RIC
strategies can be constructed in \f$O(N \log N)\f$ time, where \f$N\f$ strategies can be constructed in \cgalBigO{N \log N} time, where \f$N\f$
is the overall number of edges in the arrangement, but the constant is the overall number of edges in the arrangement, but the constant
hidden in the \f$O()\f$ notation for the trapezoidal map RIC strategy hidden in the \cgalBigO{&nbsp;} notation for the trapezoidal map RIC strategy
is much larger. Thus, construction needed by the landmark algorithm is is much larger. Thus, construction needed by the landmark algorithm is
in practice significantly faster than the construction needed by the in practice significantly faster than the construction needed by the
trapezoidal map RIC strategy. In addition, although both resulting trapezoidal map RIC strategy. In addition, although both resulting
@ -1647,7 +1647,7 @@ Section \ref arr_ssecpl. The output pairs are sorted in increasing
\f$xy\f$-lexicographical order of the query point. \f$xy\f$-lexicographical order of the query point.
The batched point-location operation is carried out by sweeping the The batched point-location operation is carried out by sweeping the
arrangement. Thus, it takes \f$O((m+N)\log{(m+N)})\f$ time, where arrangement. Thus, it takes \cgalBigO{(m+N)\log{(m+N)}} time, where
\f$N\f$ is the number of edges in the arrangement. Issuing separate \f$N\f$ is the number of edges in the arrangement. Issuing separate
queries exploiting a point-location strategy with logarithmic query queries exploiting a point-location strategy with logarithmic query
time per query, such as the trapezoidal map RIC strategy (see Section time per query, such as the trapezoidal map RIC strategy (see Section
@ -2037,11 +2037,11 @@ so it must be construct from scratch.
In the first case, we sweep over the input curves, compute their In the first case, we sweep over the input curves, compute their
intersection points, and construct the \dcel that represents their intersection points, and construct the \dcel that represents their
arrangement. This process is performed in \f$O\left((n + k)\log arrangement. This process is performed in \cgalBigO{left((n + k)\log
n\right)\f$ time, where \f$k\f$ is the total number of intersection n\right} time, where \f$k\f$ is the total number of intersection
points. The running time is asymptotically better than the time needed points. The running time is asymptotically better than the time needed
for incremental insertion if the arrangement is relatively sparse for incremental insertion if the arrangement is relatively sparse
(when \f$k\f$ is \f$O(\frac{n^2}{\log n}\f$)), but it is recommended (when \f$k\f$ is \cgalBigO{\frac{n^2}{\log n}}), but it is recommended
that this aggregate construction process be used even for dense that this aggregate construction process be used even for dense
arrangements, since the plane-sweep algorithm performs fewer geometric arrangements, since the plane-sweep algorithm performs fewer geometric
operations compared to the incremental insertion algorithms, and hence operations compared to the incremental insertion algorithms, and hence
@ -4346,7 +4346,7 @@ a point with respect to an \f$x\f$-monotone polyline, we use binary
search to locate the relevant segment that contains the point in its search to locate the relevant segment that contains the point in its
\f$x\f$-range. Then, we compute the position of the point with respect \f$x\f$-range. Then, we compute the position of the point with respect
to this segment. Thus, operations on \f$x\f$-monotone polylines of to this segment. Thus, operations on \f$x\f$-monotone polylines of
size \f$m\f$ typically take \f$O(\log m)\f$ time. size \f$m\f$ typically take \cgalBigO{\log m} time.
You are free to choose the underlying segment traits class. Your You are free to choose the underlying segment traits class. Your
decision could be based, for example, on the number of expected decision could be based, for example, on the number of expected

View File

@ -12,9 +12,9 @@ Seidel \cgalCite{s-sfira-91} (see also [\cgalCite{bkos-cgaa-00} Chapter 6).
It subdivides each arrangement face to pseudo-trapezoidal cells, each It subdivides each arrangement face to pseudo-trapezoidal cells, each
of constant complexity, and constructs and maintains a linear-size search of constant complexity, and constructs and maintains a linear-size search
structure on top of these cells, such that each query can be answered structure on top of these cells, such that each query can be answered
in \f$ O(\log n)\f$ time, where \f$ n\f$ is the complexity of the arrangement. in \cgalBigO{\log n} time, where \f$ n\f$ is the complexity of the arrangement.
Constructing the search structures takes \f$ O(n \log n)\f$ expected time Constructing the search structures takes \cgalBigO{n \log n} expected time
and may require a small number of rebuilds \cgalCite{hkh-iiplgtds-12}. Therefore and may require a small number of rebuilds \cgalCite{hkh-iiplgtds-12}. Therefore
attaching a trapezoidal point-location object to an existing arrangement attaching a trapezoidal point-location object to an existing arrangement
may incur some overhead in running times. In addition, the point-location may incur some overhead in running times. In addition, the point-location

View File

@ -105,7 +105,7 @@ locate(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
} }
} }
// Obtain a extended traits-class object. // Obtain an extended traits-class object.
const Gt2* geom_traits = arr.geometry_traits(); const Gt2* geom_traits = arr.geometry_traits();
/* We would like to avoid copy construction of the geometry traits class. /* We would like to avoid copy construction of the geometry traits class.

View File

@ -447,7 +447,7 @@ namespace CGAL {
} }
// a empty class used to have different types between Curve_2 and X_monotone_curve_2 // an empty class used to have different types between Curve_2 and X_monotone_curve_2
// in Arr_circular_line_arc_traits_2. // in Arr_circular_line_arc_traits_2.
namespace internal_Argt_traits{ namespace internal_Argt_traits{
struct Not_X_Monotone{}; struct Not_X_Monotone{};

View File

@ -231,7 +231,7 @@ overlay(const Arrangement_on_surface_2<GeometryTraitsA_2, TopologyTraitsA>& arr1
xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2); xcvs_vec[i] = Ovl_x_monotone_curve_2(eit2->curve(), invalid_he1, he2);
} }
// Obtain a extended traits-class object and define the sweep-line visitor. // Obtain an extended traits-class object and define the sweep-line visitor.
const typename Arr_res::Traits_adaptor_2* traits_adaptor = const typename Arr_res::Traits_adaptor_2* traits_adaptor =
arr.traits_adaptor(); arr.traits_adaptor();

View File

@ -411,7 +411,7 @@ public:
} }
}; };
/*! Obtain a Equal_2 function object. */ /*! Obtain an `Equal_2` function object. */
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ return (Equal_2(m_base_traits->equal_2_object())); } { return (Equal_2(m_base_traits->equal_2_object())); }

View File

@ -2419,7 +2419,7 @@ protected:
/*! Obtain the index of the subcurve in the polycurve that contains the /*! Obtain the index of the subcurve in the polycurve that contains the
* point q in its x-range. The function performs a binary search, so if the * point q in its x-range. The function performs a binary search, so if the
* point q is in the x-range of the polycurve with n subcurves, the subcurve * point q is in the x-range of the polycurve with n subcurves, the subcurve
* containing it can be located in O(log n) operations. * containing it can be located in \cgalBigO{log n} operations.
* \param cv The polycurve curve. * \param cv The polycurve curve.
* \param q The point. * \param q The point.
* \return An index i such that q is in the x-range of cv[i]. * \return An index i such that q is in the x-range of cv[i].

View File

@ -109,7 +109,7 @@ decompose(const Arrangement_on_surface_2<GeometryTraits_2, TopologyTraits>& arr,
} }
} }
// Obtain a extended traits-class object. // Obtain an extended traits-class object.
const Gt2* geom_traits = arr.geometry_traits(); const Gt2* geom_traits = arr.geometry_traits();
/* We would like to avoid copy construction of the geometry traits class. /* We would like to avoid copy construction of the geometry traits class.

View File

@ -737,7 +737,7 @@ insert_non_intersecting_curve
if (vh1 != nullptr) { if (vh1 != nullptr) {
if (vh2 != nullptr) { if (vh2 != nullptr) {
// Both endpoints are associated with a existing vertices. // Both endpoints are associated with existing vertices.
// In this case insert_at_vertices() already returns a halfedge // In this case insert_at_vertices() already returns a halfedge
// directed from left to right. // directed from left to right.
new_he = arr.insert_at_vertices(c, new_he = arr.insert_at_vertices(c,

View File

@ -524,7 +524,7 @@ public:
/*! \class /*! \class
* A class defining a textual (\ascii) input/output format for arrangements * A class defining a textual (\ascii) input/output format for arrangements
* that store auxiliary dat with all their DCEL records, as they are templated * that store auxiliary dat with all their DCEL records, as they are templated
* by a extended DCEL class. * by an extended DCEL class.
*/ */
template <class Arrangement_> template <class Arrangement_>
class Arr_extended_dcel_text_formatter : class Arr_extended_dcel_text_formatter :

View File

@ -440,7 +440,7 @@ public:
{ return (m_base_eq(p1.base(), p2.base())); } { return (m_base_eq(p1.base(), p2.base())); }
}; };
/*! Obtain a Equal_2 function object */ /*! Obtain an `Equal_2` function object */
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ return (Equal_2(m_base_traits->equal_2_object())); } { return (Equal_2(m_base_traits->equal_2_object())); }

View File

@ -23,7 +23,7 @@
* This class can be further split into two, where one derives from the other, * This class can be further split into two, where one derives from the other,
* such that the derived class handles the case of inserting non-intersecting * such that the derived class handles the case of inserting non-intersecting
* curves into a non-empty arrangement, and the base class handles the case of * curves into a non-empty arrangement, and the base class handles the case of
* inserting non-intersecting curves into a empty arrangement. * inserting non-intersecting curves into an empty arrangement.
*/ */
#include <CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h> #include <CGAL/Surface_sweep_2/Arr_construction_ss_visitor.h>

View File

@ -705,7 +705,7 @@ public:
{ return m_base_equal(xcv1.base(), xcv2.base()); } { return m_base_equal(xcv1.base(), xcv2.base()); }
}; };
/*! Obtain a Equal_2 functor object. */ /*! Obtain an `Equal_2` functor object. */
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ return Equal_2(m_base_traits->equal_2_object()); } { return Equal_2(m_base_traits->equal_2_object()); }

View File

@ -9,7 +9,7 @@ find_package(CGAL REQUIRED)
# create a target per cppfile # create a target per cppfile
file( file(
GLOB_RECURSE cppfiles GLOB cppfiles
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
*.cpp) *.cpp)
foreach(cppfile ${cppfiles}) foreach(cppfile ${cppfiles})

View File

@ -42,7 +42,7 @@ namespace CGAL {
* <a href="https://www.boost.org/doc/libs/release/libs/graph/doc/filtered_graph.html"><code>boost::filtered_graph</code></a>, * <a href="https://www.boost.org/doc/libs/release/libs/graph/doc/filtered_graph.html"><code>boost::filtered_graph</code></a>,
* this class only requires a way to access the selected faces and will automatically select the * this class only requires a way to access the selected faces and will automatically select the
* edges/halfedges and vertices present in the adapted graph. A vertex is selected if it is incident to at least one * edges/halfedges and vertices present in the adapted graph. A vertex is selected if it is incident to at least one
* selected face. A edge is selected if it is incident to at least a selected face. A halfedge is selected if its edge * selected face. An edge is selected if it is incident to at least a selected face. A halfedge is selected if its edge
* is selected. * is selected.
* *
* Since this class is a model of the `FaceGraph` concept, there is a restriction on the set of selected faces: * Since this class is a model of the `FaceGraph` concept, there is a restriction on the set of selected faces:

View File

@ -22,7 +22,7 @@ int main()
Mesh mesh2(sm2); Mesh mesh2(sm2);
try { try {
if( target( *(halfedges(mesh).first), mesh2) == *(vertices(mesh).first)){ if( target( *(halfedges(mesh).first), mesh2) == *(vertices(mesh).first)){
CGAL_error_msg("The previous lie should have throw a exception"); CGAL_error_msg("The previous line should have throw an exception");
} }
} catch(...){ } catch(...){
std::cerr << "we caught it" << std::endl; std::cerr << "we caught it" << std::endl;

View File

@ -1,125 +0,0 @@
#define BOOST_TEST_MODULE graph_traits test
#include <boost/test/unit_test.hpp>
#include <boost/test/floating_point_comparison.hpp>
BOOST_AUTO_TEST_CASE( edges_test )
{
edge_iterator eb, ee;
vertex_iterator vb, ve;
Surface_fixture f;
boost::tie(eb, ee) = edges(f.m);
boost::tie(vb, ve) = vertices(f.m);
BOOST_CHECK(std::distance(eb, ee) == 7);
BOOST_CHECK(std::distance(vb, ve) == 5);
Cube_fixture cf;
boost::tie(eb, ee) = edges(cf.m);
boost::tie(vb, ve) = vertices(cf.m);
BOOST_CHECK(std::distance(eb, ee) == 18);
BOOST_CHECK(std::distance(vb, ve) == 8);
}
BOOST_AUTO_TEST_CASE( out_edges_test )
{
Surface_fixture f;
BOOST_CHECK(out_degree(f.u, f.m) == 2);
BOOST_CHECK(out_degree(f.v, f.m) == 4);
std::pair<out_edge_iterator, out_edge_iterator> out = out_edges(f.v, f.m);
BOOST_CHECK(std::distance(out.first, out.second) == 4);
out_edge_iterator it = out.first;
while(it != out.second) {
// the source should always be u
BOOST_CHECK(source(*it, f.m) == f.v);
// the target never
BOOST_CHECK(target(*it, f.m) != f.v);
++it;
}
}
BOOST_AUTO_TEST_CASE( in_edges_test )
{
Surface_fixture f;
BOOST_CHECK(in_degree(f.u, f.m) == 2);
BOOST_CHECK(in_degree(f.x, f.m) == 3);
BOOST_CHECK(in_degree(f.v, f.m) == 4);
std::pair<in_edge_iterator, in_edge_iterator> in = in_edges(f.v, f.m);
BOOST_CHECK(std::distance(in.first, in.second) == 4);
in_edge_iterator it = in.first;
while(it != in.second) {
// the source should never be u
BOOST_CHECK(source(*it, f.m) != f.v);
// the target must always be u
BOOST_CHECK(target(*it, f.m) == f.v);
++it;
}
}
BOOST_AUTO_TEST_CASE( in_out_equality )
{
// in and out degrees must be equal for each vertex
Cube_fixture f;
for(Sm::Vertex_iterator it = f.m.vertices_begin();
it != f.m.vertices_end(); ++it) {
BOOST_CHECK(in_degree(*it, f.m) == out_degree(*it, f.m));
}
}
BOOST_AUTO_TEST_CASE( face_test )
{
Surface_fixture f;
std::pair<enclosure_iterator, enclosure_iterator>
enc = enclosure(f.f1, f.m);
BOOST_CHECK(enc.first != enc.second);
BOOST_CHECK(std::distance(enc.first, enc.second) == 3);
enclosure_iterator begin = enc.first;
while(begin != enc.second)
{
BOOST_CHECK(face(*begin, f.m) == f.f1);
++begin;
}
}
BOOST_AUTO_TEST_CASE( weight_map_test )
{
Surface_fixture f;
Cube_fixture c;
CGAL::SM_edge_weight_pmap<K> wm1 = boost::get(boost::edge_weight, c.m);
edge_iterator eb, ee;
boost::test_tools::check_is_close_t check_close;
for(boost::tie(eb, ee) = edges(c.m); eb != ee; ++eb) {
BOOST_CHECK(
check_close(wm1[*eb], 2.0, boost::test_tools::percent_tolerance_t<double>(0.00001))
|| check_close(wm1[*eb], 2.82843, boost::test_tools::percent_tolerance_t<double>(0.001)));
}
}
BOOST_AUTO_TEST_CASE( vertices_test )
{
Surface_fixture f;
// boost::property_map<Sm,boost::vertex_index_t>::type vi_map = get(f.m, boost::vertex_index);
// vertex_iterator b,e;
// for(boost::tie(b,e) = vertices(f.m);
// b!= e;
// ++b){
// std::cout << boost::get(vi_map, *(b)) << std::endl;
// }
// boost::property_map<Sm,boost::edge_weight_t>::type ew_map = get(f.m, boost::edge_weight);
// edge_iterator be, ee;
// for(boost::tie(be,ee) = edges(f.m);
// be!= ee;
// ++be){
// std::cout << boost::get(ew_map, *(be)) << std::endl;
// }
}

View File

@ -21,18 +21,18 @@ int main()
SM sm_in, sm_out; SM sm_in, sm_out;
Point_3 p0(0,0,0), p1(1,0,0), p2(0,1,0); Point_3 p0(0,0,0), p1(1,0,0), p2(0,1,0);
CGAL::make_triangle(p0, p1, p2, sm_out); CGAL::make_triangle(p0, p1, p2, sm_out);
bool ok = CGAL::write_off("tmp.off", sm_out); bool ok = CGAL::write_off("tmp_deprecated.off", sm_out);
assert(ok); assert(ok);
ok = CGAL::read_off("tmp.off", sm_in); ok = CGAL::read_off("tmp_deprecated.off", sm_in);
assert(ok); assert(ok);
assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1); assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1);
sm_in.clear(); sm_in.clear();
std::ofstream os("tmp.off"); std::ofstream os("tmp_deprecated.off");
ok = CGAL::write_off(os, sm_out); ok = CGAL::write_off(os, sm_out);
assert(ok); assert(ok);
os.close(); os.close();
std::ifstream is("tmp.off"); std::ifstream is("tmp_deprecated.off");
ok = CGAL::read_off(is, sm_in); ok = CGAL::read_off(is, sm_in);
assert(ok); assert(ok);
assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1); assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1);
@ -40,18 +40,18 @@ int main()
sm_in.clear(); sm_in.clear();
#ifdef CGAL_USE_VTK #ifdef CGAL_USE_VTK
//vtk //vtk
os.open("tmp.vtp"); os.open("tmp_deprecated.vtp");
ok = CGAL::write_vtp(os, sm_out); ok = CGAL::write_vtp(os, sm_out);
assert(ok); assert(ok);
os.close(); os.close();
ok = CGAL::IO::read_VTP("tmp.vtp", sm_in); ok = CGAL::IO::read_VTP("tmp_deprecated.vtp", sm_in);
assert(ok); assert(ok);
assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1); assert(num_vertices(sm_in) == 3 && num_faces(sm_in) == 1);
sm_in.clear(); sm_in.clear();
#endif #endif
//wrl //wrl
os.open("tmp.wrl"); os.open("tmp_deprecated.wrl");
ok = CGAL::write_wrl(os, sm_out); ok = CGAL::write_wrl(os, sm_out);
assert(ok); assert(ok);
os.close(); os.close();

View File

@ -451,10 +451,10 @@ To fix the problem, we modify the weights \f$w_i\f$ as
</center> </center>
After the above normalization, this gives us the precise algorithm to compute Wachspress coordinates After the above normalization, this gives us the precise algorithm to compute Wachspress coordinates
but with \f$O(n^2)\f$ performance only. The max speed \f$O(n)\f$ algorithm uses the standard but with \cgalBigO{n^2} performance only. The max speed \cgalBigO{n} algorithm uses the standard
weights \f$w_i\f$. Note that mathematically this modification does not change the coordinates. One should weights \f$w_i\f$. Note that mathematically this modification does not change the coordinates. One should
be cautious when using the unnormalized Wachspress weights. In that case, you must choose the be cautious when using the unnormalized Wachspress weights. In that case, you must choose the
\f$O(n)\f$ type. \cgalBigO{n} type.
It is known that for strictly convex polygons the denominator's zero set of the It is known that for strictly convex polygons the denominator's zero set of the
Wachspress coordinates (\f$W^{wp} = 0~\f$) is a curve, which (in many cases) lies quite Wachspress coordinates (\f$W^{wp} = 0~\f$) is a curve, which (in many cases) lies quite
@ -507,10 +507,10 @@ To fix the problem, similarly to the previous subsection, we modify the weights
</center> </center>
After the above normalization, this yields the precise algorithm to compute discrete harmonic coordinates After the above normalization, this yields the precise algorithm to compute discrete harmonic coordinates
but with \f$O(n^2)\f$ performance only. The max speed \f$O(n)\f$ algorithm uses the standard but with \cgalBigO{n^2} performance only. The max speed \cgalBigO{n} algorithm uses the standard
weights \f$w_i\f$. Again, mathematically this modification does not change the coordinates, weights \f$w_i\f$. Again, mathematically this modification does not change the coordinates,
one should be cautious when using the unnormalized discrete harmonic weights. In that case, one should be cautious when using the unnormalized discrete harmonic weights. In that case,
you must choose the \f$O(n)\f$ type. you must choose the \cgalBigO{n} type.
\b Warning: as for Wachspress coordinates, we do not recommend using discrete harmonic coordinates \b Warning: as for Wachspress coordinates, we do not recommend using discrete harmonic coordinates
for exterior points, because the curve \f$W^{dh} = 0\f$ may have several components, for exterior points, because the curve \f$W^{dh} = 0\f$ may have several components,
@ -563,7 +563,7 @@ After the normalization of these weights as before
\f$b_i = \frac{w_i}{W^{mv}}\qquad\f$ with \f$\qquad W^{mv} = \sum_{j=1}^n w_j\f$ \f$b_i = \frac{w_i}{W^{mv}}\qquad\f$ with \f$\qquad W^{mv} = \sum_{j=1}^n w_j\f$
</center> </center>
we obtain the max precision \f$O(n^2)\f$ algorithm. The max speed \f$O(n)\f$ algorithm computes the we obtain the max precision \cgalBigO{n^2} algorithm. The max speed \cgalBigO{n} algorithm computes the
weights \f$w_i\f$ using the pseudocode from <a href="https://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf">here</a>. weights \f$w_i\f$ using the pseudocode from <a href="https://www.inf.usi.ch/hormann/nsfworkshop/presentations/Hormann.pdf">here</a>.
These weights These weights
@ -575,7 +575,7 @@ with \f$\qquad t_i = \frac{\text{det}(d_i, d_{i+1})}{r_ir_{i+1} + d_id_{i+1}}\f$
are also normalized. Note that they are unstable if a query point is closer than \f$\approx 1.0e-10\f$ are also normalized. Note that they are unstable if a query point is closer than \f$\approx 1.0e-10\f$
to the polygon boundary, similarly to Wachspress and discrete harmonic coordinates and to the polygon boundary, similarly to Wachspress and discrete harmonic coordinates and
one should be cautious when using the unnormalized mean value weights. In that case, you must choose the one should be cautious when using the unnormalized mean value weights. In that case, you must choose the
\f$O(n)\f$ type. \cgalBigO{n} type.
\anchor compute_hm_coord \anchor compute_hm_coord
@ -654,17 +654,17 @@ The resulting timings for all closed-form coordinates can be found in the figure
\cgalFigureBegin{analytic_timings, analytic_timings.png} \cgalFigureBegin{analytic_timings, analytic_timings.png}
Time in seconds to compute \f$n\f$ coordinate values for a polygon with \f$n\f$ vertices Time in seconds to compute \f$n\f$ coordinate values for a polygon with \f$n\f$ vertices
at 1 million query points with the max speed \f$O(n)\f$ algorithms (dashed) and at 1 million query points with the max speed \cgalBigO{n} algorithms (dashed) and
the max precision \f$0(n^2)\f$ algorithms (solid) for Wachspress (blue), discrete the max precision \f$0(n^2)\f$ algorithms (solid) for Wachspress (blue), discrete
harmonic (red), and mean value (green) coordinates. harmonic (red), and mean value (green) coordinates.
\cgalFigureEnd \cgalFigureEnd
From the figure above we observe that the \f$O(n^2)\f$ algorithm is as fast From the figure above we observe that the \cgalBigO{n^2} algorithm is as fast
as the \f$O(n)\f$ algorithm if we have a polygon with a small number of vertices. as the \cgalBigO{n} algorithm if we have a polygon with a small number of vertices.
But as the number of vertices is increased, the linear algorithm outperforms the squared one, But as the number of vertices is increased, the linear algorithm outperforms the squared one,
as expected. One of the reasons for this behavior is that for a small number of vertices as expected. One of the reasons for this behavior is that for a small number of vertices
the multiplications of \f$n-2\f$ elements inside the \f$O(n^2)\f$ algorithm take almost the the multiplications of \f$n-2\f$ elements inside the \cgalBigO{n^2} algorithm take almost the
same time as the corresponding divisions in the \f$O(n)\f$ algorithm. For a polygon with same time as the corresponding divisions in the \cgalBigO{n} algorithm. For a polygon with
many vertices, these multiplications are substantially slower. many vertices, these multiplications are substantially slower.
To benchmark harmonic coordinates, we used a MacBook Pro 2018 with 2.2 GHz Intel Core i7 processor (6 cores) To benchmark harmonic coordinates, we used a MacBook Pro 2018 with 2.2 GHz Intel Core i7 processor (6 cores)

View File

@ -387,7 +387,7 @@ public:
} }
}; };
/*! Get a Equal_2 functor object. */ /*! Get an `Equal_2` functor object. */
Equal_2 equal_2_object() const Equal_2 equal_2_object() const
{ {
return Equal_2(m_base_traits->equal_2_object()); return Equal_2(m_base_traits->equal_2_object());

View File

@ -119,7 +119,7 @@ We implement Khachyian's algorithm for rounding
polytopes \cgalCite{cgal:k-rprnm-96}. Internally, we use polytopes \cgalCite{cgal:k-rprnm-96}. Internally, we use
`double`-arithmetic and (initially a single) `double`-arithmetic and (initially a single)
Cholesky-decomposition. The algorithm's running time is Cholesky-decomposition. The algorithm's running time is
\f$ {\cal O}(nd^2(\epsilon^{-1}+\ln d + \ln\ln(n)))\f$, where \f$ n=|P|\f$ and \cgalBigO{nd^2(\epsilon^{-1}+\ln d + \ln\ln(n))}, where \f$ n=|P|\f$ and
\f$ 1+\epsilon\f$ is the desired approximation ratio. \f$ 1+\epsilon\f$ is the desired approximation ratio.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -76,7 +76,7 @@ We implement two algorithms, the LP-algorithm and a
heuristic \cgalCite{msw-sblp-92}. As described in the documentation of heuristic \cgalCite{msw-sblp-92}. As described in the documentation of
concept `MinSphereOfSpheresTraits`, each has its advantages and concept `MinSphereOfSpheresTraits`, each has its advantages and
disadvantages: Our implementation of the LP-algorithm has maximal disadvantages: Our implementation of the LP-algorithm has maximal
expected running time \f$ O(2^d n)\f$, while the heuristic comes without expected running time \cgalBigO{2^d n}, while the heuristic comes without
any complexity guarantee. In particular, the LP-algorithm runs in any complexity guarantee. In particular, the LP-algorithm runs in
linear time for fixed dimension \f$ d\f$. (These running times hold for the linear time for fixed dimension \f$ d\f$. (These running times hold for the
arithmetic model, so they count the number of operations on arithmetic model, so they count the number of operations on

View File

@ -245,7 +245,7 @@ must be a model for `RectangularPCenterTraits_2`.
\cgalHeading{Implementation} \cgalHeading{Implementation}
The runtime is linear for \f$ p \in \{2,\,3\}\f$ and The runtime is linear for \f$ p \in \{2,\,3\}\f$ and
\f$ \mathcal{O}(n \cdot \log n)\f$ for \f$ p = 4\f$ where \f$ n\f$ is the number of \cgalBigO{n \cdot \log n} for \f$ p = 4\f$ where \f$ n\f$ is the number of
input points. These runtimes are worst case optimal. The \f$ 3\f$-center input points. These runtimes are worst case optimal. The \f$ 3\f$-center
algorithm uses a prune-and-search technique described in algorithm uses a prune-and-search technique described in
\cgalCite{cgal:h-slacr-99}. The \f$ 4\f$-center implementation uses sorted matrix \cgalCite{cgal:h-slacr-99}. The \f$ 4\f$-center implementation uses sorted matrix

View File

@ -79,7 +79,7 @@ The recommended choice is the first, which is a synonym to the one
of the other two methods which we consider "the best in practice." of the other two methods which we consider "the best in practice."
In case of `CGAL::LP_algorithm`, the minsphere will be computed In case of `CGAL::LP_algorithm`, the minsphere will be computed
using the LP-algorithm \cgalCite{msw-sblp-92}, which in our using the LP-algorithm \cgalCite{msw-sblp-92}, which in our
implementation has maximal expected running time \f$ O(2^d n)\f$ (in the implementation has maximal expected running time \cgalBigO{2^d n} (in the
number of operations on the number type `FT`). In case of number of operations on the number type `FT`). In case of
`CGAL::Farthest_first_heuristic`, a simple heuristic will be `CGAL::Farthest_first_heuristic`, a simple heuristic will be
used instead which seems to work fine in practice, but comes without used instead which seems to work fine in practice, but comes without

View File

@ -350,12 +350,12 @@ parameter the function switches from the streamed segment-tree
algorithm to the two-way-scan algorithm, see \cgalCite{cgal:ze-fsbi-02} algorithm to the two-way-scan algorithm, see \cgalCite{cgal:ze-fsbi-02}
for the details. for the details.
The streamed segment-tree algorithm needs \f$ O(n \log^d (n) + k)\f$ The streamed segment-tree algorithm needs \cgalBigO{n \log^d (n) + k}
worst-case running time and \f$ O(n)\f$ space, where \f$ n\f$ is the number of worst-case running time and \cgalBigO{n} space, where \f$ n\f$ is the number of
boxes in both input sequences, \f$ d\f$ the (constant) dimension of the boxes in both input sequences, \f$ d\f$ the (constant) dimension of the
boxes, and \f$ k\f$ the output complexity, i.e., the number of pairwise boxes, and \f$ k\f$ the output complexity, i.e., the number of pairwise
intersections of the boxes. The two-way-scan algorithm needs \f$ O(n \log intersections of the boxes. The two-way-scan algorithm needs \cgalBigO{n \log
(n) + l)\f$ worst-case running time and \f$ O(n)\f$ space, where \f$ l\f$ is the (n) + l} worst-case running time and \cgalBigO{n} space, where \f$ l\f$ is the
number of pairwise overlapping intervals in one dimensions (the number of pairwise overlapping intervals in one dimensions (the
dimension where the algorithm is used instead of the segment tree). dimension where the algorithm is used instead of the segment tree).
Note that \f$ l\f$ is not necessarily related to \f$ k\f$ and using the Note that \f$ l\f$ is not necessarily related to \f$ k\f$ and using the

View File

@ -77,7 +77,7 @@ namespace CGAL {
\cgalHeading{Implementation} \cgalHeading{Implementation}
The algorithm is trivially testing all pairs and runs therefore in time The algorithm is trivially testing all pairs and runs therefore in time
\f$ O(nm)\f$ where \f$ n\f$ is the size of the first sequence and \f$ m\f$ is the \cgalBigO{nm} where \f$ n\f$ is the size of the first sequence and \f$ m\f$ is the
size of the second sequence. size of the second sequence.
*/ */
@ -219,12 +219,12 @@ void box_intersection_all_pairs_d(
algorithm to the two-way-scan algorithm, see \cgalCite{cgal:ze-fsbi-02} algorithm to the two-way-scan algorithm, see \cgalCite{cgal:ze-fsbi-02}
for the details. for the details.
The streamed segment-tree algorithm needs \f$ O(n \log^d (n) + k)\f$ The streamed segment-tree algorithm needs \cgalBigO{n \log^d (n) + k}
worst-case running time and \f$ O(n)\f$ space, where \f$ n\f$ is the number of worst-case running time and \cgalBigO{n} space, where \f$ n\f$ is the number of
boxes in both input sequences, \f$ d\f$ the (constant) dimension of the boxes in both input sequences, \f$ d\f$ the (constant) dimension of the
boxes, and \f$ k\f$ the output complexity, i.e., the number of pairwise boxes, and \f$ k\f$ the output complexity, i.e., the number of pairwise
intersections of the boxes. The two-way-scan algorithm needs \f$ O(n \log intersections of the boxes. The two-way-scan algorithm needs \cgalBigO{n \log
(n) + l)\f$ worst-case running time and \f$ O(n)\f$ space, where \f$ l\f$ is the (n) + l} worst-case running time and \cgalBigO{n} space, where \f$ l\f$ is the
number of pairwise overlapping intervals in one dimensions (the number of pairwise overlapping intervals in one dimensions (the
dimension where the algorithm is used instead of the segment tree). dimension where the algorithm is used instead of the segment tree).
Note that \f$ l\f$ is not necessarily related to \f$ k\f$ and using the Note that \f$ l\f$ is not necessarily related to \f$ k\f$ and using the
@ -397,7 +397,7 @@ namespace CGAL {
\cgalHeading{Implementation} \cgalHeading{Implementation}
The algorithm is trivially testing all pairs and runs therefore in time The algorithm is trivially testing all pairs and runs therefore in time
\f$ O(n^2)\f$ where \f$ n\f$ is the size of the input sequence. This algorithm \cgalBigO{n^2} where \f$ n\f$ is the size of the input sequence. This algorithm
does not use the id-number of the boxes. does not use the id-number of the boxes.
*/ */

View File

@ -246,7 +246,7 @@ Circulator_from_iterator();
/*! /*!
a circulator `c` initialized to refer to the element a circulator `c` initialized to refer to the element
`*cur` in a range `[begin, end)`. `*cur` in a range `[begin, end)`.
The circulator `c` refers to a empty sequence The circulator `c` refers to an empty sequence
if `begin==end`. if `begin==end`.
*/ */
@ -255,7 +255,7 @@ const I& end, const I& cur = begin);
/*! /*!
a copy of circulator `d` referring to the element `*cur`. a copy of circulator `d` referring to the element `*cur`.
The circulator `c` refers to a empty sequence The circulator `c` refers to an empty sequence
if `d` does so. if `d` does so.
*/ */

View File

@ -16,6 +16,7 @@
#include <map> #include <map>
#include <memory> #include <memory>
#include <CGAL/assertions.h>
#define CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT 100000000 #define CGAL_CLASSIFICATION_IMAGE_SIZE_LIMIT 100000000
@ -38,12 +39,15 @@ class Image
std::shared_ptr<Map> m_sparse; std::shared_ptr<Map> m_sparse;
Type m_default; Type m_default;
// Forbid using copy constructor
Image (const Image&)
{
}
public: public:
// Forbid using copy constructor
// Make it public for a strange VC++ std17 boost-1_82 error
// https://github.com/boostorg/core/issues/148
Image(const Image&)
{
CGAL_assertion(false);
}
Image () : m_width(0), m_height(0), m_depth(0) Image () : m_width(0), m_height(0), m_depth(0)
{ {

View File

@ -168,7 +168,7 @@ Considering these different advantages and drawbacks, you can choose to use gene
The diagram in \cgalFigureRef{fig_cmap_diagramme_class} shows the different classes of the package. `Combinatorial_map` is the main class (see Section \ref sseccombinatorialmap "Combinatorial Maps"). It allows to manage darts and attributes (see Section \ref ssecattributes "Cell Attributes"). Users can customize a combinatorial map thanks to an items class (see Section \ref ssecitem "Combinatorial Map Items"), which defines the information associated with darts and the attribute types. These types may be different for different dimensions, and they may also be void (note that the main concepts of `GenericMap`, `GenericMapItems` and `CellAttribute` are shared between combinatorial maps and generalized maps). The diagram in \cgalFigureRef{fig_cmap_diagramme_class} shows the different classes of the package. `Combinatorial_map` is the main class (see Section \ref sseccombinatorialmap "Combinatorial Maps"). It allows to manage darts and attributes (see Section \ref ssecattributes "Cell Attributes"). Users can customize a combinatorial map thanks to an items class (see Section \ref ssecitem "Combinatorial Map Items"), which defines the information associated with darts and the attribute types. These types may be different for different dimensions, and they may also be void (note that the main concepts of `GenericMap`, `GenericMapItems` and `CellAttribute` are shared between combinatorial maps and generalized maps).
The darts and attributes are accessed through <I>descriptors</I> (either Indices or Handles). A handle is a model of the `Handle` concept, thus supporting the two dereference operators `operator*` and `operator->`. All handles are model of `LessThanComparable` and `Hashable`, that is they can be used as keys in containers such as `std::map` and `std::unordered_map`. An index is a model of the `Index` concept, which is mainly an integer which is convertible from and to std::size_t. Indices can be used as index into vectors which store properties (cf. one example in Section \ref ssecexample3DCMWI "3D Combinatorial Map using Indices"). The darts and attributes are accessed through <I>descriptors</I> (either Indices or Handles). A handle is a model of the `Handle` concept, thus supporting the two dereference operators `operator*` and `operator->`. All handles are model of `LessThanComparable` and `Hashable`, that is they can be used as keys in containers such as `std::map` and `std::unordered_map`. An index is a model of the `Index` concept, which is mainly an integer which is convertible from and to std::size_t. Indices can be used as index into vectors which store properties (cf. one example in Section \ref ssecexample3DCMWI "3D Combinatorial Map Using Indices").
\cgalFigureBegin{fig_cmap_diagramme_class,cmap_diagramme_class.svg} \cgalFigureBegin{fig_cmap_diagramme_class,cmap_diagramme_class.svg}
UML diagram of the main classes of the package. k is the number of non void attributes. UML diagram of the main classes of the package. k is the number of non void attributes.
@ -297,7 +297,7 @@ Several functions allow to create specific configurations of darts into a combin
\subsection ssecadvmarks Boolean Marks \subsection ssecadvmarks Boolean Marks
It is often necessary to mark darts, for example to retrieve in <I>O(1)</I> if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a combinatorial map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GenericMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `cm` an instance of a combinatorial map): It is often necessary to mark darts, for example to retrieve in \cgalBigO{1} if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a combinatorial map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GenericMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `cm` an instance of a combinatorial map):
<ul> <ul>
<li> get a new free mark: `size_type m = cm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available); <li> get a new free mark: `size_type m = cm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available);
<li> set mark `m` for a given dart `d0`: `cm.`\link GenericMap::mark `mark(d0,m)`\endlink; <li> set mark `m` for a given dart `d0`: `cm.`\link GenericMap::mark `mark(d0,m)`\endlink;
@ -393,6 +393,8 @@ Example of \link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2`\e
`cm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink. `cm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0`\f$ \in \f$ \link GenericMap::darts `cm.darts()`\endlink.
`cm.`\link GenericMap::insert_cell_1_between_two_cells_2 `insert_cell_1_between_two_cells_2(d1,d2)`\endlink adds a 1-cell between the two faces containing containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cells are merged in one. This operation is possible if <I>d1</I>\f$ \not \in \f$ \f$ \langle{}\f$\f$ \beta_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_1_between_two_cells_2 `is_insertable_cell_1_between_two_cells_2(d1,d2)`\endlink.
`cm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_cmap_insert_facet}). `cm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `cm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_cmap_insert_facet}).
\cgalFigureBegin{fig_cmap_insert_facet,cmap_insert_facet.svg} \cgalFigureBegin{fig_cmap_insert_facet,cmap_insert_facet.svg}
@ -456,6 +458,24 @@ The second line is the result after the removal operations. We retrieve the orig
Example of high level operations. Left: Initial 3D combinatorial map after the creation of the combinatorial hexahedron. Middle: Combinatorial map obtained after the two 1-cell insertions. The two 2-cells were split in two. Right: Combinatorial map obtained after the 2-cell insertion. The 3-cell was split in two. Example of high level operations. Left: Initial 3D combinatorial map after the creation of the combinatorial hexahedron. Middle: Combinatorial map obtained after the two 1-cell insertions. The two 2-cells were split in two. Right: Combinatorial map obtained after the 2-cell insertion. The 3-cell was split in two.
\cgalFigureEnd \cgalFigureEnd
\subsection Combinatorial_mapInsertion Insert an Edge Between Two Different Faces
\anchor ssecexempleinsertion
This example shows the use of \link GenericMap::insert_cell_1_between_two_cells_2 `insert_cell_1_between_two_cells_2`\endlink operation. First we create a combinatorial hexahedron and a face with 4 edges. This face is inserted in the face of the hexahedron containing dart d1. We display the characteristics of the combinatorial map and check its validity. Then we count and display the number of 2-free darts.
\cgalExample{Combinatorial_map/map_3_insert.cpp}
The output is:
\verbatim
#Darts=30, #0-cells=12, #1-cells=17, #2-cells=6, #3-cells=1, #ccs=1, valid=1
Number of 2-free darts: 4
\endverbatim
We can verify that there are 6 2-cells after the insertion since the squared face was inserted as a hole in one face of the hexahedron. We can also see that there are 4 2-free darts, which are the darts of the squared face. Since they bound an hole, there is no face filling the hole and thus 4 darts are 2-free.
See also a similar example for Linear cell complex \ref Linear_cell_complexInsert "Insert an Edge Between Two Different Faces".
\subsection Combinatorial_mapA4DGenericMap A 4D Combinatorial Map \subsection Combinatorial_mapA4DGenericMap A 4D Combinatorial Map
In this example, a 4-dimensional combinatorial map is used. Two tetrahedral cells are created and sewn by \f$ \beta_4\f$. Then the numbers of cells of the combinatorial map are displayed, and its validity is checked. In this example, a 4-dimensional combinatorial map is used. Two tetrahedral cells are created and sewn by \f$ \beta_4\f$. Then the numbers of cells of the combinatorial map are displayed, and its validity is checked.
@ -502,7 +522,7 @@ Lastly we remove the dynamic onmerge functor (step 7). This is done by initializ
\cgalExample{Combinatorial_map/map_3_dynamic_onmerge.cpp} \cgalExample{Combinatorial_map/map_3_dynamic_onmerge.cpp}
\subsection ssecexample3DCMWI 3D Combinatorial Map using Indices \subsection ssecexample3DCMWI 3D Combinatorial Map Using Indices
In this example, a 3-dimensional combinatorial map is used, but using indices instead of handles. Two vectors are created to store some external information associated with darts and 3-attributes. Since descriptors are indices, they can directly be used to access elements of the vector. In this example, a 3-dimensional combinatorial map is used, but using indices instead of handles. Two vectors are created to store some external information associated with darts and 3-attributes. Since descriptors are indices, they can directly be used to access elements of the vector.

View File

@ -267,12 +267,12 @@ using One_dart_per_cell_const_range = unspecified_type;
/// @{ /// @{
/*! /*!
Returns true iff the generic map is empty, i.e.\ it contains no dart. Returns `true` iff the generic map is empty, i.e.\ it contains no dart.
*/ */
bool is_empty() const; bool is_empty() const;
/*! /*!
Returns true iff the generic map is without <I>i</I>-boundary. Returns `true` iff the generic map is without <I>i</I>-boundary.
The map is without <I>i</I>-boundary if there is no `i`-free dart. The map is without <I>i</I>-boundary if there is no `i`-free dart.
\pre 1\f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink. \pre 1\f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink.
@ -280,7 +280,7 @@ The map is without <I>i</I>-boundary if there is no `i`-free dart.
bool is_without_boundary(unsigned int i) const; bool is_without_boundary(unsigned int i) const;
/*! /*!
Returns true iff the generic map is without boundary in all dimensions. Returns `true` iff the generic map is without boundary in all dimensions.
*/ */
bool is_without_boundary() const; bool is_without_boundary() const;
@ -308,18 +308,18 @@ Returns an upper bound of the id of <I>i</I>-attributes descriptors if indices a
template <unsigned int i> template <unsigned int i>
size_type upper_bound_on_attribute_ids() const; size_type upper_bound_on_attribute_ids() const;
/*! Returns true if `d` is a descriptor of a used dart (i.e.\ valid). /*! Returns `true` if `d` is a descriptor of a used dart (i.e.\ valid).
*/ */
bool is_dart_used(Dart_const_descriptor d) const; bool is_dart_used(Dart_const_descriptor d) const;
/*! /*!
Returns true iff dart `d` is <I>i</I>-free. Returns `true` iff dart `d` is <I>i</I>-free.
\pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink. \pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink.
*/ */
bool is_free(Dart_const_descriptor d, unsigned int i) const; bool is_free(Dart_const_descriptor d, unsigned int i) const;
/*! /*!
Returns true iff dart `d` is <I>i</I>-free. Returns `true` iff dart `d` is <I>i</I>-free.
\pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink. \pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink.
*/ */
template<unsigned int i> template<unsigned int i>
@ -477,7 +477,7 @@ A shortcut for \link GenericMap::dart_of_attribute(typename Attribute_const_desc
template<unsigned int i> template<unsigned int i>
Dart_const_descriptor dart(Dart_const_descriptor adart) const; Dart_const_descriptor dart(Dart_const_descriptor adart) const;
/*! Returns true if ah points to a used i-attribute (i.e.\ valid). /*! Returns `true` if ah points to a used i-attribute (i.e.\ valid).
\pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink, and <I>i</I>-attributes are non `void`. \pre 0 \f$ \leq \f$ <I>i</I> \f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink, and <I>i</I>-attributes are non `void`.
*/ */
template<unsigned int i> template<unsigned int i>
@ -703,13 +703,13 @@ void correct_invalid_attributes();
/// \cond SKIP_IN_MANUAL boost::function \endcond /// \cond SKIP_IN_MANUAL boost::function \endcond
/// \name Dynamic Onmerge/Onsplit functors /// \name Dynamic On-Merge/On-Split functors
/// @{ /// @{
/*! /*!
Return the current dynamic onsplit function associated with i-attributes. Return the current dynamic on-split function associated with i-attributes.
This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters. This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters.
The onsplit function is returned by reference so that we can modify it. The on-split function is returned by reference so that we can modify it.
*/ */
template<int i> template<int i>
boost::function<void(typename Attribute_type< i >::type&, boost::function<void(typename Attribute_type< i >::type&,
@ -717,7 +717,7 @@ void correct_invalid_attributes();
onsplit_function(); onsplit_function();
/*! /*!
Return the current dynamic onsplit function associated with i-attributes, when *this is const. Return the current dynamic on-split function associated with i-attributes, when *this is const.
This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters. This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters.
*/ */
template<int i> template<int i>
@ -726,9 +726,9 @@ void correct_invalid_attributes();
onsplit_function() const; onsplit_function() const;
/*! /*!
Return the current dynamic onmerge function associated with i-attributes. Return the current dynamic on-merge function associated with i-attributes.
This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters. This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters.
The onmerge function is returned by reference so that we can modify it. The on-merge function is returned by reference so that we can modify it.
*/ */
template<int i> template<int i>
boost::function<void(typename Attribute_type< i >::type&, boost::function<void(typename Attribute_type< i >::type&,
@ -736,7 +736,7 @@ void correct_invalid_attributes();
onmerge_function(); onmerge_function();
/*! /*!
Return the current dynamic onmerge function associated with i-attributes, when *this is const. Return the current dynamic on-merge function associated with i-attributes, when *this is const.
This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters. This is a boost::function returning void and having two references to \link GenericMap::Attribute_type `Attribute_type<i>::type`\endlink as parameters.
*/ */
template<int i> template<int i>
@ -756,13 +756,13 @@ index. If there is no more available free mark, throw the exception Exception_no
size_type get_new_mark() const; size_type get_new_mark() const;
/*! /*!
Returns true iff `m` is a reserved mark of the generic map. Returns `true` iff `m` is a reserved mark of the generic map.
\pre 0\f$ \leq \f$ <I>m</I> \f$ < \f$ \link GenericMap::NB_MARKS `NB_MARKS`\endlink. \pre 0\f$ \leq \f$ <I>m</I> \f$ < \f$ \link GenericMap::NB_MARKS `NB_MARKS`\endlink.
*/ */
bool is_reserved(size_type m) const; bool is_reserved(size_type m) const;
/*! /*!
Returns true iff dart `d` is marked for `m`. Returns `true` iff dart `d` is marked for `m`.
\pre \link GenericMap::is_reserved `is_reserved(m)`\endlink and `d`\f$ \in \f$ `darts()`. \pre \link GenericMap::is_reserved `is_reserved(m)`\endlink and `d`\f$ \in \f$ `darts()`.
*/ */
bool is_marked(Dart_const_descriptor d, size_type m) const; bool is_marked(Dart_const_descriptor d, size_type m) const;
@ -820,9 +820,9 @@ void free_mark(size_type m) const;
Creates a combinatorial hexahedron (six combinatorial quadrangles 2-sewn together), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial hexahedron. Creates a combinatorial hexahedron (six combinatorial quadrangles 2-sewn together), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial hexahedron.
\pre `dimension` \f$\geq\f$ 2. \pre `dimension` \f$\geq\f$ 2.
\sa `make_edge` \sa `make_edge()`
\sa `make_combinatorial_polygon` \sa `make_combinatorial_polygon()`
\sa `make_combinatorial_tetrahedron` \sa `make_combinatorial_tetrahedron()`
*/ */
Dart_descriptor make_combinatorial_hexahedron(); Dart_descriptor make_combinatorial_hexahedron();
@ -831,9 +831,9 @@ Dart_descriptor make_combinatorial_hexahedron();
Creates a combinatorial polygon of length `lg` (a cycle of `lg` edges), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial polygon. Creates a combinatorial polygon of length `lg` (a cycle of `lg` edges), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial polygon.
\pre `dimension`\f$ \geq\f$ 1 and `lg`\f$ >\f$ 0. \pre `dimension`\f$ \geq\f$ 1 and `lg`\f$ >\f$ 0.
\sa `make_edge` \sa `make_edge()`
\sa `make_combinatorial_tetrahedron` \sa `make_combinatorial_tetrahedron()`
\sa `make_combinatorial_hexahedron` \sa `make_combinatorial_hexahedron()`
*/ */
Dart_descriptor make_combinatorial_polygon(unsigned int lg); Dart_descriptor make_combinatorial_polygon(unsigned int lg);
@ -841,9 +841,9 @@ Dart_descriptor make_combinatorial_polygon(unsigned int lg);
Creates a combinatorial tetrahedron (four combinatorial triangles 2-sewn together), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial tetrahedron. Creates a combinatorial tetrahedron (four combinatorial triangles 2-sewn together), and adds it in the generic map. Returns a descriptor on one dart of this combinatorial tetrahedron.
\pre `dimension`\f$ \geq\f$ 2. \pre `dimension`\f$ \geq\f$ 2.
\sa `make_edge` \sa `make_edge()`
\sa `make_combinatorial_polygon` \sa `make_combinatorial_polygon()`
\sa `make_combinatorial_hexahedron` \sa `make_combinatorial_hexahedron()`
*/ */
Dart_descriptor make_combinatorial_tetrahedron(); Dart_descriptor make_combinatorial_tetrahedron();
@ -851,9 +851,9 @@ Dart_descriptor make_combinatorial_tetrahedron();
Creates an isolated edge (two darts sewn to represent one edge and two vertices) and adds it in the generic map. Returns a descriptor on one dart of this edge. Creates an isolated edge (two darts sewn to represent one edge and two vertices) and adds it in the generic map. Returns a descriptor on one dart of this edge.
\pre `dimension`\f$ \geq\f$ 2. \pre `dimension`\f$ \geq\f$ 2.
\sa `make_combinatorial_polygon` \sa `make_combinatorial_polygon()`
\sa `make_combinatorial_tetrahedron` \sa `make_combinatorial_tetrahedron()`
\sa `make_combinatorial_hexahedron` \sa `make_combinatorial_hexahedron()`
*/ */
Dart_descriptor make_edge(); Dart_descriptor make_edge();
@ -868,17 +868,18 @@ Inserts a 0-cell in the 1-cell containing `d`. Returns `next(d)`, a descriptor o
See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_vertex} and for generalized map in \cgalFigureRef{fig_gmap_insert_vertex}. See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_vertex} and for generalized map in \cgalFigureRef{fig_gmap_insert_vertex}.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 1-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<1>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 1-attribute associated with <I>d</I> and <I>a'</I> the new 1-attribute created during the operation. If set, the dynamic onsplit function of 1-attributes is also called on <I>a</I> and <I>a'</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 1-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<1>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 1-attribute associated with <I>d</I> and <I>a'</I> the new 1-attribute created during the operation. If set, the dynamic on-split function of 1-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin \cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2` \sa `insert_cell_1_between_two_cells_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_dangling_cell_1_in_cell_2()`
\sa `remove_cell<i>` \sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `remove_cell<i>()`
*/ */
Dart_descriptor insert_cell_0_in_cell_1(Dart_descriptor d); Dart_descriptor insert_cell_0_in_cell_1(Dart_descriptor d);
@ -888,17 +889,18 @@ Inserts a 0-cell in the 2-cell containing `d`. The 2-cell is split in triangles,
See examples for combinatorial map in \cgalFigureRef{fig_cmap_triangulation} and for generalized map in \cgalFigureRef{fig_gmap_triangulation}. See examples for combinatorial map in \cgalFigureRef{fig_cmap_triangulation} and for generalized map in \cgalFigureRef{fig_gmap_triangulation}.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 2-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<2>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 2-attribute associated with `d` and <I>a'</I> each new 2-attribute created during the operation. If set, the dynamic onsplit function of 2-attributes is also called on <I>a</I> and <I>a'</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 2-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<2>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 2-attribute associated with `d` and <I>a'</I> each new 2-attribute created during the operation. If set, the dynamic on-split function of 2-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin \cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2` \sa `insert_cell_1_between_two_cells_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_dangling_cell_1_in_cell_2()`
\sa `remove_cell<i>` \sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `remove_cell<i>()`
*/ */
Dart_descriptor insert_cell_0_in_cell_2(Dart_descriptor d); Dart_descriptor insert_cell_0_in_cell_2(Dart_descriptor d);
@ -908,39 +910,68 @@ Inserts a 1-cell in the 2-cell containing `d1` and `d2`. Returns `previous(d1)`,
See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_edge} and for generalized map in \cgalFigureRef{fig_gmap_insert_edge}. See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_edge} and for generalized map in \cgalFigureRef{fig_gmap_insert_edge}.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 2-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<2>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 2-attribute associated with `d` and <I>a'</I> the new 2-attribute created during the operation. If set, the dynamic onsplit function of 2-attributes is also called on <I>a</I> and <I>a'</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 2-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<2>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 2-attribute associated with `d1` and <I>a'</I> the new 2-attribute created during the operation. If set, the dynamic on-split function of 2-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin \cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `is_insertable_cell_1_in_cell_2` \sa `is_insertable_cell_1_in_cell_2()`
\sa `insert_cell_0_in_cell_1` \sa `insert_cell_0_in_cell_1()`
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2` \sa `insert_cell_1_between_two_cells_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_dangling_cell_1_in_cell_2()`
\sa `remove_cell<i>` \sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `remove_cell<i>()`
*/ */
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor d1, Dart_descriptor d2); Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor d1, Dart_descriptor d2);
/*!
Inserts a 1-cell between the 2-cell containing `d1` and the one containing `d2`. Returns `previous(d1)`, a descriptor on one dart belonging to the new 1-cell.
\pre `is_insertable_cell_1_between_two_cells_2(d1,d2)`.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, call \link CellAttribute::On_merge `Attribute_type<i>::type::On_merge`\endlink(<I>a</I>,<I>a'</I>) is called for all enabled i-attributes, for i>=2, with <I>a</I> the original 2-attribute associated with `d1` and <I>a'</I> the original 2-attribute associated with `d2`. If set, the dynamic on-merge function of i-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd
\sa `is_insertable_cell_1_between_two_cells_2()`
\sa `insert_cell_0_in_cell_1()`
\sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `remove_cell<i>()`
*/
Dart_descriptor insert_cell_1_between_two_cells_2(Dart_descriptor d1, Dart_descriptor d2);
/*! Call `insert_cell_1_in_cell_2()` if `is_insertable_cell_1_in_cell_2(d1, d2)`, otherwise call `insert_cell_1_between_two_cells_2()`.
\sa `insert_cell_1_in_cell_2()`
\sa `insert_cell_1_between_two_cells_2()`
\sa `is_insertable_cell_1_in_cell_2()`
*/
Dart_descriptor insert_cell_1(Dart_descriptor d1, Dart_descriptor d2);
/*! /*!
Inserts a 2-cell along the path of 1-cells containing darts given by the range `[afirst,alast)`. Returns `opposite<2>(*afirst)`, a descriptor on one dart belonging to the new 2-cell. Inserts a 2-cell along the path of 1-cells containing darts given by the range `[afirst,alast)`. Returns `opposite<2>(*afirst)`, a descriptor on one dart belonging to the new 2-cell.
\pre `is_insertable_cell_2_in_cell_3(afirst,alast)`. \pre `is_insertable_cell_2_in_cell_3(afirst,alast)`.
See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_facet} and for generalized map in \cgalFigureRef{fig_gmap_insert_facet}. See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_facet} and for generalized map in \cgalFigureRef{fig_gmap_insert_facet}.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 3-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<3>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 3-attribute associated with `d` and <I>a'</I> the new 3-attribute created during the operation. If set, the dynamic onsplit function of 3-attributes is also called on <I>a</I> and <I>a'</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if 3-attributes are non `void`, \link CellAttribute::On_split `Attribute_type<3>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called, with <I>a</I> the original 3-attribute associated with `d` and <I>a'</I> the new 3-attribute created during the operation. If set, the dynamic on-split function of 3-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin \cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `is_insertable_cell_2_in_cell_3<InputIterator>` \sa `is_insertable_cell_2_in_cell_3<InputIterator>()`
\sa `insert_cell_0_in_cell_1` \sa `insert_cell_0_in_cell_1()`
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2` \sa `insert_cell_1_between_two_cells_2()`
\sa `remove_cell<i>` \sa `insert_dangling_cell_1_in_cell_2()`
\sa `remove_cell<i>()`
*/ */
template <class InputIterator> template <class InputIterator>
Dart_descriptor insert_cell_2_in_cell_3(InputIterator afirst, InputIterator alast); Dart_descriptor insert_cell_2_in_cell_3(InputIterator afirst, InputIterator alast);
@ -955,45 +986,57 @@ See examples for combinatorial map in \cgalFigureRef{fig_cmap_insert_edge} and f
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `insert_cell_0_in_cell_1` \sa `insert_cell_0_in_cell_1()`
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_cell_1_between_two_cells_2()`
\sa `remove_cell<i>` \sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `remove_cell<i>()`
*/ */
Dart_descriptor insert_dangling_cell_1_in_cell_2(Dart_descriptor d); Dart_descriptor insert_dangling_cell_1_in_cell_2(Dart_descriptor d);
/*! /*!
Returns true iff it is possible to insert a 1-cell in the generic map between `d1` and `d2`. Returns `true` iff it is possible to insert a 1-cell in the generic map between `d1` and `d2`.
This is possible if `d1`\f$ \neq \f$ `d2` and `d1` can be reached from `d2` by using some `previous` and `next` calls. This is possible if `d1`\f$ \neq \f$ `d2` and `d1` can be reached from `d2` by using some `previous` and `next` calls.
\pre \link GenericMap::dimension `dimension`\endlink \f$ \geq\f$ 2, `d1`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink, and `d2`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink. \pre \link GenericMap::dimension `dimension`\endlink \f$ \geq\f$ 2, `d1`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink, and `d2`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink.
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `is_insertable_cell_2_in_cell_3<InputIterator>` \sa `is_insertable_cell_2_in_cell_3<InputIterator>()`
*/ */
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor d1, Dart_const_descriptor d2); bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor d1, Dart_const_descriptor d2);
/*! /*!
Returns true iff it is possible to insert a 2-cell in the generic map along the path of darts given by the range `[afirst,alast)`. The 2-cell can be inserted iff the ordered list of darts form a closed path of edges inside a same volume. Returns `true` iff it is possible to insert a 1-cell in the generic map between `d1` and `d2`.
This is possible if `d1`\f$ \neq \f$ `d2` and `d1` can not be reached from `d2` by using some `previous` and `next` calls.
\pre \link GenericMap::dimension `dimension`\endlink \f$ \geq\f$ 2, `d1`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink, and `d2`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink.
\sa `insert_cell_1_between_two_cells_2()`
*/
bool is_insertable_cell_1_between_two_cells_2(Dart_const_descriptor d1, Dart_const_descriptor d2);
/*!
Returns `true` iff it is possible to insert a 2-cell in the generic map along the path of darts given by the range `[afirst,alast)`. The 2-cell can be inserted iff the ordered list of darts form a closed path of edges inside a same volume.
\pre \link GenericMap::dimension `dimension`\endlink \f$ \geq\f$ 3. \pre \link GenericMap::dimension `dimension`\endlink \f$ \geq\f$ 3.
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_cell_2_in_cell_3<InputIterator>()`
\sa `is_insertable_cell_1_in_cell_2` \sa `is_insertable_cell_1_in_cell_2()`
*/ */
template <class InputIterator> template <class InputIterator>
bool is_insertable_cell_2_in_cell_3(InputIterator afirst, InputIterator alast); bool is_insertable_cell_2_in_cell_3(InputIterator afirst, InputIterator alast);
/*! /*!
Returns true iff the <I>i</I>-cell containing `d` can be removed. Returns `true` iff the <I>i</I>-cell containing `d` can be removed.
An <I>i</I>-cell can be removed if `i`==\link GenericMap::dimension `dimension`\endlink or if `i`==\link GenericMap::dimension `dimension`\endlink-1 or if `i`\f$ < \f$ \link GenericMap::dimension `dimension`\endlink-1 and the <I>i</I>-cell containing `d` is incident to at most two (<I>i+1</I>)-cells. An <I>i</I>-cell can be removed if `i`==\link GenericMap::dimension `dimension`\endlink or if `i`==\link GenericMap::dimension `dimension`\endlink-1 or if `i`\f$ < \f$ \link GenericMap::dimension `dimension`\endlink-1 and the <I>i</I>-cell containing `d` is incident to at most two (<I>i+1</I>)-cells.
\pre 0\f$ \leq \f$ `i`\f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink and `d`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink. \pre 0\f$ \leq \f$ `i`\f$ \leq \f$ \link GenericMap::dimension `dimension`\endlink and `d`\f$ \in \f$ \link GenericMap::darts `darts()`\endlink.
\sa `remove_cell<i>` \sa `remove_cell<i>()`
*/ */
template <unsigned int i> template <unsigned int i>
bool is_removable(Dart_const_descriptor d); bool is_removable(Dart_const_descriptor d);
@ -1004,20 +1047,21 @@ Removes the <I>i</I>-cell containing `d`. Returns the number of darts removed fr
See examples in \cgalFigureRef{fig_cmap_insert_vertex}, \cgalFigureRef{fig_cmap_insert_edge} and \cgalFigureRef{fig_cmap_insert_facet}. See examples in \cgalFigureRef{fig_cmap_insert_vertex}, \cgalFigureRef{fig_cmap_insert_edge} and \cgalFigureRef{fig_cmap_insert_facet}.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if `i`\f$ < \f$ \link GenericMap::dimension `dimension`\endlink, and <I>i+1</I>-attributes are non `void`, and if there are two distinct (<I>i+1</I>)-cells around dart `d`, \link CellAttribute::On_merge `Attribute_type<i+1>::type::On_merge`\endlink(<I>a1</I>,<I>a2</I>) is called, with <I>a1</I> the (<I>i+1</I>)-attribute associated to `d`, and <I>a2</I> the (<I>i+1</I>)-attribute associated to \f$ \beta_{i+1}\f$(<I>d</I>). If set, the dynamic onmerge function of <I>i+1</I>-attributes is also called on <I>a1</I> and <I>a2</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if `i`\f$ < \f$ \link GenericMap::dimension `dimension`\endlink, and <I>i+1</I>-attributes are non `void`, and if there are two distinct (<I>i+1</I>)-cells around dart `d`, \link CellAttribute::On_merge `Attribute_type<i+1>::type::On_merge`\endlink(<I>a1</I>,<I>a2</I>) is called, with <I>a1</I> the (<I>i+1</I>)-attribute associated to `d`, and <I>a2</I> the (<I>i+1</I>)-attribute associated to \f$ \beta_{i+1}\f$(<I>d</I>). If set, the dynamic on-merge function of <I>i+1</I>-attributes is also called on <I>a1</I> and <I>a2</I>.
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if a <I>j</I>-cell is disconnected in two <I>j</I>-cells during the operation, and if <I>j</I>-attributes are non void, \link CellAttribute::On_split `Attribute_type<j>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called with <I>a</I> the original <I>j</I>-attribute and <I>a'</I> the new <I>j</I>-attribute created due to the disconnection. If set, the dynamic onsplit function of <i>j</i>-attributes is also called on <I>a</I> and <I>a'</I>. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==true`, if a <I>j</I>-cell is disconnected in two <I>j</I>-cells during the operation, and if <I>j</I>-attributes are non void, \link CellAttribute::On_split `Attribute_type<j>::type::On_split`\endlink(<I>a</I>,<I>a'</I>) is called with <I>a</I> the original <I>j</I>-attribute and <I>a'</I> the new <I>j</I>-attribute created due to the disconnection. If set, the dynamic on-split function of <i>j</i>-attributes is also called on <I>a</I> and <I>a'</I>.
\cgalAdvancedBegin \cgalAdvancedBegin
If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation. If \link GenericMap::are_attributes_automatically_managed `are_attributes_automatically_managed()`\endlink`==false`, non void attributes are not updated; thus the generic map can be no more valid after this operation.
\cgalAdvancedEnd \cgalAdvancedEnd
\sa `is_removable<i>` \sa `is_removable<i>()`
\sa `insert_cell_0_in_cell_1` \sa `insert_cell_0_in_cell_1()`
\sa `insert_cell_0_in_cell_2` \sa `insert_cell_0_in_cell_2()`
\sa `insert_cell_1_in_cell_2` \sa `insert_cell_1_in_cell_2()`
\sa `insert_dangling_cell_1_in_cell_2` \sa `insert_cell_1_between_two_cells_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>` \sa `insert_dangling_cell_1_in_cell_2()`
\sa `insert_cell_2_in_cell_3<InputIterator>()`
*/ */
template <unsigned int i> template <unsigned int i>
size_type remove_cell(Dart_descriptor d); size_type remove_cell(Dart_descriptor d);

View File

@ -6,4 +6,5 @@
\example Combinatorial_map/map_3_with_colored_facets.cpp \example Combinatorial_map/map_3_with_colored_facets.cpp
\example Combinatorial_map/map_3_dynamic_onmerge.cpp \example Combinatorial_map/map_3_dynamic_onmerge.cpp
\example Combinatorial_map/map_3_index.cpp \example Combinatorial_map/map_3_index.cpp
\example Combinatorial_map/map_3_insert.cpp
*/ */

View File

@ -0,0 +1,34 @@
#include <CGAL/Combinatorial_map.h>
#include <iostream>
#include <cstdlib>
#include <cassert>
typedef CGAL::Combinatorial_map<3> CMap_3;
typedef CMap_3::Dart_descriptor Dart_descriptor;
int main()
{
CMap_3 cm;
// Create one combinatorial hexahedron
Dart_descriptor d1 = cm.make_combinatorial_hexahedron();
// Create one square face
Dart_descriptor d2=cm.make_combinatorial_polygon(4);
assert(cm.is_insertable_cell_1_between_two_cells_2(d1,d2));
// Insert the square face as a hole of the face of the hexahedron containing d1
cm.insert_cell_1_between_two_cells_2(d1, d2);
// Display the combinatorial map characteristics.
cm.display_characteristics(std::cout)<<", valid="
<<cm.is_valid()<<std::endl;
std::size_t nb=0;
for(Dart_descriptor dh=cm.darts().begin(); dh!=cm.darts().end(); ++dh)
{ if (cm.is_free<2>(dh)) ++nb; }
std::cout<<"Number of 2-free darts: "<<nb<<std::endl;
return EXIT_SUCCESS;
}

View File

@ -1154,7 +1154,7 @@ namespace CGAL {
} }
/** Unmark all the darts of the map for a given mark. /** Unmark all the darts of the map for a given mark.
* If all the darts are marked or unmarked, this operation takes O(1) * If all the darts are marked or unmarked, this operation takes \cgalBigO{1}
* operations, otherwise it traverses all the darts of the map. * operations, otherwise it traverses all the darts of the map.
* @param amark the given mark. * @param amark the given mark.
*/ */
@ -1639,11 +1639,14 @@ namespace CGAL {
static_assert(i<=dimension); static_assert(i<=dimension);
static_assert(Helper::template Dimension_index<i>::value>=0, static_assert(Helper::template Dimension_index<i>::value>=0,
"set_attribute<i> but i-attributes are disabled"); "set_attribute<i> but i-attributes are disabled");
for ( typename Dart_of_cell_range<i>::iterator it(*this, dh); for (typename Dart_of_cell_range<i>::iterator it(*this, dh);
it.cont(); ++it) it.cont(); ++it)
{ {
this->template set_dart_attribute<i>(it, ah); this->template set_dart_attribute<i>(it, ah);
} }
if(ah!=null_descriptor)
// To ensure that the dart of this attribute is dh
{ this->template set_dart_of_attribute<i>(ah, dh); }
} }
/// @return a Attributes_range<i> (range through all the /// @return a Attributes_range<i> (range through all the
@ -4410,7 +4413,8 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1, bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const Dart_const_descriptor adart2) const
{ {
if ( adart1==adart2 ) return false; if (adart1==adart2 || adart1==null_descriptor) return false;
if (adart2==null_descriptor) return true;
for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1); for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1);
it.cont(); ++it ) it.cont(); ++it )
{ {
@ -4427,15 +4431,81 @@ namespace CGAL {
* same vertex than adart1. * same vertex than adart1.
*/ */
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1, Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1,
Dart_descriptor adart2, Dart_descriptor adart2,
bool update_attributes=true) bool update_attributes=true)
{ {
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
if ( adart2==null_descriptor ) if ( adart2==null_descriptor )
return insert_dangling_cell_1_in_cell_2(adart1, null_descriptor, return insert_dangling_cell_1_in_cell_2(adart1, null_descriptor,
update_attributes); update_attributes);
return generic_insert_cell_1(adart1, adart2, false, update_attributes);
}
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2)); /** Test if an edge can be inserted between two different 2-cells
* between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
* @return true iff an edge can be inserted between adart1 and adart2.
*/
bool is_insertable_cell_1_between_two_cells_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const
{
if (adart1==adart2 || adart1==null_descriptor || adart2==null_descriptor)
{ return false; }
for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1);
it.cont(); ++it )
{
if ( it==adart2 ) return false;
}
return true;
}
/** Insert an edge between two different 2-cells, between two given darts.
* @param adart1 a first dart of the first facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the second facet (!=null_descriptor && !=null_dart_descriptor).
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1_between_two_cells_2(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_between_two_cells_2(adart1, adart2));
return generic_insert_cell_1(adart1, adart2, true, update_attributes);
}
/** Insert an edge between two given darts. If the two darts belong to the same facet, call
* insert_cell_1_in_cell_2, otherwise call insert_cell_1_between_two_cells_2.
* @param adart1 a first dart (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
if(is_insertable_cell_1_in_cell_2(adart1, adart2))
{ return insert_cell_1_in_cell_2(adart1, adart2, update_attributes); }
return insert_cell_1_between_two_cells_2(adart1, adart2, update_attributes);
}
/** Generic method to insert a 1-cell, either in a 2-cell (cf. insert_cell_1_in_cell_2)
* or between two different 2-cells (cf. insert_cell_1_between_two_cells_2).
* Indeed the code is the same, except for the group/degroup attribute.
* merge is true if adart1 and adart2 belongs to two different facets; in this case
* the two facets should be merged (they are now linked by the new edge);
* merge is false it adart1 and adart2 belongs to the same facet; in this case
* the facet is split in two.
* Internal method not supposed to be called by users.
*/
Dart_descriptor generic_insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool merge,
bool update_attributes)
{
size_type m1=get_new_mark(); size_type m1=get_new_mark();
CMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1); CMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1);
@ -4492,7 +4562,7 @@ namespace CGAL {
} }
this->template basic_link_beta_for_involution<2>(d2, d1); this->template basic_link_beta_for_involution<2>(d2, d1);
for ( unsigned int dim=3; dim<=dimension; ++dim) for (unsigned int dim=3; dim<=dimension; ++dim)
{ {
if ( !is_free(it1, dim) && if ( !is_free(it1, dim) &&
is_marked(beta(it1, dim), treated) ) is_marked(beta(it1, dim), treated) )
@ -4509,7 +4579,19 @@ namespace CGAL {
if (are_attributes_automatically_managed() && update_attributes) if (are_attributes_automatically_managed() && update_attributes)
{ {
internal::Degroup_attribute_functor_run<Self, 2>::run(*this, d1, d2); if(merge)
{ // Here we group all enabled attributes starting from 2 to dimension
Helper::template Foreach_enabled_attributes
<internal::Group_attribute_functor<Self>, 2>::run(*this, adart1, adart2);
// And we need to group also beta_i(adart1) and beta_i(adart2) for all
// enabled attributes starting from 3 dimension. Indeed when two i-cells
// are grouped for adart1 and adart2, this group also all beta_j two by two
// except for beta_i.
Helper::template Foreach_enabled_attributes
<internal::Group_neighboor_attribute<Self>, 3>::run(*this, adart1, adart2);
}
else // Here we degroup 2-attributes
{ internal::Degroup_attribute_functor_run<Self, 2>::run(*this, adart1, adart2); }
} }
negate_mark(m1); negate_mark(m1);

View File

@ -36,12 +36,19 @@
* non nullptr, we override all the i-attribute of the second i-cell to the * non nullptr, we override all the i-attribute of the second i-cell to the
* first i-attribute. * first i-attribute.
* *
* Group_neighboor_attribute to group the <i>-attributes of beta_i(d1) and
* beta_i(d2) if they exist.
*
* Degroup_attribute_functor_run<CMap> to degroup one i-attributes in two * Degroup_attribute_functor_run<CMap> to degroup one i-attributes in two
* (except for j-adim). * (except for j-adim).
* *
* Test_split_attribute_functor<CMap,i> to test if there is some i-attributes * Test_split_attribute_functor<CMap,i> to test if there is some i-attributes
* that are split after an operation. Modified darts are given in a * that are split after an operation. Modified darts are given in a
* std::deque. * std::deque.
*
* Set_dart_of_attribute_if_marked<CMap, i> to set the dart of the i-attribute
* associated with a dart if the old dart is marked. Used in remove_cell
* functions.
*/ */
namespace CGAL namespace CGAL
{ {
@ -238,7 +245,8 @@ struct Group_nonvoid_attribute_functor_run
{ {
static void run(CMap& amap, static void run(CMap& amap,
typename CMap::Dart_descriptor adart1, typename CMap::Dart_descriptor adart1,
typename CMap::Dart_descriptor adart2) typename CMap::Dart_descriptor adart2,
bool dart1_deleted=true)
{ {
static_assert( 1<=i && i<=CMap::dimension ); static_assert( 1<=i && i<=CMap::dimension );
static_assert( i!=j ); static_assert( i!=j );
@ -251,8 +259,13 @@ struct Group_nonvoid_attribute_functor_run
a2=amap.template attribute<i>(adart2); a2=amap.template attribute<i>(adart2);
// If the two attributes are equal, nothing to do. // If the two attributes are equal, nothing to do.
if ( a1 == a2 ) return; if (a1==a2)
{
if(a1!=CMap::null_descriptor && dart1_deleted &&
amap.template dart_of_attribute<i>(a1)==adart1)
{ amap.template set_dart_of_attribute<i>(a1, adart2); }
return;
}
typename CMap::Dart_descriptor toSet = amap.null_descriptor; typename CMap::Dart_descriptor toSet = amap.null_descriptor;
// If the attribute associated to adart1 is nullptr, set it with // If the attribute associated to adart1 is nullptr, set it with
@ -268,6 +281,8 @@ struct Group_nonvoid_attribute_functor_run
} }
} }
amap.template set_attribute<i>(toSet, a1); amap.template set_attribute<i>(toSet, a1);
if(dart1_deleted && toSet==adart1)
{ amap.template set_dart_of_attribute<i>(a1, adart2); }
} }
}; };
// Specialization for i=0 and 2<=j. We update 0-attributes for beta_j j>=2. // Specialization for i=0 and 2<=j. We update 0-attributes for beta_j j>=2.
@ -277,7 +292,8 @@ struct Group_nonvoid_attribute_functor_run<CMap, 0, j, T>
{ {
static void run( CMap& amap, static void run( CMap& amap,
typename CMap::Dart_descriptor dh1, typename CMap::Dart_descriptor dh1,
typename CMap::Dart_descriptor dh2 ) typename CMap::Dart_descriptor dh2,
bool dart1_deleted=true)
{ {
static_assert static_assert
( CMap::Helper::template Dimension_index<0>::value>=0, ( CMap::Helper::template Dimension_index<0>::value>=0,
@ -306,6 +322,8 @@ struct Group_nonvoid_attribute_functor_run<CMap, 0, j, T>
} }
} }
amap.template set_attribute<0>(toSet, a1); amap.template set_attribute<0>(toSet, a1);
if(dart1_deleted && toSet==dh1)
{ amap.template set_dart_of_attribute<0>(a1, od); }
} }
} }
// Second extremity // Second extremity
@ -338,7 +356,8 @@ struct Group_nonvoid_attribute_functor_run<CMap, 0, 0, T>
{ {
static void run( CMap& amap, static void run( CMap& amap,
typename CMap::Dart_descriptor dh1, typename CMap::Dart_descriptor dh1,
typename CMap::Dart_descriptor dh2 ) typename CMap::Dart_descriptor dh2,
bool dart1_deleted=true)
{ {
static_assert static_assert
( CMap::Helper::template Dimension_index<0>::value>=0, ( CMap::Helper::template Dimension_index<0>::value>=0,
@ -364,6 +383,8 @@ struct Group_nonvoid_attribute_functor_run<CMap, 0, 0, T>
} }
} }
amap.template set_attribute<0>(toSet, a1); amap.template set_attribute<0>(toSet, a1);
if(dart1_deleted && toSet==dh1)
{ amap.template set_dart_of_attribute<0>(a1, od); }
} }
} }
} }
@ -375,7 +396,8 @@ struct Group_nonvoid_attribute_functor_run<CMap, 0, 1, T>
{ {
static void run( CMap& amap, static void run( CMap& amap,
typename CMap::Dart_descriptor dh1, typename CMap::Dart_descriptor dh1,
typename CMap::Dart_descriptor dh2 ) typename CMap::Dart_descriptor dh2,
bool=true)
{ {
static_assert static_assert
( CMap::Helper::template Dimension_index<0>::value>=0, ( CMap::Helper::template Dimension_index<0>::value>=0,
@ -411,7 +433,8 @@ struct Group_nonvoid_attribute_functor_run<CMap,i,i,T>
{ {
static void run(CMap&, static void run(CMap&,
typename CMap::Dart_descriptor, typename CMap::Dart_descriptor,
typename CMap::Dart_descriptor) typename CMap::Dart_descriptor,
bool=true)
{} {}
}; };
// Specialization for i=1 and j=0. Do nothing as edges attributes are not // Specialization for i=1 and j=0. Do nothing as edges attributes are not
@ -421,7 +444,8 @@ struct Group_nonvoid_attribute_functor_run<CMap,1,0,T>
{ {
static void run(CMap&, static void run(CMap&,
typename CMap::Dart_descriptor, typename CMap::Dart_descriptor,
typename CMap::Dart_descriptor) typename CMap::Dart_descriptor,
bool=true)
{} {}
}; };
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -432,8 +456,10 @@ struct Group_attribute_functor_run
{ {
static void run( CMap& amap, static void run( CMap& amap,
typename CMap::Dart_descriptor d1, typename CMap::Dart_descriptor d1,
typename CMap::Dart_descriptor d2) typename CMap::Dart_descriptor d2,
{ Group_nonvoid_attribute_functor_run<CMap, i, j, T>::run(amap, d1, d2); } bool dart1_deleted=true)
{ Group_nonvoid_attribute_functor_run<CMap, i, j, T>::
run(amap, d1, d2, dart1_deleted); }
}; };
// Specialization for void attributes. // Specialization for void attributes.
template<typename CMap, unsigned int i, unsigned int j> template<typename CMap, unsigned int i, unsigned int j>
@ -441,7 +467,8 @@ struct Group_attribute_functor_run<CMap, i, j, CGAL::Void>
{ {
static void run( CMap&, static void run( CMap&,
typename CMap::Dart_descriptor, typename CMap::Dart_descriptor,
typename CMap::Dart_descriptor ) typename CMap::Dart_descriptor,
bool=true)
{} {}
}; };
// ************************************************************************ // ************************************************************************
@ -464,6 +491,22 @@ struct Group_attribute_functor
run(amap,adart1,adart2); } run(amap,adart1,adart2); }
}; };
// ************************************************************************ // ************************************************************************
/// Group i-attribute of beta_i(d1) and beta_i(d2) if they exist.
template<typename CMap>
struct Group_neighboor_attribute
{
template<unsigned int i>
static void run(CMap& amap, typename CMap::Dart_descriptor d1,
typename CMap::Dart_descriptor d2)
{
if(!amap.template is_free<i>(d1) && !amap.template is_free<i>(d2))
{
CGAL::internal::Group_attribute_functor_run<CMap, i>::run
(amap, amap.template opposite<i>(d1), amap.template opposite<i>(d2), false);
}
}
};
// ************************************************************************
// Functor used to degroup one i-attribute of one i-cell in two, except the // Functor used to degroup one i-attribute of one i-cell in two, except the
// attribute of j. // attribute of j.
template<typename CMap, unsigned int i, unsigned int j=CMap::dimension+1, template<typename CMap, unsigned int i, unsigned int j=CMap::dimension+1,
@ -1022,6 +1065,28 @@ struct Test_split_attribute_functor
} }
}; };
// ************************************************************************ // ************************************************************************
template<typename CMap, unsigned int i,
typename T=typename CMap::template Attribute_type<i>::type>
struct Set_dart_of_attribute_if_marked
{
static void run(CMap& amap, typename CMap::Dart_descriptor d1,
typename CMap::size_type amark)
{
if(amap.template attribute<i>(d1)!=CMap::null_descriptor &&
amap.template dart<i>(d1)!=CMap::null_descriptor &&
amap.is_marked(amap.template dart<i>(d1), amark))
{ amap.template dart<i>(d1)=d1; }
}
};
// Specialization for void attributes.
template<typename CMap, unsigned int i>
struct Set_dart_of_attribute_if_marked<CMap, i, CGAL::Void>
{
static void run(CMap&, typename CMap::Dart_descriptor,
typename CMap::size_type)
{}
};
// ************************************************************************
} // namespace internal } // namespace internal
} // namespace CGAL } // namespace CGAL

View File

@ -342,23 +342,24 @@ namespace CGAL
//is called for case k only if the k'th type in the tuple //is called for case k only if the k'th type in the tuple
//is different from Void. Note that to the converse of Foreach_static //is different from Void. Note that to the converse of Foreach_static
//Functor are called from n =0 to k //Functor are called from n =0 to k
template <class Functor,class T,int n=0> template <class Functor,class T,int n=0, int startn=0>
struct Foreach_static_restricted; struct Foreach_static_restricted;
template <class Functor,class Head, class ... Items,int n> template <class Functor,class Head, class ... Items,int n, int startn>
struct Foreach_static_restricted<Functor, struct Foreach_static_restricted<Functor,
std::tuple<Head,Items...>,n> std::tuple<Head,Items...>,n, startn>
{ {
template <class ... T> template <class ... T>
static void run(T& ... t){ static void run(T& ... t){
Conditionnal_run<Functor,n,Head>::run(t...); if(n>=startn)
{ Conditionnal_run<Functor,n,Head>::run(t...); }
Foreach_static_restricted Foreach_static_restricted
<Functor,std::tuple<Items...>,n+1>::run(t...); <Functor,std::tuple<Items...>, n+1, startn>::run(t...);
} }
}; };
template <class Functor,int n> template <class Functor,int n, int startn>
struct Foreach_static_restricted<Functor,std::tuple<>,n>{ struct Foreach_static_restricted<Functor,std::tuple<>,n, startn>{
template <class ... T> template <class ... T>
static void run(T& ... ){} static void run(T& ... ){}
}; };
@ -609,13 +610,13 @@ namespace CGAL
struct Attribute_const_range<d, CGAL::Void> struct Attribute_const_range<d, CGAL::Void>
{ typedef CGAL::Void type; }; { typedef CGAL::Void type; };
// To iterate onto each enabled attributes // To iterate onto each enabled attributes, starting from startn-attributes (0 by default)
template <class Functor> template <class Functor, int startn=0>
struct Foreach_enabled_attributes struct Foreach_enabled_attributes
{ {
template <class ...Ts> template <class ...Ts>
static void run(Ts& ... t) static void run(Ts& ... t)
{ Foreach_static_restricted<Functor, Attributes>::run(t...); } { Foreach_static_restricted<Functor, Attributes, 0, startn>::run(t...); }
}; };
// To iterate onto each enabled attributes, except j-attributes // To iterate onto each enabled attributes, except j-attributes
template <class Functor, unsigned int j> template <class Functor, unsigned int j>

View File

@ -107,8 +107,10 @@ namespace CGAL
{ {
// We group the two (i+1)-cells incident if they exist. // We group the two (i+1)-cells incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
{
CGAL::internal::Group_attribute_functor_run<CMap, i+1>:: CGAL::internal::Group_attribute_functor_run<CMap, i+1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be removed
}
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified
@ -148,6 +150,9 @@ namespace CGAL
if ( d1!=amap.null_dart_descriptor ) if ( d1!=amap.null_dart_descriptor )
{ {
internal::Set_dart_of_attribute_if_marked<CMap, i+1>::
run(amap, d1, mark);
if ( d2!=amap.null_dart_descriptor && d1!=d2 ) if ( d2!=amap.null_dart_descriptor && d1!=d2 )
{ {
amap.template basic_link_beta<i>(d1, d2); amap.template basic_link_beta<i>(d1, d2);
@ -353,7 +358,7 @@ namespace CGAL
// We group the two edges incident if they exist. // We group the two edges incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
CGAL::internal::Group_attribute_functor_run<CMap, 1>:: CGAL::internal::Group_attribute_functor_run<CMap, 1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be removed
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified
@ -369,6 +374,9 @@ namespace CGAL
{ {
if ( !amap.template is_free<0>(*it) ) if ( !amap.template is_free<0>(*it) )
{ {
internal::Set_dart_of_attribute_if_marked<CMap, 1>::
run(amap, amap.template beta<0>(*it), mark);
if ( !amap.template is_free<1>(*it) && if ( !amap.template is_free<1>(*it) &&
amap.template beta<0>(*it)!=(*it) ) amap.template beta<0>(*it)!=(*it) )
{ {
@ -523,7 +531,7 @@ namespace CGAL
// We group the two (i-1)-cells incident if they exist. // We group the two (i-1)-cells incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
CGAL::internal::Group_attribute_functor_run<CMap,i-1>:: CGAL::internal::Group_attribute_functor_run<CMap,i-1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be removed
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified
@ -677,7 +685,7 @@ namespace CGAL
// We group the two vertices incident if they exist. // We group the two vertices incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
CGAL::internal::Group_attribute_functor_run<CMap, 0, 1>:: CGAL::internal::Group_attribute_functor_run<CMap, 0, 1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be removed
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified

View File

@ -738,6 +738,9 @@ public:
size_type index(const_iterator cit) const size_type index(const_iterator cit) const
{ return static_cast<size_type>(cit); } { return static_cast<size_type>(cit); }
size_type index(Index idx) const
{ return static_cast<size_type>(idx); }
// Returns whether the iterator "cit" is in the range [begin(), end()]. // Returns whether the iterator "cit" is in the range [begin(), end()].
// This function is mostly useful for purposes of efficient debugging at // This function is mostly useful for purposes of efficient debugging at
// higher levels. // higher levels.

View File

@ -1012,6 +1012,17 @@ bool test3D()
map.insert_cell_1_in_cell_2(d1, map.beta(d1,1,1)); map.insert_cell_1_in_cell_2(d1, map.beta(d1,1,1));
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl; map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
map.clear(); map.clear();
d1 = map.make_combinatorial_polygon(4);
d2 = map.make_combinatorial_polygon(4);
map.insert_cell_1_between_two_cells_2(d1, d2);
if(!map.is_valid())
{
map.display_characteristics(cout) << ", valid=" << map.is_valid() << endl;
std::cout<<"ERROR after map.insert_cell_1_between_two_cells_2(d1, d2);"<<std::endl;
assert(false);
return false;
}
map.clear(); map.clear();
cout << "***************************** TEST INSERT EDGE 3D DONE." cout << "***************************** TEST INSERT EDGE 3D DONE."

View File

@ -160,7 +160,7 @@ In constructing Theta graphs, this functor uses the algorithm from
Chapter 4 of the book by Narasimhan and Smid \cgalCite{cgal:ns-gsn-07}. Chapter 4 of the book by Narasimhan and Smid \cgalCite{cgal:ns-gsn-07}.
Basically, it is a sweep line algorithm and uses a Basically, it is a sweep line algorithm and uses a
balanced search tree to store the vertices that have already been scanned. balanced search tree to store the vertices that have already been scanned.
It has the complexity of \f$O(n \log n)\f$, where \f$n\f$ is the number of vertices in the plane. It has the complexity of \cgalBigO{n \log n}, where \f$n\f$ is the number of vertices in the plane.
This complexity has been proved to be optimal. This complexity has been proved to be optimal.
For more details on how to use this `Construct_theta_graph_2` functor to write an application to build Theta graphs, For more details on how to use this `Construct_theta_graph_2` functor to write an application to build Theta graphs,
@ -178,13 +178,13 @@ The functor `Construct_yao_graph_2` has a similar definition as `Construct_theta
The way of using these two template parameters is the same as that of `Construct_theta_graph_2`, The way of using these two template parameters is the same as that of `Construct_theta_graph_2`,
so please refer to the previous subsection for the details. We note here that construction algorithm for Yao graph so please refer to the previous subsection for the details. We note here that construction algorithm for Yao graph
is a slight adaptation of the algorithm for constructing Theta graph, having a complexity of \f$O(n^2)\f$. is a slight adaptation of the algorithm for constructing Theta graph, having a complexity of \cgalBigO{n^2}.
The increase of complexity in this adaptation is because in constructing Theta graph, The increase of complexity in this adaptation is because in constructing Theta graph,
the searching of the 'closest' node by projection distance can be done by a balanced search tree, the searching of the 'closest' node by projection distance can be done by a balanced search tree,
but in constructing Yao graph, the searching of the 'closest' node by Euclidean distance cannot be but in constructing Yao graph, the searching of the 'closest' node by Euclidean distance cannot be
done by a balanced search tree. done by a balanced search tree.
Note that an optimal algorithm for constructing Yao graph with a complexity of \f$O(n \log n)\f$ is Note that an optimal algorithm for constructing Yao graph with a complexity of \cgalBigO{n \log n} is
described in \cgalCite{cgal:cht-oacov-90}. However, this algorithm is much more complex to implement than described in \cgalCite{cgal:cht-oacov-90}. However, this algorithm is much more complex to implement than
the current algorithm implemented, and it can hardly reuse the codes for constructing Theta graphs, the current algorithm implemented, and it can hardly reuse the codes for constructing Theta graphs,
so it is not implemented in this package right now. so it is not implemented in this package right now.
@ -304,7 +304,7 @@ and `Construct_yao_graph_2` construct full Theta and Yao graphs. They also provi
to compute Half Theta and Yao graphs. As mentioned in Section \ref sec_CBS_mydefinitions, to compute Half Theta and Yao graphs. As mentioned in Section \ref sec_CBS_mydefinitions,
only the edges for the odd or even cones are added to the graph in an Half Theta and Yao only the edges for the odd or even cones are added to the graph in an Half Theta and Yao
graph. To do so, the constructor of the functors provides a parameter of type graph. To do so, the constructor of the functors provides a parameter of type
`Cones_selected` which is a enumeration that contains the following possible values: `Cones_selected` which is an enumeration that contains the following possible values:
`ALL_CONES`, `EVEN_CONES` and `ODD_CONES`. Users should include the `ALL_CONES`, `EVEN_CONES` and `ODD_CONES`. Users should include the
`CGAL/Cone_spanners_enum_2.h` header file to use these enum values. The following are the `CGAL/Cone_spanners_enum_2.h` header file to use these enum values. The following are the
examples on the functor constructions for Half Theta and Yao Graphs. examples on the functor constructions for Half Theta and Yao Graphs.

View File

@ -18,11 +18,11 @@ Minkowski sums of the convex pieces, and unite the pair-wise sums.
While it is desirable to have a decomposition into a minimum number of While it is desirable to have a decomposition into a minimum number of
pieces, this problem is known to be NP-hard \cgalCite{c-cpplb-84}. Our pieces, this problem is known to be NP-hard \cgalCite{c-cpplb-84}. Our
implementation decomposes a Nef polyhedron \f$ N\f$ into \f$ O(r^2)\f$ convex implementation decomposes a Nef polyhedron \f$ N\f$ into \cgalBigO{r^2} convex
pieces, where \f$ r\f$ is the number of edges that have two adjacent pieces, where \f$ r\f$ is the number of edges that have two adjacent
facets that span an angle of more than 180 degrees with respect to the facets that span an angle of more than 180 degrees with respect to the
interior of the polyhedron. Those edges are also called reflex edges. interior of the polyhedron. Those edges are also called reflex edges.
The bound of \f$ O(r^2)\f$ convex pieces is worst-case The bound of \cgalBigO{r^2} convex pieces is worst-case
optimal \cgalCite{c-cpplb-84}. optimal \cgalCite{c-cpplb-84}.
\cgalFigureBegin{figverticalDecomposition,two_cubes_all_in_one.png} \cgalFigureBegin{figverticalDecomposition,two_cubes_all_in_one.png}

View File

@ -6,7 +6,7 @@
\cgalPkgPicture{Convex_decomposition_3/fig/Convex_decomposition_3-teaser.png} \cgalPkgPicture{Convex_decomposition_3/fig/Convex_decomposition_3-teaser.png}
\cgalPkgSummaryBegin \cgalPkgSummaryBegin
\cgalPkgAuthor{Peter Hachenberger} \cgalPkgAuthor{Peter Hachenberger}
\cgalPkgDesc{This packages provides a function for decomposing a bounded polyhedron into convex sub-polyhedra. The decomposition yields \f$ O(r^2)\f$ convex pieces, where \f$ r\f$ is the number of edges, whose adjacent facets form an angle of more than 180 degrees with respect to the polyhedron's interior. This bound is worst-case optimal. } \cgalPkgDesc{This packages provides a function for decomposing a bounded polyhedron into convex sub-polyhedra. The decomposition yields \cgalBigO{r^2} convex pieces, where \f$ r\f$ is the number of edges, whose adjacent facets form an angle of more than 180 degrees with respect to the polyhedron's interior. This bound is worst-case optimal. }
\cgalPkgManuals{Chapter_Convex_Decomposition_of_Polyhedra,PkgConvexDecomposition3Ref} \cgalPkgManuals{Chapter_Convex_Decomposition_of_Polyhedra,PkgConvexDecomposition3Ref}
\cgalPkgSummaryEnd \cgalPkgSummaryEnd
\cgalPkgShortInfoBegin \cgalPkgShortInfoBegin

View File

@ -41,12 +41,12 @@ The function `convex_decomposition_3()` inserts additional facets
into the given `Nef_polyhedron_3` `N`, such that each bounded into the given `Nef_polyhedron_3` `N`, such that each bounded
marked volume (the outer volume is unbounded) is subdivided into convex marked volume (the outer volume is unbounded) is subdivided into convex
pieces. The modified polyhedron represents a decomposition into pieces. The modified polyhedron represents a decomposition into
\f$ O(r^2)\f$ convex pieces, where \f$ r\f$ is the number of edges that have two \cgalBigO{r^2} convex pieces, where \f$ r\f$ is the number of edges that have two
adjacent facets that span an angle of more than 180 degrees with adjacent facets that span an angle of more than 180 degrees with
respect to the interior of the polyhedron. respect to the interior of the polyhedron.
The worst-case running time of our implementation is The worst-case running time of our implementation is
\f$ O(n^2r^4\sqrt[3]{nr^2}\log{(nr)})\f$, where \f$ n\f$ is the complexity of \cgalBigO{n^2r^4\sqrt[3]{nr^2}\log{(nr)}}, where \f$ n\f$ is the complexity of
the polyhedron (the complexity of a `Nef_polyhedron_3` is the sum the polyhedron (the complexity of a `Nef_polyhedron_3` is the sum
of its `Vertices`, `Halfedges` and `SHalfedges`) and \f$ r\f$ of its `Vertices`, `Halfedges` and `SHalfedges`) and \f$ r\f$
is the number of reflex edges. is the number of reflex edges.

View File

@ -44,7 +44,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
This function uses the algorithm of Akl and This function uses the algorithm of Akl and
Toussaint \cgalCite{at-fcha-78} that requires \f$ O(n \log n)\f$ time for \f$ n\f$ input Toussaint \cgalCite{at-fcha-78} that requires \cgalBigO{n \log n} time for \f$ n\f$ input
points. points.

View File

@ -45,7 +45,7 @@ functions that return instances of these types:
This function implements the non-recursive variation of This function implements the non-recursive variation of
Eddy's algorithm \cgalCite{e-nchap-77} described in \cgalCite{b-chfsp-78}. Eddy's algorithm \cgalCite{e-nchap-77} described in \cgalCite{b-chfsp-78}.
This algorithm requires \f$ O(n h)\f$ time This algorithm requires \cgalBigO{n h} time
in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points. in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
*/ */
template <class InputIterator, class OutputIterator, class Traits> template <class InputIterator, class OutputIterator, class Traits>

View File

@ -47,7 +47,7 @@ This function implements Eddy's algorithm
\cgalCite{e-nchap-77}, which is the two-dimensional version of the quickhull \cgalCite{e-nchap-77}, which is the two-dimensional version of the quickhull
algorithm \cgalCite{bdh-qach-96}. algorithm \cgalCite{bdh-qach-96}.
This algorithm requires \f$ O(n h)\f$ time This algorithm requires \cgalBigO{n h} time
in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points. in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
*/ */

View File

@ -44,7 +44,7 @@ functions that return instances of these types:
This function implements Andrew's variant of the Graham This function implements Andrew's variant of the Graham
scan algorithm \cgalCite{a-aeach-79} and follows the presentation of Mehlhorn scan algorithm \cgalCite{a-aeach-79} and follows the presentation of Mehlhorn
\cgalCite{m-mdscg-84}. This algorithm requires \f$ O(n \log n)\f$ time \cgalCite{m-mdscg-84}. This algorithm requires \cgalBigO{n \log n} time
in the worst case for \f$ n\f$ input points. in the worst case for \f$ n\f$ input points.
@ -101,7 +101,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
This algorithm requires \f$ O(n)\f$ time in the worst case for This algorithm requires \cgalBigO{n} time in the worst case for
\f$ n\f$ input points. \f$ n\f$ input points.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -44,7 +44,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
This function uses the Jarvis march (gift-wrapping) This function uses the Jarvis march (gift-wrapping)
algorithm \cgalCite{j-ichfs-73}. This algorithm requires \f$ O(n h)\f$ time algorithm \cgalCite{j-ichfs-73}. This algorithm requires \cgalBigO{n h} time
in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points. in the worst case for \f$ n\f$ input points with \f$ h\f$ extreme points.
*/ */
@ -97,7 +97,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
The function uses the Jarvis march (gift-wrapping) algorithm \cgalCite{j-ichfs-73}. The function uses the Jarvis march (gift-wrapping) algorithm \cgalCite{j-ichfs-73}.
This algorithm requires \f$ O(n h)\f$ time in the worst This algorithm requires \cgalBigO{n h} time in the worst
case for \f$ n\f$ input points with \f$ h\f$ extreme points case for \f$ n\f$ input points with \f$ h\f$ extreme points
\pre `start_p` and `stop_p` are extreme points with respect to \pre `start_p` and `stop_p` are extreme points with respect to

View File

@ -47,9 +47,9 @@ functions that return instances of these types:
One of two algorithms is used, One of two algorithms is used,
depending on the type of iterator used to specify the input points. For depending on the type of iterator used to specify the input points. For
input iterators, the algorithm used is that of Bykat \cgalCite{b-chfsp-78}, which input iterators, the algorithm used is that of Bykat \cgalCite{b-chfsp-78}, which
has a worst-case running time of \f$ O(n h)\f$, where \f$ n\f$ is the number of input has a worst-case running time of \cgalBigO{n h}, where \f$ n\f$ is the number of input
points and \f$ h\f$ is the number of extreme points. For all other types of points and \f$ h\f$ is the number of extreme points. For all other types of
iterators, the \f$ O(n \log n)\f$ algorithm of of Akl and Toussaint iterators, the \cgalBigO{n \log n} algorithm of of Akl and Toussaint
\cgalCite{at-fcha-78} is used. \cgalCite{at-fcha-78} is used.
@ -128,7 +128,7 @@ functions that return instances of these types:
This function uses Andrew's variant of Graham's scan algorithm This function uses Andrew's variant of Graham's scan algorithm
\cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}. The algorithm has worst-case running time \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}. The algorithm has worst-case running time
of \f$ O(n \log n)\f$ for \f$ n\f$ input points. of \cgalBigO{n \log n} for \f$ n\f$ input points.
*/ */
@ -192,7 +192,7 @@ functions that return instances of these types:
This function uses Andrew's This function uses Andrew's
variant of Graham's scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}. The algorithm variant of Graham's scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}. The algorithm
has worst-case running time of \f$ O(n \log n)\f$ for \f$ n\f$ input points. has worst-case running time of \cgalBigO{n \log n} for \f$ n\f$ input points.
*/ */
template <class InputIterator, class OutputIterator> template <class InputIterator, class OutputIterator>

View File

@ -32,7 +32,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
The algorithm requires \f$ O(n)\f$ time for a set of \f$ n\f$ input points. The algorithm requires \cgalBigO{n} time for a set of \f$ n\f$ input points.
@ -80,7 +80,7 @@ functions that return instances of these types:
\cgalHeading{Implementation} \cgalHeading{Implementation}
The algorithm requires \f$ O(n)\f$ time for a set of \f$ n\f$ input points. The algorithm requires \cgalBigO{n} time for a set of \f$ n\f$ input points.

View File

@ -52,17 +52,17 @@ class need not be specified and defaults to types and operations defined
in the kernel in which the input point type is defined. in the kernel in which the input point type is defined.
Given a sequence of \f$ n\f$ input points with \f$ h\f$ extreme points, Given a sequence of \f$ n\f$ input points with \f$ h\f$ extreme points,
the function `convex_hull_2()` uses either the output-sensitive \f$ O(n h)\f$ algorithm of Bykat \cgalCite{b-chfsp-78} the function `convex_hull_2()` uses either the output-sensitive \cgalBigO{n h} algorithm of Bykat \cgalCite{b-chfsp-78}
(a non-recursive version of the quickhull \cgalCite{bdh-qach-96} algorithm) or the algorithm of Akl and Toussaint, which requires \f$ O(n \log n)\f$ time (a non-recursive version of the quickhull \cgalCite{bdh-qach-96} algorithm) or the algorithm of Akl and Toussaint, which requires \cgalBigO{n \log n} time
in the worst case. The algorithm chosen depends on the kind of in the worst case. The algorithm chosen depends on the kind of
iterator used to specify the input points. These two algorithms are iterator used to specify the input points. These two algorithms are
also available via the functions `ch_bykat()` and `ch_akl_toussaint()`, also available via the functions `ch_bykat()` and `ch_akl_toussaint()`,
respectively. Also available are respectively. Also available are
the \f$ O(n \log n)\f$ Graham-Andrew scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84} the \cgalBigO{n \log n} Graham-Andrew scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}
(`ch_graham_andrew()`), (`ch_graham_andrew()`),
the \f$ O(n h)\f$ Jarvis march algorithm \cgalCite{j-ichfs-73} the \cgalBigO{n h} Jarvis march algorithm \cgalCite{j-ichfs-73}
(`ch_jarvis()`), (`ch_jarvis()`),
and Eddy's \f$ O(n h)\f$ algorithm \cgalCite{e-nchap-77} and Eddy's \cgalBigO{n h} algorithm \cgalCite{e-nchap-77}
(`ch_eddy()`), which corresponds to the (`ch_eddy()`), which corresponds to the
two-dimensional version of the quickhull algorithm. two-dimensional version of the quickhull algorithm.
The linear-time algorithm of Melkman for producing the convex hull of The linear-time algorithm of Melkman for producing the convex hull of
@ -105,7 +105,7 @@ provide the computation of the counterclockwise
sequence of extreme points on the lower hull and upper hull, sequence of extreme points on the lower hull and upper hull,
respectively. The algorithm used in these functions is respectively. The algorithm used in these functions is
Andrew's variant of Graham's scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84}, Andrew's variant of Graham's scan algorithm \cgalCite{a-aeach-79}, \cgalCite{m-mdscg-84},
which has worst-case running time of \f$ O(n \log n)\f$. which has worst-case running time of \cgalBigO{n \log n}.
There are also functions available for computing certain subsequences There are also functions available for computing certain subsequences
of the sequence of extreme points on the convex hull. The function of the sequence of extreme points on the convex hull. The function

View File

@ -16,7 +16,7 @@ vertices of the convex hull).
\cgalHeading{Implementation} \cgalHeading{Implementation}
This function implements the tests described in \cgalCite{mnssssu-cgpvg-96} to This function implements the tests described in \cgalCite{mnssssu-cgpvg-96} to
determine convexity and requires \f$ O(e + f)\f$ time for a polyhedron with determine convexity and requires \cgalBigO{e + f} time for a polyhedron with
\f$ e\f$ edges and \f$ f\f$ faces. \f$ e\f$ edges and \f$ f\f$ faces.

View File

@ -180,7 +180,7 @@ halfspace_intersection_interior_point_3(PlaneIterator begin, PlaneIterator end)
typedef typename Kernel_traits<typename std::iterator_traits<PlaneIterator>::value_type>::Kernel K; typedef typename Kernel_traits<typename std::iterator_traits<PlaneIterator>::value_type>::Kernel K;
// choose exact integral type // choose exact integral type
typedef typename internal::Exact_field_selector<void*>::Type ET; typedef typename internal::Exact_field_selector<typename K::FT>::Type ET;
// find a point inside the intersection // find a point inside the intersection
internal::Interior_polyhedron_3<K, ET> interior; internal::Interior_polyhedron_3<K, ET> interior;

View File

@ -69,7 +69,7 @@ The time and space requirements are input dependent. Let \f$C_1\f$, \f$C_2\f$, \
let \f$ k_i\f$ be the number of facets of \f$ C_i\f$ that are visible from \f$ x\f$ let \f$ k_i\f$ be the number of facets of \f$ C_i\f$ that are visible from \f$ x\f$
and that are not already facets of \f$ C_{i-1}\f$. and that are not already facets of \f$ C_{i-1}\f$.
Then the time for inserting \f$ x\f$ is \f$ O(dim \sum_i k_i)\f$ and Then the time for inserting \f$ x\f$ is \cgalBigO{dim \sum_i k_i} and
the number of new simplices constructed during the insertion of \f$x\f$ the number of new simplices constructed during the insertion of \f$x\f$
is the number of facets of the hull which were not already facets is the number of facets of the hull which were not already facets
of the hull before the insertion. of the hull before the insertion.

View File

@ -241,6 +241,18 @@ else()
"#EXTRACT_ALL_NO_DETAILED_IF_EMPTY = NO") "#EXTRACT_ALL_NO_DETAILED_IF_EMPTY = NO")
endif() endif()
option(CGAL_NO_ADDITIONAL_DETAILS
"Use CGAL special doxygen setting NO_ADDITIONAL_DETAILS." ON)
if(CGAL_NO_ADDITIONAL_DETAILS)
set(CGAL_OPT_NO_ADDITIONAL_DETAILS
"NO_ADDITIONAL_DETAILS = YES")
else()
# The default is NO, so we could leave it out, but it is better to have a commented out placeholder
# this will work for versions with and without the setting.
set(CGAL_OPT_NO_ADDITIONAL_DETAILS
"#NO_ADDITIONAL_DETAILS = NO")
endif()
#we use two directories for the generation/reading of tag files to prevent issues #we use two directories for the generation/reading of tag files to prevent issues
#if the targets are built in parallel #if the targets are built in parallel
set(CGAL_DOC_TAG_GEN_DIR "${CMAKE_BINARY_DIR}/doc_gen_tags") set(CGAL_DOC_TAG_GEN_DIR "${CMAKE_BINARY_DIR}/doc_gen_tags")
@ -402,6 +414,15 @@ else()
endforeach() endforeach()
endif() endif()
#special cases
foreach(pkg "Mesher_level")
if(CGAL_BRANCH_BUILD)
set(CGAL_${pkg}_INCLUDE_DIR "${CGAL_ROOT}/${pkg}/include")
else()
set(CGAL_${pkg}_INCLUDE_DIR "${CGAL_ROOT}/include")
endif()
endforeach()
option(CGAL_BUILD_THREE_DOC "Build the documentation of the Three package" OFF) option(CGAL_BUILD_THREE_DOC "Build the documentation of the Three package" OFF)
if(NOT CGAL_BUILD_THREE_DOC) if(NOT CGAL_BUILD_THREE_DOC)

View File

@ -169,7 +169,7 @@ complexity are known. Also, the theoretic interest in efficiency for
realistic inputs, as opposed to worst-case situations, is realistic inputs, as opposed to worst-case situations, is
growing \cgalCite{v-ffrim-97}. growing \cgalCite{v-ffrim-97}.
For practical purposes, insight into the constant factors hidden in the For practical purposes, insight into the constant factors hidden in the
\f$ O\f$-notation is necessary, especially if there are several competing \cgalBigO{&nbsp;}-notation is necessary, especially if there are several competing
algorithms. algorithms.
Therefore, different implementations should be supplied if there is Therefore, different implementations should be supplied if there is

View File

@ -7,7 +7,7 @@
\authors Stefan Schirra \authors Stefan Schirra
The layer of geometry kernels provides The layer of geometry kernels provides
basic geometric entities of constant size\cgalFootnote{In dimension \f$ d\f$, an entity of size \f$ O(d)\f$ is considered to be of constant size.} and basic geometric entities of constant size\cgalFootnote{In dimension \f$ d\f$, an entity of size \cgalBigO{d} is considered to be of constant size.} and
primitive operations on them. Each entity is provided as both a primitive operations on them. Each entity is provided as both a
stand-alone class, which is parameterized by a kernel class, and as a stand-alone class, which is parameterized by a kernel class, and as a
type in the kernel class. Each operation in the kernel is provided via type in the kernel class. Each operation in the kernel is provided via

View File

@ -159,9 +159,9 @@ ALIASES = "cgal=%CGAL" \
"cgalPkgSince{1}=<B>Introduced in:</B> \cgal \1<BR>" \ "cgalPkgSince{1}=<B>Introduced in:</B> \cgal \1<BR>" \
"cgalPkgDependsOn{1}=<B>Depends on:</B> \1 <BR>" \ "cgalPkgDependsOn{1}=<B>Depends on:</B> \1 <BR>" \
"cgalPkgLicense{1}=<B>License:</B> \1 <BR>" \ "cgalPkgLicense{1}=<B>License:</B> \1 <BR>" \
"cgalPkgDemo{2}=<B>Windows Demo:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{2}=<B>Windows demo:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDemo{4}=<B>Windows Demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{4}=<B>Windows demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDemo{6}=<B>Windows Demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\6\">\5</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{6}=<B>Windows demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\6\">\5</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDescriptionEnd=" \ "cgalPkgDescriptionEnd=" \
"cgalModifBegin=\htmlonly <div class=\"CGALModification\"> \endhtmlonly \xrefitem Modification \"Modifications\" \"MODIFICATIONS\" " \ "cgalModifBegin=\htmlonly <div class=\"CGALModification\"> \endhtmlonly \xrefitem Modification \"Modifications\" \"MODIFICATIONS\" " \
"cgalModifEnd=\htmlonly </div> \endhtmlonly \latexonly END MODIFICATIONS \endlatexonly" \ "cgalModifEnd=\htmlonly </div> \endhtmlonly \latexonly END MODIFICATIONS \endlatexonly" \
@ -188,7 +188,9 @@ ALIASES = "cgal=%CGAL" \
"cgalParamNEnd=</ul> \htmlonly[block] </div> \endhtmlonly </td><td></td></tr>" \ "cgalParamNEnd=</ul> \htmlonly[block] </div> \endhtmlonly </td><td></td></tr>" \
"cgalParamSectionBegin{1}=\cgalParamNBegin{\1}" \ "cgalParamSectionBegin{1}=\cgalParamNBegin{\1}" \
"cgalParamSectionEnd=\cgalParamNEnd" \ "cgalParamSectionEnd=\cgalParamNEnd" \
"cgalParamPrecondition{1}=<li><b>Precondition: </b>\1</li>" "cgalParamPrecondition{1}=<li><b>Precondition: </b>\1</li>" \
"cgalBigO{1}=\f$O(\1)\f$" \
"cgalBigOLarge{1}=\f$O\left(\1\right)\f$"
# Doxygen selects the parser to use depending on the extension of the files it # Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given # parses. With this tag you can assign which parser to use for a given
@ -262,7 +264,7 @@ EXTRACT_ALL = YES
# the EXTRACT_ALL tag is set to NO. # the EXTRACT_ALL tag is set to NO.
# The default value is: NO. # The default value is: NO.
EXTRACT_ALL_NO_DETAILED_IF_EMPTY = YES ${CGAL_OPT_EXTRACT_ALL_NO_DETAILED_IF_EMPTY}
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be
# included in the documentation. # included in the documentation.
@ -658,7 +660,8 @@ PREDEFINED = DOXYGEN_RUNNING \
"CGAL_NP_CLASS_1=NamedParameters1" \ "CGAL_NP_CLASS_1=NamedParameters1" \
"CGAL_NP_TEMPLATE_PARAMETERS_2=NamedParameters2 = CGAL::parameters::Default_named_parameter" \ "CGAL_NP_TEMPLATE_PARAMETERS_2=NamedParameters2 = CGAL::parameters::Default_named_parameter" \
"CGAL_NP_CLASS_2=NamedParameters2" \ "CGAL_NP_CLASS_2=NamedParameters2" \
CGAL_DEPRECATED CGAL_DEPRECATED \
CGAL_DEPRECATED_MSG(name)=
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to external references # Configuration options related to external references

View File

@ -168,9 +168,9 @@ ALIASES = "cgal=%CGAL" \
"cgalPkgSince{1}=<B>Introduced in:</B> \cgal \1<BR>" \ "cgalPkgSince{1}=<B>Introduced in:</B> \cgal \1<BR>" \
"cgalPkgDependsOn{1}=<B>Depends on:</B> \1 <BR>" \ "cgalPkgDependsOn{1}=<B>Depends on:</B> \1 <BR>" \
"cgalPkgLicense{1}=<B>License:</B> \1 <BR>" \ "cgalPkgLicense{1}=<B>License:</B> \1 <BR>" \
"cgalPkgDemo{2}=<B>Windows Demo:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{2}=<B>Windows demo:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDemo{4}=<B>Windows Demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{4}=<B>Windows demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDemo{6}=<B>Windows Demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\6\">\5</a><BR><B>Common Demo Dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \ "cgalPkgDemo{6}=<B>Windows demos:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\2\">\1</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\4\">\3</a>, <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/\6\">\5</a><BR><B>Common demo dlls:</B> <a href=\"https://www.cgal.org/demo/${CGAL_CREATED_VERSION_NUM}/CGAL-demoDLLs.zip\">dlls</a><BR>" \
"cgalPkgDescriptionEnd=" \ "cgalPkgDescriptionEnd=" \
"cgalModifBegin=\htmlonly <div class=\"CGALModification\"> \endhtmlonly \xrefitem Modification \"Modifications\" \"MODIFICATIONS\"" \ "cgalModifBegin=\htmlonly <div class=\"CGALModification\"> \endhtmlonly \xrefitem Modification \"Modifications\" \"MODIFICATIONS\"" \
"cgalModifEnd=\htmlonly </div> \endhtmlonly \latexonly END MODIFICATIONS \endlatexonly" \ "cgalModifEnd=\htmlonly </div> \endhtmlonly \latexonly END MODIFICATIONS \endlatexonly" \
@ -197,7 +197,9 @@ ALIASES = "cgal=%CGAL" \
"cgalParamNEnd=</ul> \htmlonly[block] </div> \endhtmlonly </td><td></td></tr>" \ "cgalParamNEnd=</ul> \htmlonly[block] </div> \endhtmlonly </td><td></td></tr>" \
"cgalParamSectionBegin{1}=\cgalParamNBegin{\1}" \ "cgalParamSectionBegin{1}=\cgalParamNBegin{\1}" \
"cgalParamSectionEnd=\cgalParamNEnd" \ "cgalParamSectionEnd=\cgalParamNEnd" \
"cgalParamPrecondition{1}=<li><b>Precondition: </b>\1</li>" "cgalParamPrecondition{1}=<li><b>Precondition: </b>\1</li>" \
"cgalBigO{1}=\f$O(\1)\f$" \
"cgalBigOLarge{1}=\f$O\left(\1\right)\f$"
# Doxygen selects the parser to use depending on the extension of the files it # Doxygen selects the parser to use depending on the extension of the files it
# parses. With this tag you can assign which parser to use for a given # parses. With this tag you can assign which parser to use for a given
@ -643,7 +645,9 @@ PREDEFINED = DOXYGEN_RUNNING \
"CGAL_NP_CLASS_1=NamedParameters1" \ "CGAL_NP_CLASS_1=NamedParameters1" \
"CGAL_NP_TEMPLATE_PARAMETERS_2=NamedParameters2 = CGAL::parameters::Default_named_parameter" \ "CGAL_NP_TEMPLATE_PARAMETERS_2=NamedParameters2 = CGAL::parameters::Default_named_parameter" \
"CGAL_NP_CLASS_2=NamedParameters2" \ "CGAL_NP_CLASS_2=NamedParameters2" \
CGAL_DEPRECATED CGAL_DEPRECATED \
CGAL_DEPRECATED_MSG(name)=
#--------------------------------------------------------------------------- #---------------------------------------------------------------------------
# Configuration options related to external references # Configuration options related to external references
@ -791,5 +795,5 @@ GENERATE_LEGEND = NO
# NO_ADDITIONAL_DETAILS tag is set to YES. This tag has no effect if # NO_ADDITIONAL_DETAILS tag is set to YES. This tag has no effect if
# the EXTRACT_ALL tag is set to NO. # the EXTRACT_ALL tag is set to NO.
# The default value is: NO. # The default value is: NO.
NO_ADDITIONAL_DETAILS = YES ${CGAL_OPT_NO_ADDITIONAL_DETAILS}

View File

@ -296,7 +296,7 @@ Several functions allow to create specific configurations of darts into a genera
\subsection ssecadvmarksgmap Boolean Marks \subsection ssecadvmarksgmap Boolean Marks
It is often necessary to mark darts, for example to retrieve in <I>O(1)</I> if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a generalized map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GeneralizedMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `gm` an instance of a generalized map): It is often necessary to mark darts, for example to retrieve in \cgalBigO{1} if a given dart was already processed during a specific algorithm, for example, iteration over a given range. Users can also mark specific parts of a generalized map (for example mark all the darts belonging to objects having specific semantics). To answer these needs, a `GeneralizedMap` has a certain number of Boolean marks (fixed by the constant \link GenericMap::NB_MARKS `NB_MARKS`\endlink). When one wants to use a Boolean mark, the following methods are available (with `gm` an instance of a generalized map):
<ul> <ul>
<li> get a new free mark: `size_type m = gm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available); <li> get a new free mark: `size_type m = gm.`\link GenericMap::get_new_mark `get_new_mark()`\endlink (throws the exception Exception_no_more_available_mark if no mark is available);
<li> set mark `m` for a given dart `d0`: `gm.`\link GenericMap::mark `mark(d0,m)`\endlink; <li> set mark `m` for a given dart `d0`: `gm.`\link GenericMap::mark `mark(d0,m)`\endlink;
@ -399,6 +399,8 @@ Example of \link GenericMap::insert_cell_1_in_cell_2 `insert_cell_1_in_cell_2`\e
`gm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink. `gm.`\link GenericMap::insert_dangling_cell_1_in_cell_2 `insert_dangling_cell_1_in_cell_2(d0)`\endlink adds a 1-cell in the 2-cell containing dart `d0`, the 1-cell being attached by only one of its vertex to the 0-cell containing dart `d0`. This operation is possible if `d0` \f$ \in \f$ \link GenericMap::darts `gm.darts()`\endlink.
`gm.`\link GenericMap::insert_cell_1_between_two_cells_2 `insert_cell_1_between_two_cells_2(d1,d2)`\endlink adds a 1-cell between the two faces containing containing darts `d1` and `d2`, between the two 0-cells containing darts `d1` and `d2`. The 2-cells are merged in one. This operation is possible if <I>d1</I>\f$ \not \in \f$ \f$ \langle{}\f$\f$ \alpha_0, \alpha_1\f$\f$ \rangle{}\f$(<I>d2</I>) which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_1_between_two_cells_2 `is_insertable_cell_1_between_two_cells_2(d1,d2)`\endlink.
`gm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_gmap_insert_facet}). `gm.`\link GenericMap::insert_cell_2_in_cell_3 `insert_cell_2_in_cell_3(itbegin,itend)`\endlink adds a 2-cell in the 3-cell containing all the darts between `itbegin` and `itend`, along the path of 1-cells containing darts in [`itbegin`,`itend`). The 3-cell is split in two. This operation is possible if all the darts in [`itbegin`,`itend`) form a closed path inside a same 3-cell which can be tested thanks to `gm.`\link GenericMap::is_insertable_cell_2_in_cell_3 `is_insertable_cell_2_in_cell_3(itbegin,itend)`\endlink (see example on \cgalFigureRef{fig_gmap_insert_facet}).
\cgalFigureBegin{fig_gmap_insert_facet,gmap_insert_facet.svg} \cgalFigureBegin{fig_gmap_insert_facet,gmap_insert_facet.svg}
@ -478,6 +480,24 @@ The second line is the result after the removal operations. We retrieve the orig
Example of high level operations. Left: Initial 3D generalized map after the creation of the generalized hexahedron. Middle: Generalized map obtained after the two 1-cell insertions. The two 2-cells were split in two. Right: Generalized map obtained after the 2-cell insertion. The 3-cell was split in two. Example of high level operations. Left: Initial 3D generalized map after the creation of the generalized hexahedron. Middle: Generalized map obtained after the two 1-cell insertions. The two 2-cells were split in two. Right: Generalized map obtained after the 2-cell insertion. The 3-cell was split in two.
\cgalFigureEnd \cgalFigureEnd
\subsection Generalized_mapInsertion Insert an edge between two different faces
\anchor ssecexempleinsertiongmap
This example shows the use of \link GenericMap::insert_cell_1_between_two_cells_2 `insert_cell_1_between_two_cells_2`\endlink operation. First we create a combinatorial hexahedron and a face with 4 edges. This face is inserted in the face of the hexahedron containing dart d1. We display the characteristics of the generalized map and check its validity. Then we count and display the number of 2-free darts.
\cgalExample{Generalized_map/gmap_3_insert.cpp}
The output is:
\verbatim
#Darts=60, #0-cells=12, #1-cells=17, #2-cells=6, #3-cells=1, #ccs=1, orientable=true, valid=1
Number of 2-free darts: 8
\endverbatim
We can verify that there are 6 2-cells after the insertion since the squared face was inserted as a hole in one face of the hexahedron. We can also see that there are 8 2-free darts, which are the darts of the squared face. Since they bound an hole, there is no face filling the hole and thus 8 darts are 2-free.
See also a similar example for Linear cell complex \ref Linear_cell_complexInsert "Insert an Edge Between Two Different Faces".
\subsection Generalized_mapA4DGeneralizedMap A 4D Generalized Map \subsection Generalized_mapA4DGeneralizedMap A 4D Generalized Map
In this example, a 4-dimensional generalized map is used. Two tetrahedral cells are created and sewn by \f$ \alpha_4\f$. Then the numbers of cells of the generalized map are displayed, and its validity is checked. In this example, a 4-dimensional generalized map is used. Two tetrahedral cells are created and sewn by \f$ \alpha_4\f$. Then the numbers of cells of the generalized map are displayed, and its validity is checked.

View File

@ -7,4 +7,5 @@
\example Generalized_map/gmap_3_with_colored_facets.cpp \example Generalized_map/gmap_3_with_colored_facets.cpp
\example Generalized_map/gmap_3_dynamic_onmerge.cpp \example Generalized_map/gmap_3_dynamic_onmerge.cpp
\example Generalized_map/gmap_3_index.cpp \example Generalized_map/gmap_3_index.cpp
\example Generalized_map/gmap_3_insert.cpp
*/ */

View File

@ -0,0 +1,34 @@
#include <CGAL/Generalized_map.h>
#include <iostream>
#include <cstdlib>
#include <cassert>
typedef CGAL::Generalized_map<3> GMap_3;
typedef GMap_3::Dart_descriptor Dart_descriptor;
int main()
{
GMap_3 gm;
// Create one combinatorial hexahedron
Dart_descriptor d1 = gm.make_combinatorial_hexahedron();
// Create one square face
Dart_descriptor d2=gm.make_combinatorial_polygon(4);
assert(gm.is_insertable_cell_1_between_two_cells_2(d1,d2));
// Insert the square face as a hole of the face of the hexahedron containing d1
gm.insert_cell_1_between_two_cells_2(d1, d2);
// Display the combinatorial map characteristics.
gm.display_characteristics(std::cout)<<", valid="
<<gm.is_valid()<<std::endl;
std::size_t nb=0;
for(Dart_descriptor dh=gm.darts().begin(); dh!=gm.darts().end(); ++dh)
{ if (gm.is_free<2>(dh)) ++nb; }
std::cout<<"Number of 2-free darts: "<<nb<<std::endl;
return EXIT_SUCCESS;
}

View File

@ -1038,7 +1038,7 @@ namespace CGAL {
} }
/** Unmark all the darts of the map for a given mark. /** Unmark all the darts of the map for a given mark.
* If all the darts are marked or unmarked, this operation takes O(1) * If all the darts are marked or unmarked, this operation takes \cgalBigO{1}
* operations, otherwise it traverses all the darts of the map. * operations, otherwise it traverses all the darts of the map.
* @param amark the given mark. * @param amark the given mark.
*/ */
@ -1464,11 +1464,14 @@ namespace CGAL {
static_assert(i<=dimension); static_assert(i<=dimension);
static_assert(Helper::template Dimension_index<i>::value>=0, static_assert(Helper::template Dimension_index<i>::value>=0,
"set_attribute<i> but i-attributes are disabled"); "set_attribute<i> but i-attributes are disabled");
for ( typename Dart_of_cell_range<i>::iterator it(*this, dh); for (typename Dart_of_cell_range<i>::iterator it(*this, dh);
it.cont(); ++it) it.cont(); ++it)
{ {
this->template set_dart_attribute<i>(it, ah); this->template set_dart_attribute<i>(it, ah);
} }
if(ah!=null_descriptor)
// To ensure that the dart of this attribute is dh
{ this->template set_dart_of_attribute<i>(ah, dh); }
} }
/// @return a Attributes_range<i> (range through all the /// @return a Attributes_range<i> (range through all the
@ -3512,7 +3515,9 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1, bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) Dart_const_descriptor adart2)
{ {
if ( adart1==adart2 || adart1==this->template alpha<0>(adart2) ) if (adart2==null_descriptor) return true;
if (adart1==adart2 || adart1==this->template alpha<0>(adart2) ||
adart1==null_descriptor || this->template is_free<1>(adart2))
return false; return false;
for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1); for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1);
it.cont(); ++it ) it.cont(); ++it )
@ -3525,29 +3530,104 @@ namespace CGAL {
/** Insert an edge in a 2-cell between two given darts. /** Insert an edge in a 2-cell between two given darts.
* @param adart1 a first dart of the facet (!=null_descriptor && !=null_dart_descriptor). * @param adart1 a first dart of the facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the facet. If null_descriptor insert a dangling edge. * @param adart2 a second dart of the facet. If null_descriptor insert a dangling edge.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the * @return a dart of the new edge, and not incident to the
* same vertex than adart1. * same vertex than adart1.
*/ */
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1, Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1,
Dart_descriptor adart2, Dart_descriptor adart2,
bool update_attributes=true, typename Attribute_descriptor<0>::
typename Attribute_descriptor<0>::type type ah=null_descriptor,
ah=null_descriptor) bool update_attributes=true)
{ {
if ( adart2!=null_descriptor) CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
{ return generic_insert_cell_1(adart1, adart2, false, update_attributes, ah);
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2)); }
}
/** Test if an edge can be inserted between two different 2-cells
* between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
* @return true iff an edge can be inserted between adart1 and adart2.
*/
bool is_insertable_cell_1_between_two_cells_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const
{
if (adart1==adart2 || adart1==null_descriptor || adart2==null_descriptor)
{ return false; }
for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1);
it.cont(); ++it )
{
if ( it==adart2 ) return false;
}
for(unsigned int d=3; d<=dimension; ++d)
{ if(is_free(adart1, d)!=is_free(adart2, d)) { return false; }}
return true;
}
/** Insert an edge between two different 2-cells, between two given darts.
* @param adart1 a first dart of the first facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the second facet (!=null_descriptor && !=null_dart_descriptor).
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1_between_two_cells_2(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_between_two_cells_2(adart1, adart2));
return generic_insert_cell_1(adart1, adart2, true, update_attributes);
}
/** Insert an edge between two given darts. If the two darts belong to the same facet, call
* insert_cell_1_in_cell_2, otherwise call insert_cell_1_between_two_cells_2.
* @param adart1 a first dart (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true,
typename Attribute_descriptor<0>::type
ah=null_descriptor)
{
CGAL_assertion(adart1!=null_descriptor);
if(is_insertable_cell_1_in_cell_2(adart1, adart2))
{ return insert_cell_1_in_cell_2(adart1, adart2, update_attributes, ah); }
return insert_cell_1_between_two_cells_2(adart1, adart2, update_attributes);
}
/** Generic method to insert a 1-cell, either in a 2-cell (cf. insert_cell_1_in_cell_2)
* or between two different 2-cells (cf. insert_cell_1_between_two_cells_2).
* Indeed the code is the same, except for the group/degroup attribute.
* merge is true if adart1 and adart2 belongs to two different facets; in this case
* the two facets should be merged (they are now linked by the new edge);
* merge is false it adart1 and adart2 belongs to the same facet; in this case
* the facet is split in two.
* Internal method not supposed to be called by users.
*/
Dart_descriptor generic_insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool merge,
bool update_attributes=true,
typename Attribute_descriptor<0>::type
ah=null_descriptor)
{
/* CGAL::GMap_dart_iterator_basic_of_involution<Self,1> will contain all /* CGAL::GMap_dart_iterator_basic_of_involution<Self,1> will contain all
* alpha_i except alpha_0, alpha_1 and alpha_2, i.e. this is * alpha_i except alpha_0, alpha_1 and alpha_2, i.e. this is
* <alpha_3,...,alpha_d> * <alpha_3,...,alpha_d>
*/ */
Dart_descriptor dart2_a1=null_descriptor;
if(adart2!=null_descriptor) { dart2_a1=alpha<1>(adart2); }
size_type m1=get_new_mark(); size_type m1=get_new_mark();
CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1); CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1);
size_type m2=get_new_mark(); size_type m2=get_new_mark();
CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it2(*this, adart2, m2); CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it2(*this, dart2_a1, m2);
Dart_descriptor d1=null_descriptor; Dart_descriptor d1=null_descriptor;
Dart_descriptor d2=null_descriptor; Dart_descriptor d2=null_descriptor;
@ -3565,13 +3645,13 @@ namespace CGAL {
if (!isfree1) if (!isfree1)
{ {
d3 = create_dart(); d3 = create_dart();
d4 = create_dart(); d4 = create_dart();
this->template basic_link_alpha<2>(d1, d3); this->template basic_link_alpha<2>(d1, d3);
this->template basic_link_alpha<2>(d2, d4); this->template basic_link_alpha<2>(d2, d4);
} }
for ( unsigned int dim=3; dim<=dimension; ++dim) for (unsigned int dim=3; dim<=dimension; ++dim)
{ {
if ( !is_free(it1, dim) && if ( !is_free(it1, dim) &&
is_marked(alpha(it1, dim), treated) ) is_marked(alpha(it1, dim), treated) )
@ -3598,7 +3678,7 @@ namespace CGAL {
} }
this->template link_alpha<1>(it1, d1); this->template link_alpha<1>(it1, d1);
if ( adart2!=null_descriptor ) if (adart2!=null_descriptor)
{ {
CGAL_assertion (it2.cont()); CGAL_assertion (it2.cont());
this->template link_alpha<1>(it2, d2); this->template link_alpha<1>(it2, d2);
@ -3626,9 +3706,25 @@ namespace CGAL {
if (are_attributes_automatically_managed() && update_attributes) if (are_attributes_automatically_managed() && update_attributes)
{ {
if ( !this->template is_free<2>(d1) && d2!=null_descriptor ) if(merge)
CGAL::internal::GMap_degroup_attribute_functor_run<Self, 2>:: { // Here we group all enabled attributes starting from 2 to dimension
run(*this, d1, this->template alpha<2>(d1)); Helper::template Foreach_enabled_attributes
<internal::Group_attribute_functor<Self>, 2>::
run(*this, adart1, adart2);
// And we need to group also alpha_i(adart1) and alpha_i(adart2) for all
// enabled attributes starting from 3 dimension. Indeed when two i-cells
// are grouped for adart1 and adart2, this group also all alpha_j two by two
// except for alpha_i.
Helper::template Foreach_enabled_attributes
<internal::Group_neighboor_attribute<Self>, 3>::run(*this, adart1, adart2);
}
else // Here we degroup 2-attributes
{
if (!this->template is_free<2>(d1) && d2!=null_descriptor)
{ CGAL::internal::GMap_degroup_attribute_functor_run<Self, 2>::
run(*this, d1, this->template alpha<2>(d1)); }
}
} }
negate_mark(m1); negate_mark(m1);
@ -3673,7 +3769,8 @@ namespace CGAL {
typename Attribute_descriptor<0>:: typename Attribute_descriptor<0>::
type ah=null_descriptor, type ah=null_descriptor,
bool update_attributes=true ) bool update_attributes=true )
{ return insert_cell_1_in_cell_2(adart1, null_descriptor, update_attributes, ah); } { return insert_cell_1_in_cell_2(adart1, null_descriptor, ah,
update_attributes); }
/** Test if a 2-cell can be inserted onto a given 3-cell along /** Test if a 2-cell can be inserted onto a given 3-cell along
* a path of edges. * a path of edges.

View File

@ -132,7 +132,8 @@ struct GMap_group_attribute_functor_run
{ {
static void run(GMap& amap, static void run(GMap& amap,
typename GMap::Dart_descriptor adart1, typename GMap::Dart_descriptor adart1,
typename GMap::Dart_descriptor adart2) typename GMap::Dart_descriptor adart2,
bool dart1_deleted=true)
{ {
static_assert( i<=GMap::dimension ); static_assert( i<=GMap::dimension );
static_assert( i!=j ); static_assert( i!=j );
@ -145,7 +146,13 @@ struct GMap_group_attribute_functor_run
a2=amap.template attribute<i>(adart2); a2=amap.template attribute<i>(adart2);
// If the two attributes are equal, nothing to do. // If the two attributes are equal, nothing to do.
if ( a1 == a2 ) return; if ( a1 == a2 )
{
if(a1!=GMap::null_descriptor && dart1_deleted &&
amap.template dart_of_attribute<i>(a1)==adart1)
{ amap.template set_dart_of_attribute<i>(a1, adart2); }
return;
}
typename GMap::Dart_descriptor toSet = amap.null_descriptor; typename GMap::Dart_descriptor toSet = amap.null_descriptor;
@ -162,15 +169,18 @@ struct GMap_group_attribute_functor_run
} }
} }
amap.template set_attribute<i>(toSet, a1); amap.template set_attribute<i>(toSet, a1);
if(dart1_deleted && toSet==adart1)
{ amap.template set_dart_of_attribute<i>(a1, adart2); }
} }
}; };
// Specialization for void attributes. // Specialization for void attributes.
template<typename GMap, unsigned int i, unsigned int j> template<typename GMap, unsigned int i, unsigned int j>
struct GMap_group_attribute_functor_run<GMap, i, j, CGAL::Void> struct GMap_group_attribute_functor_run<GMap, i, j, CGAL::Void>
{ {
static void run( GMap&, static void run(GMap&,
typename GMap::Dart_descriptor, typename GMap::Dart_descriptor,
typename GMap::Dart_descriptor ) typename GMap::Dart_descriptor,
bool=true)
{} {}
}; };
// Specialization for i=j. Do nothing as j is the dimension to not consider. // Specialization for i=j. Do nothing as j is the dimension to not consider.
@ -179,7 +189,8 @@ struct GMap_group_attribute_functor_run<GMap,i,i,T>
{ {
static void run(GMap&, static void run(GMap&,
typename GMap::Dart_descriptor, typename GMap::Dart_descriptor,
typename GMap::Dart_descriptor) typename GMap::Dart_descriptor,
bool=true)
{} {}
}; };
// ************************************************************************ // ************************************************************************

View File

@ -91,8 +91,9 @@ namespace CGAL
it.cont(); ++it ) it.cont(); ++it )
{ {
to_erase.push_back(it); to_erase.push_back(it);
if ( !amap.template is_free<i+1>(it) && dg1==amap.null_descriptor ) if (dg1==amap.null_descriptor && !amap.template is_free<i+1>(it) &&
{ dg1=it; dg2=amap.template alpha<i+1>(it); } !amap.template is_free<i>(amap.template alpha<i+1>(it)))
{ dg1=it; dg2=amap.template alpha<i+1, i>(it); }
amap.mark(it, mark); amap.mark(it, mark);
++res; ++res;
} }
@ -102,7 +103,7 @@ namespace CGAL
// We group the two (i+1)-cells incident if they exist. // We group the two (i+1)-cells incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
CGAL::internal::GMap_group_attribute_functor_run<GMap, i+1>:: CGAL::internal::GMap_group_attribute_functor_run<GMap, i+1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be deleted
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified
@ -136,6 +137,9 @@ namespace CGAL
modified_darts.push_back(d2); modified_darts.push_back(d2);
amap.mark(d2, mark_modified_darts); amap.mark(d2, mark_modified_darts);
} }
internal::Set_dart_of_attribute_if_marked<GMap, i+1>::
run(amap, d1, mark);
} }
} }
} }
@ -320,7 +324,7 @@ namespace CGAL
// We group the two (i-1)-cells incident if they exist. // We group the two (i-1)-cells incident if they exist.
if ( dg1!=amap.null_descriptor ) if ( dg1!=amap.null_descriptor )
CGAL::internal::GMap_group_attribute_functor_run<GMap,i-1>:: CGAL::internal::GMap_group_attribute_functor_run<GMap,i-1>::
run(amap, dg1, dg2); run(amap, dg1, dg2, true); // true because dg1 will be deleted
} }
// During the operation, we store in modified_darts the darts modified // During the operation, we store in modified_darts the darts modified

View File

@ -149,7 +149,7 @@ bool test_edge_insertion(GMAP& gmap)
trace_test_begin(); trace_test_begin();
d1 = gmap.make_combinatorial_polygon(4); d1 = gmap.make_combinatorial_polygon(4);
gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1,0)); gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1));
if ( !check_number_of_cells_3(gmap, 4, 5, 2, 1, 1) ) if ( !check_number_of_cells_3(gmap, 4, 5, 2, 1, 1) )
return false; return false;
gmap.clear(); gmap.clear();
@ -158,7 +158,7 @@ bool test_edge_insertion(GMAP& gmap)
d1 = gmap.make_combinatorial_polygon(4); d1 = gmap.make_combinatorial_polygon(4);
d2 = gmap.make_combinatorial_polygon(4); d2 = gmap.make_combinatorial_polygon(4);
gmap.template sew<3>(d1, d2); gmap.template sew<3>(d1, d2);
gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1,0)); gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1));
if ( !check_number_of_cells_3(gmap, 4, 5, 2, 2, 1) ) if ( !check_number_of_cells_3(gmap, 4, 5, 2, 2, 1) )
return false; return false;
gmap.clear(); gmap.clear();
@ -167,18 +167,11 @@ bool test_edge_insertion(GMAP& gmap)
d1 = gmap.make_combinatorial_polygon(4); d1 = gmap.make_combinatorial_polygon(4);
d2 = gmap.make_combinatorial_polygon(4); d2 = gmap.make_combinatorial_polygon(4);
gmap.template sew<2>(d1, d2); gmap.template sew<2>(d1, d2);
gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1,0)); gmap.insert_cell_1_in_cell_2(d1, gmap.alpha(d1,0,1));
if ( !check_number_of_cells_3(gmap, 6, 8, 3, 1, 1) ) if ( !check_number_of_cells_3(gmap, 6, 8, 3, 1, 1) )
return false; return false;
gmap.clear(); gmap.clear();
trace_test_begin();
d1 = gmap.create_dart();
gmap.insert_dangling_cell_1_in_cell_2(d1);
if ( !check_number_of_cells_3(gmap, 2, 2, 1, 1, 1) )
return false;
gmap.clear();
trace_test_begin(); trace_test_begin();
d1 = gmap.make_edge(); d1 = gmap.make_edge();
gmap.template sew<1>(d1, gmap.alpha(d1, 0)); gmap.template sew<1>(d1, gmap.alpha(d1, 0));

View File

@ -54,7 +54,7 @@ bool test(const std::string& s)
for(std::size_t i=0; i<NB; ++i) for(std::size_t i=0; i<NB; ++i)
{ {
typename GMap::Dart_descriptor typename GMap::Dart_descriptor
newd=m.insert_cell_1_in_cell_2(dd, m.template alpha<0,1,0>(dd)); newd=m.insert_cell_1_in_cell_2(dd, m.template alpha<0,1>(dd));
if(m.template attribute<2>(newd)==GMap::null_descriptor) if(m.template attribute<2>(newd)==GMap::null_descriptor)
{ {
std::cout<<"ERROR1: "<<s<<": " std::cout<<"ERROR1: "<<s<<": "

View File

@ -28,8 +28,8 @@ The generated polygon will have an average number of vertices \f$ n^\frac{1}{3}(
The implementation is based on an incremental construction of a convex hull. At each step, we choose a number of points to pick uniformly at random in the disc. Then, a subset of these points, that won't change the convex hull, is evaluated using a Binomial law. The implementation is based on an incremental construction of a convex hull. At each step, we choose a number of points to pick uniformly at random in the disc. Then, a subset of these points, that won't change the convex hull, is evaluated using a Binomial law.
As these points won't be generated, the time and size complexities are reduced \cgalCite{Devillers2014Generator}. As these points won't be generated, the time and size complexities are reduced \cgalCite{Devillers2014Generator}.
A tradeoff between time and memory is provided with the option `fast`, true by default. Using the `fast` option, both time and size expected complexities are \f$O\left(n^\frac{1}{3}\log^\frac{2}{3}n \right)\f$. A tradeoff between time and memory is provided with the option `fast`, true by default. Using the `fast` option, both time and size expected complexities are \cgalBigOLarge{n^\frac{1}{3}\log^\frac{2}{3}n}.
If this option is disabled, the expected size complexity becomes \f$O\left(n^\frac{1}{3}\right)\f$ but the expected time complexity becomes \f$O\left(n^\frac{1}{3}\log^2 n \right)\f$. If this option is disabled, the expected size complexity becomes \cgalBigOLarge{n^\frac{1}{3}} but the expected time complexity becomes \cgalBigOLarge{n^\frac{1}{3}\log^2 n}.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -31,8 +31,8 @@ R >` for some representation class `R`,
\cgalHeading{Implementation} \cgalHeading{Implementation}
The implementation uses the centroid method The implementation uses the centroid method
described in \cgalCite{cgal:s-zkm-96} and has a worst case running time of \f$ O(r described in \cgalCite{cgal:s-zkm-96} and has a worst case running time of \cgalBigO{r
\cdot n + n \cdot \log n)\f$, where \f$ r\f$ is the time needed by `pg` \cdot n + n \cdot \log n}, where \f$ r\f$ is the time needed by `pg`
to generate a random point. to generate a random point.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -37,11 +37,11 @@ The default traits class `Default_traits` is the kernel in which
The implementation is based on the method of eliminating self-intersections in The implementation is based on the method of eliminating self-intersections in
a polygon by using so-called "2-opt" moves. Such a move eliminates an a polygon by using so-called "2-opt" moves. Such a move eliminates an
intersection between two edges by reversing the order of the vertices between intersection between two edges by reversing the order of the vertices between
the edges. No more than \f$ O(n^3)\f$ such moves are required to simplify a polygon the edges. No more than \cgalBigO{n^3} such moves are required to simplify a polygon
defined on \f$ n\f$ points \cgalCite{ls-utstp-82}. defined on \f$ n\f$ points \cgalCite{ls-utstp-82}.
Intersecting edges are detected using a simple sweep through the vertices Intersecting edges are detected using a simple sweep through the vertices
and then one intersection is chosen at random to eliminate after each sweep. and then one intersection is chosen at random to eliminate after each sweep.
The worse-case running time is therefore \f$ O(n^4 \log n)\f$. The worse-case running time is therefore \cgalBigO{n^4 \log n}.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -194,7 +194,7 @@ This method is automatically called once, before the first call to paintGL().
Overload init() instead of this method to modify viewer specific OpenGL state. Overload init() instead of this method to modify viewer specific OpenGL state.
If a 4.3 context could not be set, a ES 2.0 context will be used instead. If a 4.3 context could not be set, an ES 2.0 context will be used instead.
\see `isOpenGL_4_3()` \see `isOpenGL_4_3()`
*/ */
CGAL_INLINE_FUNCTION CGAL_INLINE_FUNCTION

View File

@ -24,7 +24,7 @@ removal.
\cgalHeading{Implementation} \cgalHeading{Implementation}
Currently, `HalfedgeDS_default` is derived from `CGAL::HalfedgeDS_list<Traits>`. Currently, `HalfedgeDS_default` is derived from `CGAL::HalfedgeDS_list<Traits>`.
The copy constructor and the assignment operator need \f$ O(n)\f$ time with The copy constructor and the assignment operator need \cgalBigO{n} time with
\f$ n\f$ the total number of vertices, halfedges, and faces. \f$ n\f$ the total number of vertices, halfedges, and faces.
*/ */

View File

@ -20,7 +20,7 @@ iterators that supports removal.
\cgalHeading{Implementation} \cgalHeading{Implementation}
`HalfedgeDS_list` uses internally the `CGAL::In_place_list` container class. `HalfedgeDS_list` uses internally the `CGAL::In_place_list` container class.
The copy constructor and the assignment operator need \f$ O(n)\f$ time with The copy constructor and the assignment operator need \cgalBigO{n} time with
\f$ n\f$ the total number of vertices, halfedges, and faces. \f$ n\f$ the total number of vertices, halfedges, and faces.
`CGAL_ALLOCATOR(int)` is used as default argument for the `CGAL_ALLOCATOR(int)` is used as default argument for the

View File

@ -223,8 +223,8 @@ The algorithm is as follows:
The time complexity of the algorithm is determined primarily by the The time complexity of the algorithm is determined primarily by the
choice of linear solver. In the current implementation, Cholesky choice of linear solver. In the current implementation, Cholesky
prefactorization is roughly \f$ O(N^{1.5})\f$ and computation of distances is prefactorization is roughly \cgalBigO{N^{1.5}} and computation of distances is
roughly \f$ O(N)\f$, where \f$ N\f$ is the number of vertices in the triangulation. roughly \cgalBigO{N}, where \f$ N\f$ is the number of vertices in the triangulation.
The algorithm uses two \f$ N \times N\f$ matrices, both with the same pattern of The algorithm uses two \f$ N \times N\f$ matrices, both with the same pattern of
non-zeros (in average 7 non-zeros non-zeros (in average 7 non-zeros
per row/column). The cost of computation is independent of the size per row/column). The cost of computation is independent of the size

View File

@ -208,7 +208,7 @@ public:
/// @{ /// @{
/*! /*!
Inserts the point `p` in the triangulation. Inserts the point `p` in the triangulation.
If the point `p` coincides with a existing vertex, then the vertex is returned If the point `p` coincides with an existing vertex, then the vertex is returned
and the triangulation is not modified. The optional parameter `start` is used and the triangulation is not modified. The optional parameter `start` is used
to initialize the location of `p`. to initialize the location of `p`.
*/ */

View File

@ -880,7 +880,7 @@ public:
Face_handle locate(const Point& query, Locate_type& lt, int &li, Face_handle hint = Face_handle()) const Face_handle locate(const Point& query, Locate_type& lt, int &li, Face_handle hint = Face_handle()) const
{ {
// Perform an Euclidean location first and get close to the hyperbolic face containing the query point // Perform a Euclidean location first and get close to the hyperbolic face containing the query point
typename Base::Locate_type blt; typename Base::Locate_type blt;
Face_handle fh = Base::locate(query, blt, li, hint); Face_handle fh = Base::locate(query, blt, li, hint);
@ -901,7 +901,7 @@ public:
CGAL_assertion(!is_infinite(fh)); CGAL_assertion(!is_infinite(fh));
// This case corresponds to when the point is located on an Euclidean edge. // This case corresponds to when the point is located on a Euclidean edge.
if(lt == EDGE) if(lt == EDGE)
{ {
// Here because the call to `side_of_hyperbolic_triangle` might change `li` // Here because the call to `side_of_hyperbolic_triangle` might change `li`

View File

@ -14,8 +14,8 @@ that do not contain any point of the point set.
\cgalHeading{Implementation} \cgalHeading{Implementation}
The algorithm is an implementation of \cgalCite{o-naler-90}. The runtime of an The algorithm is an implementation of \cgalCite{o-naler-90}. The runtime of an
insertion or a removal is \f$ O(\log n)\f$. A query takes \f$ O(n^2)\f$ worst insertion or a removal is \cgalBigO{\log n}. A query takes \cgalBigO{n^2} worst
case time and \f$ O(n \log n)\f$ expected time. The working storage is \f$ case time and \cgalBigO{n \log n} expected time. The working storage is \f$
O(n)\f$. O(n)\f$.
*/ */

View File

@ -32,8 +32,8 @@ convex polygon (oriented clock- or counterclockwise).
\cgalHeading{Implementation} \cgalHeading{Implementation}
The implementation uses monotone matrix search The implementation uses monotone matrix search
\cgalCite{akmsw-gamsa-87} and has a worst case running time of \f$ O(k \cgalCite{akmsw-gamsa-87} and has a worst case running time of \cgalBigO{k
\cdot n + n \cdot \log n)\f$, where \f$ n\f$ is the number of vertices in \cdot n + n \cdot \log n}, where \f$ n\f$ is the number of vertices in
\f$ P\f$. \f$ P\f$.
*/ */
@ -89,8 +89,8 @@ where `K` is a model of `Kernel`.
\cgalHeading{Implementation} \cgalHeading{Implementation}
The implementation uses monotone matrix search The implementation uses monotone matrix search
\cgalCite{akmsw-gamsa-87} and has a worst case running time of \f$ O(k \cgalCite{akmsw-gamsa-87} and has a worst case running time of \cgalBigO{k
\cdot n + n \cdot \log n)\f$, where \f$ n\f$ is the number of vertices in \cdot n + n \cdot \log n}, where \f$ n\f$ is the number of vertices in
\f$ P\f$. \f$ P\f$.
\cgalHeading{Example} \cgalHeading{Example}
@ -158,8 +158,8 @@ defined that computes the squareroot of a number.
\cgalHeading{Implementation} \cgalHeading{Implementation}
The implementation uses monotone matrix search The implementation uses monotone matrix search
\cgalCite{akmsw-gamsa-87} and has a worst case running time of \f$ O(k \cgalCite{akmsw-gamsa-87} and has a worst case running time of \cgalBigO{k
\cdot n + n \cdot \log n)\f$, where \f$ n\f$ is the number of vertices in \cdot n + n \cdot \log n}, where \f$ n\f$ is the number of vertices in
\f$ P\f$. \f$ P\f$.
\cgalHeading{Example} \cgalHeading{Example}

View File

@ -46,7 +46,7 @@ namespace CGAL {
The algorithm checks all the empty rectangles that are bounded by either The algorithm checks all the empty rectangles that are bounded by either
points or edges of the bounding box (other empty rectangles can be enlarged points or edges of the bounding box (other empty rectangles can be enlarged
and remain empty). There are O(n^2) such rectangles. It is done in three and remain empty). There are \cgalBigO{n^2} such rectangles. It is done in three
phases. In the first one empty rectangles that are bounded by two opposite phases. In the first one empty rectangles that are bounded by two opposite
edges of the bounding box are checked. In the second one, other empty edges of the bounding box are checked. In the second one, other empty
rectangles that are bounded by one or two edges of the bounding box are rectangles that are bounded by one or two edges of the bounding box are

12
Installation/.reuse/dep5 Normal file
View File

@ -0,0 +1,12 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Upstream-Name: CGAL
Upstream-Contact: CGAL Editorial Board <info@cgal.org>
Source: https://github.com/CGAL/cgal
Files: *.cmake *.md doc/* doc_html/* scripts/* developer_scripts/* package_info/* demo/* examples/* src/* test/* benchmarks/* benchmark/* data/* cmake/*
Copyright: 1995-2023 The CGAL Project
License: CC0-1.0
Files: include/CGAL/Qt/ImageInterface.ui include/CGAL/Qt/resources/qglviewer-icon.xpm AUTHORS CMakeLists.txt README auxiliary/cgal_create_cmake_script.1 auxiliary/gmp/README include/CGAL/license/gpl_package_list.txt auxiliary/cgal_app.icns copyright VERSION
Copyright: 1995-2023 The CGAL Project
License: CC0-1.0

View File

@ -23,10 +23,23 @@ Release date: October 2023
#### Envelopes of Surfaces in 3D #### Envelopes of Surfaces in 3D
- ** Breaking change**: Construct_projected_boundary_2 in `EnvelopeTraits_3` is now using `std::variant` instead of `Object` - ** Breaking change**: Construct_projected_boundary_2 in `EnvelopeTraits_3` is now using `std::variant` instead of `Object`
### [Combinatorial Maps](https://doc.cgal.org/6.0/Manual/packages.html#PkgCombinatorialMaps) and [Generalized Maps](https://doc.cgal.org/6.0/Manual/packages.html#PkgGeneralizedMaps)
- Added the function `insert_cell_1_between_two_cells_2()` to the `GenericMap` concept, which enables users to insert an edge between two different faces in order to create faces with holes.
### [3D Mesh Generation](https://doc.cgal.org/6.0/Manual/packages.html#PkgMesh3)
- **Breaking change**: Removed the concept `TriangleAccessor`, the template parameter `TriangleAccessor`, as well
as the class `Triangle_accessor`. They were no longer used for several releases.
- Removed the class templates `Gray_image_mesh_domain_3`, `Implicit_mesh_domain_3`, and `Labeled_image_mesh_domain_3`
which are deprecated since CGAL-4.13.
[Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6) [Release 5.6](https://github.com/CGAL/cgal/releases/tag/v5.6)
----------- -----------
Release date: June 2023 Release date: July 2023
### General Changes ### General Changes
@ -44,7 +57,7 @@ Release date: June 2023
instead of `void`, that is used inside the class `Region_growing` for detecting if the input instead of `void`, that is used inside the class `Region_growing` for detecting if the input
conditions for the new region are satisfied. This change affects only user-defined types of regions. conditions for the new region are satisfied. This change affects only user-defined types of regions.
- **Breaking change**: The constructors of all models used together with the region growing algorithm - **Breaking change**: The constructors of all models used together with the region growing algorithm
now enable users to provide parameters through the [named parameters](https://doc.cgal.org/latest/BGL/group__bgl__namedparameters.html) mechanism. now enable users to provide parameters through the [named parameters](https://doc.cgal.org/5.6/BGL/group__bgl__namedparameters.html) mechanism.
- All fitting classes in the region growing framework are now using better versions of the region - All fitting classes in the region growing framework are now using better versions of the region
conditions, more precise and faster, including the correct normal orientations. conditions, more precise and faster, including the correct normal orientations.
- Added new models of the concept `RegionType` for getting linear regions in a set of 2D and 3D - Added new models of the concept `RegionType` for getting linear regions in a set of 2D and 3D
@ -197,6 +210,13 @@ Release date: June 2023
to describe 3D simplicial meshes, and makes the data structure independent to describe 3D simplicial meshes, and makes the data structure independent
from the [tetrahedral mesh generation](https://doc.cgal.org/5.6/Manual/packages.html#PkgMesh3) package. from the [tetrahedral mesh generation](https://doc.cgal.org/5.6/Manual/packages.html#PkgMesh3) package.
### [Tetrahedral Remeshing](https://doc.cgal.org/5.6/Manual/packages.html#PkgTetrahedralRemeshing)
- **Breaking change**: The template parameters of
[`CGAL::Tetrahedral_remeshing::Remeshing_vertex_base_3`](https://doc.cgal.org/5.6/Tetrahedral_remeshing/group__PkgTetrahedralRemeshingClasses.html#ga7ef4f8c0c1ed715c34389ea4ee851a92)
and
[`CGAL::Tetrahedral_remeshing::Remeshing_cell_base_3`](https://doc.cgal.org/5.6/Tetrahedral_remeshing/classCGAL_1_1Tetrahedral__remeshing_1_1Remeshing__cell__base__3.html)
have been modified.
### [3D Mesh Generation](https://doc.cgal.org/5.6/Manual/packages.html#PkgMesh3) ### [3D Mesh Generation](https://doc.cgal.org/5.6/Manual/packages.html#PkgMesh3)
- Added two new named parameters to the named constructor - Added two new named parameters to the named constructor

View File

@ -15,7 +15,7 @@
# .. variable:: CGAL_DISABLE_GMP # .. variable:: CGAL_DISABLE_GMP
# #
# If set, the `GMP` library will not be used. If # If set, the `GMP` library will not be used. If
# :variable:`WITH_LEDA` is not used either, a efficient exact # :variable:`WITH_LEDA` is not used either, an efficient exact
# number types are used by CGAL kernels for exact computation. # number types are used by CGAL kernels for exact computation.
# #
# .. variable:: WITH_LEDA # .. variable:: WITH_LEDA

View File

@ -84,7 +84,7 @@ function(tbb_extract_real_library library real_library)
set(_elf_magic "7f454c46") set(_elf_magic "7f454c46")
file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX) file(READ ${library} _hex_data OFFSET 0 LIMIT 4 HEX)
if(_hex_data STREQUAL _elf_magic) if(_hex_data STREQUAL _elf_magic)
#we have opened a elf binary so this is what #we have opened an elf binary so this is what
#we should link to #we should link to
set(${real_library} "${library}" PARENT_SCOPE) set(${real_library} "${library}" PARENT_SCOPE)
return() return()

View File

@ -112,6 +112,7 @@
#include <boost/version.hpp> #include <boost/version.hpp>
#include <CGAL/version.h> #include <CGAL/version.h>
#include <CGAL/version_checker.h>
//----------------------------------------------------------------------// //----------------------------------------------------------------------//
// platform specific workaround flags (CGAL_CFG_...) // platform specific workaround flags (CGAL_CFG_...)

View File

@ -0,0 +1,53 @@
// Copyright (c) 2023 GeometryFactory.
// All rights reserved.
//
// This file is part of CGAL (www.cgal.org)
//
// $URL$
// $Id$
// SPDX-License-Identifier: LGPL-3.0-or-later OR LicenseRef-Commercial
//
// Author(s) : -
#ifndef CGAL_VERSION_CHECKER_H
#define CGAL_VERSION_CHECKER_H
#include <CGAL/version_macros.h>
// All files including this header are meant to work with a given version of CGAL
// When using forked headers, set the following macro to the version of CGAL
// you want to use.
//// Set the 3 following macros to the version of CGAL you want to use
//#define CGAL_COMPATIBLE_VERSION_MAJOR 6
//#define CGAL_COMPATIBLE_VERSION_MINOR 0
//#define CGAL_COMPATIBLE_VERSION_PATCH 0
// Set the following macros to 1 to get a warning/an error
// when using a possibly incompatible version of CGAL
#define CGAL_VERSION_CHECKER_ERROR 0
#define CGAL_VERSION_CHECKER_WARNING 0
#define CGAL_COMPATIBLE_VERSION_STR CGAL_STR(CGAL_COMPATIBLE_VERSION_MAJOR) "." \
CGAL_STR(CGAL_COMPATIBLE_VERSION_MINOR) "." \
CGAL_STR(CGAL_COMPATIBLE_VERSION_PATCH)
// Check that the version of CGAL used is the one expected
#if CGAL_COMPATIBLE_VERSION_MAJOR != CGAL_VERSION_MAJOR \
|| CGAL_COMPATIBLE_VERSION_MINOR != CGAL_VERSION_MINOR \
|| CGAL_COMPATIBLE_VERSION_PATCH != CGAL_VERSION_PATCH
#if CGAL_VERSION_CHECKER_WARNING || CGAL_VERSION_CHECKER_ERROR
#pragma message("These headers are meant to be used with CGAL " CGAL_COMPATIBLE_VERSION_STR " only."\
" You are using CGAL version: " CGAL_STR(CGAL_VERSION) ".")
#ifdef CGAL_VERSION_CHECKER_ERROR
#error "Incompatible version of CGAL"
#endif
#endif
#endif
#endif // CGAL_VERSION_CHECKER_H

View File

@ -924,9 +924,9 @@ int main()
{ {
CGAL::Set_ieee_double_precision pfr; CGAL::Set_ieee_double_precision pfr;
Test< CGAL::Simple_cartesian<CGAL::internal::Exact_field_selector<void*>::Type > >().run(); Test< CGAL::Simple_cartesian<CGAL::internal::Exact_field_selector<double>::Type > >().run();
Test< CGAL::Cartesian<double> >().run(); Test< CGAL::Cartesian<double> >().run();
Test< CGAL::Homogeneous<CGAL::internal::Exact_field_selector<void*>::Type > >().run(); Test< CGAL::Homogeneous<CGAL::internal::Exact_field_selector<double>::Type > >().run();
Test< CGAL::Exact_predicates_inexact_constructions_kernel >().run(); Test< CGAL::Exact_predicates_inexact_constructions_kernel >().run();
Test< CGAL::Exact_predicates_exact_constructions_kernel >().run(); Test< CGAL::Exact_predicates_exact_constructions_kernel >().run();
} }

Some files were not shown because too many files have changed in this diff Show More