Merge branch 'master' into BGL-Alpha_expansion_graphcut-GF
This commit is contained in:
+5
-5
@@ -47,11 +47,11 @@ env:
|
||||
- PACKAGE='Stream_support Subdivision_method_3 Surface_mesh '
|
||||
- PACKAGE='Surface_mesh_approximation Surface_mesh_deformation Surface_mesh_parameterization '
|
||||
- PACKAGE='Surface_mesh_segmentation Surface_mesh_shortest_path Surface_mesh_simplification '
|
||||
- PACKAGE='Surface_mesh_skeletonization Surface_mesher Surface_sweep_2 '
|
||||
- PACKAGE='TDS_2 TDS_3 Testsuite '
|
||||
- PACKAGE='Three Triangulation Triangulation_2 '
|
||||
- PACKAGE='Triangulation_3 Union_find Visibility_2 '
|
||||
- PACKAGE='Voronoi_diagram_2 wininst '
|
||||
- PACKAGE='Surface_mesh_skeletonization Surface_mesh_topology Surface_mesher '
|
||||
- PACKAGE='Surface_sweep_2 TDS_2 TDS_3 '
|
||||
- PACKAGE='Testsuite Three Triangulation '
|
||||
- PACKAGE='Triangulation_2 Triangulation_3 Union_find '
|
||||
- PACKAGE='Visibility_2 Voronoi_diagram_2 wininst '
|
||||
compiler: clang
|
||||
install:
|
||||
- echo "$PWD"
|
||||
|
||||
@@ -122,6 +122,7 @@ Surface_mesh_segmentation
|
||||
Surface_mesh_shortest_path
|
||||
Surface_mesh_simplification
|
||||
Surface_mesh_skeletonization
|
||||
Surface_mesh_topology
|
||||
Surface_mesher
|
||||
Surface_sweep_2
|
||||
TDS_2
|
||||
|
||||
+10
-4
@@ -5,11 +5,17 @@
|
||||
|
||||
DO_IGNORE=FALSE
|
||||
cd $1
|
||||
if [ ! -f "$2/package_info/$2/dependencies" ];then
|
||||
|
||||
if [ ! -d "$2" ]; then
|
||||
echo "$2 : MISSING PACKAGE. Ignoring."
|
||||
DO_IGNORE=TRUE
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -f "$2/package_info/$2/dependencies" ];then
|
||||
echo "No dependencies found for $2"
|
||||
bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen
|
||||
|
||||
|
||||
bash Scripts/developer_scripts/cgal_check_dependencies.sh --check_headers /usr/bin/doxygen
|
||||
exit 1
|
||||
fi
|
||||
LIST_OF_FILES=$(git diff --name-only origin/master... |cut -d/ -f1 |uniq |sort)
|
||||
|
||||
@@ -75,7 +75,7 @@ using Intersection_and_primitive_id = unspecified_type;
|
||||
|
||||
/// \name Splitting
|
||||
/// During the construction of the AABB tree, the primitives are
|
||||
/// splitted according to some comparison functions related to the longest axis:
|
||||
/// split according to some comparison functions related to the longest axis:
|
||||
/// @{
|
||||
|
||||
/*!
|
||||
|
||||
+4
-1
@@ -60,6 +60,8 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
std::ifstream in((argc>1)?argv[1]:"data/half.xyz");
|
||||
double per = (argc>2)?boost::lexical_cast<double>(argv[2]):0;
|
||||
double radius_ratio_bound = (argc>3)?boost::lexical_cast<double>(argv[3]):5.0;
|
||||
|
||||
std::vector<Point_3> points;
|
||||
std::vector<Facet> facets;
|
||||
|
||||
@@ -71,7 +73,8 @@ int main(int argc, char* argv[])
|
||||
CGAL::advancing_front_surface_reconstruction(points.begin(),
|
||||
points.end(),
|
||||
std::back_inserter(facets),
|
||||
perimeter);
|
||||
perimeter,
|
||||
radius_ratio_bound);
|
||||
|
||||
std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n";
|
||||
std::copy(points.begin(),
|
||||
|
||||
-1
@@ -3,7 +3,6 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Point_with_normal_3.h>
|
||||
#include <CGAL/Shape_detection/Efficient_RANSAC.h>
|
||||
#include <CGAL/structure_point_set.h>
|
||||
#include <CGAL/Delaunay_triangulation_3.h>
|
||||
|
||||
@@ -369,9 +369,9 @@ concept. The second template parameter is a tag that indicates what
|
||||
operations are allowed in the computations that take place within the
|
||||
traits class.
|
||||
The two possible values of the `Method_tag` parameter are
|
||||
`Ring_tag` and `Sqrt_field_tag`. When
|
||||
`Ring_tag` is used, only ring operations are used during the
|
||||
evaluation of the predicates, whereas if `Sqrt_field_tag` is
|
||||
`Integral_domain_without_division_tag` and `Field_with_sqrt_tag`. When
|
||||
`Integral_domain_without_division_tag` is used, only ring operations are used during the
|
||||
evaluation of the predicates, whereas if `Field_with_sqrt_tag` is
|
||||
chosen, all four field operations, as well as square roots, are used
|
||||
during the predicate evaluation.
|
||||
|
||||
@@ -379,32 +379,22 @@ The `Apollonius_graph_traits_2<K,Method_tag>` class provides exact
|
||||
predicates if the number type in the kernel `K` is an exact number
|
||||
type. This is to be associated with the type of operations allowed for
|
||||
the predicate evaluation. For example `MP_Float` as number
|
||||
type, with `Ring_tag` as tag will give exact predicates,
|
||||
whereas `MP_Float` with `Sqrt_field_tag` will give
|
||||
type, with `Integral_domain_without_division_tag` as tag will give exact predicates,
|
||||
whereas `MP_Float` with `Field_with_sqrt_tag` will give
|
||||
inexact predicates.
|
||||
|
||||
Since using an exact number type may be too slow, the
|
||||
`Apollonius_graph_traits_2<K,Method_tag>` class is designed to
|
||||
support the dynamic filtering of \cgal through the
|
||||
`Filtered_exact<CT,ET>` mechanism. In particular if `CT`
|
||||
is an inexact number type that supports the operations denoted by the
|
||||
tag `Method_tag` and `ET` is an exact number type for these
|
||||
operations, then kernel with number type
|
||||
`Filtered_exact<CT,ET>` will yield exact predicates for the
|
||||
Apollonius graph traits. To give a concrete example,
|
||||
`CGAL::Filtered_exact<double,CGAL::MP_Float>` with
|
||||
`Ring_tag` will produce exact predicates.
|
||||
|
||||
Another possibility for fast and exact predicate evaluation is to use
|
||||
the
|
||||
`Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
|
||||
class. This class is the analog of a filtered kernel. It takes a
|
||||
Although exact number types provide exact predicates and constructions,
|
||||
their use often results in unacceptably large runtimes.
|
||||
The class `Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
|
||||
aims to paliate this shortcoming. Similar to a filtered kernel, it takes a
|
||||
constructions kernel `CK`, a filtering kernel `FK` and an
|
||||
exact kernel `EK`, as well as the corresponding tags
|
||||
(`CM`, `FM` and `EM`, respectively).
|
||||
It evaluates the predicates by first using the filtering kernel, and
|
||||
if this fails the evaluation is performed using the exact kernel. The
|
||||
constructions are done using the kernel `CK`, which means that
|
||||
Predicates are evaluated by first using the filtering kernel, and
|
||||
if this fails the evaluation is performed using the exact kernel,
|
||||
thus yielding exact predicates at a generally much cheaper cost
|
||||
than directly using an exact number type. The constructions
|
||||
are done using the kernel `CK`, which means that
|
||||
they are not necessarily exact. All template parameters except
|
||||
`CK` have default values, which are explained in the reference
|
||||
manual.
|
||||
|
||||
@@ -20,8 +20,8 @@ This class has six template parameters. The first, third and fifth
|
||||
template parameters must be a models of the `Kernel` concept. The
|
||||
second, fourth and sixth template parameters correspond to how
|
||||
predicates are evaluated. There are two predefined possible values for
|
||||
`Method_tag`, namely `CGAL::Sqrt_field_tag` and
|
||||
`CGAL::Ring_tag`. The first one must be used when the number type
|
||||
`Method_tag`, namely `CGAL::Field_with_sqrt_tag` and
|
||||
`CGAL::Integral_domain_without_division_tag`. The first one must be used when the number type
|
||||
used in the representation supports the exact evaluation of signs of
|
||||
expressions involving all four basic operations and square roots,
|
||||
whereas the second one requires the exact evaluation of signs of
|
||||
@@ -31,7 +31,7 @@ The way the predicates are evaluated is discussed in
|
||||
\cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}.
|
||||
|
||||
The default values for the template parameters are as follows:
|
||||
`CM = CGAL::Ring_tag`,
|
||||
`CM = CGAL::Integral_domain_without_division_tag`,
|
||||
`EK = CGAL::Simple_cartesian<CGAL::MP_Float>`,
|
||||
`EM = CM`,
|
||||
`FK = CGAL::Simple_cartesian<CGAL::Interval_nt<false> >`,
|
||||
@@ -41,8 +41,8 @@ The default values for the template parameters are as follows:
|
||||
|
||||
\sa `Kernel`
|
||||
\sa `ApolloniusGraphTraits_2`
|
||||
\sa `CGAL::Ring_tag`
|
||||
\sa `CGAL::Sqrt_field_tag`
|
||||
\sa `CGAL::Integral_domain_without_division_tag`
|
||||
\sa `CGAL::Field_with_sqrt_tag`
|
||||
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
|
||||
\sa `CGAL::Apollonius_graph_traits_2<K,Method_tag>`
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ This class has two template parameters. The first template parameter
|
||||
must be a model of the `Kernel` concept. The second template
|
||||
parameter corresponds to how predicates are evaluated. There are two
|
||||
predefined possible values for `Method_tag`, namely
|
||||
`CGAL::Sqrt_field_tag` and `CGAL::Ring_tag`. The first one
|
||||
`CGAL::Field_with_sqrt_tag` and `CGAL::Integral_domain_without_division_tag`. The first one
|
||||
must be used when the number type used in the representation supports
|
||||
the exact evaluation of signs of expressions involving all four basic
|
||||
operations and square roots, whereas the second one requires the exact
|
||||
evaluation of signs of ring-type expressions, i.e., expressions
|
||||
involving only additions, subtractions and multiplications. The
|
||||
default value for `Method_tag` is `CGAL::Ring_tag`.
|
||||
default value for `Method_tag` is `CGAL::Integral_domain_without_division_tag`.
|
||||
The way the predicates are evaluated is discussed in
|
||||
\cgalCite{cgal:ke-ppawv-02}, \cgalCite{cgal:ke-rctac-03}.
|
||||
|
||||
@@ -24,8 +24,8 @@ The way the predicates are evaluated is discussed in
|
||||
|
||||
\sa `Kernel`
|
||||
\sa `ApolloniusGraphTraits_2`
|
||||
\sa `CGAL::Ring_tag`
|
||||
\sa `CGAL::Sqrt_field_tag`
|
||||
\sa `CGAL::Integral_domain_without_division_tag`
|
||||
\sa `CGAL::Field_with_sqrt_tag`
|
||||
\sa `CGAL::Apollonius_graph_2<Gt,Agds>`
|
||||
\sa `CGAL::Apollonius_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
|
||||
|
||||
|
||||
@@ -5,5 +5,6 @@ Algebraic_foundations
|
||||
Circulator
|
||||
Stream_support
|
||||
Voronoi_diagram_2
|
||||
Number_types
|
||||
TDS_2
|
||||
Triangulation_2
|
||||
|
||||
@@ -1,38 +0,0 @@
|
||||
// Copyright (c) 2003,2004 INRIA Sophia-Antipolis (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
// Author(s) : Menelaos Karavelas <mkaravel@iacm.forth.gr>
|
||||
|
||||
|
||||
|
||||
#ifndef CGAL_CHECK_FILTER_H
|
||||
#define CGAL_CHECK_FILTER_H
|
||||
|
||||
#include <CGAL/license/Apollonius_graph_2.h>
|
||||
|
||||
|
||||
#undef CGAL_IA_NEW_FILTERS
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template < class T>
|
||||
void must_be_filtered(const T&)
|
||||
{}
|
||||
|
||||
#if defined CGAL_ARITHMETIC_FILTER_H
|
||||
template < class CT, class ET, class Type, bool Protection, class Cache>
|
||||
void must_be_filtered(const Filtered_exact<CT, ET, Type, Protection,
|
||||
Cache> &)
|
||||
{ dont_compile(CT(), ET()); }
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -165,6 +165,7 @@ public:
|
||||
//---------------------------------
|
||||
typedef typename CK_traits::Construct_object_2 Construct_object_2;
|
||||
typedef typename CK_traits::Assign_2 Assign_2;
|
||||
typedef typename CK_traits::Construct_point_2 Construct_point_2;
|
||||
|
||||
// CONSTRUCTIONS
|
||||
//--------------
|
||||
@@ -329,6 +330,10 @@ public:
|
||||
return Construct_object_2();
|
||||
}
|
||||
|
||||
Construct_point_2
|
||||
construct_point_2_object() const {
|
||||
return Construct_point_2();
|
||||
}
|
||||
|
||||
// CONSTRUCTIONS
|
||||
//--------------
|
||||
|
||||
@@ -75,6 +75,8 @@ public:
|
||||
|
||||
// CONSTRUCTIONS
|
||||
//--------------
|
||||
typedef typename Kernel::Construct_point_2 Construct_point_2;
|
||||
|
||||
// vertex and dual site
|
||||
typedef CGAL_APOLLONIUS_GRAPH_2_NS::Construct_Apollonius_vertex_2<Kernel>
|
||||
/* */ Construct_Apollonius_vertex_2;
|
||||
@@ -142,6 +144,10 @@ public:
|
||||
return Construct_object_2();
|
||||
}
|
||||
|
||||
Construct_point_2
|
||||
construct_point_2_object() const {
|
||||
return Construct_point_2();
|
||||
}
|
||||
|
||||
// CONSTRUCTIONS
|
||||
//--------------
|
||||
|
||||
@@ -83,6 +83,10 @@ public:
|
||||
this->p2 = p2;
|
||||
}
|
||||
|
||||
int compute_k(const FT tt) const {
|
||||
return int(CGAL::to_double(CGAL::sqrt(tt / this->STEP)));
|
||||
}
|
||||
|
||||
void generate_points(std::vector<Point_2>& p) const
|
||||
{
|
||||
if ( CGAL::is_zero(this->r) ) {
|
||||
@@ -91,76 +95,70 @@ public:
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// FT STEP = W.width() / 100.0;
|
||||
|
||||
FT s0, s1;
|
||||
|
||||
s0 = t(p1);
|
||||
s1 = t(p2);
|
||||
|
||||
if (CGAL::compare(s0, s1) == LARGER) {
|
||||
if (CGAL::compare(s0, s1) == LARGER)
|
||||
std::swap(s0, s1);
|
||||
}
|
||||
|
||||
p.clear();
|
||||
|
||||
if ( !(CGAL::is_positive(s0)) &&
|
||||
!(CGAL::is_negative(s1)) ) {
|
||||
FT tt;
|
||||
int k;
|
||||
if ( !(CGAL::is_positive(s0)) && !(CGAL::is_negative(s1)) )
|
||||
{
|
||||
FT tt = FT(-this->STEP);
|
||||
int k = -1;
|
||||
|
||||
p.push_back( this->o );
|
||||
k = 1;
|
||||
tt = FT(-this->STEP);
|
||||
while ( CGAL::compare(tt, s0) == LARGER ) {
|
||||
p.insert( p.begin(), f(tt) );
|
||||
k--;
|
||||
tt = -FT(k * k) * this->STEP;
|
||||
|
||||
while ( CGAL::compare(tt, s0) == LARGER )
|
||||
{
|
||||
p.insert( p.begin(), f(tt) );
|
||||
--k;
|
||||
tt = - FT(k * k) * this->STEP;
|
||||
}
|
||||
|
||||
p.insert( p.begin(), f(s0) );
|
||||
|
||||
k = 1;
|
||||
tt = FT(this->STEP);
|
||||
while ( CGAL::compare(tt, s1) == SMALLER ) {
|
||||
p.push_back( f(tt) );
|
||||
k++;
|
||||
tt = FT(k * k) * this->STEP;
|
||||
while ( CGAL::compare(tt, s1) == SMALLER )
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
++k;
|
||||
tt = FT(k * k) * this->STEP;
|
||||
}
|
||||
p.push_back( f(s1) );
|
||||
} else if ( !(CGAL::is_negative(s0)) &&
|
||||
!(CGAL::is_negative(s1)) ) {
|
||||
FT tt;
|
||||
int k;
|
||||
}
|
||||
else if ( !(CGAL::is_negative(s0)) && !(CGAL::is_negative(s1)) )
|
||||
{
|
||||
FT tt = s0;
|
||||
int k = - compute_k(-tt);
|
||||
|
||||
|
||||
p.push_back( f(s0) );
|
||||
|
||||
tt = s0;
|
||||
k = int(CGAL::to_double(CGAL::sqrt(tt / this->STEP)));
|
||||
|
||||
while ( CGAL::compare(tt, s1) == SMALLER ) {
|
||||
if ( CGAL::compare(tt, s0) != SMALLER )
|
||||
p.push_back( f(tt) );
|
||||
k++;
|
||||
tt = FT(k * k) * this->STEP;
|
||||
do
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
++k;
|
||||
tt = FT(k * k) * this->STEP;
|
||||
}
|
||||
p.push_back( f(s1) );
|
||||
} else {
|
||||
FT tt;
|
||||
int k;
|
||||
while ( CGAL::compare(tt, s0) == LARGER && CGAL::compare(tt, s1) == SMALLER );
|
||||
|
||||
p.push_back( f(s1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT tt = s1;
|
||||
int k = compute_k(tt);
|
||||
|
||||
tt = s1;
|
||||
k = int(CGAL::to_double(-CGAL::sqrt(-tt / this->STEP)));
|
||||
|
||||
while ( CGAL::compare(tt, s0) == LARGER ) {
|
||||
if ( CGAL::compare(tt, s1) != LARGER )
|
||||
p.push_back( f(tt) );
|
||||
k--;
|
||||
tt = -FT(k * k) * this->STEP;
|
||||
do
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
--k;
|
||||
tt = - FT(k * k) * this->STEP;
|
||||
}
|
||||
while ( CGAL::compare(tt, s0) == LARGER && CGAL::compare(tt, s1) == SMALLER );
|
||||
|
||||
p.push_back( f(s0) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,85 +62,100 @@ public:
|
||||
this->p2 = p2;
|
||||
}
|
||||
|
||||
int compute_k(const FT& tt) const {
|
||||
return int(CGAL::sqrt(CGAL::to_double(tt) / 2));
|
||||
int compute_k(const FT tt, const FT STEP) const {
|
||||
return int(CGAL::to_double(CGAL::sqrt(tt / STEP)));
|
||||
}
|
||||
|
||||
// s0 and s1 define a desired drawing "range"
|
||||
void generate_points(std::vector<Point_2>& p,
|
||||
const FT STEP = FT(2)) const
|
||||
const FT STEP,
|
||||
FT s0, FT s1) const
|
||||
{
|
||||
FT s0, s1;
|
||||
|
||||
s0 = t(p1);
|
||||
s1 = t(p2);
|
||||
|
||||
if (CGAL::compare(s0, s1) == LARGER) {
|
||||
std::swap(s0, s1);
|
||||
}
|
||||
CGAL_precondition(STEP > 0);
|
||||
|
||||
p.clear();
|
||||
|
||||
if ( !(CGAL::is_positive(s0)) &&
|
||||
!(CGAL::is_negative(s1)) ) {
|
||||
FT tt;
|
||||
int k;
|
||||
if (CGAL::compare(s0, s1) == LARGER)
|
||||
std::swap(s0, s1);
|
||||
|
||||
// This is a parabola segment that exists between only between p1 and p2 so we gotta crop
|
||||
// the desired range to actually fit the parabola segment
|
||||
FT tp1 = t(p1), tp2 = t(p2);
|
||||
|
||||
if (CGAL::compare(tp1, tp2) == LARGER)
|
||||
std::swap(tp1, tp2);
|
||||
|
||||
if(tp2 < s0 || s1 < tp1) // nothing to draw because the ranges are completely disjoint
|
||||
return;
|
||||
|
||||
s0 = (std::max)(s0, tp1);
|
||||
s1 = (std::min)(s1, tp2);
|
||||
|
||||
if ( !(CGAL::is_positive(s0)) && !(CGAL::is_negative(s1)) )
|
||||
{
|
||||
FT tt = - STEP;
|
||||
int k = -1;
|
||||
|
||||
p.push_back( this->o );
|
||||
k = -1;
|
||||
|
||||
tt = - STEP;
|
||||
while ( CGAL::compare(tt, s0) == LARGER ) {
|
||||
p.insert( p.begin(), f(tt) );
|
||||
k--;
|
||||
tt = -FT(k * k) * STEP;
|
||||
// no need to check tt < s1 since we have tt < 0, s1 >= 0 and tt is moving towards -inf
|
||||
while ( CGAL::compare(tt, s0) == LARGER )
|
||||
{
|
||||
p.insert( p.begin(), f(tt) );
|
||||
--k;
|
||||
tt = - FT(k * k) * STEP;
|
||||
}
|
||||
p.insert( p.begin(), f(s0) );
|
||||
|
||||
k = 1;
|
||||
tt = STEP;
|
||||
while ( CGAL::compare(tt, s1) == SMALLER ) {
|
||||
p.push_back( f(tt) );
|
||||
k++;
|
||||
tt = FT(k * k) * STEP;
|
||||
|
||||
// no need to check tt > s0 since we have tt > 0, s0 <= 0 and tt is moving towards +inf
|
||||
while ( CGAL::compare(tt, s1) == SMALLER )
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
++k;
|
||||
tt = FT(k * k) * STEP;
|
||||
}
|
||||
p.push_back( f(s1) );
|
||||
} else if ( !(CGAL::is_negative(s0)) &&
|
||||
!(CGAL::is_negative(s1)) ) {
|
||||
FT tt;
|
||||
int k;
|
||||
}
|
||||
else if ( !(CGAL::is_negative(s0)) && !(CGAL::is_negative(s1)) )
|
||||
{
|
||||
FT tt = s0;
|
||||
int k = compute_k(tt, STEP);
|
||||
|
||||
|
||||
p.push_back( f(s0) );
|
||||
|
||||
tt = s0;
|
||||
k = compute_k(tt);
|
||||
|
||||
while ( CGAL::compare(tt, s1) == SMALLER ) {
|
||||
if ( CGAL::compare(tt, s0) != SMALLER )
|
||||
p.push_back( f(tt) );
|
||||
k++;
|
||||
tt = FT(k * k) * STEP;
|
||||
do
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
++k;
|
||||
tt = FT(k * k) * STEP;
|
||||
}
|
||||
p.push_back( f(s1) );
|
||||
} else {
|
||||
FT tt;
|
||||
int k;
|
||||
while ( CGAL::compare(tt, s0) == LARGER && CGAL::compare(tt, s1) == SMALLER );
|
||||
|
||||
p.push_back( f(s1) );
|
||||
}
|
||||
else
|
||||
{
|
||||
FT tt = s1;
|
||||
int k = - compute_k(-tt, STEP);
|
||||
|
||||
tt = s1;
|
||||
k = -compute_k(-tt);
|
||||
|
||||
while ( CGAL::compare(tt, s0) == LARGER ) {
|
||||
if ( CGAL::compare(tt, s1) != LARGER )
|
||||
p.push_back( f(tt) );
|
||||
k--;
|
||||
tt = -FT(k * k) * STEP;
|
||||
do
|
||||
{
|
||||
p.push_back( f(tt) );
|
||||
--k;
|
||||
tt = - FT(k * k) * STEP;
|
||||
}
|
||||
while ( CGAL::compare(tt, s0) == LARGER && CGAL::compare(tt, s1) == SMALLER );
|
||||
|
||||
p.push_back( f(s0) );
|
||||
}
|
||||
}
|
||||
|
||||
void generate_points(std::vector<Point_2>& p,
|
||||
const FT STEP = FT(2)) const
|
||||
{
|
||||
return generate_points(p, STEP, t(p1), t(p2));
|
||||
}
|
||||
|
||||
template< class Stream >
|
||||
void draw(Stream& W) const
|
||||
|
||||
@@ -3,76 +3,31 @@
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
#define DONT_USE_FILTERED_EXACT
|
||||
|
||||
// choose number type
|
||||
#include <CGAL/MP_Float.h>
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
# include <CGAL/Filtered_exact.h>
|
||||
#endif
|
||||
|
||||
typedef double inexact_type;
|
||||
typedef CGAL::MP_Float exact_type;
|
||||
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Filtered_exact<inexact_type,exact_type> number_t;
|
||||
#endif
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Simple_cartesian<number_t> Kernel;
|
||||
#endif
|
||||
|
||||
typedef CGAL::Integral_domain_without_division_tag Method_tag;
|
||||
|
||||
#include "./include/test.h"
|
||||
|
||||
|
||||
typedef CGAL::Simple_cartesian<inexact_type> CK;
|
||||
typedef CGAL::Simple_cartesian<exact_type> EK;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
{
|
||||
std::ifstream ifs_algo("./data/algo.dat");
|
||||
std::ifstream ifs_algo("./data/algo.dat");
|
||||
assert( ifs_algo );
|
||||
|
||||
assert( ifs_algo );
|
||||
|
||||
std::cout << "testing the Apollonius graph class..." << std::flush;
|
||||
bool algo_ok =
|
||||
CGAL::test_algo<Kernel,Method_tag,std::ifstream>(ifs_algo);
|
||||
|
||||
assert( algo_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_algo.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
{
|
||||
std::ifstream ifs_algo("./data/algo.dat");
|
||||
|
||||
assert( ifs_algo );
|
||||
|
||||
std::cout << "testing the Apollonius graph class"
|
||||
<< " with filtered traits..." << std::flush;
|
||||
bool algo_ok =
|
||||
CGAL::test_filtered_traits_algo<CK,Method_tag,EK,Method_tag,
|
||||
std::ifstream>(ifs_algo);
|
||||
|
||||
assert( algo_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_algo.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << "testing the Apollonius graph class" << " with filtered traits..." << std::flush;
|
||||
bool algo_ok = CGAL::test_filtered_traits_algo<CK,Method_tag,EK,Method_tag,std::ifstream>(ifs_algo);
|
||||
assert( algo_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,79 +3,31 @@
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
#define DNOT_USE_FILTERED_EXACT
|
||||
|
||||
// choose number type
|
||||
#include <CGAL/MP_Float.h>
|
||||
|
||||
#ifndef DNOT_USE_FILTERED_EXACT
|
||||
# include <CGAL/Filtered_exact.h>
|
||||
#endif
|
||||
|
||||
typedef double inexact_type;
|
||||
typedef CGAL::MP_Float exact_type;
|
||||
|
||||
#ifndef DNOT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Filtered_exact<inexact_type,exact_type> number_t;
|
||||
#endif
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
|
||||
#ifndef DNOT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Simple_cartesian<number_t> K;
|
||||
#endif
|
||||
|
||||
typedef CGAL::Integral_domain_without_division_tag Method_tag;
|
||||
|
||||
#include "./include/test.h"
|
||||
|
||||
|
||||
typedef CGAL::Simple_cartesian<inexact_type> CK;
|
||||
typedef CGAL::Simple_cartesian<exact_type> EK;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef DNOT_USE_FILTERED_EXACT
|
||||
{
|
||||
std::ifstream ifs_hierarchy("./data/hierarchy.dat");
|
||||
std::ifstream ifs_hierarchy("./data/hierarchy.dat");
|
||||
assert( ifs_hierarchy );
|
||||
|
||||
assert( ifs_hierarchy );
|
||||
std::cout << "testing the Apollonius graph hierarchy class" << " with filtered traits..." << std::flush;
|
||||
bool hierarchy_ok = CGAL::test_filtered_traits_hierarchy_algo<CK,Method_tag,EK,Method_tag,std::ifstream>(ifs_hierarchy);
|
||||
|
||||
std::cout << "testing the Apollonius graph hierarchy class..."
|
||||
<< std::flush;
|
||||
bool hierarchy_ok =
|
||||
CGAL::test_hierarchy_algo<Kernel,Method_tag,
|
||||
std::ifstream>(ifs_hierarchy);
|
||||
|
||||
assert( hierarchy_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_hierarchy.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
{
|
||||
std::ifstream ifs_hierarchy("./data/hierarchy.dat");
|
||||
|
||||
assert( ifs_hierarchy );
|
||||
|
||||
std::cout << "testing the Apollonius graph hierarchy class"
|
||||
<< " with filtered traits..." << std::flush;
|
||||
bool hierarchy_ok =
|
||||
CGAL::test_filtered_traits_hierarchy_algo<CK,Method_tag,EK,
|
||||
Method_tag,std::ifstream>(ifs_hierarchy);
|
||||
|
||||
assert( hierarchy_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_hierarchy.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
assert( hierarchy_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,79 +2,33 @@
|
||||
#include <fstream>
|
||||
#include <cassert>
|
||||
|
||||
#define DONT_USE_FILTERED_EXACT
|
||||
|
||||
// choose number type
|
||||
#include <CGAL/MP_Float.h>
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
# include <CGAL/Filtered_exact.h>
|
||||
#endif
|
||||
|
||||
typedef double inexact_type;
|
||||
typedef CGAL::MP_Float exact_type;
|
||||
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Filtered_exact<inexact_type,exact_type> number_t;
|
||||
#endif
|
||||
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
typedef CGAL::Simple_cartesian<number_t> Kernel;
|
||||
#endif
|
||||
|
||||
typedef CGAL::Integral_domain_without_division_tag Method_tag;
|
||||
|
||||
#include "./include/test.h"
|
||||
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> CK;
|
||||
typedef CGAL::Simple_cartesian<CGAL::MP_Float> EK;
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
#ifndef DONT_USE_FILTERED_EXACT
|
||||
{
|
||||
std::ifstream ifs_traits("./data/traits.dat");
|
||||
std::ifstream ifs_traits("./data/traits.dat");
|
||||
assert( ifs_traits );
|
||||
|
||||
assert( ifs_traits );
|
||||
std::cout << "testing the filtered traits class..." << std::flush;
|
||||
|
||||
// bool is_ok =
|
||||
// CGAL::test_traits<Kernel,CGAL::Integral_domain_without_division_tag,std::ifstream>(ifs_traits);
|
||||
CGAL::Filtered_traits_tester<CK,Method_tag,EK,Method_tag> test_traits;
|
||||
bool traits_ok = test_traits();
|
||||
assert( traits_ok );
|
||||
|
||||
std::cout << "testing the traits class..." << std::flush;
|
||||
|
||||
CGAL::Traits_tester<Kernel,Method_tag> test_traits;
|
||||
bool traits_ok = test_traits();
|
||||
|
||||
assert( traits_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_traits.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
#endif
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
{
|
||||
std::ifstream ifs_traits("./data/traits.dat");
|
||||
|
||||
assert( ifs_traits );
|
||||
|
||||
std::cout << "testing the filtered traits class..." << std::flush;
|
||||
|
||||
CGAL::Filtered_traits_tester<CK,Method_tag,EK,Method_tag> test_traits;
|
||||
bool traits_ok = test_traits();
|
||||
|
||||
assert( traits_ok );
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
ifs_traits.close();
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << " done!" << std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `HalfedgeDS_face_max_base_with_id` is a model of the `HalfedgeDSFace`
|
||||
concept.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `HalfedgeDS_halfedge_max_base_with_id` is a model of the `HalfedgeDSHalfedge`
|
||||
concept.
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `HalfedgeDS_vertex_max_base_with_id` is a model of the `HalfedgeDSVertex`
|
||||
concept. It is
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `Linear_cell_complex_bgl_min_items` defines `void` as the information associated with darts, darts have ids and 0- and 2-attributes are enabled and have ids.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `Linear_cell_complex_for_bgl_combinatorial_map_helper` defines a `CGAL::Linear_cell_complex_for_combinatorial_map` as inner type, named `type`, having `CGAL::Linear_cell_complex_bgl_min_items` as items class. With this item class, no information are associated with darts, darts have ids and 0- and 2-attributes are enabled and have ids.
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `Polyhedron_items_with_id_3` is a model of the `PolyhedronItems_3`
|
||||
concept. It provides definitions for vertices with points, halfedges,
|
||||
@@ -63,7 +63,7 @@ public:
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
Given a `CGAL::Polyhedron_3`,
|
||||
for each simplex type (vertex, halfedge, facet) associates an index from
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `Triangulation_face_base_with_id_2` is a model of the
|
||||
concept `TriangulationFaceBase_2`, the base face of a
|
||||
2D-triangulation. It provides an integer field that can be used to
|
||||
2D-triangulation. It provides an integer field that can be used to
|
||||
index faces for \sc{Bgl} algorithms.
|
||||
|
||||
Note that the user is in charge of setting indices correctly before
|
||||
running a graph algorithm.
|
||||
running a graph algorithm, by calling the function
|
||||
`CGAL::set_triangulation_ids(Triangulation&)`.
|
||||
|
||||
\tparam TriangulationTraits_2 is the geometric traits class
|
||||
and must be a model of `TriangulationTraits_2`.
|
||||
@@ -42,4 +43,19 @@ int& id();
|
||||
/// @}
|
||||
|
||||
}; /* end Triangulation_face_base_with_id_2 */
|
||||
|
||||
/// \ingroup BGLGraphExternalIndices
|
||||
///
|
||||
/// This function initializes vertex, edge, and face indices of the triangulation `tr` and must
|
||||
/// be called prior to using `tr` as a BGL graph in an algorithm that requires
|
||||
/// vertex, halfedge, edge, or face indices.
|
||||
///
|
||||
/// \tparam Triangulation a 2D triangulation of \cgal, whose combinatorial data structure
|
||||
/// has been initialized with the vertex and face classes `Triangulation_vertex_base_with_id_2`
|
||||
/// and `Triangulation_face_base_with_id_2`.
|
||||
///
|
||||
/// \sa the \ref PkgTriangulation2 package
|
||||
template <typename Triangulation>
|
||||
void set_triangulation_ids(Triangulation& tr);
|
||||
|
||||
} /* end namespace CGAL */
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
\ingroup PkgBGLHelper
|
||||
\ingroup BGLGraphExternalIndices
|
||||
|
||||
The class `Triangulation_vertex_base_with_id_2` is a model of the
|
||||
concept `TriangulationVertexBase_2`, the base vertex of a
|
||||
@@ -9,7 +9,8 @@ concept `TriangulationVertexBase_2`, the base vertex of a
|
||||
index vertices for \sc{Bgl} algorithms.
|
||||
|
||||
Note that the user is in charge of setting indices correctly before
|
||||
running a graph algorithm.
|
||||
running a graph algorithm, by calling the function
|
||||
`CGAL::set_triangulation_ids(Triangulation&)`.
|
||||
|
||||
\tparam TriangulationTraits_2 is the geometric traits class
|
||||
and must be a model of `TriangulationTraits_2`.
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
/// Boost Namespace
|
||||
namespace boost {
|
||||
/// CGAL Namespace
|
||||
namespace CGAL {
|
||||
|
||||
/// \ingroup PkgBGLProperties
|
||||
/// @{
|
||||
|
||||
/// The constant `edge_index` is a property tag which identifies the <i>index</i> property of an edge of a \sc{Bgl}
|
||||
/// <a href="https://www.boost.org/libs/graph/doc/Graph.html"><code>Graph</code></a>.
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
enum edge_index_t { edge_index};
|
||||
|
||||
/// The constant `vertex_index` is a property tag which identifies the <i>index</i> property of a vertex of a \sc{Bgl}
|
||||
/// <a href="https://www.boost.org/libs/graph/doc/Graph.html"><code>Graph</code></a>.
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
@@ -20,13 +15,17 @@ enum vertex_index_t { vertex_index };
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
enum halfedge_index_t { halfedge_index };
|
||||
|
||||
/// The constant `edge_index` is a property tag which identifies the <i>index</i> property of an edge of a \sc{Bgl}
|
||||
/// <a href="https://www.boost.org/libs/graph/doc/Graph.html"><code>Graph</code></a>.
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
enum edge_index_t { edge_index };
|
||||
|
||||
/// The constant `face_index` is a property tag which identifies the <i>index</i> property of a face of a `FaceGraph`.
|
||||
///
|
||||
/// This is a property tag introduced by \cgal.
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
enum face_index_t { face_index };
|
||||
|
||||
|
||||
/// The constant `vertex_point` is a property tag which refers to the geometric embedding property of
|
||||
/// a vertex of a `HalfedgeGraph`.
|
||||
///
|
||||
@@ -34,12 +33,22 @@ enum face_index_t { face_index };
|
||||
/// \cgalModels <a href="https://www.boost.org/libs/graph/doc/PropertyTag.html"><code>PropertyTag</code></a>
|
||||
enum vertex_point_t { vertex_point };
|
||||
|
||||
|
||||
/// @}
|
||||
} // namespace boost
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
/// \ingroup PkgBGLProperties
|
||||
///
|
||||
/// \brief graph_has_property is used to indicate if a model of `HalfedgeGraph` or `FaceGraph`
|
||||
/// has an internal property associated with the given `PropertyTag`.
|
||||
///
|
||||
/// It inherits from \link Tag_true `CGAL::Tag_true` \endlink if there is a
|
||||
/// default internal property map for the corresponding property tag and from
|
||||
/// \link Tag_false `CGAL::Tag_false` \endlink otherwise.
|
||||
///
|
||||
/// \tparam Graph a model of `HalfedgeGraph` or `FaceGraph`
|
||||
/// \tparam PropertyTag the type of a property tag referring to the property of interest.
|
||||
///
|
||||
template<typename Graph, typename PropertyTag>
|
||||
struct graph_has_property;
|
||||
|
||||
/// @{
|
||||
|
||||
|
||||
@@ -38,38 +38,51 @@ a \cgal point type as value type. \n
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{vertex_index_map} \anchor BGL_vertex_index_map
|
||||
is the property map containing the index of each vertex of the input polygon mesh.\n
|
||||
is the property map associating a unique index to each vertex of a polygon mesh `g`,
|
||||
between `0` and `num_vertices(g)-1`.
|
||||
If this parameter is not passed, internal machinery will create and initialize a vertex index
|
||||
property map, either using the internal property map if it exists or using an external map. The latter
|
||||
might result in - slightly - worsened performance in case of non-constant complexity for index access.\n
|
||||
<b>Type:</b> a class model of `ReadablePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh>::%vertex_descriptor` as key type and the value type
|
||||
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::vertex_index_t>::type>::value_type \endcode
|
||||
<b>Default:</b> \code boost::get(CGAL::vertex_index, pmesh)\endcode
|
||||
<b>Default:</b> an initialized vertex index property map
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{halfedge_index_map} \anchor BGL_halfedge_index_map
|
||||
is the property map containing the index of each halfedge of the input polygon mesh.\n
|
||||
is the property map associating a unique index to each halfedge of a polygon mesh,
|
||||
between `0` and `num_halfedges(g)-1`.
|
||||
If this parameter is not passed, internal machinery will create and initialize a halfedge index
|
||||
property map, either using the internal property map if it exists or using an external map. The latter
|
||||
might result in - slightly - worsened performance in case of non-constant complexity for index access.\n
|
||||
<b>Type:</b> a class model of `ReadablePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh>::%halfedge_descriptor` as key type and the value type:
|
||||
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::halfedge_index_t>::type>::value_type \endcode
|
||||
<b>Default:</b> \code boost::get(CGAL::halfedge_index, pmesh)\endcode
|
||||
If this internal property map exists, its values should be initialized.
|
||||
<b>Default:</b> an initialized halfedge index property map
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{edge_index_map} \anchor BGL_edge_index_map
|
||||
is the property map containing the index of each edge of the input polygon mesh.\n
|
||||
is the property map associating a unique index to each edge of a polygon mesh,
|
||||
between `0` and `num_edges(g)-1`.
|
||||
If this parameter is not passed, internal machinery will create and initialize a edge index
|
||||
property map, either using the internal property map if it exists or using an external map. The latter
|
||||
might result in - slightly - worsened performance in case of non-constant complexity for index access.\n
|
||||
<b>Type:</b> a class model of `ReadablePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh>::%edge_descriptor` as key type and the value type:
|
||||
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::edge_index_t>::type>::value_type \endcode
|
||||
<b>Default:</b> \code boost::get(CGAL::edge_index, pmesh)\endcode
|
||||
If this internal property map exists, its values should be initialized.
|
||||
<b>Default:</b> an initialized edge index property map
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{face_index_map} \anchor BGL_face_index_map
|
||||
is the property map containing the index of each face of the input polygon mesh.\n
|
||||
is the property map associating a unique index to each face of a polygon mesh,
|
||||
between `0` and `num_faces(g)-1`.
|
||||
If this parameter is not passed, internal machinery will create and initialize a face index
|
||||
property map, either using the internal property map if it exists or using an external map. The latter
|
||||
might result in - slightly - worsened performance in case of non-constant complexity for index access.\n
|
||||
<b>Type:</b> a class model of `ReadablePropertyMap` with
|
||||
`boost::graph_traits<PolygonMesh>::%face_descriptor` as key type and the value type:
|
||||
\code typename boost::property_traits<typename boost::property_map<PolygonMesh, CGAL::face_index_t>::type>::value_type \endcode
|
||||
<b>Default:</b> \code boost::get(CGAL::face_index, pmesh)\endcode
|
||||
If this internal property map exists, its values should be initialized.
|
||||
<b>Default:</b> an initialized face index property map
|
||||
\cgalNPEnd
|
||||
|
||||
\cgalNPBegin{edge_is_constrained_map} \anchor BGL_edge_is_constrained_map
|
||||
|
||||
@@ -443,7 +443,7 @@ the requirement for traversal of all faces in a graph.
|
||||
/// \defgroup PkgBGLPropertiesDynamic Dynamic Properties
|
||||
/// \ingroup PkgBGLRef
|
||||
|
||||
/// \defgroup PkgBGLHelper Helper Classes
|
||||
/// \defgroup PkgBGLGraphExternalIndices External Indices
|
||||
/// \ingroup PkgBGLRef
|
||||
|
||||
/// \defgroup PkgBGLHelperFct Helper Functions
|
||||
@@ -473,8 +473,11 @@ The dynamic property tags enable to associate information to simplices of a `Fac
|
||||
*/
|
||||
|
||||
/*!
|
||||
\addtogroup PkgBGLHelper
|
||||
Several classes that enable to store ids in vertices/halfedges/faces of a `CGAL::Polyhedron_3`, as well as adapters such as `CGAL::Dual`.
|
||||
\addtogroup BGLGraphExternalIndices
|
||||
A number of BGL and \cgal algorithms require the graph to have (initialized) integer-like indices
|
||||
for its vertices, edges, or faces. However, not all graphs intrinsically offer a natural way
|
||||
to attach a unique ID to each element. The following classes and functions paliate this
|
||||
by attaching and initializing external IDs to the elements of the graph.
|
||||
*/
|
||||
|
||||
/*!
|
||||
@@ -575,25 +578,25 @@ Methods to read and write graphs.
|
||||
- `MutableFaceGraph`
|
||||
|
||||
\cgalCRPSection{Properties}
|
||||
- `boost::vertex_index_t`
|
||||
- `boost::halfedge_index_t`
|
||||
- `boost::edge_index_t`
|
||||
- `boost::face_index_t`
|
||||
- `boost::vertex_point_t`
|
||||
- `CGAL::vertex_index_t`
|
||||
- `CGAL::halfedge_index_t`
|
||||
- `CGAL::edge_index_t`
|
||||
- `CGAL::face_index_t`
|
||||
- `CGAL::vertex_point_t`
|
||||
|
||||
\cgalCRPSection{%CGAL Classes Adapted for the Graph API}
|
||||
|
||||
Different \cgal types have been adapted as graphs for the \sc{Bgl}. All
|
||||
A number of \cgal structures have been adapted as graphs for the \sc{Bgl}. All
|
||||
adapted types are listed here. The pages document which concepts they
|
||||
model, the properties they support, and any possible caveats that a
|
||||
user might encounter.
|
||||
|
||||
- \link BGLSMGT `boost::graph_traits< CGAL::Surface_mesh<P> >` \endlink
|
||||
- \link BGLPolyGT `boost::graph_traits< CGAL::Polyhedron_3<T> >` \endlink
|
||||
- \link BGLLCCGT `boost::graph_traits< CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink
|
||||
- \link BGLSeam_meshGT `boost::graph_traits< CGAL::Seam_mesh<T> >` \endlink
|
||||
- \link BGLT2GT `boost::graph_traits< CGAL::Triangulation_2<GT, TDS> >` \endlink
|
||||
- \link BGLArgtGT `boost::graph_traits< CGAL::Arrangement_2<T,DC> >` \endlink
|
||||
- \link BGLSMGT `boost::graph_traits<CGAL::Surface_mesh<P> >` \endlink
|
||||
- \link BGLPolyGT `boost::graph_traits<CGAL::Polyhedron_3<T> >` \endlink
|
||||
- \link BGLLCCGT `boost::graph_traits<CGAL::Linear_cell_complex_for_combinatorial_map<...> >` \endlink
|
||||
- \link BGLSeam_meshGT `boost::graph_traits<CGAL::Seam_mesh<T> >` \endlink
|
||||
- \link BGLT2GT `boost::graph_traits<CGAL::Triangulation_2<GT, TDS> >` \endlink and other 2D triangulations
|
||||
- \link BGLArgtGT `boost::graph_traits<CGAL::Arrangement_2<T, DC> >` \endlink
|
||||
- \link BGLOMPAK `boost::graph_traits<OpenMesh::PolyMesh_ArrayKernelT<K> >` \endlink
|
||||
- \link BGLOMTMAK `boost::graph_traits<OpenMesh::TriMesh_ArrayKernelT<K> >` \endlink
|
||||
|
||||
@@ -643,6 +646,8 @@ user might encounter.
|
||||
- `CGAL::clear()`
|
||||
- `CGAL::copy_face_graph()`
|
||||
|
||||
- `CGAL::set_triangulation_ids()`
|
||||
|
||||
\cgalCRPSection{Iterators}
|
||||
- `CGAL::Halfedge_around_source_iterator`
|
||||
- `CGAL::Halfedge_around_target_iterator`
|
||||
|
||||
@@ -55,6 +55,7 @@ int main(int argc, char* argv[])
|
||||
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_output_iterator(std::inserter(v2v, v2v.end()))
|
||||
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end())));
|
||||
std::ofstream out("reverse.off");
|
||||
out.precision(17);
|
||||
out << S;
|
||||
}
|
||||
return 0;
|
||||
|
||||
@@ -43,6 +43,7 @@ int main(int argc, char* argv[])
|
||||
{
|
||||
CGAL::copy_face_graph(S, T1);
|
||||
std::ofstream out("sm.off");
|
||||
out.precision(17);
|
||||
out << T1;
|
||||
}
|
||||
|
||||
@@ -81,6 +82,7 @@ int main(int argc, char* argv[])
|
||||
boost::unordered_map<source_face_descriptor, tm_face_descriptor> f2f;
|
||||
CGAL::copy_face_graph(T1, S, std::inserter(v2v, v2v.end()), std::inserter(h2h, h2h.end()));
|
||||
std::ofstream out("reverse.off");
|
||||
out.precision(17);
|
||||
out << S;
|
||||
CGAL::copy_face_graph(T1, S, CGAL::parameters::vertex_to_vertex_map(boost::make_assoc_property_map(v2v))
|
||||
.halfedge_to_halfedge_output_iterator(std::inserter(h2h, h2h.end()))
|
||||
|
||||
@@ -20,6 +20,7 @@ int main()
|
||||
CGAL::make_quad(Point(0,0,1), Point(1,0,1),Point(1,1,1),Point(0,1,1), sm);
|
||||
|
||||
std::ofstream out("out.inp");
|
||||
out.precision(17);
|
||||
CGAL::write_inp(out, sm, "out.inp", "S4R");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -702,19 +702,35 @@ add_face(const VertexRange& vr, Graph& g)
|
||||
break;
|
||||
|
||||
case 3: // both are new
|
||||
if (halfedge(v, g) == boost::graph_traits<Graph>::null_halfedge())
|
||||
{
|
||||
set_halfedge(v, outer_prev, g);
|
||||
next_cache.push_back(NextCacheEntry(outer_prev, outer_next));
|
||||
// try to pick a border halfedge with v as target
|
||||
halfedge_descriptor hv = halfedge(v, g);
|
||||
if (hv != boost::graph_traits<Graph>::null_halfedge() && !is_border(hv, g))
|
||||
{
|
||||
for(halfedge_descriptor h_around_v : halfedges_around_target(hv, g))
|
||||
if (is_border(h_around_v, g))
|
||||
{
|
||||
hv = h_around_v;
|
||||
break;
|
||||
}
|
||||
if (!is_border(hv, g))
|
||||
hv = boost::graph_traits<Graph>::null_halfedge();
|
||||
}
|
||||
|
||||
if (hv == boost::graph_traits<Graph>::null_halfedge())
|
||||
{
|
||||
set_halfedge(v, outer_prev, g);
|
||||
next_cache.push_back(NextCacheEntry(outer_prev, outer_next));
|
||||
}
|
||||
else
|
||||
{
|
||||
border_prev = hv;
|
||||
border_next = next(border_prev, g);
|
||||
next_cache.push_back(NextCacheEntry(border_prev, outer_next));
|
||||
next_cache.push_back(NextCacheEntry(outer_prev, border_next));
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
border_prev = halfedge(v, g);
|
||||
border_next = next(border_prev, g);
|
||||
next_cache.push_back(NextCacheEntry(border_prev, outer_next));
|
||||
next_cache.push_back(NextCacheEntry(outer_prev, border_next));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// set inner link
|
||||
@@ -1323,7 +1339,7 @@ flip_edge(typename boost::graph_traits<Graph>::halfedge_descriptor h,
|
||||
template<typename Graph>
|
||||
bool
|
||||
does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||
Graph& g)
|
||||
const Graph& g)
|
||||
{
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||
@@ -1423,7 +1439,7 @@ does_satisfy_link_condition(typename boost::graph_traits<Graph>::edge_descriptor
|
||||
template<typename Graph>
|
||||
bool
|
||||
satisfies_link_condition(typename boost::graph_traits<Graph>::edge_descriptor e,
|
||||
Graph& g)
|
||||
const Graph& g)
|
||||
{
|
||||
return does_satisfy_link_condition(e, g);
|
||||
}
|
||||
|
||||
@@ -16,23 +16,24 @@
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/boost/graph/iterator.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
#include <CGAL/boost/graph/named_params_helper.h>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
#include <CGAL/assertions.h>
|
||||
#include <boost/unordered_set.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <CGAL/boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <CGAL/Default.h>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
|
||||
#include <boost/dynamic_bitset.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/iterator/filter_iterator.hpp>
|
||||
#include <boost/range/has_range_iterator.hpp>
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
#ifdef DOXYGEN_RUNNING
|
||||
#define CGAL_BGL_NP_TEMPLATE_PARAMETERS NamedParameters
|
||||
#define CGAL_BGL_NP_CLASS NamedParameters
|
||||
#endif
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
namespace CGAL {
|
||||
|
||||
/*!
|
||||
* \ingroup PkgBGLAdaptors
|
||||
@@ -62,18 +63,18 @@ namespace CGAL
|
||||
* missing if the default is fine.
|
||||
*
|
||||
* \tparam Graph must be a model of a `FaceListGraph`, `HalfedgeListGraph`, and \bgllink{VertexListGraph}.
|
||||
* \tparam FIMap a model of `ReadablePropertyMap` with `face_descriptor` as key and `graph_traits<Graph>::%faces_size_type` as value
|
||||
* \tparam VIMap a model of `ReadablePropertyMap` with `vertex_descriptor` as key and `graph_traits<Graph>::%vertices_size_type` as value
|
||||
* \tparam HIMap a model of `ReadablePropertyMap` with `halfedge_descriptor` as key and `graph_traits<Graph>::%halfedges_size_type` as value
|
||||
* \tparam FIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%face_descriptor` as key and `graph_traits<Graph>::%faces_size_type` as value
|
||||
* \tparam VIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%vertex_descriptor` as key and `graph_traits<Graph>::%vertices_size_type` as value
|
||||
* \tparam HIMap a model of `ReadablePropertyMap` with `graph_traits<Graph>::%halfedge_descriptor` as key and `graph_traits<Graph>::%halfedges_size_type` as value
|
||||
*
|
||||
* \cgalModels `FaceListGraph`
|
||||
* \cgalModels `HalfedgeListGraph`
|
||||
* \cgalModels \bgllink{VertexListGraph}
|
||||
*/
|
||||
template<typename Graph,
|
||||
typename FIMap = typename boost::property_map<Graph, CGAL::face_index_t>::type,
|
||||
typename VIMap = typename boost::property_map<Graph, boost::vertex_index_t>::type,
|
||||
typename HIMap = typename boost::property_map<Graph, CGAL::halfedge_index_t>::type>
|
||||
typename FIMap = Default,
|
||||
typename VIMap = Default,
|
||||
typename HIMap = Default>
|
||||
struct Face_filtered_graph
|
||||
{
|
||||
typedef boost::graph_traits<Graph> gt;
|
||||
@@ -93,10 +94,15 @@ struct Face_filtered_graph
|
||||
#endif
|
||||
|
||||
// non documented types
|
||||
typedef typename boost::property_traits< FIMap >::value_type face_index_type;
|
||||
typedef typename boost::property_traits< VIMap >::value_type vertex_index_type;
|
||||
typedef typename boost::property_traits< HIMap >::value_type halfedge_index_type;
|
||||
typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> Self;
|
||||
typedef typename Default::Get<FIMap, typename CGAL::GetInitializedFaceIndexMap<Graph>::const_type>::type FIM;
|
||||
typedef typename Default::Get<VIMap, typename CGAL::GetInitializedVertexIndexMap<Graph>::const_type>::type VIM;
|
||||
typedef typename Default::Get<HIMap, typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::const_type>::type HIM;
|
||||
|
||||
typedef typename boost::property_traits<FIM>::value_type face_index_type;
|
||||
typedef typename boost::property_traits<VIM>::value_type vertex_index_type;
|
||||
typedef typename boost::property_traits<HIM>::value_type halfedge_index_type;
|
||||
|
||||
typedef Face_filtered_graph<Graph, FIMap, VIMap, HIMap> Self;
|
||||
|
||||
/*!
|
||||
* \brief Constructor where the set of selected faces is specified as a range of patch ids.
|
||||
@@ -115,31 +121,31 @@ struct Face_filtered_graph
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{face_index_map}
|
||||
* a property map containing an index for each face initialized from 0 to `num_vertices(graph)`
|
||||
* a property map containing for each face of `graph` a unique index between `0` and `num_faces(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalParamBegin{vertex_index_map}
|
||||
* a property map containing an index for each vertex initialized 0 to `num_vertices(graph)`
|
||||
* a property map containing for each vertex of `graph` a unique index between `0` and `num_vertices(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalParamBegin{halfedge_index_map}
|
||||
* a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)`
|
||||
* a property map containing for each halfedge of `graph` a unique index between `0` and `num_halfedges(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*/
|
||||
template <typename FacePatchIndexMap, class FacePatchIndexRange, class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||
Face_filtered_graph(const Graph& graph,
|
||||
const FacePatchIndexRange& selected_face_patch_indices,
|
||||
FacePatchIndexMap face_patch_index_map,
|
||||
const CGAL_BGL_NP_CLASS& np
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, typename boost::enable_if<
|
||||
typename boost::has_range_const_iterator<FacePatchIndexRange>::type
|
||||
>::type* = 0
|
||||
#endif
|
||||
)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph)))
|
||||
, vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph)))
|
||||
, himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph)))
|
||||
FacePatchIndexMap face_patch_index_map,
|
||||
const CGAL_BGL_NP_CLASS& np
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, typename boost::enable_if<
|
||||
typename boost::has_range_const_iterator<FacePatchIndexRange>::type
|
||||
>::type* = 0
|
||||
#endif
|
||||
)
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph, np)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph, np)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph, np))
|
||||
{
|
||||
set_selected_faces(selected_face_patch_indices, face_patch_index_map);
|
||||
}
|
||||
@@ -152,10 +158,10 @@ struct Face_filtered_graph
|
||||
typename boost::has_range_const_iterator<FacePatchIndexRange>::type
|
||||
>::type* = 0
|
||||
)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(get(CGAL::face_index, graph))
|
||||
, vimap(get(boost::vertex_index, graph))
|
||||
, himap(get(CGAL::halfedge_index, graph))
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph))
|
||||
{
|
||||
set_selected_faces(selected_face_patch_indices, face_patch_index_map);
|
||||
}
|
||||
@@ -175,38 +181,37 @@ struct Face_filtered_graph
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{face_index_map}
|
||||
* a property map containing an index for each face initialized from 0 to `num_vertices(graph)`
|
||||
* a property map containing for each face of `graph` a unique index between `0` and `num_faces(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalParamBegin{vertex_index_map}
|
||||
* a property map containing an index for each vertex initialized 0 to `num_vertices(graph)`
|
||||
* a property map containing for each vertex of `graph` a unique index between `0` and `num_vertices(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalParamBegin{halfedge_index_map}
|
||||
* a property map containing an index for each halfedge initialized 0 to `num_halfedges(graph)`
|
||||
* a property map containing for each halfedge of `graph` a unique index between `0` and `num_halfedges(graph)-1`
|
||||
* \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*/
|
||||
template <typename FacePatchIndexMap, class CGAL_BGL_NP_TEMPLATE_PARAMETERS>
|
||||
Face_filtered_graph(const Graph& graph,
|
||||
typename boost::property_traits<FacePatchIndexMap>::value_type selected_face_patch_index,
|
||||
FacePatchIndexMap face_patch_index_map,
|
||||
const CGAL_BGL_NP_CLASS& np
|
||||
)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph)))
|
||||
, vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph)))
|
||||
, himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph)))
|
||||
typename boost::property_traits<FacePatchIndexMap>::value_type selected_face_patch_index,
|
||||
FacePatchIndexMap face_patch_index_map,
|
||||
const CGAL_BGL_NP_CLASS& np)
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph, np)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph, np)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph, np))
|
||||
{
|
||||
set_selected_faces(selected_face_patch_index, face_patch_index_map);
|
||||
}
|
||||
|
||||
template <typename FacePatchIndexMap>
|
||||
Face_filtered_graph(const Graph& graph,
|
||||
typename boost::property_traits<FacePatchIndexMap>::value_type pid,
|
||||
FacePatchIndexMap face_patch_index_map)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(get(CGAL::face_index, graph))
|
||||
, vimap(get(boost::vertex_index, graph))
|
||||
, himap(get(CGAL::halfedge_index, graph))
|
||||
typename boost::property_traits<FacePatchIndexMap>::value_type pid,
|
||||
FacePatchIndexMap face_patch_index_map)
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph))
|
||||
{
|
||||
set_selected_faces(pid, face_patch_index_map);
|
||||
}
|
||||
@@ -236,10 +241,10 @@ struct Face_filtered_graph
|
||||
Face_filtered_graph(const Graph& graph,
|
||||
const FaceRange& selected_faces,
|
||||
const CGAL_BGL_NP_CLASS& np)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::face_index), get_const_property_map(face_index, graph)))
|
||||
, vimap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::vertex_index), get_const_property_map(boost::vertex_index, graph)))
|
||||
, himap(parameters::choose_parameter(parameters::get_parameter(np, internal_np::halfedge_index), get_const_property_map(halfedge_index, graph)))
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph, np)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph, np)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph, np))
|
||||
{
|
||||
set_selected_faces(selected_faces);
|
||||
}
|
||||
@@ -247,10 +252,10 @@ struct Face_filtered_graph
|
||||
template <typename FaceRange>
|
||||
Face_filtered_graph(const Graph& graph,
|
||||
const FaceRange& selected_faces)
|
||||
: _graph(const_cast<Graph&>(graph))
|
||||
, fimap(get(CGAL::face_index, graph))
|
||||
, vimap(get(boost::vertex_index, graph))
|
||||
, himap(get(CGAL::halfedge_index, graph))
|
||||
: _graph(const_cast<Graph&>(graph)),
|
||||
fimap(CGAL::get_initialized_face_index_map(graph)),
|
||||
vimap(CGAL::get_initialized_vertex_index_map(graph)),
|
||||
himap(CGAL::get_initialized_halfedge_index_map(graph))
|
||||
{
|
||||
set_selected_faces(selected_faces);
|
||||
}
|
||||
@@ -293,12 +298,12 @@ struct Face_filtered_graph
|
||||
template<class FacePatchIndexRange, class FacePatchIndexMap>
|
||||
void set_selected_faces(const FacePatchIndexRange& selected_face_patch_indices,
|
||||
FacePatchIndexMap face_patch_index_map
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
, typename boost::enable_if<
|
||||
typename boost::has_range_const_iterator<FacePatchIndexRange>::type
|
||||
>::type* = 0
|
||||
#endif
|
||||
)
|
||||
#endif
|
||||
)
|
||||
{
|
||||
face_indices.clear();
|
||||
vertex_indices.clear();
|
||||
@@ -407,7 +412,7 @@ struct Face_filtered_graph
|
||||
return selected_halfedges.count();
|
||||
}
|
||||
|
||||
Property_map_binder< FIMap, typename Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type >
|
||||
Property_map_binder<FIM, typename Pointer_property_map<typename boost::property_traits<FIM>::value_type>::type>
|
||||
get_face_index_map() const
|
||||
{
|
||||
if (face_indices.empty())
|
||||
@@ -422,7 +427,7 @@ struct Face_filtered_graph
|
||||
return bind_property_maps(fimap, make_property_map(face_indices) );
|
||||
}
|
||||
|
||||
Property_map_binder< VIMap, typename Pointer_property_map< typename boost::property_traits< VIMap >::value_type >::type >
|
||||
Property_map_binder<VIM, typename Pointer_property_map<typename boost::property_traits<VIM>::value_type>::type>
|
||||
get_vertex_index_map() const
|
||||
{
|
||||
if (vertex_indices.empty())
|
||||
@@ -437,7 +442,7 @@ struct Face_filtered_graph
|
||||
return bind_property_maps(vimap, make_property_map(vertex_indices) );
|
||||
}
|
||||
|
||||
Property_map_binder< HIMap, typename Pointer_property_map< typename boost::property_traits< HIMap >::value_type >::type >
|
||||
Property_map_binder<HIM, typename Pointer_property_map<typename boost::property_traits<HIM>::value_type >::type>
|
||||
get_halfedge_index_map() const
|
||||
{
|
||||
if (halfedge_indices.empty())
|
||||
@@ -510,9 +515,9 @@ struct Face_filtered_graph
|
||||
|
||||
private:
|
||||
Graph& _graph;
|
||||
FIMap fimap;
|
||||
VIMap vimap;
|
||||
HIMap himap;
|
||||
FIM fimap;
|
||||
VIM vimap;
|
||||
HIM himap;
|
||||
boost::dynamic_bitset<> selected_faces;
|
||||
boost::dynamic_bitset<> selected_vertices;
|
||||
boost::dynamic_bitset<> selected_halfedges;
|
||||
@@ -1142,38 +1147,40 @@ CGAL_FILTERED_FACE_GRAPH_DYNAMIC_PMAP_SPECIALIZATION(dynamic_face_property_t)
|
||||
|
||||
#undef CGAL_FILTERED_FACE_GRAPH_DYNAMIC_PMAP_SPECIALIZATION
|
||||
|
||||
|
||||
|
||||
//specializations for indices
|
||||
template<typename Graph,
|
||||
typename FIMap,
|
||||
typename VIMap,
|
||||
typename HIMap>
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::face_index_t>{
|
||||
typedef typename CGAL::Property_map_binder< FIMap,
|
||||
typename CGAL::Pointer_property_map< typename boost::property_traits< FIMap >::value_type >::type > type;
|
||||
typedef type const_type;
|
||||
template<typename Graph, typename FIMap, typename VIMap, typename HIMap>
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::face_index_t>
|
||||
{
|
||||
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::FIM FIM;
|
||||
typedef typename CGAL::Property_map_binder<FIM,
|
||||
typename CGAL::Pointer_property_map<
|
||||
typename boost::property_traits<FIM>::value_type>::type> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<typename Graph, typename FIMap, typename VIMap, typename HIMap>
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t>
|
||||
{
|
||||
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::VIM VIM;
|
||||
typedef typename CGAL::Property_map_binder<VIM,
|
||||
typename CGAL::Pointer_property_map<
|
||||
typename boost::property_traits<VIM>::value_type>::type> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<typename Graph,
|
||||
typename FIMap,
|
||||
typename VIMap,
|
||||
typename HIMap>
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, boost::vertex_index_t>{
|
||||
typedef typename CGAL::Property_map_binder< VIMap,
|
||||
typename CGAL::Pointer_property_map< typename boost::property_traits< VIMap >::value_type >::type > type;
|
||||
typedef type const_type;
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::halfedge_index_t>
|
||||
{
|
||||
typedef typename CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>::HIM HIM;
|
||||
typedef typename CGAL::Property_map_binder<HIM,
|
||||
typename CGAL::Pointer_property_map<
|
||||
typename boost::property_traits<HIM>::value_type>::type> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template<typename Graph,
|
||||
typename FIMap,
|
||||
typename VIMap,
|
||||
typename HIMap>
|
||||
} // namespace boost
|
||||
|
||||
struct property_map<CGAL::Face_filtered_graph<Graph, FIMap, VIMap, HIMap>, CGAL::halfedge_index_t>{
|
||||
typedef typename CGAL::Property_map_binder< HIMap,
|
||||
typename CGAL::Pointer_property_map< typename boost::property_traits< HIMap >::value_type >::type > type;
|
||||
typedef type const_type;
|
||||
};
|
||||
}// namespace boost
|
||||
#endif // CGAL_BOOST_GRAPH_FACE_FILTERED_GRAPH_H
|
||||
|
||||
@@ -42,17 +42,14 @@ void partition_dual_graph(const TriangleMesh& tm,
|
||||
CGAL_precondition(CGAL::is_triangle_mesh(tm));
|
||||
CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1"));
|
||||
|
||||
using parameters::choose_parameter;
|
||||
using parameters::get_parameter;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
|
||||
// vertex index map
|
||||
typedef typename CGAL::GetVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
|
||||
Indices indices = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||
get_const_property_map(boost::vertex_index, tm));
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
|
||||
Indices indices = CGAL::get_initialized_vertex_index_map(tm, np);
|
||||
|
||||
idx_t nn = static_cast<idx_t>(num_vertices(tm));
|
||||
idx_t ne = static_cast<idx_t>(num_faces(tm));
|
||||
@@ -136,9 +133,6 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts,
|
||||
/// based on the mesh's dual graph. The resulting partition is stored in the vertex and/or face
|
||||
/// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters".
|
||||
///
|
||||
/// Property map for `CGAL::vertex_index_t` should be either available
|
||||
/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters".
|
||||
///
|
||||
/// \param tm a triangle mesh
|
||||
/// \param nparts the number of parts in the final partition
|
||||
/// \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
@@ -148,7 +142,7 @@ void partition_dual_graph(const TriangleMesh& tm, int nparts,
|
||||
///
|
||||
/// \cgalNamedParamsBegin
|
||||
/// \cgalParamBegin{vertex_index_map}
|
||||
/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`.
|
||||
/// is a property map containing for each vertex of `tm` a unique index between `0` and `num_vertices(tm)-1`.
|
||||
/// \cgalParamEnd
|
||||
/// \cgalParamBegin{METIS_options}
|
||||
/// is a parameter used in to pass options to the METIS mesh
|
||||
|
||||
@@ -77,17 +77,14 @@ void partition_graph(const TriangleMesh& tm,
|
||||
CGAL_precondition(CGAL::is_triangle_mesh(tm));
|
||||
CGAL_precondition_msg(nparts > 1, ("Partitioning requires a number of parts > 1"));
|
||||
|
||||
using parameters::choose_parameter;
|
||||
using parameters::get_parameter;
|
||||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_iterator face_iterator;
|
||||
|
||||
//Vertex index map
|
||||
typedef typename CGAL::GetVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
|
||||
Indices indices = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||
get_const_property_map(boost::vertex_index, tm));
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<TriangleMesh, NamedParameters>::type Indices;
|
||||
Indices indices = CGAL::get_initialized_vertex_index_map(tm, np);
|
||||
|
||||
idx_t nn = static_cast<idx_t>(num_vertices(tm));
|
||||
idx_t ne = static_cast<idx_t>(num_faces(tm));
|
||||
@@ -168,9 +165,6 @@ void partition_graph(const TriangleMesh& tm, int nparts,
|
||||
/// mesh's nodal graph. The resulting partition is stored in the vertex and/or face
|
||||
/// property maps that are passed as parameters using \ref bgl_namedparameters "Named Parameters".
|
||||
///
|
||||
/// Property map for `CGAL::vertex_index_t` should be either available
|
||||
/// as an internal property map to `tm` or provided as \ref bgl_namedparameters "Named Parameters".
|
||||
///
|
||||
/// \param tm a triangle mesh
|
||||
/// \param nparts the number of parts in the final partition
|
||||
/// \param np optional \ref bgl_namedparameters "Named Parameters" described below
|
||||
@@ -180,7 +174,7 @@ void partition_graph(const TriangleMesh& tm, int nparts,
|
||||
///
|
||||
/// \cgalNamedParamsBegin
|
||||
/// \cgalParamBegin{vertex_index_map}
|
||||
/// is a property map containing the index of each vertex of `tm` intialized from `0` to `num_vertices(tm)-1`.
|
||||
/// is a property map containing for each vertex of `tm` a unique index between `0` and `num_vertices(tm)-1`.
|
||||
/// \cgalParamEnd
|
||||
/// \cgalParamBegin{METIS_options}
|
||||
/// is a parameter used in to pass options to the METIS mesh
|
||||
|
||||
@@ -194,6 +194,20 @@ get_parameter(const Named_function_parameters<T, Tag, Base>& np, Query_tag tag)
|
||||
return internal_np::get_parameter_impl(static_cast<const internal_np::Named_params_impl<T, Tag, Base>&>(np), tag);
|
||||
}
|
||||
|
||||
// single parameter so that we can avoid a default construction
|
||||
template <typename D>
|
||||
D choose_parameter(const internal_np::Param_not_found&)
|
||||
{
|
||||
return D();
|
||||
}
|
||||
|
||||
template <typename D, typename T>
|
||||
const T& choose_parameter(const T& t)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
// Two parameters, non-trivial default value
|
||||
template <typename D>
|
||||
D choose_parameter(const internal_np::Param_not_found&, const D& d)
|
||||
{
|
||||
@@ -201,8 +215,7 @@ D choose_parameter(const internal_np::Param_not_found&, const D& d)
|
||||
}
|
||||
|
||||
template <typename T, typename D>
|
||||
const T&
|
||||
choose_parameter(const T& t, const D&)
|
||||
const T& choose_parameter(const T& t, const D&)
|
||||
{
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -124,8 +124,8 @@ public:
|
||||
/// The type for the objects used to identify halfedges in the underlying mesh.
|
||||
typedef typename boost::graph_traits<TM>::halfedge_descriptor TM_halfedge_descriptor;
|
||||
|
||||
/// The type for the iterators that traverse through the complete halfedge set of the underlying mesh.
|
||||
typedef typename boost::graph_traits<TM>::halfedge_iterator TM_halfedge_iterator;
|
||||
/// The type for the iterators that traverse through the complete halfedge set of the underlying mesh.
|
||||
typedef typename boost::graph_traits<TM>::halfedge_iterator TM_halfedge_iterator;
|
||||
|
||||
/// The type for the objects used to identify edges in the underlying mesh.
|
||||
typedef typename boost::graph_traits<TM>::edge_descriptor TM_edge_descriptor;
|
||||
@@ -439,6 +439,11 @@ public:
|
||||
{
|
||||
return ! (e1 == e2);
|
||||
}
|
||||
|
||||
friend std::size_t hash_value(const edge_descriptor& ed)
|
||||
{
|
||||
return hash_value((std::min)(ed.hd, ed.mesh_->opposite(ed.hd)));
|
||||
}
|
||||
};
|
||||
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
|
||||
@@ -199,13 +199,8 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
||||
typedef typename boost::graph_traits<TargetMesh>::halfedge_descriptor tm_halfedge_descriptor;
|
||||
std::vector<tm_halfedge_descriptor> hedges(num_halfedges(sm));
|
||||
|
||||
// init halfedge index map
|
||||
/// \TODO shall we keep that?
|
||||
helpers::init_halfedge_indices(const_cast<SourceMesh&>(sm),
|
||||
get(boost::halfedge_index, sm));
|
||||
|
||||
copy_face_graph_impl(sm, tm,
|
||||
bind_property_maps(get(boost::halfedge_index, sm),
|
||||
bind_property_maps(get_initialized_halfedge_index_map(sm),
|
||||
make_property_map(hedges)),
|
||||
v2v, h2h, f2f,
|
||||
sm_vpm, tm_vpm);
|
||||
@@ -333,18 +328,19 @@ void copy_face_graph(const SourceMesh& sm, TargetMesh& tm,
|
||||
{
|
||||
using parameters::choose_parameter;
|
||||
using parameters::get_parameter;
|
||||
|
||||
internal::copy_face_graph(sm, tm,
|
||||
CGAL::graph_has_property<SourceMesh,boost::halfedge_index_t>(),
|
||||
choose_parameter(get_parameter(np1, internal_np::vertex_to_vertex_output_iterator),
|
||||
impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))),
|
||||
impl::make_functor(get_parameter(np1, internal_np::vertex_to_vertex_map))),
|
||||
choose_parameter(get_parameter(np1, internal_np::halfedge_to_halfedge_output_iterator),
|
||||
impl::make_functor(get_parameter(np1, internal_np::halfedge_to_halfedge_map))),
|
||||
impl::make_functor(get_parameter(np1, internal_np::halfedge_to_halfedge_map))),
|
||||
choose_parameter(get_parameter(np1, internal_np::face_to_face_output_iterator),
|
||||
impl::make_functor(get_parameter(np1, internal_np::face_to_face_map))),
|
||||
impl::make_functor(get_parameter(np1, internal_np::face_to_face_map))),
|
||||
choose_parameter(get_parameter(np1, internal_np::vertex_point),
|
||||
get(vertex_point, sm)),
|
||||
get(vertex_point, sm)),
|
||||
choose_parameter(get_parameter(np2, internal_np::vertex_point),
|
||||
get(vertex_point, tm)));
|
||||
get(vertex_point, tm)));
|
||||
}
|
||||
|
||||
template <typename SourceMesh, typename TargetMesh>
|
||||
|
||||
@@ -0,0 +1,307 @@
|
||||
// Copyright (c) 2020 GeometryFactory (France). 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) : Mael Rouxel-Labbé
|
||||
// Maxime Gimeno
|
||||
|
||||
#ifndef CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS
|
||||
#define CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS
|
||||
|
||||
#include <CGAL/assertions.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
#include <CGAL/use.h>
|
||||
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
|
||||
namespace CGAL {
|
||||
namespace BGL {
|
||||
namespace internal {
|
||||
|
||||
// Check that an index map has been correctly initialized
|
||||
template <typename DescriptorRange, typename IndexMap>
|
||||
bool is_index_map_valid(IndexMap idmap,
|
||||
const std::size_t num_simplices,
|
||||
const DescriptorRange& range)
|
||||
{
|
||||
typedef typename boost::property_traits<IndexMap>::value_type Id_type;
|
||||
|
||||
Id_type max_id = static_cast<Id_type>(num_simplices);
|
||||
std::vector<bool> indices(max_id);
|
||||
for(const auto& d : range)
|
||||
{
|
||||
const Id_type id = get(idmap, d);
|
||||
if(id >= 0 && id < max_id && !indices[id])
|
||||
{
|
||||
indices[id] = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef CGAL_BGL_INDEX_MAP_DEBUG
|
||||
std::cerr << "Invalid ID: " << id << " num_simplices: " << num_simplices << std::endl;
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename VertexIndexPropertyMap, typename Graph>
|
||||
bool is_index_map_valid(const CGAL::internal_np::vertex_index_t, VertexIndexPropertyMap vertex_index_map, const Graph& g)
|
||||
{
|
||||
return is_index_map_valid(vertex_index_map, num_vertices(g), vertices(g));
|
||||
}
|
||||
|
||||
template <typename HalfedgeIndexPropertyMap, typename Graph>
|
||||
bool is_index_map_valid(const CGAL::internal_np::halfedge_index_t, HalfedgeIndexPropertyMap halfedge_index_map, const Graph& g)
|
||||
{
|
||||
return is_index_map_valid(halfedge_index_map, num_halfedges(g), halfedges(g));
|
||||
}
|
||||
|
||||
template <typename EdgeIndexPropertyMap, typename Graph>
|
||||
bool is_index_map_valid(const CGAL::internal_np::edge_index_t, EdgeIndexPropertyMap edge_index_map, const Graph& g)
|
||||
{
|
||||
return is_index_map_valid(edge_index_map, num_edges(g), edges(g));
|
||||
}
|
||||
|
||||
template <typename FaceIndexPropertyMap, typename Graph>
|
||||
bool is_index_map_valid(const CGAL::internal_np::face_index_t, FaceIndexPropertyMap face_index_map, const Graph& g)
|
||||
{
|
||||
return is_index_map_valid(face_index_map, num_faces(g), faces(g));
|
||||
}
|
||||
|
||||
template <typename PropertyTag, typename IndexPropertyMap, typename Graph>
|
||||
void initialize_index_map(const PropertyTag, IndexPropertyMap, const Graph&)
|
||||
{
|
||||
// Unknown parameter; should never be here.
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
|
||||
template <typename IndexPropertyMap,
|
||||
typename Graph,
|
||||
bool is_writable = CGAL::internal::Is_writable_property_map<IndexPropertyMap>::value>
|
||||
struct Index_map_initializer
|
||||
{
|
||||
void operator()(const CGAL::internal_np::vertex_index_t, IndexPropertyMap vertex_index_map, const Graph& g)
|
||||
{
|
||||
typename boost::property_traits<IndexPropertyMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<Graph>::vertex_descriptor vd : vertices(g))
|
||||
put(vertex_index_map, vd, i++);
|
||||
}
|
||||
|
||||
void operator()(const CGAL::internal_np::halfedge_index_t, IndexPropertyMap halfedge_index_map, const Graph& g)
|
||||
{
|
||||
typename boost::property_traits<IndexPropertyMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<Graph>::halfedge_descriptor hd : halfedges(g))
|
||||
put(halfedge_index_map, hd, i++);
|
||||
}
|
||||
|
||||
void operator()(const CGAL::internal_np::edge_index_t, IndexPropertyMap edge_index_map, const Graph& g)
|
||||
{
|
||||
typename boost::property_traits<IndexPropertyMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<Graph>::edge_descriptor ed : edges(g))
|
||||
put(edge_index_map, ed, i++);
|
||||
}
|
||||
|
||||
void operator()(const CGAL::internal_np::face_index_t, IndexPropertyMap face_index_map, const Graph& g)
|
||||
{
|
||||
typename boost::property_traits<IndexPropertyMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<Graph>::face_descriptor fd : faces(g))
|
||||
put(face_index_map, fd, i++);
|
||||
}
|
||||
|
||||
template <typename PropertyTag>
|
||||
void operator()(const PropertyTag, IndexPropertyMap, const Graph&)
|
||||
{
|
||||
// Unknown parameter; should never be here.
|
||||
CGAL_assertion(false);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename IndexPropertyMap, typename Graph>
|
||||
struct Index_map_initializer<IndexPropertyMap, Graph, false>
|
||||
{
|
||||
template <typename PropertyTag>
|
||||
void operator()(const PropertyTag, IndexPropertyMap, const Graph&)
|
||||
{
|
||||
// The property map is not writable; should never be here.
|
||||
CGAL_assertion_msg(false, "You are trying to initialize a non-writable property map");
|
||||
}
|
||||
};
|
||||
|
||||
// Just for convenience, define the following functions:
|
||||
//
|
||||
// BGL::internal::initialize_vertex_index_map()
|
||||
// BGL::internal::initialize_halfedge_index_map()
|
||||
// BGL::internal::initialize_edge_index_map()
|
||||
// BGL::internal::initialize_face_index_map()
|
||||
|
||||
#define CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(TYPE) \
|
||||
template <typename WritableIndexPropertyMap, typename Graph> \
|
||||
void initialize_##TYPE##_index_map(WritableIndexPropertyMap index_map, \
|
||||
const Graph& g) \
|
||||
{ \
|
||||
Index_map_initializer<WritableIndexPropertyMap, Graph> initializer; \
|
||||
initializer(CGAL::internal_np::TYPE##_index_t{}, index_map, g); \
|
||||
}
|
||||
|
||||
CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(vertex)
|
||||
CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(halfedge)
|
||||
CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(edge)
|
||||
CGAL_DEF_INITIALIZE_ID_MAP_FUNCTION(face)
|
||||
|
||||
#undef CGAL_DEF_INITIALIZE_ID_FUCNTION
|
||||
|
||||
// Using the pmap passed in named parameters -------------------------------------------------------
|
||||
template <typename IndexMap, typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
|
||||
IndexMap get_initialized_index_map_const(const IndexMap index_map,
|
||||
const PropertyTag p, Tag, DynamicTag,
|
||||
const Graph& g)
|
||||
{
|
||||
CGAL_USE(g);
|
||||
CGAL_USE(p);
|
||||
|
||||
// If you are passing a pmap via NPs, it must be initialized
|
||||
CGAL_assertion(is_index_map_valid(p, index_map, g));
|
||||
|
||||
return index_map;
|
||||
}
|
||||
|
||||
template <typename IndexMap, typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
|
||||
IndexMap get_initialized_index_map(const IndexMap index_map,
|
||||
const PropertyTag p, Tag, DynamicTag,
|
||||
Graph& g)
|
||||
{
|
||||
CGAL_USE(g);
|
||||
CGAL_USE(p);
|
||||
|
||||
// If you are passing a pmap via NPs, it must be initialized
|
||||
CGAL_assertion(is_index_map_valid(p, index_map, g));
|
||||
|
||||
return index_map;
|
||||
}
|
||||
|
||||
// Using the internal to the mesh ------------------------------------------------------------------
|
||||
template <typename InternalIndexMap, typename PropertyTag, typename Graph>
|
||||
InternalIndexMap
|
||||
get_initialized_internal_index_map(InternalIndexMap index_map,
|
||||
const PropertyTag p,
|
||||
const Graph& g)
|
||||
{
|
||||
if(CGAL::internal::Is_writable_property_map<InternalIndexMap>::value)
|
||||
{
|
||||
if(!is_index_map_valid(p, index_map, g))
|
||||
Index_map_initializer<InternalIndexMap, Graph>{}(p, index_map, g);
|
||||
}
|
||||
else // not writable
|
||||
{
|
||||
CGAL_assertion(is_index_map_valid(p, index_map, g));
|
||||
}
|
||||
|
||||
return index_map;
|
||||
}
|
||||
|
||||
template <typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
|
||||
typename boost::property_map<Graph, Tag>::const_type
|
||||
get_initialized_index_map_const(CGAL::internal_np::Param_not_found,
|
||||
const PropertyTag p, const Tag tag, DynamicTag,
|
||||
const Graph& g)
|
||||
{
|
||||
return get_initialized_internal_index_map(get(tag, g), p, g);
|
||||
}
|
||||
|
||||
// same as above, non-const graph overload
|
||||
template <typename PropertyTag, typename Tag, typename DynamicTag, typename Graph>
|
||||
typename boost::property_map<Graph, Tag>::type
|
||||
get_initialized_index_map(CGAL::internal_np::Param_not_found,
|
||||
const PropertyTag p, const Tag tag, DynamicTag,
|
||||
Graph& g)
|
||||
{
|
||||
// From now on the correct property map has been acquired
|
||||
// and there is no need to distinguish between const and non-const mesh
|
||||
return get_initialized_internal_index_map(get(tag, g), p, g);
|
||||
}
|
||||
|
||||
// Create a dynamic property and initialize it -----------------------------------------------------
|
||||
template <typename DynamicIndexMap, typename PropertyTag, typename Graph>
|
||||
DynamicIndexMap
|
||||
get_initialized_dynamic_index_map(DynamicIndexMap index_map,
|
||||
const PropertyTag p,
|
||||
const Graph& g)
|
||||
{
|
||||
#ifdef CGAL_PERFORMANCE_WARNINGS
|
||||
std::cerr << "Warning: the automatically selected index map is a dynamic property map,"
|
||||
<< " which might not have constant-time access complexity." << std::endl;
|
||||
#endif
|
||||
|
||||
Index_map_initializer<DynamicIndexMap, Graph>{}(p, index_map, g);
|
||||
return index_map;
|
||||
}
|
||||
|
||||
template <typename PropertyTag, typename DynamicTag, typename Graph>
|
||||
typename boost::property_map<Graph, DynamicTag>::const_type
|
||||
get_initialized_index_map_const(CGAL::internal_np::Param_not_found,
|
||||
const PropertyTag p, const DynamicTag dtag, DynamicTag,
|
||||
const Graph& g)
|
||||
{
|
||||
return get_initialized_dynamic_index_map(get(dtag, g), p, g);
|
||||
}
|
||||
|
||||
// same as above, non-const graph overload
|
||||
template <typename PropertyTag, typename DynamicTag, typename Graph>
|
||||
typename boost::property_map<Graph, DynamicTag>::type
|
||||
get_initialized_index_map(CGAL::internal_np::Param_not_found,
|
||||
const PropertyTag p, const DynamicTag dtag, DynamicTag,
|
||||
Graph& g)
|
||||
{
|
||||
// From now on the correct property map has been acquired
|
||||
// and there is no need to distinguish between const and non-const mesh
|
||||
return get_initialized_dynamic_index_map(get(dtag, g), p, g);
|
||||
}
|
||||
|
||||
template <typename PropertyTag, typename Tag, typename DynamicTag,
|
||||
typename Graph,
|
||||
typename NamedParameters = Named_function_parameters<bool, internal_np::all_default_t> >
|
||||
class GetInitializedIndexMap
|
||||
{
|
||||
public:
|
||||
// Check if there is an internal property map; if not, we must a dynamic property map
|
||||
typedef typename boost::mpl::if_c<
|
||||
CGAL::graph_has_property<Graph, Tag>::value, Tag, DynamicTag>::type Final_tag;
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
PropertyTag,
|
||||
NamedParameters,
|
||||
typename boost::property_map<Graph, Final_tag>::const_type>::type const_type;
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
PropertyTag,
|
||||
NamedParameters,
|
||||
typename boost::property_map<Graph, Final_tag>::type>::type type;
|
||||
|
||||
static const_type get_const(const PropertyTag p, const Graph& g, const NamedParameters& np)
|
||||
{
|
||||
return BGL::internal::get_initialized_index_map_const(parameters::get_parameter(np, p),
|
||||
p, Final_tag{}, DynamicTag{}, g);
|
||||
}
|
||||
|
||||
static type get(const PropertyTag p, Graph& g, const NamedParameters& np)
|
||||
{
|
||||
return BGL::internal::get_initialized_index_map(parameters::get_parameter(np, p),
|
||||
p, Final_tag{}, DynamicTag{}, g);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
} // namespace BGL
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_BOOST_GRAPH_INITIALIZED_INTERNAL_INDEX_MAPS_HELPERS
|
||||
@@ -417,13 +417,9 @@ write_polys(std::ostream& os,
|
||||
{
|
||||
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Mesh>::face_iterator face_iterator;
|
||||
typedef typename CGAL::GetVertexIndexMap<Mesh, NamedParameters>::type Vimap;
|
||||
|
||||
using parameters::get_parameter;
|
||||
using parameters::choose_parameter;
|
||||
|
||||
Vimap V = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||
get_const_property_map(boost::vertex_index, mesh));
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Mesh, NamedParameters>::const_type Vimap;
|
||||
Vimap V = CGAL::get_initialized_vertex_index_map(mesh, np);
|
||||
|
||||
std::vector<std::size_t> connectivity_table;
|
||||
std::vector<std::size_t> offsets;
|
||||
@@ -456,13 +452,9 @@ write_polys_tag(std::ostream& os,
|
||||
{
|
||||
typedef typename boost::graph_traits<Mesh>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Mesh>::face_iterator face_iterator;
|
||||
typedef typename CGAL::GetVertexIndexMap<Mesh, NamedParameters>::type Vimap;
|
||||
|
||||
using parameters::get_parameter;
|
||||
using parameters::choose_parameter;
|
||||
|
||||
Vimap V = choose_parameter(get_parameter(np, internal_np::vertex_index),
|
||||
get_const_property_map(boost::vertex_index, mesh));
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Mesh, NamedParameters>::const_type Vimap;
|
||||
Vimap V = CGAL::get_initialized_vertex_index_map(mesh, np);
|
||||
|
||||
std::string formatattribute =
|
||||
binary ? " format=\"appended\"" : " format=\"ascii\"";
|
||||
@@ -638,8 +630,7 @@ write_polys_points(std::ostream& os,
|
||||
* `CGAL::vertex_point_t` must be available in `TriangleMesh`.
|
||||
* \cgalParamEnd
|
||||
* \cgalParamBegin{vertex_index_map} the property map with the indices associated to
|
||||
* the vertices of `mesh`. If this parameter is omitted, an internal property map for
|
||||
* `CGAL::vertex_index_t` must be available in `TriangleMesh`.
|
||||
* the vertices of `mesh`.
|
||||
* \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
*/
|
||||
|
||||
@@ -19,18 +19,19 @@
|
||||
#ifndef CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
|
||||
#define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
|
||||
|
||||
#include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
|
||||
#include <CGAL/boost/graph/Named_function_parameters.h>
|
||||
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
#include <CGAL/Kernel_traits.h>
|
||||
#include <CGAL/Origin.h>
|
||||
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/boost/graph/properties.h>
|
||||
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/has_xxx.hpp>
|
||||
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
@@ -41,8 +42,8 @@ namespace CGAL {
|
||||
class Lapack_svd;
|
||||
struct Alpha_expansion_boost_adjacency_list_tag;
|
||||
//
|
||||
|
||||
|
||||
|
||||
|
||||
//helper classes
|
||||
template<typename PolygonMesh, typename PropertyTag>
|
||||
class property_map_selector
|
||||
@@ -105,7 +106,8 @@ namespace CGAL {
|
||||
property_map_selector<PolygonMesh, PropertyTag> pms;
|
||||
return pms.get_const_pmap(p, pmesh);
|
||||
}
|
||||
// shortcut for accessing the value type of the property map
|
||||
|
||||
// Shortcut for accessing the value type of the property map
|
||||
template <class Graph, class Property>
|
||||
class property_map_value {
|
||||
typedef typename boost::property_map<Graph, Property>::const_type PMap;
|
||||
@@ -113,7 +115,8 @@ namespace CGAL {
|
||||
typedef typename boost::property_traits<PMap>::value_type type;
|
||||
};
|
||||
|
||||
template<typename PolygonMesh, typename NamedParameters>
|
||||
template<typename PolygonMesh,
|
||||
typename NamedParameters = Named_function_parameters<bool, internal_np::all_default_t> >
|
||||
class GetVertexPointMap
|
||||
{
|
||||
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::const_type
|
||||
@@ -175,37 +178,105 @@ namespace CGAL {
|
||||
> ::type type;
|
||||
};
|
||||
|
||||
template<typename PolygonMesh, typename NamedParameters>
|
||||
class GetFaceIndexMap
|
||||
{
|
||||
typedef typename property_map_selector<PolygonMesh, boost::face_index_t>::type DefaultMap;
|
||||
typedef typename property_map_selector<PolygonMesh, boost::face_index_t>::const_type DefaultMap_const;
|
||||
public:
|
||||
typedef typename internal_np::Lookup_named_param_def <
|
||||
internal_np::face_index_t,
|
||||
NamedParameters,
|
||||
DefaultMap
|
||||
> ::type type;
|
||||
typedef typename internal_np::Lookup_named_param_def <
|
||||
internal_np::face_index_t,
|
||||
NamedParameters,
|
||||
DefaultMap_const
|
||||
> ::type const_type;
|
||||
typedef typename boost::is_same<type, DefaultMap>::type Is_internal_map;
|
||||
typedef typename boost::is_same<const_type, DefaultMap_const>::type Is_internal_map_const;
|
||||
};
|
||||
// Define the following structs:
|
||||
//
|
||||
// GetInitializedVertexIndexMap
|
||||
// GetInitializedHalfedgeIndexMap
|
||||
// GetInitializedEdgeIndexMap
|
||||
// GetInitializedFaceIndexMap
|
||||
|
||||
template<typename PolygonMesh, typename NamedParameters>
|
||||
class GetVertexIndexMap
|
||||
{
|
||||
typedef typename property_map_selector<PolygonMesh, boost::vertex_index_t>::type DefaultMap;
|
||||
public:
|
||||
typedef typename internal_np::Lookup_named_param_def <
|
||||
internal_np::vertex_index_t,
|
||||
NamedParameters,
|
||||
DefaultMap
|
||||
> ::type type;
|
||||
};
|
||||
#define CGAL_DEF_GET_INDEX_TYPE(CTYPE, DTYPE, STYPE) \
|
||||
template <typename Graph, \
|
||||
typename NamedParameters = \
|
||||
CGAL::Named_function_parameters<bool, CGAL::internal_np::all_default_t> > \
|
||||
struct GetInitialized##CTYPE##IndexMap \
|
||||
: public BGL::internal::GetInitializedIndexMap<internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph, NamedParameters> \
|
||||
{ };
|
||||
|
||||
CGAL_DEF_GET_INDEX_TYPE(Vertex, vertex, typename boost::graph_traits<Graph>::vertices_size_type)
|
||||
CGAL_DEF_GET_INDEX_TYPE(Halfedge, halfedge, typename boost::graph_traits<Graph>::halfedges_size_type)
|
||||
CGAL_DEF_GET_INDEX_TYPE(Edge, edge, typename boost::graph_traits<Graph>::edges_size_type)
|
||||
CGAL_DEF_GET_INDEX_TYPE(Face, face, typename boost::graph_traits<Graph>::faces_size_type)
|
||||
|
||||
#undef CGAL_DEF_GET_INDEX_TYPE
|
||||
|
||||
// Define the following functions:
|
||||
//
|
||||
// get_initialized_vertex_index_map()
|
||||
// get_initialized_halfedge_index_map()
|
||||
// get_initialized_edge_index_map()
|
||||
// get_initialized_face_index_map()
|
||||
//
|
||||
// The function returns:
|
||||
// - the index property map passed in the NPs, if passed in the NPs; it must be initialized by the user;
|
||||
// - the internal index property map if it is the graph has one. It is initialized if needed and possible;
|
||||
// - an initialized dynamic pmap otherwise.
|
||||
|
||||
#define CGAL_DEF_GET_INITIALIZED_INDEX_MAP(DTYPE, STYPE) \
|
||||
template <typename Graph, \
|
||||
typename NamedParameters> \
|
||||
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph, NamedParameters>::const_type \
|
||||
get_initialized_##DTYPE##_index_map(const Graph& g, \
|
||||
const NamedParameters& np) \
|
||||
{ \
|
||||
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph, NamedParameters> Index_map_getter; \
|
||||
return Index_map_getter::get_const(CGAL::internal_np::DTYPE##_index_t{}, g, np); \
|
||||
} \
|
||||
template <typename Graph> \
|
||||
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph>::const_type \
|
||||
get_initialized_##DTYPE##_index_map(const Graph& g) \
|
||||
{ \
|
||||
return get_initialized_##DTYPE##_index_map(g, CGAL::parameters::all_default()); \
|
||||
} \
|
||||
/* same as above, non-const version*/ \
|
||||
template <typename Graph, \
|
||||
typename NamedParameters, \
|
||||
/*otherwise compilers will try to use 'Graph := const PM' and things will go badly*/ \
|
||||
std::enable_if_t< \
|
||||
!std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \
|
||||
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph, NamedParameters>::type \
|
||||
get_initialized_##DTYPE##_index_map(Graph& g, \
|
||||
const NamedParameters& np) \
|
||||
{ \
|
||||
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph, NamedParameters> Index_map_getter; \
|
||||
return Index_map_getter::get(CGAL::internal_np::DTYPE##_index_t{}, g, np); \
|
||||
} \
|
||||
template <typename Graph, \
|
||||
std::enable_if_t< \
|
||||
!std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \
|
||||
typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
|
||||
boost::DTYPE##_index_t, \
|
||||
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
|
||||
Graph>::type \
|
||||
get_initialized_##DTYPE##_index_map(Graph& g) \
|
||||
{ \
|
||||
return get_initialized_##DTYPE##_index_map(g, CGAL::parameters::all_default()); \
|
||||
}
|
||||
|
||||
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(vertex, typename boost::graph_traits<Graph>::vertices_size_type)
|
||||
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(halfedge, typename boost::graph_traits<Graph>::halfedges_size_type)
|
||||
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(edge, typename boost::graph_traits<Graph>::edges_size_type)
|
||||
CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::faces_size_type)
|
||||
|
||||
#undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP
|
||||
|
||||
template<typename PolygonMesh, typename NamedParameters>
|
||||
class GetFaceNormalMap
|
||||
@@ -230,8 +301,45 @@ namespace CGAL {
|
||||
> ::type type;
|
||||
};
|
||||
|
||||
namespace Point_set_processing_3
|
||||
|
||||
namespace internal {
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
|
||||
}
|
||||
|
||||
template<typename PointRange,
|
||||
typename NamedParameters = Named_function_parameters<bool, internal_np::all_default_t>,
|
||||
bool has_nested_iterator = internal::Has_nested_type_iterator<PointRange>::value>
|
||||
class GetPointMap
|
||||
{
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Point;
|
||||
typedef typename CGAL::Identity_property_map<Point> DefaultPMap;
|
||||
|
||||
public:
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
internal_np::point_t,
|
||||
NamedParameters,
|
||||
DefaultPMap
|
||||
> ::type type;
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
internal_np::point_t,
|
||||
NamedParameters,
|
||||
DefaultPMap
|
||||
> ::type const_type;
|
||||
};
|
||||
|
||||
// to please compiler instantiating non valid overloads
|
||||
template<typename PointRange, typename NamedParameters>
|
||||
class GetPointMap<PointRange, NamedParameters, false>
|
||||
{
|
||||
struct Dummy_point{};
|
||||
public:
|
||||
typedef typename CGAL::Identity_property_map<Dummy_point> type;
|
||||
typedef typename CGAL::Identity_property_map<Dummy_point> const_type;
|
||||
};
|
||||
|
||||
namespace Point_set_processing_3 {
|
||||
|
||||
template <typename ValueType>
|
||||
struct Fake_point_range
|
||||
{
|
||||
@@ -255,41 +363,6 @@ namespace CGAL {
|
||||
}
|
||||
}
|
||||
|
||||
namespace internal{
|
||||
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
|
||||
}
|
||||
|
||||
template<typename PointRange, typename NamedParameters,
|
||||
bool has_nested_iterator=internal::Has_nested_type_iterator<PointRange>::value>
|
||||
class GetPointMap
|
||||
{
|
||||
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Point;
|
||||
typedef typename CGAL::Identity_property_map<Point> DefaultPMap;
|
||||
|
||||
public:
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
internal_np::point_t,
|
||||
NamedParameters,
|
||||
DefaultPMap
|
||||
> ::type type;
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def<
|
||||
internal_np::point_t,
|
||||
NamedParameters,
|
||||
DefaultPMap
|
||||
> ::type const_type;
|
||||
};
|
||||
|
||||
// to please compiler instantiating non valid overloads
|
||||
template<typename PointRange, typename NamedParameters>
|
||||
class GetPointMap<PointRange, NamedParameters, false>
|
||||
{
|
||||
struct Dummy_point{};
|
||||
public:
|
||||
typedef typename CGAL::Identity_property_map<Dummy_point> type;
|
||||
typedef typename CGAL::Identity_property_map<Dummy_point> const_type;
|
||||
};
|
||||
|
||||
template<typename PointRange>
|
||||
class GetFT
|
||||
{
|
||||
@@ -380,7 +453,7 @@ namespace CGAL {
|
||||
DefaultPMap
|
||||
> ::type const_type;
|
||||
};
|
||||
|
||||
|
||||
template<typename NamedParameters>
|
||||
class GetPlaneIndexMap
|
||||
{
|
||||
@@ -428,7 +501,7 @@ namespace CGAL {
|
||||
};
|
||||
|
||||
} // namespace Point_set_processing_3
|
||||
|
||||
|
||||
template<typename NamedParameters, typename DefaultSolver>
|
||||
class GetSolver
|
||||
{
|
||||
@@ -461,10 +534,10 @@ namespace CGAL {
|
||||
typedef int Matrix;
|
||||
static FT solve (const Matrix&, Vector&) { return 0.; }
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
typedef DummySvdTraits NoTraits;
|
||||
|
||||
|
||||
typedef typename internal_np::Lookup_named_param_def <
|
||||
internal_np::svd_traits_t,
|
||||
NamedParameters,
|
||||
@@ -488,8 +561,6 @@ namespace CGAL {
|
||||
DefaultImplementation
|
||||
>::type type;
|
||||
};
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@ CGAL_add_named_parameter(face_index_t, face_index, face_index_map)
|
||||
CGAL_add_named_parameter(vertex_index_t, vertex_index, vertex_index_map)
|
||||
CGAL_add_named_parameter(graph_visitor_t, graph_visitor, visitor)
|
||||
|
||||
CGAL_add_named_parameter(point_t, point_map, point_map)
|
||||
|
||||
CGAL_add_named_parameter(edge_is_constrained_t, edge_is_constrained, edge_is_constrained_map)
|
||||
CGAL_add_named_parameter(first_index_t, first_index, first_index)
|
||||
CGAL_add_named_parameter(number_of_iterations_t, number_of_iterations, number_of_iterations)
|
||||
@@ -83,6 +85,9 @@ CGAL_add_named_parameter(use_angle_smoothing_t, use_angle_smoothing, use_angle_s
|
||||
CGAL_add_named_parameter(use_area_smoothing_t, use_area_smoothing, use_area_smoothing)
|
||||
CGAL_add_named_parameter(use_Delaunay_flips_t, use_Delaunay_flips, use_Delaunay_flips)
|
||||
CGAL_add_named_parameter(do_project_t, do_project, do_project)
|
||||
CGAL_add_named_parameter(area_threshold_t, area_threshold, area_threshold)
|
||||
CGAL_add_named_parameter(volume_threshold_t, volume_threshold, volume_threshold)
|
||||
CGAL_add_named_parameter(dry_run_t, dry_run, dry_run)
|
||||
|
||||
// List of named parameters that we use in the package 'Surface Mesh Simplification'
|
||||
CGAL_add_named_parameter(get_cost_policy_t, get_cost_policy, get_cost)
|
||||
@@ -91,14 +96,14 @@ CGAL_add_named_parameter(get_placement_policy_t, get_placement_policy, get_place
|
||||
//to be documented
|
||||
CGAL_add_named_parameter(face_normal_t, face_normal, face_normal_map)
|
||||
CGAL_add_named_parameter(random_seed_t, random_seed, random_seed)
|
||||
CGAL_add_named_parameter(tolerance_map_t, tolerance_map, tolerance_map)
|
||||
CGAL_add_named_parameter(do_lock_mesh_t, do_lock_mesh, do_lock_mesh)
|
||||
CGAL_add_named_parameter(do_simplify_border_t, do_simplify_border, do_simplify_border)
|
||||
|
||||
//internal
|
||||
CGAL_add_named_parameter(weight_calculator_t, weight_calculator, weight_calculator)
|
||||
CGAL_add_named_parameter(use_bool_op_to_clip_surface_t, use_bool_op_to_clip_surface, use_bool_op_to_clip_surface)
|
||||
|
||||
// List of named parameters used in the Point Set Processing package
|
||||
CGAL_add_named_parameter(point_t, point_map, point_map)
|
||||
CGAL_add_named_parameter(query_point_t, query_point_map, query_point_map)
|
||||
CGAL_add_named_parameter(normal_t, normal_map, normal_map)
|
||||
CGAL_add_named_parameter(diagonalize_traits_t, diagonalize_traits, diagonalize_traits)
|
||||
@@ -120,6 +125,15 @@ CGAL_add_named_parameter(plane_index_t, plane_index_map, plane_index_map)
|
||||
CGAL_add_named_parameter(select_percentage_t, select_percentage, select_percentage)
|
||||
CGAL_add_named_parameter(require_uniform_sampling_t, require_uniform_sampling, require_uniform_sampling)
|
||||
CGAL_add_named_parameter(point_is_constrained_t, point_is_constrained, point_is_constrained_map)
|
||||
CGAL_add_named_parameter(transformation_t, transformation, transformation)
|
||||
CGAL_add_named_parameter(point_set_filters_t, point_set_filters, point_set_filters)
|
||||
CGAL_add_named_parameter(matcher_t, matcher, matcher)
|
||||
CGAL_add_named_parameter(outlier_filters_t, outlier_filters, outlier_filters)
|
||||
CGAL_add_named_parameter(error_minimizer_t, error_minimizer, error_minimizer)
|
||||
CGAL_add_named_parameter(transformation_checkers_t, transformation_checkers, transformation_checkers)
|
||||
CGAL_add_named_parameter(inspector_t, inspector, inspector)
|
||||
CGAL_add_named_parameter(logger_t, logger, logger)
|
||||
CGAL_add_named_parameter(pointmatcher_config_t, pointmatcher_config, pointmatcher_config)
|
||||
|
||||
// List of named parameters used in Surface_mesh_approximation package
|
||||
CGAL_add_named_parameter(verbose_level_t, verbose_level, verbose_level)
|
||||
@@ -141,3 +155,9 @@ CGAL_add_named_parameter(proxies_t, proxies, proxies)
|
||||
CGAL_add_named_parameter(anchors_t, anchors, anchors)
|
||||
CGAL_add_named_parameter(triangles_t, triangles, triangles)
|
||||
|
||||
CGAL_add_named_parameter(number_of_samples_t, number_of_samples, number_of_samples)
|
||||
CGAL_add_named_parameter(accuracy_t, accuracy, accuracy)
|
||||
CGAL_add_named_parameter(maximum_running_time_t, maximum_running_time, maximum_running_time)
|
||||
CGAL_add_named_parameter(overlap_t, overlap, overlap)
|
||||
CGAL_add_named_parameter(maximum_normal_deviation_t, maximum_normal_deviation, maximum_normal_deviation)
|
||||
|
||||
|
||||
@@ -14,72 +14,45 @@
|
||||
#define CGAL_BOOST_GRAPH_BGL_PROPERTIES_H
|
||||
|
||||
#include <CGAL/property_map.h>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
#include <CGAL/basic.h>
|
||||
|
||||
#include <boost/graph/properties.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <CGAL/Dynamic_property_map.h>
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <type_traits>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace CGAL{
|
||||
/// \ingroup PkgBGLProperties
|
||||
/// \brief graph_has_property is used to indicate if
|
||||
/// a model of `HalfedgeGraph` or `FaceGraph`
|
||||
/// has an internal property associated with the
|
||||
/// given `PropertyTag`.
|
||||
///
|
||||
/// It inherits from `CGAL::Tag_true` if there is a
|
||||
/// default internal property map for the
|
||||
/// corresponding property tag and from
|
||||
/// `CGAL::Tag_false` otherwise.
|
||||
///
|
||||
/// \tparam Graph a model of `HalfedgeGraph` or `FaceGraph`
|
||||
/// \tparam PropertyTag the type of a property tag
|
||||
/// referring to the property of interest.
|
||||
///
|
||||
template<typename Graph, typename PropertyTag>
|
||||
struct graph_has_property
|
||||
#ifndef DOXYGEN_RUNNING
|
||||
: CGAL::Tag_false
|
||||
#endif
|
||||
{};
|
||||
}
|
||||
/// Boost Namespace
|
||||
struct graph_has_property : CGAL::Tag_false { };
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
namespace boost {
|
||||
|
||||
/// \ingroup PkgBGLProperties
|
||||
/// @{
|
||||
|
||||
/// A property tag which refers to the geometric embedding property
|
||||
/// of a vertex of a \ref HalfedgeGraph.
|
||||
enum vertex_point_t { vertex_point };
|
||||
enum vertex_external_index_t { vertex_external_index } ;
|
||||
|
||||
/// A property tag which refers to the property
|
||||
/// of a halfedge of being a border halfedge.
|
||||
enum edge_external_index_t { edge_external_index } ;
|
||||
// vertex_index_t is defined in boost
|
||||
enum vertex_external_index_t { vertex_external_index };
|
||||
|
||||
/// A property tag which identifies the *index* property of
|
||||
/// a halfedge of a \ref HalfedgeGraph.
|
||||
enum halfedge_index_t { halfedge_index };
|
||||
enum halfedge_external_index_t { halfedge_external_index } ;
|
||||
enum halfedge_index_t { halfedge_index };
|
||||
enum halfedge_external_index_t { halfedge_external_index };
|
||||
|
||||
// edge_index_t is defined in boost
|
||||
enum edge_external_index_t { edge_external_index };
|
||||
|
||||
/// A property tag which identifies the *index* property of
|
||||
/// a face of a \ref FaceGraph.
|
||||
enum face_index_t { face_index };
|
||||
enum face_external_index_t { face_external_index } ;
|
||||
enum face_external_index_t { face_external_index };
|
||||
|
||||
|
||||
struct cgal_no_property
|
||||
{
|
||||
typedef bool type;
|
||||
typedef const bool const_type;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
// Introduce those two tags so we can use BOOST_INSTALL_PROPERTY
|
||||
// macro. This is dangerous because we now rely on implementation
|
||||
// details.
|
||||
@@ -97,12 +70,16 @@ BOOST_INSTALL_PROPERTY(face, external_index);
|
||||
namespace CGAL {
|
||||
using boost::vertex_point_t;
|
||||
using boost::vertex_point;
|
||||
using boost::vertex_index_t;
|
||||
using boost::vertex_index;
|
||||
using boost::vertex_external_index_t;
|
||||
using boost::vertex_external_index;
|
||||
using boost::halfedge_index_t;
|
||||
using boost::halfedge_index;
|
||||
using boost::halfedge_external_index_t;
|
||||
using boost::halfedge_external_index;
|
||||
using boost::edge_index_t;
|
||||
using boost::edge_index;
|
||||
using boost::edge_external_index_t;
|
||||
using boost::edge_external_index;
|
||||
using boost::face_index_t;
|
||||
@@ -111,128 +88,7 @@ using boost::face_external_index_t;
|
||||
using boost::face_external_index;
|
||||
} // CGAL
|
||||
|
||||
namespace CGAL{
|
||||
namespace helpers {
|
||||
|
||||
// matches read-write property maps
|
||||
template <class PolygonMesh, class FaceIndexMap, class Tag>
|
||||
void init_face_indices(PolygonMesh& pm,
|
||||
FaceIndexMap& fid,
|
||||
boost::read_write_property_map_tag,
|
||||
Tag)
|
||||
{
|
||||
typename boost::property_traits<FaceIndexMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<PolygonMesh>::face_descriptor fd :
|
||||
faces(pm))
|
||||
{
|
||||
put(fid, fd, i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
template <class PolygonMesh, class VertexIndexMap, class Tag>
|
||||
void init_vertex_indices(PolygonMesh& pm,
|
||||
VertexIndexMap& vid,
|
||||
boost::read_write_property_map_tag,
|
||||
Tag)
|
||||
{
|
||||
typename boost::property_traits<VertexIndexMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<PolygonMesh>::vertex_descriptor vd :
|
||||
vertices(pm))
|
||||
{
|
||||
put(vid, vd, i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
template <class PolygonMesh, class HalfedgeIndexMap, class Tag>
|
||||
void init_halfedge_indices(PolygonMesh& pm,
|
||||
HalfedgeIndexMap& hid,
|
||||
boost::read_write_property_map_tag,
|
||||
Tag)
|
||||
{
|
||||
typename boost::property_traits<HalfedgeIndexMap>::value_type i = 0;
|
||||
for(typename boost::graph_traits<PolygonMesh>::halfedge_descriptor hd :
|
||||
halfedges(pm))
|
||||
{
|
||||
put(hid, hd, i);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
// matches mutable Lvalue property maps
|
||||
template <class PolygonMesh, class FaceIndexMap>
|
||||
void init_face_indices(PolygonMesh& pm,
|
||||
FaceIndexMap& fid,
|
||||
boost::lvalue_property_map_tag,
|
||||
boost::false_type)
|
||||
{
|
||||
init_face_indices(pm, fid,
|
||||
boost::read_write_property_map_tag(), boost::false_type());
|
||||
}
|
||||
template <class PolygonMesh, class VertexIndexMap>
|
||||
void init_vertex_indices(PolygonMesh& pm,
|
||||
VertexIndexMap& vid,
|
||||
boost::lvalue_property_map_tag,
|
||||
boost::false_type)
|
||||
{
|
||||
init_vertex_indices(pm, vid,
|
||||
boost::read_write_property_map_tag(), boost::false_type());
|
||||
}
|
||||
template <class PolygonMesh, class HalfedgeIndexMap>
|
||||
void init_halfedge_indices(PolygonMesh& pm,
|
||||
HalfedgeIndexMap& hid,
|
||||
boost::lvalue_property_map_tag,
|
||||
boost::false_type)
|
||||
{
|
||||
init_halfedge_indices(pm, hid,
|
||||
boost::read_write_property_map_tag(), boost::false_type());
|
||||
}
|
||||
|
||||
// matches all other types of property map
|
||||
template <class PolygonMesh, class FaceIndexMap, class MapTag, class Tag>
|
||||
void init_face_indices(PolygonMesh&, FaceIndexMap, MapTag, Tag)
|
||||
{}
|
||||
template <class PolygonMesh, class VertexIndexMap, class MapTag, class Tag>
|
||||
void init_vertex_indices(PolygonMesh&, VertexIndexMap, MapTag, Tag)
|
||||
{}
|
||||
template <class PolygonMesh, class HalfedgeIndexMap, class MapTag, class Tag>
|
||||
void init_halfedge_indices(PolygonMesh&, HalfedgeIndexMap, MapTag, Tag)
|
||||
{}
|
||||
|
||||
template <class PolygonMesh, class FaceIndexMap>
|
||||
void init_face_indices(PolygonMesh& pm, FaceIndexMap fid)
|
||||
{
|
||||
init_face_indices(pm, fid,
|
||||
typename boost::property_traits<FaceIndexMap>::category(),
|
||||
typename boost::is_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::property_traits<FaceIndexMap>::reference
|
||||
>::type >::type() );
|
||||
}
|
||||
|
||||
template <class PolygonMesh, class VertexIndexMap>
|
||||
void init_vertex_indices(PolygonMesh& pm, VertexIndexMap vid)
|
||||
{
|
||||
init_vertex_indices(pm, vid,
|
||||
typename boost::property_traits<VertexIndexMap>::category(),
|
||||
typename boost::is_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::property_traits<VertexIndexMap>::reference
|
||||
>::type >::type() );
|
||||
}
|
||||
|
||||
template <class PolygonMesh, class HalfedgeIndexMap>
|
||||
void init_halfedge_indices(PolygonMesh& pm, HalfedgeIndexMap hid)
|
||||
{
|
||||
init_halfedge_indices(pm, hid,
|
||||
typename boost::property_traits<HalfedgeIndexMap>::category(),
|
||||
typename boost::is_const<
|
||||
typename boost::remove_reference<
|
||||
typename boost::property_traits<HalfedgeIndexMap>::reference
|
||||
>::type >::type() );
|
||||
}
|
||||
|
||||
} //namespace helpers
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
|
||||
template<typename Polyhedron, typename Handle>
|
||||
@@ -260,8 +116,8 @@ struct Edge_index_accessor
|
||||
};
|
||||
|
||||
template<typename Handle, typename ValueType, typename Reference,
|
||||
bool is_const = boost::is_const<
|
||||
typename boost::remove_reference<Reference>::type >::value>
|
||||
bool is_const = std::is_const<
|
||||
typename std::remove_reference<Reference>::type >::value>
|
||||
struct Point_accessor
|
||||
: boost::put_get_helper< Reference, Point_accessor<Handle, ValueType, Reference> >
|
||||
{
|
||||
@@ -293,6 +149,32 @@ struct Point_accessor<Handle, ValueType, ConstReference, true>
|
||||
reference operator[](Handle h) const { return h->point(); }
|
||||
};
|
||||
|
||||
// this one is basically 'readable_property_map_tag'
|
||||
template <typename PropertyMap,
|
||||
typename PropertyMapCategory = typename boost::property_traits<PropertyMap>::category>
|
||||
struct Is_writable_property_map : CGAL::Tag_false { };
|
||||
|
||||
template <typename PropertyMap>
|
||||
struct Is_writable_property_map<PropertyMap, boost::writable_property_map_tag> : CGAL::Tag_true { };
|
||||
|
||||
template <typename PropertyMap>
|
||||
struct Is_writable_property_map<PropertyMap, boost::read_write_property_map_tag> : CGAL::Tag_true { };
|
||||
|
||||
// 'lvalue_pmap_tag' is annoying, because the property map is allowed to be non-mutable,
|
||||
// but boost::lvalue_property_map_tag is defined as:
|
||||
// struct lvalue_property_map_tag : public read_write_property_map_tag
|
||||
// so we can't just check that 'writable_property_map_tag' is a base of the the lvalue tag.
|
||||
//
|
||||
// This checks if the reference is non-const, which is not completely correct: map[key] returning
|
||||
// a non-const reference doesn't mean that 'put(map, key, val)' exists, which is what a writable
|
||||
// property map must define.
|
||||
template <typename PropertyMap>
|
||||
struct Is_writable_property_map<PropertyMap, boost::lvalue_property_map_tag>
|
||||
: boost::mpl::if_c<std::is_const<typename std::remove_reference<
|
||||
typename boost::property_traits<PropertyMap>::reference>::type>::value,
|
||||
CGAL::Tag_false, CGAL::Tag_true>::type
|
||||
{ };
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Needed by PMP::detec_features and Mesh_3
|
||||
@@ -303,12 +185,12 @@ enum vertex_time_stamp_t { vertex_time_stamp};
|
||||
enum halfedge_time_stamp_t { halfedge_time_stamp};
|
||||
enum face_time_stamp_t { face_time_stamp};
|
||||
|
||||
template <typename ID>
|
||||
template<typename ID>
|
||||
struct vertex_incident_patches_t {
|
||||
typedef ID type;
|
||||
};
|
||||
|
||||
template <typename ID>
|
||||
template<typename ID>
|
||||
struct face_patch_id_t {
|
||||
typedef ID type;
|
||||
};
|
||||
|
||||
@@ -112,6 +112,39 @@ struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::vertex_point_t>
|
||||
typedef CGAL::Seam_mesh_point_map<TM, SEM, SVM> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template <class TM, class SEM, class SVM, typename T>
|
||||
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_vertex_property_t<T> >
|
||||
{
|
||||
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::vertex_descriptor vertex_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<vertex_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template <class TM, class SEM, class SVM, typename T>
|
||||
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_halfedge_property_t<T> >
|
||||
{
|
||||
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::halfedge_descriptor halfedge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<halfedge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
|
||||
template <class TM, class SEM, class SVM, typename T>
|
||||
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_edge_property_t<T> >
|
||||
{
|
||||
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::edge_descriptor edge_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<edge_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
|
||||
template <class TM, class SEM, class SVM, typename T>
|
||||
struct property_map<CGAL::Seam_mesh<TM, SEM, SVM>, CGAL::dynamic_face_property_t<T> >
|
||||
{
|
||||
typedef typename boost::graph_traits<CGAL::Seam_mesh<TM, SEM, SVM> >::face_descriptor face_descriptor;
|
||||
typedef CGAL::internal::Dynamic_property_map<face_descriptor,T> type;
|
||||
typedef type const_type;
|
||||
};
|
||||
} // namespace boost
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
@@ -578,32 +578,44 @@ void expand_face_selection_for_removal(const FaceRange& faces_to_be_deleted,
|
||||
next_around_vertex = opposite( next(hd, tm), tm);
|
||||
if (hd==start) break;
|
||||
}
|
||||
if ( get(is_selected, face(next_around_vertex, tm) ) ) continue; //all incident faces will be removed
|
||||
if ( is_border(next_around_vertex,tm) || get(is_selected, face(next_around_vertex, tm) ) ) continue; //all incident faces will be removed
|
||||
|
||||
while( true )
|
||||
{
|
||||
// collect non-selected faces
|
||||
std::vector<halfedge_descriptor> faces_traversed;
|
||||
bool non_selected_face_range_has_boundary = false; // handle non-manifold situations when crossing a border
|
||||
do
|
||||
{
|
||||
faces_traversed.push_back(next_around_vertex);
|
||||
next_around_vertex = opposite( next(next_around_vertex, tm), tm);
|
||||
if (is_border(next_around_vertex,tm))
|
||||
{
|
||||
next_around_vertex = opposite( next(next_around_vertex, tm), tm);
|
||||
if (!get(is_selected, face(next_around_vertex, tm) ))
|
||||
{
|
||||
non_selected_face_range_has_boundary=true; // always non-manifold after removal of the selection
|
||||
break;
|
||||
}
|
||||
}
|
||||
CGAL_assertion(!is_border(next_around_vertex,tm));
|
||||
}
|
||||
while( !get(is_selected, face(next_around_vertex, tm) ) );
|
||||
|
||||
// go over the connected components of faces to remove
|
||||
do{
|
||||
if (!non_selected_face_range_has_boundary)
|
||||
{
|
||||
// go over the connected components of faces to remove
|
||||
do{
|
||||
if (next_around_vertex==start)
|
||||
break;
|
||||
next_around_vertex = opposite( next(next_around_vertex, tm), tm);
|
||||
}
|
||||
while(is_border(next_around_vertex,tm) || get(is_selected, face(next_around_vertex, tm) ) );
|
||||
|
||||
if (next_around_vertex==start)
|
||||
break;
|
||||
next_around_vertex = opposite( next(next_around_vertex, tm), tm);
|
||||
}
|
||||
while( get(is_selected, face(next_around_vertex, tm) ) );
|
||||
|
||||
if (next_around_vertex==start)
|
||||
break;
|
||||
// else we simply mark the range of traversed faces and start a new range after the border
|
||||
|
||||
for(halfedge_descriptor f_hd : faces_traversed)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
OFF
|
||||
9 7 0
|
||||
0 0 0
|
||||
1 0 0
|
||||
2 0 0
|
||||
2 1 0
|
||||
2 2 0
|
||||
1 2 0
|
||||
0 2 0
|
||||
0 1 0
|
||||
1 1 0
|
||||
3 0 1 8
|
||||
3 1 2 8
|
||||
3 2 3 8
|
||||
3 3 4 8
|
||||
3 5 6 8
|
||||
3 6 7 8
|
||||
3 7 0 8
|
||||
@@ -402,6 +402,44 @@ test_swap_edges()
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void
|
||||
add_face_bug()
|
||||
{
|
||||
typedef boost::graph_traits<T> GT;
|
||||
typedef typename GT::vertex_descriptor vertex_descriptor;
|
||||
typedef typename GT::halfedge_descriptor halfedge_descriptor;
|
||||
|
||||
T g;
|
||||
|
||||
std::vector<vertex_descriptor> vs;
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(0,1,0)
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(4,1,0)
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(5,2,0)
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(4,0,0)
|
||||
|
||||
CGAL::Euler::add_face(CGAL::make_array(vs[0], vs[1], vs[2]), g);
|
||||
CGAL::Euler::add_face(CGAL::make_array(vs[1], vs[3], vs[2]), g);
|
||||
|
||||
// force vertex halfedge to not be a border halfedge
|
||||
for(vertex_descriptor v : vertices(g))
|
||||
{
|
||||
halfedge_descriptor h = halfedge(v, g);
|
||||
if ( CGAL::is_border(h, g) )
|
||||
set_halfedge(v, prev(opposite(h, g), g), g);
|
||||
assert(target(halfedge(v, g), g)==v);
|
||||
}
|
||||
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(0,0,0)
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(1,0,0)
|
||||
CGAL::Euler::add_face(CGAL::make_array(vs[4],vs[5],vs[0]), g);
|
||||
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(2,0,0)
|
||||
vs.push_back( add_vertex(g) ); // Kernel::Point_3(3,0,0)
|
||||
CGAL::Euler::add_face(CGAL::make_array(vs[6],vs[7],vs[1]), g);
|
||||
CGAL::Euler::add_face(CGAL::make_array(vs[7],vs[3],vs[1]), g);
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void
|
||||
test_Euler_operations()
|
||||
@@ -421,6 +459,7 @@ test_Euler_operations()
|
||||
join_split_inverse<Graph>();
|
||||
does_satisfy_link_condition<Graph>();
|
||||
test_swap_edges<Graph>();
|
||||
add_face_bug<Graph>();
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
@@ -491,13 +491,13 @@ int main()
|
||||
|
||||
|
||||
typedef boost::graph_traits<Polyhedron> PolyTraits;
|
||||
typedef boost::property_map<Polyhedron, boost::vertex_point_t>::type VPMap;
|
||||
typedef boost::property_map<Polyhedron, boost::vertex_point_t>::const_type VPMap;
|
||||
typedef PolyTraits::face_descriptor poly_face_descriptor;
|
||||
typedef boost::associative_property_map< std::map<poly_face_descriptor,
|
||||
PolyTraits::faces_size_type> > FCMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::face_external_index_t>::type FIMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::vertex_external_index_t>::type VIMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::halfedge_external_index_t>::type HIMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::face_external_index_t>::const_type FIMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::vertex_external_index_t>::const_type VIMap;
|
||||
typedef boost::property_map<Polyhedron, CGAL::halfedge_external_index_t>::const_type HIMap;
|
||||
typedef CGAL::Face_filtered_graph<Polyhedron, FIMap, VIMap, HIMap> Poly_Adapter;
|
||||
auto poly = std::make_unique<Polyhedron>();
|
||||
CGAL::make_tetrahedron(
|
||||
@@ -516,14 +516,14 @@ int main()
|
||||
FCMap poly_fccmap(fc_map);
|
||||
|
||||
VPMap vpmap = get(boost::vertex_point, *poly);
|
||||
CGAL::Polygon_mesh_processing::connected_components(*poly, poly_fccmap, CGAL::Polygon_mesh_processing::parameters::
|
||||
edge_is_constrained_map(Constraint<Polyhedron, VPMap >(*poly, vpmap)).
|
||||
face_index_map(poly_fimap));
|
||||
CGAL::Polygon_mesh_processing::connected_components(*poly, poly_fccmap,
|
||||
CGAL::Polygon_mesh_processing::parameters::edge_is_constrained_map(Constraint<Polyhedron, VPMap >(*poly, vpmap))
|
||||
.face_index_map(poly_fimap));
|
||||
Poly_Adapter poly_adapter(*poly,
|
||||
pids,
|
||||
poly_fccmap,
|
||||
CGAL::parameters::face_index_map(poly_fimap).
|
||||
vertex_index_map(poly_vimap).
|
||||
halfedge_index_map(poly_himap));
|
||||
CGAL::parameters::face_index_map(poly_fimap)
|
||||
.vertex_index_map(poly_vimap)
|
||||
.halfedge_index_map(poly_himap));
|
||||
test_mesh<Polyhedron, FCMap, Poly_Adapter>(poly_adapter);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,68 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
|
||||
typedef CGAL::Surface_mesh<Kernel::Point_3> SM;
|
||||
typedef boost::graph_traits<SM>::face_descriptor face_descriptor;
|
||||
|
||||
void border_cases()
|
||||
{
|
||||
SM sm_ref;
|
||||
std::ifstream input("data/nm_selection_removal.off");
|
||||
input >> sm_ref;
|
||||
|
||||
{
|
||||
SM sm = sm_ref;
|
||||
std::vector<SM::Face_index> faces_to_remove;
|
||||
faces_to_remove.push_back(SM::Face_index(5));
|
||||
faces_to_remove.push_back(SM::Face_index(6));
|
||||
SM::Property_map<SM::Face_index, bool> is_selected = sm.add_property_map<SM::Face_index, bool>("f:is_selected", false).first;
|
||||
is_selected[SM::Face_index(5)]=true;
|
||||
is_selected[SM::Face_index(6)]=true;
|
||||
CGAL::expand_face_selection_for_removal(faces_to_remove,
|
||||
sm,
|
||||
is_selected);
|
||||
int i=0;
|
||||
for(face_descriptor fh : sm.faces())
|
||||
if(!is_selected[fh]) ++i;
|
||||
assert(i==4);
|
||||
}
|
||||
|
||||
{
|
||||
SM sm = sm_ref;
|
||||
std::vector<SM::Face_index> faces_to_remove;
|
||||
faces_to_remove.push_back(SM::Face_index(4));
|
||||
faces_to_remove.push_back(SM::Face_index(6));
|
||||
SM::Property_map<SM::Face_index, bool> is_selected = sm.add_property_map<SM::Face_index, bool>("f:is_selected", false).first;
|
||||
is_selected[SM::Face_index(4)]=true;
|
||||
is_selected[SM::Face_index(6)]=true;
|
||||
CGAL::expand_face_selection_for_removal(faces_to_remove,
|
||||
sm,
|
||||
is_selected);
|
||||
int i=0;
|
||||
for(face_descriptor fh : sm.faces())
|
||||
if(!is_selected[fh]) ++i;
|
||||
|
||||
assert(i==1 || i==4); // depends on the start point
|
||||
}
|
||||
|
||||
{
|
||||
SM sm = sm_ref;
|
||||
std::vector<SM::Face_index> faces_to_remove;
|
||||
faces_to_remove.push_back(SM::Face_index(4));
|
||||
faces_to_remove.push_back(SM::Face_index(5));
|
||||
faces_to_remove.push_back(SM::Face_index(6));
|
||||
SM::Property_map<SM::Face_index, bool> is_selected = sm.add_property_map<SM::Face_index, bool>("f:is_selected", false).first;
|
||||
is_selected[SM::Face_index(4)]=true;
|
||||
is_selected[SM::Face_index(5)]=true;
|
||||
is_selected[SM::Face_index(6)]=true;
|
||||
CGAL::expand_face_selection_for_removal(faces_to_remove,
|
||||
sm,
|
||||
is_selected);
|
||||
int i=0;
|
||||
for(face_descriptor fh : sm.faces())
|
||||
if(!is_selected[fh]) ++i;
|
||||
assert(i==4); // depends on the start point
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
SM sm;
|
||||
@@ -60,6 +122,8 @@ int main()
|
||||
assert( sm.number_of_faces()+30 < nb_input_faces);
|
||||
assert(is_valid_polygon_mesh(sm));
|
||||
|
||||
border_cases();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
+23
-17
@@ -38,6 +38,7 @@
|
||||
#include <CGAL/boost/graph/properties_Constrained_Delaunay_triangulation_2.h>
|
||||
#include <CGAL/boost/graph/graph_traits_Constrained_triangulation_plus_2.h>
|
||||
#include <CGAL/boost/graph/properties_Constrained_triangulation_plus_2.h>
|
||||
#include <CGAL/boost/graph/Seam_mesh.h>
|
||||
|
||||
#include <CGAL/boost/graph/io.h>
|
||||
|
||||
@@ -57,6 +58,10 @@ typedef CGAL::Linear_cell_complex_for_bgl_combinatorial_map_helper
|
||||
|
||||
typedef CGAL::Surface_mesh<Point_3> SM;
|
||||
|
||||
typedef SM::Property_map<SM::Edge_index, bool> Seam_edge_pmap;
|
||||
typedef SM::Property_map<SM::Vertex_index, bool> Seam_vertex_pmap;
|
||||
typedef CGAL::Seam_mesh<SM, Seam_edge_pmap, Seam_vertex_pmap> Seam_mesh;
|
||||
|
||||
#if defined(CGAL_USE_OPENMESH)
|
||||
|
||||
#include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
@@ -73,6 +78,8 @@ typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> OMesh;
|
||||
typedef CGAL::Triangulation_vertex_base_with_id_2<Kernel> Vbb;
|
||||
typedef CGAL::Triangulation_face_base_with_id_2<Kernel> Fbb;
|
||||
|
||||
typedef CGAL::Triangulation_2<Kernel> Triangulation_no_id_2;
|
||||
|
||||
typedef CGAL::Triangulation_2<Kernel,
|
||||
CGAL::Triangulation_data_structure_2<Vbb, Fbb> > Triangulation_2;
|
||||
typedef CGAL::Delaunay_triangulation_2<Kernel,
|
||||
@@ -189,8 +196,6 @@ template <typename Tr>
|
||||
Tr build_dummy_triangulation()
|
||||
{
|
||||
typedef typename Tr::Point Point;
|
||||
typedef typename boost::graph_traits<Tr>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<Tr>::face_descriptor face_descriptor;
|
||||
|
||||
Tr t;
|
||||
t.insert(Point(0.1,0));
|
||||
@@ -199,24 +204,25 @@ Tr build_dummy_triangulation()
|
||||
t.insert(Point(0,1));
|
||||
t.insert(Point(0,2));
|
||||
|
||||
int id = 0;
|
||||
for(vertex_descriptor vd : vertices(t))
|
||||
vd->id() = id++;
|
||||
|
||||
id = 0;
|
||||
for(face_descriptor fd : faces(t))
|
||||
fd->id() = id++;
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
Triangulation_2 t2_data() { return build_dummy_triangulation<Triangulation_2>(); }
|
||||
Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation<Delaunay_triangulation_2>(); }
|
||||
Regular_triangulation_2 rt2_data() { return build_dummy_triangulation<Regular_triangulation_2>(); }
|
||||
Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation<Constrained_triangulation_2>(); }
|
||||
Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation<Constrained_Delaunay_triangulation_2>(); }
|
||||
CDT_P2 cdtp2_data() { return build_dummy_triangulation<CDT_P2>(); }
|
||||
Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation<Triangulation_hierarchy_2>(); }
|
||||
template <typename Tr>
|
||||
Tr build_dummy_triangulation_with_ids()
|
||||
{
|
||||
Tr t = build_dummy_triangulation<Tr>();
|
||||
CGAL::set_triangulation_ids(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
Triangulation_no_id_2 t2_no_id_data() { return build_dummy_triangulation<Triangulation_no_id_2>(); }
|
||||
Triangulation_2 t2_data() { return build_dummy_triangulation_with_ids<Triangulation_2>(); }
|
||||
Delaunay_triangulation_2 dt2_data() { return build_dummy_triangulation_with_ids<Delaunay_triangulation_2>(); }
|
||||
Regular_triangulation_2 rt2_data() { return build_dummy_triangulation_with_ids<Regular_triangulation_2>(); }
|
||||
Constrained_triangulation_2 ct2_data() { return build_dummy_triangulation_with_ids<Constrained_triangulation_2>(); }
|
||||
Constrained_Delaunay_triangulation_2 cdt2_data() { return build_dummy_triangulation_with_ids<Constrained_Delaunay_triangulation_2>(); }
|
||||
CDT_P2 cdtp2_data() { return build_dummy_triangulation_with_ids<CDT_P2>(); }
|
||||
Triangulation_hierarchy_2 t2h_data() { return build_dummy_triangulation_with_ids<Triangulation_hierarchy_2>(); }
|
||||
|
||||
template <typename Graph>
|
||||
struct Surface_fixture_1 {
|
||||
|
||||
@@ -1,115 +1,459 @@
|
||||
#include "test_Prefix.h"
|
||||
|
||||
#include <CGAL/boost/graph/Euler_operations.h>
|
||||
|
||||
#include <boost/unordered_set.hpp>
|
||||
|
||||
template< typename G,
|
||||
typename ForwardRange,
|
||||
typename IndexPropertyMap
|
||||
>
|
||||
void index_uniqueness(const G&,
|
||||
ForwardRange range,
|
||||
IndexPropertyMap pm)
|
||||
// #define CGAL_TEST_PROPERTIES_DEBUG
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
template <typename Key, typename Value, typename Container>
|
||||
struct Non_mutable_property_map
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef value_type reference;
|
||||
typedef boost::readable_property_map_tag category;
|
||||
|
||||
Non_mutable_property_map(const Container& c) : m_c(c) { }
|
||||
|
||||
friend reference get(const Non_mutable_property_map<Key, Value, Container>& pmap, key_type k)
|
||||
{
|
||||
return pmap.m_c.at(k);
|
||||
}
|
||||
|
||||
private:
|
||||
const Container& m_c;
|
||||
};
|
||||
|
||||
template <typename Key, typename Value, typename Container>
|
||||
struct RW_property_map
|
||||
{
|
||||
typedef Key key_type;
|
||||
typedef Value value_type;
|
||||
typedef value_type& reference;
|
||||
typedef boost::read_write_property_map_tag category;
|
||||
|
||||
RW_property_map(Container& c) : m_c(c) { }
|
||||
|
||||
friend void put(RW_property_map<Key, Value, Container>& pmap, const key_type& k, const value_type& val)
|
||||
{
|
||||
pmap.m_c[k] = val;
|
||||
}
|
||||
|
||||
friend reference get(RW_property_map<Key, Value, Container>& pmap, const key_type& k)
|
||||
{
|
||||
return pmap.m_c[k];
|
||||
}
|
||||
|
||||
private:
|
||||
Container& m_c;
|
||||
};
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
template<typename Graph,
|
||||
typename ForwardRange,
|
||||
typename IndexPropertyMap>
|
||||
void test_uniqueness(const Graph&,
|
||||
const ForwardRange& range,
|
||||
IndexPropertyMap index_map)
|
||||
{
|
||||
#ifdef CGAL_TEST_PROPERTIES_DEBUG
|
||||
std::cout << std::endl
|
||||
<< "Checking the uniqueness of the property map of type: "
|
||||
<< typeid(IndexPropertyMap).name() << std::endl;
|
||||
std::cout << "Element type: " << typeid(typename boost::range_value<ForwardRange>::type).name() << std::endl;
|
||||
#endif
|
||||
|
||||
typename boost::range_iterator<ForwardRange>::type
|
||||
begin = boost::begin(range),
|
||||
begin = boost::begin(range),
|
||||
begin2 = boost::begin(range),
|
||||
end = boost::end(range);
|
||||
|
||||
typedef boost::unordered_set<typename IndexPropertyMap::value_type> id_map;
|
||||
typedef std::pair<typename id_map::iterator, bool> resultp;
|
||||
id_map m;
|
||||
|
||||
while(begin != end) {
|
||||
resultp r = m.insert(get(pm, *begin));
|
||||
id_map m;
|
||||
while(begin != end)
|
||||
{
|
||||
resultp r = m.insert(get(index_map, *begin));
|
||||
#ifdef CGAL_TEST_PROPERTIES_DEBUG
|
||||
std::cout << "id: " << get(index_map, *begin) << std::endl;
|
||||
#endif
|
||||
++begin;
|
||||
assert(r.second);
|
||||
assert(r.second); // already seen that id
|
||||
}
|
||||
|
||||
assert(std::distance(begin2, end) == static_cast<std::ptrdiff_t>(m.size()));
|
||||
}
|
||||
|
||||
|
||||
void index_uniqueness_poly(const Polyhedron& g)
|
||||
template<typename Graph,
|
||||
typename NamedParameters>
|
||||
void test_vertex_index_map_uniqueness(const Graph& g,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Graph, NamedParameters>::type VIM;
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Graph, NamedParameters>::const_type CVIM;
|
||||
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_external_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_external_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_external_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_external_index, g));
|
||||
// in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not
|
||||
static_assert((std::is_same<VIM, CVIM>::value), "VIM, CVIM must be the same type");
|
||||
|
||||
VIM ivim = CGAL::get_initialized_vertex_index_map(g, np);
|
||||
|
||||
return test_uniqueness(g, vertices(g), ivim);
|
||||
}
|
||||
|
||||
void index_uniqueness_lcc(const LCC& g)
|
||||
template<typename Graph,
|
||||
typename NamedParameters>
|
||||
void test_halfedge_index_map_uniqueness(const Graph& g,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph, NamedParameters>::type HIM;
|
||||
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph, NamedParameters>::const_type CHIM;
|
||||
|
||||
// in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not
|
||||
static_assert((std::is_same<HIM, CHIM>::value), "HIM, CHIM must be the same type");
|
||||
|
||||
HIM ihim = CGAL::get_initialized_halfedge_index_map(g, np);
|
||||
|
||||
return test_uniqueness(g, halfedges(g), ihim);
|
||||
}
|
||||
|
||||
void index_uniqueness_sm(const SM& g)
|
||||
template<typename Graph,
|
||||
typename NamedParameters>
|
||||
void test_edge_index_map_uniqueness(const Graph& g,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph, NamedParameters>::type EIM;
|
||||
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph, NamedParameters>::const_type CEIM;
|
||||
|
||||
// in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not
|
||||
static_assert((std::is_same<EIM, CEIM>::value), "EIM, CEIM must be the same type");
|
||||
|
||||
EIM ieim = CGAL::get_initialized_edge_index_map(g, np);
|
||||
|
||||
return test_uniqueness(g, edges(g), ieim);
|
||||
}
|
||||
|
||||
#if defined(CGAL_USE_OPENMESH)
|
||||
void index_uniqueness_omesh(const OMesh& g)
|
||||
template<typename Graph,
|
||||
typename NamedParameters>
|
||||
void test_face_index_map_uniqueness(const Graph& g,
|
||||
const NamedParameters& np)
|
||||
{
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
typedef typename CGAL::GetInitializedFaceIndexMap<Graph, NamedParameters>::type FIM;
|
||||
typedef typename CGAL::GetInitializedFaceIndexMap<Graph, NamedParameters>::const_type CFIM;
|
||||
|
||||
// in the case where the map is passed by NP, its type doesn't depend on whether the mesh is const or not
|
||||
static_assert((std::is_same<FIM, CFIM>::value), "FIM, CFIM must be the same type");
|
||||
|
||||
FIM ifim = CGAL::get_initialized_face_index_map(g, np);
|
||||
|
||||
return test_uniqueness(g, faces(g), ifim);
|
||||
}
|
||||
|
||||
////////////////////////////////////////// const ///////////////////////////////////////////////////
|
||||
|
||||
template <typename Graph>
|
||||
void test_internal_index_maps_const(const Graph& g)
|
||||
{
|
||||
test_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
test_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
test_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
test_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void test_initialized_index_maps_const(const Graph& g)
|
||||
{
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Graph>::const_type VIM;
|
||||
VIM ivim = CGAL::get_initialized_vertex_index_map(g);
|
||||
test_uniqueness(g, vertices(g), ivim);
|
||||
|
||||
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::const_type HIM;
|
||||
HIM ihim = CGAL::get_initialized_halfedge_index_map(g);
|
||||
test_uniqueness(g, halfedges(g), ihim);
|
||||
|
||||
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph>::const_type EIM;
|
||||
EIM ieim = CGAL::get_initialized_edge_index_map(g);
|
||||
test_uniqueness(g, edges(g), ieim);
|
||||
|
||||
typedef typename CGAL::GetInitializedFaceIndexMap<Graph>::const_type FIM;
|
||||
FIM ifim = CGAL::get_initialized_face_index_map(g);
|
||||
test_uniqueness(g, faces(g), ifim);
|
||||
|
||||
// Passing an index map via NP
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef std::map<vertex_descriptor, int> VertexIndexMap;
|
||||
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap; // lvalue_pmap
|
||||
|
||||
int vi = static_cast<int>(num_vertices(g));
|
||||
VertexIndexMap vim;
|
||||
VertexIdPropertyMap external_vertex_index_map(vim);
|
||||
for(vertex_descriptor v : vertices(g))
|
||||
put(external_vertex_index_map, v, --vi);
|
||||
|
||||
test_vertex_index_map_uniqueness(g, CGAL::parameters::vertex_index_map(external_vertex_index_map));
|
||||
|
||||
// Read-only pmap
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef std::map<halfedge_descriptor, int> HalfedgeIndexMap;
|
||||
typedef CGAL::Non_mutable_property_map<halfedge_descriptor, int,
|
||||
HalfedgeIndexMap> HalfedgeIdPropertyMap;
|
||||
|
||||
int hi = 0;
|
||||
HalfedgeIndexMap him;
|
||||
HalfedgeIdPropertyMap external_halfedge_index_map(him);
|
||||
|
||||
// this should complain that the map is not writable (commented because it does assert)
|
||||
// CGAL::BGL::internal::initialize_halfedge_index_map(external_halfedge_index_map, g);
|
||||
|
||||
// forced to initialize the underlying map
|
||||
for(halfedge_descriptor h : halfedges(g))
|
||||
him[h] = hi++;
|
||||
|
||||
test_halfedge_index_map_uniqueness(g, CGAL::parameters::halfedge_index_map(external_halfedge_index_map));
|
||||
|
||||
// Writable pmap
|
||||
typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef boost::unordered_map<edge_descriptor, int> EdgeIndexMap;
|
||||
typedef CGAL::RW_property_map<edge_descriptor, int, EdgeIndexMap> EdgeIdPropertyMap;
|
||||
|
||||
EdgeIndexMap eim;
|
||||
EdgeIdPropertyMap external_edge_index_map(eim);
|
||||
CGAL::BGL::internal::initialize_edge_index_map(external_edge_index_map, g);
|
||||
|
||||
test_edge_index_map_uniqueness(g, CGAL::parameters::edge_index_map(external_edge_index_map));
|
||||
|
||||
// Just so face_index_map don't feel excluded
|
||||
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
|
||||
typedef std::map<face_descriptor, int> FaceIndexMap;
|
||||
typedef boost::const_associative_property_map<FaceIndexMap> FaceIdPropertyMap;
|
||||
|
||||
FaceIndexMap fim;
|
||||
FaceIdPropertyMap external_face_index_map(fim);
|
||||
|
||||
// 'const_associative_pmap' has category 'lvalue_property_map_tag' but it's not writable
|
||||
// so below should complain (commented because it does assert)
|
||||
// CGAL::BGL::internal::initialize_face_index_map(external_face_index_map, g);
|
||||
|
||||
// gotta initialize the underlying map
|
||||
int fi = 0;
|
||||
for(face_descriptor f : faces(g))
|
||||
fim[f] = fi++;
|
||||
|
||||
test_face_index_map_uniqueness(g, CGAL::parameters::face_index_map(external_face_index_map));
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void test_all_index_maps_const(const Graph& g)
|
||||
{
|
||||
#ifdef CGAL_TEST_PROPERTIES_DEBUG
|
||||
std::cout << " ---------------------------- Const graph tests" << std::endl;
|
||||
#endif
|
||||
|
||||
template <typename Triangulation>
|
||||
void index_uniqueness_tr(const Triangulation& g)
|
||||
{
|
||||
index_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
index_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
index_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
index_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
test_internal_index_maps_const(g);
|
||||
test_initialized_index_maps_const(g);
|
||||
}
|
||||
|
||||
int main()
|
||||
///////////////////////////////////// non-const ////////////////////////////////////////////////////
|
||||
|
||||
template <typename Graph>
|
||||
void test_internal_index_maps(Graph& g)
|
||||
{
|
||||
test_uniqueness(g, vertices(g), get(boost::vertex_index, g));
|
||||
test_uniqueness(g, halfedges(g), get(boost::halfedge_index, g));
|
||||
test_uniqueness(g, edges(g) , get(boost::edge_index, g));
|
||||
test_uniqueness(g, faces(g), get(boost::face_index, g));
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void test_initialized_index_maps(Graph& g)
|
||||
{
|
||||
typedef typename CGAL::GetInitializedVertexIndexMap<Graph>::type VIM;
|
||||
VIM ivim = CGAL::get_initialized_vertex_index_map(g);
|
||||
test_uniqueness(g, vertices(g), ivim);
|
||||
|
||||
typedef typename CGAL::GetInitializedHalfedgeIndexMap<Graph>::type HIM;
|
||||
HIM ihim = CGAL::get_initialized_halfedge_index_map(g);
|
||||
test_uniqueness(g, halfedges(g), ihim);
|
||||
|
||||
typedef typename CGAL::GetInitializedEdgeIndexMap<Graph>::type EIM;
|
||||
EIM ieim = CGAL::get_initialized_edge_index_map(g);
|
||||
test_uniqueness(g, edges(g), ieim);
|
||||
|
||||
typedef typename CGAL::GetInitializedFaceIndexMap<Graph>::type FIM;
|
||||
FIM ifim = CGAL::get_initialized_face_index_map(g);
|
||||
test_uniqueness(g, faces(g), ifim);
|
||||
|
||||
// Passing an index map via NP
|
||||
typedef typename boost::graph_traits<Graph>::vertex_descriptor vertex_descriptor;
|
||||
typedef std::map<vertex_descriptor, int> VertexIndexMap;
|
||||
typedef boost::associative_property_map<VertexIndexMap> VertexIdPropertyMap; // lvalue_pmap
|
||||
|
||||
int vi = static_cast<int>(num_vertices(g));
|
||||
VertexIndexMap vim;
|
||||
VertexIdPropertyMap external_vertex_index_map(vim);
|
||||
for(vertex_descriptor v : vertices(g))
|
||||
put(external_vertex_index_map, v, --vi);
|
||||
|
||||
test_vertex_index_map_uniqueness(g, CGAL::parameters::vertex_index_map(external_vertex_index_map));
|
||||
|
||||
// Read-only pmap
|
||||
typedef typename boost::graph_traits<Graph>::halfedge_descriptor halfedge_descriptor;
|
||||
typedef std::map<halfedge_descriptor, int> HalfedgeIndexMap;
|
||||
typedef CGAL::Non_mutable_property_map<halfedge_descriptor, int,
|
||||
HalfedgeIndexMap> HalfedgeIdPropertyMap;
|
||||
|
||||
int hi = 0;
|
||||
HalfedgeIndexMap him;
|
||||
HalfedgeIdPropertyMap external_halfedge_index_map(him);
|
||||
|
||||
// this should complain that the map is not writable (commented because it does assert)
|
||||
// CGAL::BGL::internal::initialize_halfedge_index_map(external_halfedge_index_map, g);
|
||||
|
||||
// forced to initialize the underlying map
|
||||
for(halfedge_descriptor h : halfedges(g))
|
||||
him[h] = hi++;
|
||||
|
||||
test_halfedge_index_map_uniqueness(g, CGAL::parameters::halfedge_index_map(external_halfedge_index_map));
|
||||
|
||||
// Writable pmap
|
||||
typedef typename boost::graph_traits<Graph>::edge_descriptor edge_descriptor;
|
||||
typedef boost::unordered_map<edge_descriptor, int> EdgeIndexMap;
|
||||
typedef CGAL::RW_property_map<edge_descriptor, int, EdgeIndexMap> EdgeIdPropertyMap;
|
||||
|
||||
EdgeIndexMap eim;
|
||||
EdgeIdPropertyMap external_edge_index_map(eim);
|
||||
CGAL::BGL::internal::initialize_edge_index_map(external_edge_index_map, g);
|
||||
|
||||
test_edge_index_map_uniqueness(g, CGAL::parameters::edge_index_map(external_edge_index_map));
|
||||
|
||||
// Just so face_index_map don't feel excluded
|
||||
typedef typename boost::graph_traits<Graph>::face_descriptor face_descriptor;
|
||||
typedef std::map<face_descriptor, int> FaceIndexMap;
|
||||
typedef boost::const_associative_property_map<FaceIndexMap> FaceIdPropertyMap;
|
||||
|
||||
FaceIndexMap fim;
|
||||
FaceIdPropertyMap external_face_index_map(fim);
|
||||
|
||||
// 'const_associative_pmap' has category 'lvalue_property_map_tag' but it's not writable
|
||||
// so below should complain (commented because it does assert)
|
||||
// CGAL::BGL::internal::initialize_face_index_map(external_face_index_map, g);
|
||||
|
||||
// gotta initialize the underlying map
|
||||
int fi = 0;
|
||||
for(face_descriptor f : faces(g))
|
||||
fim[f] = fi++;
|
||||
|
||||
test_face_index_map_uniqueness(g, CGAL::parameters::face_index_map(external_face_index_map));
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void test_all_index_maps(Graph& g)
|
||||
{
|
||||
#ifdef CGAL_TEST_PROPERTIES_DEBUG
|
||||
std::cout << " ---------------------------- Non-const graph tests" << std::endl;
|
||||
#endif
|
||||
|
||||
test_internal_index_maps(g);
|
||||
test_initialized_index_maps(g);
|
||||
}
|
||||
|
||||
template <typename Graph>
|
||||
void test_graph(Graph& g)
|
||||
{
|
||||
#ifdef CGAL_TEST_PROPERTIES_DEBUG
|
||||
std::cout << "Graph has:" << std::endl
|
||||
<< "\t" << num_vertices(g) << " vertices (actual: " << vertices(g).size() << ")" << std::endl
|
||||
<< "\t" << num_halfedges(g) << " halfedges (actual: " << halfedges(g).size() << ")" << std::endl
|
||||
<< "\t" << num_edges(g) << " edges (actual: " << edges(g).size() << ")" << std::endl
|
||||
<< "\t" << num_faces(g) << " faces (actual: " << faces(g).size() << ")" << std::endl;
|
||||
#endif
|
||||
|
||||
test_all_index_maps(g);
|
||||
test_all_index_maps_const(g);
|
||||
}
|
||||
|
||||
void test_poly(Polyhedron& g)
|
||||
{
|
||||
test_graph(g);
|
||||
|
||||
test_uniqueness(g, edges(g) , get(boost::edge_external_index, g));
|
||||
test_uniqueness(g, vertices(g), get(boost::vertex_external_index, g));
|
||||
test_uniqueness(g, faces(g), get(boost::face_external_index, g));
|
||||
test_uniqueness(g, halfedges(g), get(boost::halfedge_external_index, g));
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
std::cout << "testing Polyhedron\n";
|
||||
std::vector<Polyhedron> polys = poly_data();
|
||||
for(Polyhedron p : polys)
|
||||
index_uniqueness_poly(p);
|
||||
for(Polyhedron& p : polys)
|
||||
test_poly(p);
|
||||
|
||||
std::cout << "testing Linear_cell_complex\n";
|
||||
std::vector<LCC> lccs = lcc_data();
|
||||
for(LCC p : lccs)
|
||||
index_uniqueness_lcc(p);
|
||||
for(LCC& p : lccs)
|
||||
test_graph(p);
|
||||
|
||||
std::cout << "testing Surface_mesh\n";
|
||||
std::vector<SM> sms = sm_data();
|
||||
for(SM p : sms)
|
||||
index_uniqueness_sm(p);
|
||||
for(SM& sm : sms)
|
||||
{
|
||||
assert(!CGAL::is_empty(sm));
|
||||
|
||||
// Add some garbage
|
||||
CGAL::Euler::join_vertex(*(halfedges(sm).begin()), sm);
|
||||
|
||||
test_graph(sm);
|
||||
|
||||
// Test on a mesh with no internal index maps
|
||||
Seam_edge_pmap seam_edges = sm.add_property_map<SM::Edge_index, bool>("e:on_seam", false).first;
|
||||
Seam_vertex_pmap seam_vertices = sm.add_property_map<SM::Vertex_index, bool>("v:on_seam", false).first;
|
||||
Seam_mesh seam_mesh(sm, seam_edges, seam_vertices);
|
||||
|
||||
test_initialized_index_maps(seam_mesh);
|
||||
test_initialized_index_maps_const(seam_mesh);
|
||||
}
|
||||
|
||||
#if defined(CGAL_USE_OPENMESH)
|
||||
std::cout << "testing OpenMesh\n";
|
||||
std::vector<OMesh> omeshs = omesh_data();
|
||||
for(OMesh p : omeshs)
|
||||
index_uniqueness_omesh(p);
|
||||
for(OMesh& p : omeshs)
|
||||
test_graph(p);
|
||||
#endif
|
||||
|
||||
std::cout << "testing Triangulations\n";
|
||||
index_uniqueness_tr(t2_data());
|
||||
index_uniqueness_tr(dt2_data());
|
||||
index_uniqueness_tr(rt2_data());
|
||||
index_uniqueness_tr(ct2_data());
|
||||
index_uniqueness_tr(cdt2_data());
|
||||
index_uniqueness_tr(cdtp2_data());
|
||||
index_uniqueness_tr(t2h_data());
|
||||
|
||||
std::cerr << "done\n";
|
||||
return 0;
|
||||
Triangulation_2 t2 = t2_data();
|
||||
test_graph(t2);
|
||||
|
||||
Delaunay_triangulation_2 dt2 = dt2_data();
|
||||
test_graph(dt2);
|
||||
|
||||
Regular_triangulation_2 rt2 = rt2_data();
|
||||
test_graph(rt2);
|
||||
|
||||
Constrained_triangulation_2 ct2 = ct2_data();
|
||||
test_graph(ct2);
|
||||
|
||||
Constrained_Delaunay_triangulation_2 cdt2 = cdt2_data();
|
||||
test_graph(cdt2);
|
||||
|
||||
CDT_P2 cdtp2 = cdtp2_data();
|
||||
test_graph(cdtp2);
|
||||
|
||||
Triangulation_hierarchy_2 t2h = t2h_data();
|
||||
test_graph(t2h);
|
||||
|
||||
// no dynamic pmaps in triangulations (yet)
|
||||
// Triangulation_no_id_2 t2_no_id = t2_no_id_data();
|
||||
// test_initialized_index_maps(t2_no_id);
|
||||
// test_initialized_index_maps_const(t2_no_id);
|
||||
|
||||
std::cout << "Done!" << std::endl;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,11 @@ void test(const NamedParameters& np)
|
||||
assert(get_parameter(np, CGAL::internal_np::use_area_smoothing).v == 54);
|
||||
assert(get_parameter(np, CGAL::internal_np::use_Delaunay_flips).v == 55);
|
||||
assert(get_parameter(np, CGAL::internal_np::use_safety_constraints).v == 56);
|
||||
assert(get_parameter(np, CGAL::internal_np::area_threshold).v == 57);
|
||||
assert(get_parameter(np, CGAL::internal_np::volume_threshold).v == 58);
|
||||
assert(get_parameter(np, CGAL::internal_np::dry_run).v == 59);
|
||||
assert(get_parameter(np, CGAL::internal_np::do_lock_mesh).v == 60);
|
||||
assert(get_parameter(np, CGAL::internal_np::do_simplify_border).v == 61);
|
||||
|
||||
// Named parameters that we use in the package 'Surface Mesh Simplification'
|
||||
assert(get_parameter(np, CGAL::internal_np::get_cost_policy).v == 34);
|
||||
@@ -175,6 +180,11 @@ void test(const NamedParameters& np)
|
||||
check_same_type<54>(get_parameter(np, CGAL::internal_np::use_area_smoothing));
|
||||
check_same_type<55>(get_parameter(np, CGAL::internal_np::use_Delaunay_flips));
|
||||
check_same_type<56>(get_parameter(np, CGAL::internal_np::use_safety_constraints));
|
||||
check_same_type<57>(get_parameter(np, CGAL::internal_np::area_threshold));
|
||||
check_same_type<58>(get_parameter(np, CGAL::internal_np::volume_threshold));
|
||||
check_same_type<59>(get_parameter(np, CGAL::internal_np::dry_run));
|
||||
check_same_type<60>(get_parameter(np, CGAL::internal_np::do_lock_mesh));
|
||||
check_same_type<61>(get_parameter(np, CGAL::internal_np::do_simplify_border));
|
||||
|
||||
// Named parameters that we use in the package 'Surface Mesh Simplification'
|
||||
check_same_type<34>(get_parameter(np, CGAL::internal_np::get_cost_policy));
|
||||
@@ -193,6 +203,43 @@ void test(const NamedParameters& np)
|
||||
check_same_type<42>(get_parameter(np, CGAL::internal_np::projection_functor));
|
||||
check_same_type<46>(get_parameter(np, CGAL::internal_np::apply_per_connected_component));
|
||||
check_same_type<47>(get_parameter(np, CGAL::internal_np::output_iterator));
|
||||
|
||||
// Named parameters used in the package 'Point Set Processing'
|
||||
check_same_type<9000>(get_parameter(np, CGAL::internal_np::point_map));
|
||||
check_same_type<9001>(get_parameter(np, CGAL::internal_np::query_point_map));
|
||||
check_same_type<9002>(get_parameter(np, CGAL::internal_np::normal_map));
|
||||
check_same_type<9003>(get_parameter(np, CGAL::internal_np::diagonalize_traits));
|
||||
check_same_type<9004>(get_parameter(np, CGAL::internal_np::svd_traits));
|
||||
check_same_type<9005>(get_parameter(np, CGAL::internal_np::callback));
|
||||
check_same_type<9006>(get_parameter(np, CGAL::internal_np::sharpness_angle));
|
||||
check_same_type<9007>(get_parameter(np, CGAL::internal_np::edge_sensitivity));
|
||||
check_same_type<9008>(get_parameter(np, CGAL::internal_np::neighbor_radius));
|
||||
check_same_type<9009>(get_parameter(np, CGAL::internal_np::number_of_output_points));
|
||||
check_same_type<9010>(get_parameter(np, CGAL::internal_np::size));
|
||||
check_same_type<9011>(get_parameter(np, CGAL::internal_np::maximum_variation));
|
||||
check_same_type<9012>(get_parameter(np, CGAL::internal_np::degree_fitting));
|
||||
check_same_type<9013>(get_parameter(np, CGAL::internal_np::degree_monge));
|
||||
check_same_type<9014>(get_parameter(np, CGAL::internal_np::threshold_percent));
|
||||
check_same_type<9015>(get_parameter(np, CGAL::internal_np::threshold_distance));
|
||||
check_same_type<9016>(get_parameter(np, CGAL::internal_np::attraction_factor));
|
||||
check_same_type<9017>(get_parameter(np, CGAL::internal_np::plane_map));
|
||||
check_same_type<9018>(get_parameter(np, CGAL::internal_np::plane_index_map));
|
||||
check_same_type<9019>(get_parameter(np, CGAL::internal_np::select_percentage));
|
||||
check_same_type<9020>(get_parameter(np, CGAL::internal_np::require_uniform_sampling));
|
||||
check_same_type<9021>(get_parameter(np, CGAL::internal_np::point_is_constrained));
|
||||
check_same_type<9022>(get_parameter(np, CGAL::internal_np::number_of_samples));
|
||||
check_same_type<9023>(get_parameter(np, CGAL::internal_np::accuracy));
|
||||
check_same_type<9024>(get_parameter(np, CGAL::internal_np::maximum_running_time));
|
||||
check_same_type<9025>(get_parameter(np, CGAL::internal_np::overlap));
|
||||
check_same_type<9026>(get_parameter(np, CGAL::internal_np::transformation));
|
||||
check_same_type<9027>(get_parameter(np, CGAL::internal_np::point_set_filters));
|
||||
check_same_type<9028>(get_parameter(np, CGAL::internal_np::matcher));
|
||||
check_same_type<9029>(get_parameter(np, CGAL::internal_np::outlier_filters));
|
||||
check_same_type<9030>(get_parameter(np, CGAL::internal_np::error_minimizer));
|
||||
check_same_type<9031>(get_parameter(np, CGAL::internal_np::transformation_checkers));
|
||||
check_same_type<9032>(get_parameter(np, CGAL::internal_np::inspector));
|
||||
check_same_type<9033>(get_parameter(np, CGAL::internal_np::logger));
|
||||
check_same_type<9034>(get_parameter(np, CGAL::internal_np::maximum_normal_deviation));
|
||||
}
|
||||
|
||||
int main()
|
||||
@@ -265,7 +312,46 @@ int main()
|
||||
.use_area_smoothing(A<54>(54))
|
||||
.use_Delaunay_flips(A<55>(55))
|
||||
.use_safety_constraints(A<56>(56))
|
||||
.area_threshold(A<57>(57))
|
||||
.volume_threshold(A<58>(58))
|
||||
.dry_run(A<59>(59))
|
||||
.do_lock_mesh(A<60>(60))
|
||||
.do_simplify_border(A<61>(61))
|
||||
.point_map(A<9000>(9000))
|
||||
.query_point_map(A<9001>(9001))
|
||||
.normal_map(A<9002>(9002))
|
||||
.diagonalize_traits(A<9003>(9003))
|
||||
.svd_traits(A<9004>(9004))
|
||||
.callback(A<9005>(9005))
|
||||
.sharpness_angle(A<9006>(9006))
|
||||
.edge_sensitivity(A<9007>(9007))
|
||||
.neighbor_radius(A<9008>(9008))
|
||||
.number_of_output_points(A<9009>(9009))
|
||||
.size(A<9010>(9010))
|
||||
.maximum_variation(A<9011>(9011))
|
||||
.degree_fitting(A<9012>(9012))
|
||||
.degree_monge(A<9013>(9013))
|
||||
.threshold_percent(A<9014>(9014))
|
||||
.threshold_distance(A<9015>(9015))
|
||||
.attraction_factor(A<9016>(9016))
|
||||
.plane_map(A<9017>(9017))
|
||||
.plane_index_map(A<9018>(9018))
|
||||
.select_percentage(A<9019>(9019))
|
||||
.require_uniform_sampling(A<9020>(9020))
|
||||
.point_is_constrained_map(A<9021>(9021))
|
||||
.number_of_samples(A<9022>(9022))
|
||||
.accuracy(A<9023>(9023))
|
||||
.maximum_running_time(A<9024>(9024))
|
||||
.overlap(A<9025>(9025))
|
||||
.transformation(A<9026>(9026))
|
||||
.point_set_filters(A<9027>(9027))
|
||||
.matcher(A<9028>(9028))
|
||||
.outlier_filters(A<9029>(9029))
|
||||
.error_minimizer(A<9030>(9030))
|
||||
.transformation_checkers(A<9031>(9031))
|
||||
.inspector(A<9032>(9032))
|
||||
.logger(A<9033>(9033))
|
||||
.maximum_normal_deviation(A<9034>(9034))
|
||||
);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
+2
-2
@@ -2,6 +2,7 @@
|
||||
// We test speed of discrete harmonic coordinates on a set of automatically generated
|
||||
// points inside a regular polygon with 100 vertices. We use inexact kernel.
|
||||
|
||||
#include <CGAL/number_type_config.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Barycentric_coordinates_2/Discrete_harmonic_2.h>
|
||||
@@ -28,12 +29,11 @@ void generate_regular_polygon(const int number_of_vertices, const double polygon
|
||||
{
|
||||
const int n = number_of_vertices;
|
||||
const double r = polygon_radius;
|
||||
const double number_pi = 3.14159;
|
||||
|
||||
vertices.resize(n);
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
vertices[i] = Point(Scalar(r*sin((number_pi / n) + ((i * 2.0 * number_pi) / n))), Scalar(-r*cos((number_pi / n) + ((i * 2.0 * number_pi) / n))));
|
||||
vertices[i] = Point(Scalar(r*sin((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))), Scalar(-r*cos((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))));
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
+2
-2
@@ -2,6 +2,7 @@
|
||||
// We test speed of mean value coordinates on a set of automatically generated
|
||||
// points inside a regular polygon with 100 vertices. We use inexact kernel.
|
||||
|
||||
#include <CGAL/number_type_config.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Barycentric_coordinates_2/Mean_value_2.h>
|
||||
@@ -28,12 +29,11 @@ void generate_regular_polygon(const int number_of_vertices, const double polygon
|
||||
{
|
||||
const int n = number_of_vertices;
|
||||
const double r = polygon_radius;
|
||||
const double number_pi = 3.14159;
|
||||
|
||||
vertices.resize(n);
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
vertices[i] = Point(Scalar(r*sin((number_pi / n) + ((i * 2.0 * number_pi) / n))), Scalar(-r*cos((number_pi / n) + ((i * 2.0 * number_pi) / n))));
|
||||
vertices[i] = Point(Scalar(r*sin((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))), Scalar(-r*cos((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))));
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
+2
-2
@@ -2,6 +2,7 @@
|
||||
// We test speed of Wachspress coordinates on a set of automatically generated
|
||||
// points inside a regular polygon with 100 vertices. We use inexact kernel.
|
||||
|
||||
#include <CGAL/number_type_config.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||
#include <CGAL/Barycentric_coordinates_2/Wachspress_2.h>
|
||||
@@ -28,12 +29,11 @@ void generate_regular_polygon(const int number_of_vertices, const double polygon
|
||||
{
|
||||
const int n = number_of_vertices;
|
||||
const double r = polygon_radius;
|
||||
const double number_pi = 3.14159;
|
||||
|
||||
vertices.resize(n);
|
||||
|
||||
for(int i = 0; i < n; ++i)
|
||||
vertices[i] = Point(Scalar(r*sin((number_pi / n) + ((i * 2.0 * number_pi) / n))), Scalar(-r*cos((number_pi / n) + ((i * 2.0 * number_pi) / n))));
|
||||
vertices[i] = Point(Scalar(r*sin((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))), Scalar(-r*cos((CGAL_PI / n) + ((i * 2.0 * CGAL_PI) / n))));
|
||||
}
|
||||
|
||||
int main()
|
||||
|
||||
@@ -8,15 +8,16 @@ if ( CGAL_FOUND )
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
if (EIGEN3_FOUND)
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
endif()
|
||||
|
||||
# create a target per cppfile
|
||||
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
foreach(cppfile ${cppfiles})
|
||||
if(NOT (${cppfile} STREQUAL "ellipsoid.cpp") OR EIGEN3_FOUND)
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
if (EIGEN3_FOUND)
|
||||
get_filename_component(target ${cppfile} NAME_WE)
|
||||
CGAL_target_use_Eigen(${target})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -14,15 +14,16 @@ if ( CGAL_FOUND )
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0 QUIET) #(3.1.0 or greater)
|
||||
if (EIGEN3_FOUND)
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
endif()
|
||||
|
||||
# create a target per cppfile
|
||||
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
foreach(cppfile ${cppfiles})
|
||||
if(NOT (${cppfile} STREQUAL "Approximate_min_ellipsoid_d.cpp") OR EIGEN3_FOUND)
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
if (EIGEN3_FOUND)
|
||||
get_filename_component(target ${cppfile} NAME_WE)
|
||||
CGAL_target_use_Eigen(${target})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
@@ -242,6 +242,29 @@ void box_intersection_all_pairs_d(
|
||||
cutoff parameters are recommended. See also
|
||||
Section \ref secboxintersperformance .
|
||||
|
||||
\cgalHeading{Concurrency}
|
||||
|
||||
The first template parameter of the function enables to choose whether
|
||||
the algorithm is to be run in parallel, if `CGAL::Parallel_tag` is specified
|
||||
and %CGAL has been linked with the Intel TBB library, or sequentially,
|
||||
if `CGAL::Sequential_tag` - the default value - is specified.
|
||||
The parallelization of the algorithm is based on a divide-and-conquer
|
||||
approach: the two ranges are split in a number of smaller ranges, and
|
||||
all combinations of subranges are treated in parallel. It is thus
|
||||
recommended to use ranges of pointers to bounding boxes, to keep
|
||||
these copies light.
|
||||
|
||||
\warning The parallel mode comes with a small overhead due to the
|
||||
duplication and splitting of the input ranges. It is an improvement
|
||||
for almost all inputs, but not all. A configuration where the two ranges
|
||||
are small and entirely disjoint might result in a slightly worse
|
||||
runtime when using the parallel version. Users should benchmark both
|
||||
versions to verify that their data does not fall in this (small)
|
||||
set of inputs.
|
||||
|
||||
\warning When using the parallel mode, the callback function must
|
||||
be threadsafe.
|
||||
|
||||
\cgalHeading{Example}
|
||||
|
||||
The box implementation provided with
|
||||
@@ -274,7 +297,8 @@ void box_intersection_all_pairs_d(
|
||||
|
||||
|
||||
*/
|
||||
template< class RandomAccessIterator1,
|
||||
template< class ConcurrencyTag = CGAL::Sequential_tag,
|
||||
class RandomAccessIterator1,
|
||||
class RandomAccessIterator2,
|
||||
class Callback >
|
||||
void box_intersection_d(
|
||||
@@ -291,7 +315,8 @@ void box_intersection_d(
|
||||
Invocation with custom box traits.
|
||||
|
||||
*/
|
||||
template< class RandomAccessIterator1,
|
||||
template< class ConcurrencyTag = CGAL::Sequential_tag,
|
||||
class RandomAccessIterator1,
|
||||
class RandomAccessIterator2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_d(
|
||||
@@ -489,8 +514,11 @@ namespace CGAL {
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
||||
See the implementation section of the `box_intersection_d()`
|
||||
function.
|
||||
See the implementation section of the `box_intersection_d()` function.
|
||||
|
||||
\cgalHeading{Concurrency}
|
||||
|
||||
See the concurrency section of the `box_intersection_d()` function.
|
||||
|
||||
\cgalHeading{Example}
|
||||
|
||||
@@ -520,7 +548,8 @@ namespace CGAL {
|
||||
`RandomAccessIterator`.
|
||||
|
||||
*/
|
||||
template< class RandomAccessIterator, class Callback >
|
||||
template< class ConcurrencyTag = CGAL::Sequential_tag,
|
||||
class RandomAccessIterator, class Callback >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIterator begin, RandomAccessIterator end,
|
||||
Callback callback,
|
||||
@@ -532,7 +561,8 @@ void box_self_intersection_d(
|
||||
|
||||
Invocation with custom box traits.
|
||||
*/
|
||||
template< class RandomAccessIterator,
|
||||
template< class ConcurrencyTag = CGAL::Sequential_tag
|
||||
class RandomAccessIterator,
|
||||
class Callback, class BoxTraits >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIterator begin, RandomAccessIterator end,
|
||||
|
||||
@@ -16,34 +16,34 @@
|
||||
|
||||
#include <CGAL/license/Box_intersection_d.h>
|
||||
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Box_intersection_d/Box_d.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
namespace Box_intersection_d {
|
||||
|
||||
template<class NT_, int N, class Info_>
|
||||
class Box_with_info_d : public Box_d< NT_, N, ID_FROM_BOX_ADDRESS> {
|
||||
template<class NT_, int N, class Info_, class IdPolicy = ID_EXPLICIT>
|
||||
class Box_with_info_d
|
||||
: public Box_d< NT_, N, IdPolicy>
|
||||
{
|
||||
protected:
|
||||
Info_ m_info;
|
||||
public:
|
||||
typedef Box_d< NT_, N, ID_FROM_BOX_ADDRESS> Base;
|
||||
typedef NT_ NT;
|
||||
typedef Info_ Info;
|
||||
typedef Box_d< NT_, N, IdPolicy> Base;
|
||||
typedef NT_ NT;
|
||||
typedef Info_ Info;
|
||||
|
||||
Box_with_info_d() {}
|
||||
Box_with_info_d( Info h) : m_info(h) {}
|
||||
Box_with_info_d( bool complete, Info h): Base(complete), m_info(h) {}
|
||||
Box_with_info_d(NT l[N], NT h[N], Info n) : Base( l, h), m_info(n) {}
|
||||
Box_with_info_d( const Bbox_2& b, Info h) : Base( b), m_info(h) {}
|
||||
Box_with_info_d( const Bbox_3& b, Info h) : Base( b), m_info(h) {}
|
||||
|
||||
Info info() const { return m_info; }
|
||||
};
|
||||
|
||||
} // end namespace Box_intersection_d
|
||||
} // namespace Box_intersection_d
|
||||
} // namespace CGAL
|
||||
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif
|
||||
#endif // CGAL_BOX_INTERSECTION_D_BOX_WITH_INFO_D_H
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include <CGAL/license/Box_intersection_d.h>
|
||||
|
||||
|
||||
#include <CGAL/basic.h>
|
||||
#include <CGAL/Box_intersection_d/box_limits.h>
|
||||
|
||||
@@ -24,7 +23,6 @@
|
||||
#include <boost/random/uniform_int.hpp>
|
||||
#include <boost/random/variate_generator.hpp>
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <functional>
|
||||
@@ -93,6 +91,8 @@ void one_way_scan( RandomAccessIter1 p_begin, RandomAccessIter1 p_end,
|
||||
bool in_order = true )
|
||||
{
|
||||
typedef typename Traits::Compare Compare;
|
||||
|
||||
// Putting a parallel sort here slows down the overall parallel algorithm
|
||||
std::sort( p_begin, p_end, Compare( 0 ) );
|
||||
std::sort( i_begin, i_end, Compare( 0 ) );
|
||||
|
||||
@@ -323,7 +323,7 @@ void segment_tree( RandomAccessIter1 p_begin, RandomAccessIter1 p_end,
|
||||
RandomAccessIter2 i_begin, RandomAccessIter2 i_end,
|
||||
T lo, T hi,
|
||||
Callback callback, Predicate_traits traits,
|
||||
std::ptrdiff_t cutoff, int dim, bool in_order )
|
||||
std::ptrdiff_t cutoff, int dim, bool in_order)
|
||||
{
|
||||
typedef typename Predicate_traits::Spanning Spanning;
|
||||
typedef typename Predicate_traits::Lo_less Lo_less;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
|
||||
//
|
||||
//
|
||||
//
|
||||
// Author(s) : Lutz Kettner <kettner@mpi-sb.mpg.de>
|
||||
// Andreas Meyer <ameyer@mpi-sb.mpg.de>
|
||||
@@ -25,12 +25,191 @@
|
||||
#include <CGAL/Box_intersection_d/Box_traits_d.h>
|
||||
#include <CGAL/Box_intersection_d/box_limits.h>
|
||||
|
||||
#include <CGAL/use.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
#include <tbb/task_group.h>
|
||||
#endif
|
||||
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// THE CALLBACK MUST BE THREADSAFE IF YOU ARE USING THE PARALLEL MODE
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace CGAL {
|
||||
namespace internal {
|
||||
|
||||
// Generic call with custom predicate traits parameter.
|
||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
||||
template< class ConcurrencyTag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class Traits >
|
||||
void box_intersection_segment_tree_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback,
|
||||
const Traits& traits,
|
||||
const std::ptrdiff_t cutoff,
|
||||
const bool in_order)
|
||||
{
|
||||
typedef typename Traits::NT NT;
|
||||
|
||||
CGAL_assertion(Traits::dimension() > 0);
|
||||
const int dim = Traits::dimension() - 1;
|
||||
|
||||
const NT inf = Box_intersection_d::box_limits<NT>::inf();
|
||||
const NT sup = Box_intersection_d::box_limits<NT>::sup();
|
||||
|
||||
#ifndef CGAL_LINKED_WITH_TBB
|
||||
CGAL_static_assertion_msg (!(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value),
|
||||
"Parallel_tag is enabled but TBB is unavailable.");
|
||||
#else // CGAL_LINKED_WITH_TBB
|
||||
if(boost::is_convertible<ConcurrencyTag, Parallel_tag>::value)
|
||||
{
|
||||
// Here is an illustration for n=2.
|
||||
//
|
||||
// Doing a R1-R2 intersection with a 2-split is doing 4 subpairs in parallel
|
||||
// a-c and b-d
|
||||
// r1[0][0] --a-- r1[0][1] --b-- r1[0][2]
|
||||
// r2[0][0] --c-- r2[0][1] --d-- r2[0][2]
|
||||
//
|
||||
// a-d and b-c
|
||||
// r1[1][0] --a-- r1[1][1] --b-- r1[1][2]
|
||||
// r2[1][0] --c-- r2[1][1] --d-- r2[1][2]
|
||||
//
|
||||
// Ranges must be duplicates since sorting is performed
|
||||
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::difference_type diff_size;
|
||||
|
||||
typedef std::vector<val_t> val_container;
|
||||
typedef typename val_container::iterator It;
|
||||
|
||||
static constexpr int n = 4;
|
||||
|
||||
const diff_size r1s = std::distance(begin1, end1);
|
||||
const diff_size r2s = std::distance(begin2, end2);
|
||||
|
||||
val_container range_1_copies, range_2_copies;
|
||||
range_1_copies.reserve(r1s * n);
|
||||
range_2_copies.reserve(r2s * n);
|
||||
|
||||
const diff_size r1_step = r1s / n;
|
||||
const diff_size r2_step = r2s / n;
|
||||
|
||||
for(int i=0; i<n; ++i)
|
||||
{
|
||||
range_1_copies.insert(range_1_copies.end(), begin1, end1);
|
||||
range_2_copies.insert(range_2_copies.end(), begin2, end2);
|
||||
}
|
||||
|
||||
// for example for n=2, there's 'begin', 'mid', and 'end' but we leave out 'end' for convenience
|
||||
std::array<std::array<It, n>, n> range_1_iterators;
|
||||
std::array<std::array<It, n>, n> range_2_iterators;
|
||||
|
||||
for(int i=0; i<n; ++i)
|
||||
{
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
range_1_iterators[i][j] = range_1_copies.begin() + i * r1s + j * r1_step;
|
||||
range_2_iterators[i][j] = range_2_copies.begin() + i * r2s + j * r2_step;
|
||||
}
|
||||
}
|
||||
|
||||
tbb::task_group g;
|
||||
|
||||
for(int i=0; i<n; ++i)
|
||||
{
|
||||
for(int j=0; j<n; ++j)
|
||||
{
|
||||
// 'j' vs 'j+i', meaning for each value of 'i' we're matching r1[i] with a shifted version of r2[i]
|
||||
int r1_endi, r1_endj;
|
||||
int r2_endi, r2_endj;
|
||||
|
||||
if(i == (n-1))
|
||||
{
|
||||
if(j == (n-1)) // both very last range and very last iterator
|
||||
{
|
||||
r1_endi = -1;
|
||||
r1_endj = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r1_endi = i;
|
||||
r1_endj = j+1;
|
||||
}
|
||||
}
|
||||
else // i != (n-1)
|
||||
{
|
||||
if(j == (n-1)) // end of that range, but not of the full container
|
||||
{
|
||||
r1_endi = i+1;
|
||||
r1_endj = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r1_endi = i;
|
||||
r1_endj = j+1;
|
||||
}
|
||||
}
|
||||
|
||||
if(i == (n-1))
|
||||
{
|
||||
if(j+i == (n-1)) // both very last range and very last iterator
|
||||
{
|
||||
r2_endi = -1;
|
||||
r2_endj = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
r2_endi = i;
|
||||
r2_endj = (j+i+1)%n;
|
||||
}
|
||||
}
|
||||
else // i != (n-1)
|
||||
{
|
||||
if(j+i == (n-1)) // end of that range, but not of the full container
|
||||
{
|
||||
r2_endi = i+1;
|
||||
r2_endj = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
r2_endi = i;
|
||||
r2_endj = (j+i+1)%n;
|
||||
}
|
||||
}
|
||||
|
||||
It r1_start = range_1_iterators[i][j];
|
||||
It r1_end = (r1_endi == -1) ? range_1_copies.end() : range_1_iterators[r1_endi][r1_endj];
|
||||
It r2_start = range_2_iterators[i][(j+i)%n];
|
||||
It r2_end = (r2_endi == -1) ? range_2_copies.end() : range_2_iterators[r2_endi][r2_endj];
|
||||
CGAL_assertion(range_1_copies.begin() <= r1_start && r1_start <= r1_end && r1_end <= range_1_copies.end());
|
||||
CGAL_assertion(range_2_copies.begin() <= r2_start && r2_start <= r2_end && r2_end <= range_2_copies.end());
|
||||
|
||||
// Specify "copy by value" otherwise the values of iterators for next (i,j) iterations
|
||||
// become shared with different lambdas being run in parallel, and things go wrong
|
||||
g.run([=]{ Box_intersection_d::segment_tree( r1_start, r1_end, r2_start, r2_end,
|
||||
inf, sup, callback, traits, cutoff, dim, in_order); });
|
||||
}
|
||||
}
|
||||
|
||||
g.wait();
|
||||
}
|
||||
else
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
{
|
||||
Box_intersection_d::segment_tree(begin1, end1, begin2, end2, inf, sup, callback, traits, cutoff, dim, in_order);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
|
||||
// Generic call with custom predicate traits parameter.
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class BoxPredicateTraits >
|
||||
void box_intersection_custom_predicates_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
@@ -40,23 +219,15 @@ void box_intersection_custom_predicates_d(
|
||||
std::ptrdiff_t cutoff = 10,
|
||||
Box_intersection_d::Setting setting = Box_intersection_d::BIPARTITE)
|
||||
{
|
||||
typedef BoxPredicateTraits Traits;
|
||||
typedef typename Traits::NT NT;
|
||||
CGAL_assertion( Traits::dimension() > 0 );
|
||||
const int dim = Traits::dimension() - 1;
|
||||
const NT inf = Box_intersection_d::box_limits<NT>::inf();
|
||||
const NT sup = Box_intersection_d::box_limits<NT>::sup();
|
||||
Box_intersection_d::segment_tree(begin1, end1, begin2, end2,
|
||||
inf, sup, callback, traits, cutoff, dim, true);
|
||||
if(setting == Box_intersection_d::BIPARTITE)
|
||||
Box_intersection_d::segment_tree(begin2, end2, begin1, end1,
|
||||
inf, sup, callback, traits, cutoff, dim, false);
|
||||
internal::box_intersection_segment_tree_d<ConcurrencyTag>(begin1, end1, begin2, end2, callback, traits, cutoff, true);
|
||||
if(setting == Box_intersection_d::BIPARTITE)
|
||||
internal::box_intersection_segment_tree_d<ConcurrencyTag>(begin2, end2, begin1, end1, callback, traits, cutoff, false);
|
||||
}
|
||||
|
||||
|
||||
// Generic call with box traits parameter.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
@@ -67,18 +238,19 @@ void box_intersection_d(
|
||||
Box_intersection_d::Topology topology,
|
||||
Box_intersection_d::Setting setting)
|
||||
{
|
||||
if (topology == Box_intersection_d::CLOSED) {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||
box_intersection_custom_predicates_d(begin1, end1, begin2, end2,
|
||||
callback, Traits(), cutoff, setting);
|
||||
} else {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,false> Traits;
|
||||
box_intersection_custom_predicates_d(begin1, end1, begin2, end2,
|
||||
callback, Traits(), cutoff, setting);
|
||||
}
|
||||
if (topology == Box_intersection_d::CLOSED) {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||
box_intersection_custom_predicates_d<ConcurrencyTag>(begin1, end1, begin2, end2,
|
||||
callback, Traits(), cutoff, setting);
|
||||
} else {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,false> Traits;
|
||||
box_intersection_custom_predicates_d<ConcurrencyTag>(begin1, end1, begin2, end2,
|
||||
callback, Traits(), cutoff, setting);
|
||||
}
|
||||
}
|
||||
|
||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
@@ -86,35 +258,39 @@ void box_intersection_d(
|
||||
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff,
|
||||
Box_intersection_d::Topology topology)
|
||||
{
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback, BoxTraits box_traits, std::ptrdiff_t cutoff)
|
||||
{
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
||||
cutoff, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||
cutoff, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
template< class RandomAccessIter1, class RandomAccessIter2,
|
||||
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback, BoxTraits box_traits)
|
||||
{
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, box_traits,
|
||||
10, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, box_traits,
|
||||
10, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
|
||||
// Specialized call with default box traits.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
@@ -122,53 +298,58 @@ void box_intersection_d(
|
||||
Box_intersection_d::Topology topology,
|
||||
Box_intersection_d::Setting setting)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, topology, setting);
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, topology, setting);
|
||||
}
|
||||
|
||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback, std::ptrdiff_t cutoff,
|
||||
Box_intersection_d::Topology topology)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, topology, Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback, std::ptrdiff_t cutoff)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
cutoff, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
template< class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter1, class RandomAccessIter2, class Callback >
|
||||
void box_intersection_d(
|
||||
RandomAccessIter1 begin1, RandomAccessIter1 end1,
|
||||
RandomAccessIter2 begin2, RandomAccessIter2 end2,
|
||||
Callback callback)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
10, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
typedef typename std::iterator_traits<RandomAccessIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_d<ConcurrencyTag>( begin1, end1, begin2, end2, callback, Box_traits(),
|
||||
10, Box_intersection_d::CLOSED,
|
||||
Box_intersection_d::BIPARTITE);
|
||||
}
|
||||
|
||||
|
||||
// Generic call with box traits parameter, specialized for self-intersection.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class RandomAccessIter, class Callback, class BoxTraits >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter, class Callback, class BoxTraits >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback,
|
||||
@@ -176,49 +357,52 @@ void box_self_intersection_d(
|
||||
std::ptrdiff_t cutoff,
|
||||
Box_intersection_d::Topology topology)
|
||||
{
|
||||
// Copying rather than calling 'box_intersection_d(begin, end, begin, end, ...'
|
||||
// is necessary because the 'std::partition' and range splits on the first range
|
||||
// would be messed up by sorts on the second range otherwise.
|
||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||
std::vector< val_t> i( begin, end);
|
||||
box_intersection_d( begin, end, i.begin(), i.end(),
|
||||
callback, box_traits, cutoff, topology,
|
||||
Box_intersection_d::COMPLETE);
|
||||
// Copying rather than calling 'box_intersection_d(begin, end, begin, end, ...'
|
||||
// is necessary because the 'std::partition' and range splits on the first range
|
||||
// would be messed up by sorts on the second range otherwise.
|
||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||
std::vector< val_t> i( begin, end);
|
||||
|
||||
box_intersection_d<ConcurrencyTag>( begin, end, i.begin(), i.end(),
|
||||
callback, box_traits, cutoff, topology,
|
||||
Box_intersection_d::COMPLETE);
|
||||
}
|
||||
|
||||
template< class RandomAccessIter, class Callback, class BoxTraits >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter, class Callback, class BoxTraits >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback,
|
||||
BoxTraits box_traits,
|
||||
std::ptrdiff_t cutoff)
|
||||
{
|
||||
return box_self_intersection_d(begin, end, callback, box_traits, cutoff,
|
||||
Box_intersection_d::CLOSED);
|
||||
return box_self_intersection_d<ConcurrencyTag>(begin, end, callback, box_traits, cutoff,
|
||||
Box_intersection_d::CLOSED);
|
||||
}
|
||||
|
||||
template< class RandomAccessIter, class Callback, class BoxTraits >
|
||||
template< class ConcurrencyTag = Sequential_tag,
|
||||
class RandomAccessIter, class Callback, class BoxTraits >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback,
|
||||
BoxTraits box_traits)
|
||||
{
|
||||
return box_self_intersection_d(begin, end, callback, box_traits, 10);
|
||||
return box_self_intersection_d<ConcurrencyTag>(begin, end, callback, box_traits, 10);
|
||||
}
|
||||
|
||||
// Specialized call with default box traits, specialized for self-intersection.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class RandomAccessIter, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback)
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_self_intersection_d(begin, end, callback, Box_traits());
|
||||
box_self_intersection_d<ConcurrencyTag>(begin, end, callback, Box_traits());
|
||||
}
|
||||
|
||||
template< class RandomAccessIter, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback,
|
||||
@@ -226,10 +410,10 @@ void box_self_intersection_d(
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_self_intersection_d(begin, end, callback, Box_traits(), cutoff);
|
||||
box_self_intersection_d<ConcurrencyTag>(begin, end, callback, Box_traits(), cutoff);
|
||||
}
|
||||
|
||||
template< class RandomAccessIter, class Callback >
|
||||
template< class ConcurrencyTag = Sequential_tag, class RandomAccessIter, class Callback >
|
||||
void box_self_intersection_d(
|
||||
RandomAccessIter begin, RandomAccessIter end,
|
||||
Callback callback,
|
||||
@@ -238,28 +422,27 @@ void box_self_intersection_d(
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomAccessIter>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_self_intersection_d(begin, end, callback,
|
||||
Box_traits(), cutoff, topology );
|
||||
box_self_intersection_d<ConcurrencyTag>(begin, end, callback,
|
||||
Box_traits(), cutoff, topology );
|
||||
}
|
||||
|
||||
|
||||
// Generic call for trivial all-pairs algorithm with box traits parameter.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class ForwardIter1, class ForwardIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback, BoxTraits)
|
||||
{
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
callback, Traits());
|
||||
}
|
||||
|
||||
template< class ForwardIter1, class ForwardIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback, BoxTraits,
|
||||
@@ -269,18 +452,18 @@ void box_intersection_all_pairs_d(
|
||||
bool complete_case = (setting != Box_intersection_d::BIPARTITE);
|
||||
if (topology == Box_intersection_d::CLOSED) {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
callback, Traits(), complete_case);
|
||||
} else {
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,false> Traits;
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
Box_intersection_d::all_pairs( begin1, end1, begin2, end2,
|
||||
callback, Traits(), complete_case);
|
||||
}
|
||||
}
|
||||
|
||||
template< class ForwardIter1, class ForwardIter2,
|
||||
class Callback, class BoxTraits >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback, BoxTraits traits,
|
||||
@@ -293,20 +476,20 @@ void box_intersection_all_pairs_d(
|
||||
// Specialized call for trivial all-pairs algorithm with default box traits.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class ForwardIter1, class ForwardIter2, class Callback >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
callback, Box_traits(),
|
||||
Box_intersection_d::CLOSED );
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
callback, Box_traits(),
|
||||
Box_intersection_d::CLOSED );
|
||||
}
|
||||
|
||||
template< class ForwardIter1, class ForwardIter2, class Callback >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback,
|
||||
@@ -314,12 +497,12 @@ void box_intersection_all_pairs_d(
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
callback, Box_traits(), topology);
|
||||
}
|
||||
|
||||
template< class ForwardIter1, class ForwardIter2, class Callback >
|
||||
void box_intersection_all_pairs_d(
|
||||
void box_intersection_all_pairs_d(
|
||||
ForwardIter1 begin1, ForwardIter1 end1,
|
||||
ForwardIter2 begin2, ForwardIter2 end2,
|
||||
Callback callback,
|
||||
@@ -328,7 +511,7 @@ void box_intersection_all_pairs_d(
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIter1>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
box_intersection_all_pairs_d( begin1, end1, begin2, end2,
|
||||
callback, Box_traits(), topology, setting);
|
||||
}
|
||||
|
||||
@@ -336,7 +519,7 @@ void box_intersection_all_pairs_d(
|
||||
// specialized for self-intersection test.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class ForwardIter, class Callback, class BoxTraits >
|
||||
void box_self_intersection_all_pairs_d(
|
||||
void box_self_intersection_all_pairs_d(
|
||||
ForwardIter begin1, ForwardIter end1, Callback callback, BoxTraits /* traits */)
|
||||
{
|
||||
typedef Box_intersection_d::Predicate_traits_d<BoxTraits,true> Traits;
|
||||
@@ -344,7 +527,7 @@ void box_self_intersection_all_pairs_d(
|
||||
}
|
||||
|
||||
template< class ForwardIter, class Callback, class BoxTraits >
|
||||
void box_self_intersection_all_pairs_d(
|
||||
void box_self_intersection_all_pairs_d(
|
||||
ForwardIter begin1, ForwardIter end1, Callback callback, BoxTraits,
|
||||
Box_intersection_d::Topology topology)
|
||||
{
|
||||
@@ -361,17 +544,17 @@ void box_self_intersection_all_pairs_d(
|
||||
// specialized for self-intersection test.
|
||||
// - make all default parameters explicit overloads (workaround)
|
||||
template< class ForwardIter, class Callback >
|
||||
void box_self_intersection_all_pairs_d(
|
||||
void box_self_intersection_all_pairs_d(
|
||||
ForwardIter begin1, ForwardIter end1, Callback callback)
|
||||
{
|
||||
typedef typename std::iterator_traits<ForwardIter>::value_type val_t;
|
||||
typedef Box_intersection_d::Box_traits_d< val_t> Box_traits;
|
||||
box_self_intersection_all_pairs_d( begin1, end1, callback, Box_traits(),
|
||||
Box_intersection_d::CLOSED );
|
||||
box_self_intersection_all_pairs_d( begin1, end1, callback, Box_traits(),
|
||||
Box_intersection_d::CLOSED );
|
||||
}
|
||||
|
||||
template< class ForwardIter, class Callback >
|
||||
void box_self_intersection_all_pairs_d(
|
||||
void box_self_intersection_all_pairs_d(
|
||||
ForwardIter begin1, ForwardIter end1, Callback callback,
|
||||
Box_intersection_d::Topology topology)
|
||||
{
|
||||
|
||||
@@ -5,20 +5,23 @@
|
||||
cmake_minimum_required(VERSION 3.1...3.15)
|
||||
project( Box_intersection_d_Tests )
|
||||
|
||||
find_package( CGAL QUIET )
|
||||
|
||||
find_package(CGAL QUIET)
|
||||
find_package( TBB )
|
||||
|
||||
if ( CGAL_FOUND )
|
||||
|
||||
# create a target per cppfile
|
||||
file(GLOB cppfiles RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
foreach(cppfile ${cppfiles})
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endforeach()
|
||||
create_single_source_cgal_program( "automated_test.cpp" )
|
||||
create_single_source_cgal_program( "benchmark_box_intersection.cpp" )
|
||||
create_single_source_cgal_program( "random_set_test.cpp" )
|
||||
create_single_source_cgal_program( "test_box_grid.cpp" )
|
||||
|
||||
if( TBB_FOUND )
|
||||
CGAL_target_use_TBB( test_box_grid )
|
||||
else()
|
||||
message( STATUS "NOTICE: Intel TBB was not found. Sequential code will be used." )
|
||||
endif()
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,217 +1,297 @@
|
||||
// file: test/Box_intersection_d/box_grid.C
|
||||
// similar to examples/Box_intersection_d/box_grid.C but stricter in checking
|
||||
// and more extensive in what is tested.
|
||||
#include <CGAL/box_intersection_d.h>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
|
||||
typedef CGAL::Box_intersection_d::Box_d<int,2> Box;
|
||||
#include <CGAL/box_intersection_d.h>
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <iterator>
|
||||
#include <vector>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
#include <tbb/concurrent_vector.h>
|
||||
#endif
|
||||
|
||||
typedef CGAL::Box_intersection_d::Box_d<int, 2> Box;
|
||||
|
||||
// coordinates for 9 boxes of a grid
|
||||
int p[9*4] = { 0,0,1,1, 1,0,2,1, 2,0,3,1, // lower
|
||||
0,1,1,2, 1,1,2,2, 2,1,3,2, // middle
|
||||
0,2,1,3, 1,2,2,3, 2,2,3,3};// upper
|
||||
// 9 boxes + 2 selected boxes as query; center and upper right
|
||||
Box init_boxes[11] = { Box( p, p+ 2), Box( p+ 4, p+ 6), Box( p+ 8, p+10),
|
||||
Box( p+12, p+14), Box( p+16, p+18), Box( p+20, p+22),
|
||||
Box( p+24, p+26), Box( p+28, p+30), Box( p+32, p+34),
|
||||
Box( p+16, p+18), Box( p+32, p+34)};
|
||||
const Box init_boxes[11] = { Box( p, p+ 2), Box( p+ 4, p+ 6), Box( p+ 8, p+10),
|
||||
Box( p+12, p+14), Box( p+16, p+18), Box( p+20, p+22),
|
||||
Box( p+24, p+26), Box( p+28, p+30), Box( p+32, p+34),
|
||||
Box( p+16, p+18), Box( p+32, p+34)};
|
||||
Box boxes[11];
|
||||
Box* query = boxes+9;
|
||||
|
||||
void init() {
|
||||
for ( int i = 0; i < 11; ++i)
|
||||
boxes[i] = init_boxes[i];
|
||||
void init()
|
||||
{
|
||||
for ( int i = 0; i < 11; ++i)
|
||||
boxes[i] = init_boxes[i];
|
||||
}
|
||||
|
||||
void check_result( const char* text, std::vector<std::size_t>& result,
|
||||
const std::size_t* check, std::size_t size) {
|
||||
// sort, show, and check result
|
||||
std::sort( result.begin(), result.end());
|
||||
std::cout << text << ": got " << result.size() << " elements, expected "
|
||||
<< size << " elements\n got : ";
|
||||
std::copy( result.begin(), result.end(),
|
||||
std::ostream_iterator<std::size_t>( std::cout, ","));
|
||||
std::cout << "\n expected: ";
|
||||
std::copy( check, check+size,
|
||||
std::ostream_iterator<std::size_t>( std::cout, ","));
|
||||
std::cout << '\n' << std::endl;
|
||||
assert( result.size() == size
|
||||
&& std::equal( check, check+size, result.begin()));
|
||||
template <typename Vector>
|
||||
void check_result( const char* text,
|
||||
Vector& result,
|
||||
const std::size_t* check,
|
||||
std::size_t size)
|
||||
{
|
||||
// sort, show, and check result
|
||||
std::sort( result.begin(), result.end());
|
||||
std::cout << text << ": got " << result.size() << " elements, expected "
|
||||
<< size << " elements\n got : ";
|
||||
std::copy( result.begin(), result.end(),
|
||||
std::ostream_iterator<std::size_t>( std::cout, ","));
|
||||
std::cout << "\n expected: ";
|
||||
std::copy( check, check+size,
|
||||
std::ostream_iterator<std::size_t>( std::cout, ","));
|
||||
std::cout << '\n' << std::endl;
|
||||
assert( result.size() == size
|
||||
&& std::equal( check, check+size, result.begin()));
|
||||
}
|
||||
|
||||
// callback function object writing results to an output iterator
|
||||
template <class OutputIterator>
|
||||
struct Report {
|
||||
OutputIterator it;
|
||||
Report( OutputIterator i) : it(i) {} // store iterator in object
|
||||
// We encode both id-numbers in a single number, a.id() + 100 * b.id(),
|
||||
// and write that number to the output iterator.
|
||||
void operator()( const Box& a, const Box& b) { *it++ = a.id()+100*b.id(); }
|
||||
template <class Container>
|
||||
struct Report
|
||||
{
|
||||
Container& c_;
|
||||
|
||||
Report(Container& c) : c_(c) {} // store iterator in object
|
||||
// We encode both id-numbers in a single number, a.id() + 100 * b.id(),
|
||||
// and write that number to the output iterator.
|
||||
void operator()(const Box& a, const Box& b) { c_.push_back(a.id()+100*b.id()); }
|
||||
void operator()(const Box* a, const Box* b) { c_.push_back(a->id()+100*b->id()); }
|
||||
};
|
||||
template <class Iter> // helper function to create the function object
|
||||
Report<Iter> report( Iter it) { return Report<Iter>(it); }
|
||||
|
||||
template <class Container> // helper function to create the function object
|
||||
Report<Container> report(Container& c) { return Report<Container>(c); }
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// box_intersection_d
|
||||
// run the intersection algorithms and store results in a vector
|
||||
// ---------------------------------------------------------------------
|
||||
void test_box_intersection() {
|
||||
// intersect 3x3 with 2 query boxes, closed boxes
|
||||
init();
|
||||
std::vector<std::size_t> result;
|
||||
CGAL::box_intersection_d( boxes, boxes+9, query, query+2,
|
||||
report( std::back_inserter( result)));
|
||||
std::size_t check1[13] = {900,901,902,903,904,905,906,907,908,
|
||||
1004,1005,1007,1008};
|
||||
check_result( "Box inters. 3x3, 2, closed", result, check1, 13);
|
||||
void test_box_intersection()
|
||||
{
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
tbb::concurrent_vector<std::size_t> result;
|
||||
#else
|
||||
std::vector<std::size_t> result;
|
||||
#endif
|
||||
|
||||
// intersect 3x3 with 2 query boxes, half-open boxes and changed cutoff
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_d( boxes, boxes+9, query, query+2,
|
||||
report( std::back_inserter( result)),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check2[2] = {904,1008};
|
||||
check_result( "Box inters. 3x3, 2, half-open", result, check2, 2);
|
||||
// Some degenerate cases
|
||||
init();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(boxes, boxes, boxes, boxes,
|
||||
report(result));
|
||||
assert(result.empty());
|
||||
|
||||
// self intersect 3x2, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+6,
|
||||
report( std::back_inserter( result)));
|
||||
std::size_t check3[11] = {1,3,4,102,103,104,105,204,205,304,405};
|
||||
check_result( "Box self inters. 3x2, closed", result, check3, 11);
|
||||
init();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(boxes, boxes, query, query + 1,
|
||||
report(result));
|
||||
assert(result.empty());
|
||||
|
||||
// self intersect 3x2, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+6,
|
||||
report( std::back_inserter( result)),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check4[1] = {9999};
|
||||
check_result( "Box self inters. 3x2, half-open", result, check4, 0);
|
||||
init();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(boxes, boxes + 3, query, query,
|
||||
report(result));
|
||||
assert(result.empty());
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+11,
|
||||
report( std::back_inserter( result)),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check5[2] = {409,810};
|
||||
check_result( "Box self inters. 3x3+2, half-open", result, check5, 2);
|
||||
// With pointers
|
||||
init();
|
||||
std::vector<const Box*> range_1 = {{ boxes, boxes+1, boxes+2, boxes+3, boxes+4, boxes+5,
|
||||
boxes+6, boxes+7, boxes+8 }};
|
||||
std::vector<const Box*> range_2 = {{ query, query+1 }};
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes, full function interf.
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
std::vector<Box> boxes2( boxes, boxes+11);
|
||||
CGAL::box_intersection_d( boxes, boxes+11, boxes2.begin(), boxes2.end(),
|
||||
report( std::back_inserter( result)),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::COMPLETE);
|
||||
check_result( "Box inters. 3x3+2, half-open", result, check5, 2);
|
||||
|
||||
// compare this with the bipartite case
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
boxes2 = std::vector<Box>( boxes, boxes+11);
|
||||
CGAL::box_intersection_d( boxes, boxes+11, boxes2.begin(), boxes2.end(),
|
||||
report( std::back_inserter( result)),
|
||||
std::ptrdiff_t(20),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::BIPARTITE);
|
||||
std::size_t check6[4] = {409,810,904,1008};
|
||||
check_result( "Box inters. 3x3+2, half-open", result, check6, 4);
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(range_1.begin(), range_1.begin(),
|
||||
range_2.begin(), range_2.end(),
|
||||
report(result));
|
||||
assert(result.empty());
|
||||
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(range_1.begin(), range_1.end(),
|
||||
range_2.begin(), range_2.begin(),
|
||||
report(result));
|
||||
assert(result.empty());
|
||||
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(range_1.begin(), range_1.end(),
|
||||
range_2.begin(), range_2.end(),
|
||||
report(result));
|
||||
std::size_t check0[13] = {900,901,902,903,904,905,906,907,908,
|
||||
1004,1005,1007,1008};
|
||||
check_result( "Box inters. 3x3 (ptr), 2, closed", result, check0, 13);
|
||||
|
||||
// intersect 3x3 with 2 query boxes, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(boxes, boxes+9, query, query+1, report(result));
|
||||
std::size_t check1[13] = {900,901,902,903,904,905,906,907,908};
|
||||
check_result( "Box inters. 3x3, 2, closed", result, check1, 9);
|
||||
|
||||
// intersect 3x3 with 2 query boxes, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>(boxes, boxes+9, query, query+2, report(result));
|
||||
std::size_t check1bis[13] = {900,901,902,903,904,905,906,907,908,
|
||||
1004,1005,1007,1008};
|
||||
check_result( "Box inters. 3x3, 2, closed", result, check1bis, 13);
|
||||
|
||||
// intersect 3x3 with 2 query boxes, half-open boxes and changed cutoff
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_d( boxes, boxes+9, query, query+2,
|
||||
report(result),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check2[2] = {904,1008};
|
||||
check_result( "Box inters. 3x3, 2, half-open", result, check2, 2);
|
||||
|
||||
// intersect 3x3 with 2 query boxes, half-open boxes and changed cutoff (reversed)
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_d<CGAL::Parallel_if_available_tag>( query, query+2, boxes, boxes+9,
|
||||
report(result),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check2bis[2] = {409,810};
|
||||
check_result( "Box inters. 3x3 (reversed), 2, half-open", result, check2bis, 2);
|
||||
|
||||
// self intersect 3x2, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+6,
|
||||
report(result));
|
||||
std::size_t check3[11] = {1,3,4,102,103,104,105,204,205,304,405};
|
||||
check_result( "Box self inters. 3x2, closed", result, check3, 11);
|
||||
|
||||
// self intersect 3x2, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+6,
|
||||
report(result),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check4[1] = {9999};
|
||||
check_result( "Box self inters. 3x2, half-open", result, check4, 0);
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_d( boxes, boxes+11,
|
||||
report(result),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check5[2] = {409,810};
|
||||
check_result( "Box self inters. 3x3+2, half-open", result, check5, 2);
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes, full function interf.
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
std::vector<Box> boxes2( boxes, boxes+11);
|
||||
CGAL::box_intersection_d( boxes, boxes+11, boxes2.begin(), boxes2.end(),
|
||||
report(result),
|
||||
std::ptrdiff_t(1),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::COMPLETE);
|
||||
check_result( "Box inters. 3x3+2, half-open", result, check5, 2);
|
||||
|
||||
// compare this with the bipartite case
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
boxes2 = std::vector<Box>( boxes, boxes+11);
|
||||
CGAL::box_intersection_d( boxes, boxes+11, boxes2.begin(), boxes2.end(),
|
||||
report(result),
|
||||
std::ptrdiff_t(20),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::BIPARTITE);
|
||||
std::size_t check6[4] = {409,810,904,1008};
|
||||
check_result( "Box inters. 3x3+2, half-open", result, check6, 4);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// box_intersection_all_pairs_d
|
||||
// run the intersection algorithms and store results in a vector
|
||||
// ---------------------------------------------------------------------
|
||||
void test_box_intersection_all_pairs() {
|
||||
// intersect 3x3 with 2 query boxes, closed boxes
|
||||
init();
|
||||
std::vector<std::size_t> result;
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+9, query, query+2,
|
||||
report( std::back_inserter( result)));
|
||||
std::size_t check1[13] = {900,901,902,903,904,905,906,907,908,
|
||||
1004,1005,1007,1008};
|
||||
check_result( "All-pairs inters. 3x3, 2, closed", result, check1, 13);
|
||||
void test_box_intersection_all_pairs()
|
||||
{
|
||||
// intersect 3x3 with 2 query boxes, closed boxes
|
||||
init();
|
||||
std::vector<std::size_t> result;
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+9, query, query+2,
|
||||
report(result));
|
||||
std::size_t check1[13] = {900,901,902,903,904,905,906,907,908,
|
||||
1004,1005,1007,1008};
|
||||
check_result( "All-pairs inters. 3x3, 2, closed", result, check1, 13);
|
||||
|
||||
// intersect 3x3 with 2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+9, query, query+2,
|
||||
report( std::back_inserter( result)),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check2[2] = {904,1008};
|
||||
check_result( "All-pairs inters. 3x3, 2, half-open", result, check2, 2);
|
||||
// intersect 3x3 with 2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+9, query, query+2,
|
||||
report(result),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check2[2] = {904,1008};
|
||||
check_result( "All-pairs inters. 3x3, 2, half-open", result, check2, 2);
|
||||
|
||||
// self intersect 3x2, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+6,
|
||||
report( std::back_inserter( result)));
|
||||
std::size_t check3[11] = {100,201,300,301,400,401,402,403,501,502,504};
|
||||
check_result( "All-pairs self inters. 3x2, closed", result, check3, 11);
|
||||
// self intersect 3x2, closed boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+6,
|
||||
report(result));
|
||||
std::size_t check3[11] = {100,201,300,301,400,401,402,403,501,502,504};
|
||||
check_result( "All-pairs self inters. 3x2, closed", result, check3, 11);
|
||||
|
||||
// self intersect 3x2, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+6,
|
||||
report( std::back_inserter( result)),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check4[1] = {9999};
|
||||
check_result( "All-pairs self inters. 3x2, half-open", result, check4, 0);
|
||||
// self intersect 3x2, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+6,
|
||||
report(result),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check4[1] = {9999};
|
||||
check_result( "All-pairs self inters. 3x2, half-open", result, check4, 0);
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+11,
|
||||
report( std::back_inserter( result)),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check5[2] = {904,1008};
|
||||
check_result( "All-pairs self inters. 3x3+2, half-open", result, check5,2);
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
init();
|
||||
result.clear();
|
||||
CGAL::box_self_intersection_all_pairs_d( boxes, boxes+11,
|
||||
report(result),
|
||||
CGAL::Box_intersection_d::HALF_OPEN);
|
||||
std::size_t check5[2] = {904,1008};
|
||||
check_result( "All-pairs self inters. 3x3+2, half-open", result, check5,2);
|
||||
|
||||
// self intersect 3x3+2 query boxes, half-open boxes, full function interf.
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
std::vector<Box> boxes2( boxes, boxes+11);
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+11,
|
||||
boxes2.begin(), boxes2.end(),
|
||||
report( std::back_inserter( result)),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::COMPLETE);
|
||||
check_result( "All-pairs self inters. 3x3+2, half-open", result, check5,2);
|
||||
|
||||
// compare this with the bipartite case
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
boxes2 = std::vector<Box>( boxes, boxes+11);
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+11,
|
||||
boxes2.begin(), boxes2.end(),
|
||||
report( std::back_inserter( result)),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::BIPARTITE);
|
||||
std::size_t check6[4] = {409,810,904,1008};
|
||||
check_result( "All-pairs inters. 3x3+2, half-open", result, check6, 4);
|
||||
// self intersect 3x3+2 query boxes, half-open boxes, full function interf.
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
std::vector<Box> boxes2( boxes, boxes+11);
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+11,
|
||||
boxes2.begin(), boxes2.end(),
|
||||
report(result),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::COMPLETE);
|
||||
check_result( "All-pairs self inters. 3x3+2, half-open", result, check5,2);
|
||||
|
||||
// compare this with the bipartite case
|
||||
// self intersect 3x3+2 query boxes, half-open boxes
|
||||
// tests also mixed types for the two iterator ranges
|
||||
init();
|
||||
result.clear();
|
||||
boxes2 = std::vector<Box>( boxes, boxes+11);
|
||||
CGAL::box_intersection_all_pairs_d( boxes, boxes+11,
|
||||
boxes2.begin(), boxes2.end(),
|
||||
report(result),
|
||||
CGAL::Box_intersection_d::HALF_OPEN,
|
||||
CGAL::Box_intersection_d::BIPARTITE);
|
||||
std::size_t check6[4] = {409,810,904,1008};
|
||||
check_result( "All-pairs inters. 3x3+2, half-open", result, check6, 4);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
test_box_intersection();
|
||||
test_box_intersection_all_pairs();
|
||||
|
||||
int main() {
|
||||
test_box_intersection();
|
||||
test_box_intersection_all_pairs();
|
||||
return 0;
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -76,6 +76,10 @@ read_vtk_image_data(vtkImageData* vtk_image, Image_3::Own owning = Image_3::OWN_
|
||||
image->wdim = imageio_type.wdim;
|
||||
image->wordKind = imageio_type.wordKind;
|
||||
image->sign = imageio_type.sign;
|
||||
if (!vtk_image->GetPointData() || !vtk_image->GetPointData()->GetScalars()) {
|
||||
::_freeImage(image);
|
||||
return Image_3();
|
||||
}
|
||||
CGAL_assertion(vtk_image->GetPointData()->GetScalars()->GetNumberOfTuples() == dims[0]*dims[1]*dims[2]);
|
||||
if(owning == Image_3::OWN_THE_DATA) {
|
||||
image->data = ::ImageIO_alloc(dims[0]*dims[1]*dims[2]*image->wdim);
|
||||
|
||||
@@ -27,9 +27,7 @@ if ( CGAL_FOUND )
|
||||
include(${CGAL_USE_FILE})
|
||||
|
||||
find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater)
|
||||
if (EIGEN3_FOUND)
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
else()
|
||||
if (NOT EIGEN3_FOUND)
|
||||
message(STATUS "NOTICE: This project requires the Eigen library, and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
@@ -143,6 +141,7 @@ if ( CGAL_FOUND )
|
||||
add_library(CGAL_${IPELET} MODULE ${IPELET}.cpp)
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS CGAL_${IPELET})
|
||||
target_link_libraries(CGAL_${IPELET} PRIVATE CGAL::CGAL ${IPE_LIBRARIES})
|
||||
CGAL_target_use_Eigen(CGAL_${IPELET})
|
||||
if ( IPELET_INSTALL_DIR )
|
||||
install(TARGETS CGAL_${IPELET} DESTINATION ${IPELET_INSTALL_DIR})
|
||||
if (WITH_IPE_7)
|
||||
@@ -153,12 +152,13 @@ if ( CGAL_FOUND )
|
||||
endforeach(IPELET)
|
||||
if(CGAL_Core_FOUND)
|
||||
target_link_libraries(CGAL_cone_spanners PRIVATE CGAL::CGAL_Core)
|
||||
CGAL_target_use_Eigen(CGAL_cone_spanners)
|
||||
endif()
|
||||
#example in doc not installed
|
||||
add_library(simple_triangulation MODULE simple_triangulation.cpp)
|
||||
add_to_cached_list(CGAL_EXECUTABLE_TARGETS simple_triangulation)
|
||||
target_link_libraries(simple_triangulation ${IPE_LIBRARIES})
|
||||
|
||||
CGAL_target_use_Eigen(simple_triangulation)
|
||||
cgal_add_compilation_test(simple_triangulation)
|
||||
|
||||
else()
|
||||
|
||||
@@ -50,6 +50,15 @@ public:
|
||||
PointC2(const FT &hx, const FT &hy, const FT &hw)
|
||||
: base(hx, hy, hw) {}
|
||||
|
||||
friend void swap(Self& a, Self& b)
|
||||
#ifdef __cpp_lib_is_swappable
|
||||
noexcept(std::is_nothrow_swappable_v<Vector_2_>)
|
||||
#endif
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.base, b.base);
|
||||
}
|
||||
|
||||
const FT& x() const
|
||||
{
|
||||
return base.x();
|
||||
|
||||
@@ -24,6 +24,7 @@ namespace CGAL {
|
||||
template < class R_ >
|
||||
class PointC3
|
||||
{
|
||||
typedef PointC3<R_> Self;
|
||||
typedef typename R_::Vector_3 Vector_3;
|
||||
typedef typename R_::Point_3 Point_3;
|
||||
typedef typename R_::Aff_transformation_3 Aff_transformation_3;
|
||||
@@ -47,6 +48,15 @@ public:
|
||||
PointC3(const FT &x, const FT &y, const FT &z, const FT &w)
|
||||
: base(x, y, z, w) {}
|
||||
|
||||
friend void swap(Self& a, Self& b)
|
||||
#ifdef __cpp_lib_is_swappable
|
||||
noexcept(std::is_nothrow_swappable_v<Vector_3>)
|
||||
#endif
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.base, b.base);
|
||||
}
|
||||
|
||||
const FT & x() const
|
||||
{
|
||||
return base.x();
|
||||
|
||||
@@ -27,6 +27,7 @@ namespace CGAL {
|
||||
template < class R_ >
|
||||
class VectorC2
|
||||
{
|
||||
typedef VectorC2<R_> Self;
|
||||
typedef typename R_::FT FT;
|
||||
typedef typename R_::Point_2 Point_2;
|
||||
typedef typename R_::Vector_2 Vector_2;
|
||||
@@ -55,6 +56,15 @@ public:
|
||||
: base( hw != FT(1) ? CGAL::make_array<FT>(hx/hw, hy/hw)
|
||||
: CGAL::make_array(hx, hy) ) {}
|
||||
|
||||
friend void swap(Self& a, Self& b)
|
||||
#ifdef __cpp_lib_is_swappable
|
||||
noexcept(std::is_nothrow_swappable_v<Base>)
|
||||
#endif
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.base, b.base);
|
||||
}
|
||||
|
||||
const FT & x() const
|
||||
{
|
||||
return CGAL::get_pointee_or_identity(base)[0];
|
||||
|
||||
@@ -27,6 +27,7 @@ template < class R_ >
|
||||
class VectorC3
|
||||
{
|
||||
// https://doc.cgal.org/latest/Manual/devman_code_format.html#secprogramming_conventions
|
||||
typedef VectorC3<R_> Self;
|
||||
typedef typename R_::FT FT_;
|
||||
typedef typename R_::Point_3 Point_3;
|
||||
typedef typename R_::Vector_3 Vector_3;
|
||||
@@ -70,6 +71,15 @@ public:
|
||||
: base( w != FT_(1) ? CGAL::make_array<FT_>(x/w, y/w, z/w)
|
||||
: CGAL::make_array(x, y, z) ) {}
|
||||
|
||||
friend void swap(Self& a, Self& b)
|
||||
#ifdef __cpp_lib_is_swappable
|
||||
noexcept(std::is_nothrow_swappable_v<Base>)
|
||||
#endif
|
||||
{
|
||||
using std::swap;
|
||||
swap(a.base, b.base);
|
||||
}
|
||||
|
||||
const FT_ & x() const
|
||||
{
|
||||
return get_pointee_or_identity(base)[0];
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace CGAL {
|
||||
}
|
||||
break;
|
||||
case BIPOLAR:
|
||||
CGAL_kernel_precondition(!"This function does not accept bipolar circle as input.");
|
||||
CGAL_kernel_precondition_msg(false, "This function does not accept bipolar circle as input.");
|
||||
}
|
||||
return out_it;
|
||||
}
|
||||
|
||||
+1
-1
@@ -516,7 +516,7 @@ namespace CGAL {
|
||||
break;
|
||||
}
|
||||
case BIPOLAR:
|
||||
CGAL_kernel_precondition(!"This function does not accept bipolar circle as input.");
|
||||
CGAL_kernel_precondition_msg(false, "This function does not accept bipolar circle as input.");
|
||||
}
|
||||
|
||||
return out_it;
|
||||
|
||||
@@ -5,7 +5,6 @@ cmake_minimum_required(VERSION 3.1...3.15)
|
||||
project( Classification_Examples )
|
||||
|
||||
|
||||
|
||||
# CGAL and its components
|
||||
find_package( CGAL QUIET COMPONENTS )
|
||||
|
||||
@@ -22,127 +21,73 @@ if ( NOT Boost_FOUND )
|
||||
return()
|
||||
endif()
|
||||
|
||||
find_package( Boost OPTIONAL_COMPONENTS serialization iostreams )
|
||||
set(Classification_dependencies_met TRUE)
|
||||
|
||||
if( WIN32 )
|
||||
# to avoid a warning with old cmake
|
||||
set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp")
|
||||
set(_Boost_ZLIB_HEADERS "boost/iostreams/filter/zlib.hpp")
|
||||
find_package( Boost OPTIONAL_COMPONENTS bzip2 zlib)
|
||||
else()
|
||||
find_package(ZLIB QUIET)
|
||||
find_package( Boost OPTIONAL_COMPONENTS serialization iostreams )
|
||||
if (NOT Boost_SERIALIZATION_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost Serialization, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
if (NOT Boost_IOSTREAMS_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost IO Streams, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
find_package(OpenCV QUIET COMPONENTS core ml) # Need core + machine learning
|
||||
if (NOT OpenCV_FOUND)
|
||||
message(STATUS "NOTICE: OpenCV was not found. OpenCV random forest predicate for classification won't be available.")
|
||||
endif()
|
||||
|
||||
find_package(TensorFlow QUIET)
|
||||
if (NOT TensorFlow_FOUND)
|
||||
message(STATUS "NOTICE: TensorFlow was not found. TensorFlow neural network predicate for classification won't be available.")
|
||||
endif()
|
||||
|
||||
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
|
||||
if (NOT EIGEN3_FOUND)
|
||||
message(STATUS "This project requires the Eigen library, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
find_package(TBB QUIET)
|
||||
|
||||
find_package(OpenCV QUIET COMPONENTS core ml) # Need core + machine learning
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
|
||||
if (NOT EIGEN3_FOUND)
|
||||
message(STATUS "This project requires the Eigen library, and will not be compiled.")
|
||||
return()
|
||||
else()
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
endif()
|
||||
|
||||
|
||||
# Creating entries for all C++ files with "main" routine
|
||||
# ##########################################################
|
||||
|
||||
# Classification examples
|
||||
set(targets
|
||||
example_classification
|
||||
example_ethz_random_forest
|
||||
example_feature
|
||||
example_generation_and_training
|
||||
example_mesh_classification
|
||||
example_cluster_classification)
|
||||
|
||||
# Classification requires some C++11 features
|
||||
set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates)
|
||||
|
||||
# Libraries and flags
|
||||
set(classification_linked_libraries)
|
||||
set(classification_compile_definitions)
|
||||
|
||||
|
||||
if (Boost_SERIALIZATION_FOUND AND Boost_IOSTREAMS_FOUND)
|
||||
if(TARGET Boost::serialization AND TARGET Boost::iostreams)
|
||||
set(classification_linked_libraries Boost::serialization Boost::iostreams)
|
||||
else()
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${Boost_SERIALIZATION_LIBRARY}
|
||||
${Boost_IOSTREAMS_LIBRARY})
|
||||
endif()
|
||||
else()
|
||||
if (NOT Boost_SERIALIZATION_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost Serialization, and will not be compiled.")
|
||||
endif()
|
||||
if (NOT Boost_IOSTREAMS_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost IO Streams, and will not be compiled.")
|
||||
endif()
|
||||
if (NOT Classification_dependencies_met)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if( WIN32 )
|
||||
if (Boost_ZLIB_FOUND AND Boost_BZIP2_FOUND)
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${Boost_ZLIB_LIBRARY} ${Boost_BZIP2_LIBRARY})
|
||||
else()
|
||||
message(STATUS "NOTICE: This project requires Boost ZLIB and Boost BZIP2, and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
if(ZLIB_FOUND)
|
||||
set(classification_linked_libraries ${classification_linked_libraries} ZLIB::ZLIB)
|
||||
else()
|
||||
message(STATUS "NOTICE: This project requires ZLIB, and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
create_single_source_cgal_program( "example_classification.cpp" )
|
||||
create_single_source_cgal_program( "example_ethz_random_forest.cpp" )
|
||||
create_single_source_cgal_program( "example_feature.cpp" )
|
||||
create_single_source_cgal_program( "example_generation_and_training.cpp" )
|
||||
create_single_source_cgal_program( "example_mesh_classification.cpp" )
|
||||
create_single_source_cgal_program( "example_cluster_classification.cpp" )
|
||||
|
||||
if (OpenCV_FOUND)
|
||||
message(STATUS "Found OpenCV ${OpenCV_VERSION}")
|
||||
include_directories(${OpenCV_INCLUDE_DIRS})
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${OpenCV_LIBS})
|
||||
set(classification_compile_definitions ${classification_compile_definitions}
|
||||
"-DCGAL_LINKED_WITH_OPENCV")
|
||||
|
||||
set(targets ${targets} example_opencv_random_forest)
|
||||
else()
|
||||
message(STATUS "NOTICE: OpenCV was not found. OpenCV random forest predicate for classification won't be available.")
|
||||
create_single_source_cgal_program( "example_opencv_random_forest.cpp" )
|
||||
CGAL_target_use_OpenCV(example_opencv_random_forest)
|
||||
endif()
|
||||
|
||||
find_package(TensorFlow QUIET)
|
||||
if (TensorFlow_FOUND)
|
||||
message(STATUS "Found TensorFlow")
|
||||
include_directories( ${TensorFlow_INCLUDE_DIR} )
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${TensorFlow_LIBRARY})
|
||||
set(classification_compile_definitions ${classification_compile_definitions}
|
||||
"-DCGAL_LINKED_WITH_TENSORFLOW")
|
||||
|
||||
set(targets ${targets} example_tensorflow_neural_network)
|
||||
else()
|
||||
message(STATUS "NOTICE: TensorFlow not found, Neural Network predicate for classification won't be available.")
|
||||
create_single_source_cgal_program( "example_tensorflow_neural_network.cpp" )
|
||||
CGAL_target_use_TensorFlow(example_tensorflow_neural_network)
|
||||
endif()
|
||||
|
||||
|
||||
# Creating targets with correct libraries and flags
|
||||
foreach(target ${targets})
|
||||
create_single_source_cgal_program( "${target}.cpp" CXX_FEATURES ${needed_cxx_features} )
|
||||
foreach(target
|
||||
example_classification
|
||||
example_ethz_random_forest
|
||||
example_feature
|
||||
example_generation_and_training
|
||||
example_mesh_classification
|
||||
example_cluster_classification
|
||||
example_opencv_random_forest
|
||||
example_tensorflow_neural_network)
|
||||
if(TARGET ${target})
|
||||
target_link_libraries(${target} PUBLIC ${classification_linked_libraries})
|
||||
target_compile_definitions(${target} PUBLIC ${classification_compile_definitions})
|
||||
CGAL_target_use_Eigen(${target})
|
||||
CGAL_target_use_Boost_IOStreams(${target})
|
||||
CGAL_target_use_Boost_Serialization(${target})
|
||||
if(TBB_FOUND)
|
||||
CGAL_target_use_TBB(${target})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -11,16 +11,12 @@
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Classification.h>
|
||||
#include <CGAL/bounding_box.h>
|
||||
|
||||
#include <CGAL/tags.h>
|
||||
#include <CGAL/IO/read_ply_points.h>
|
||||
|
||||
#include <CGAL/Real_timer.h>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
typedef CGAL::Parallel_tag Concurrency_tag;
|
||||
#else
|
||||
typedef CGAL::Sequential_tag Concurrency_tag;
|
||||
#endif
|
||||
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
||||
@@ -18,11 +18,7 @@
|
||||
#include <CGAL/Shape_detection/Region_growing.h>
|
||||
#include <CGAL/Real_timer.h>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
typedef CGAL::Parallel_tag Concurrency_tag;
|
||||
#else
|
||||
typedef CGAL::Sequential_tag Concurrency_tag;
|
||||
#endif
|
||||
typedef CGAL::Parallel_if_available_tag Concurrency_tag;
|
||||
|
||||
typedef CGAL::Simple_cartesian<double> Kernel;
|
||||
typedef Kernel::Point_3 Point;
|
||||
|
||||
@@ -127,11 +127,7 @@ public:
|
||||
std::size_t num_trees = 25,
|
||||
std::size_t max_depth = 20)
|
||||
{
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
train<CGAL::Parallel_tag>(ground_truth, reset_trees, num_trees, max_depth);
|
||||
#else
|
||||
train<CGAL::Sequential_tag>(ground_truth, reset_trees, num_trees, max_depth);
|
||||
#endif
|
||||
train<CGAL::Parallel_if_available_tag>(ground_truth, reset_trees, num_trees, max_depth);
|
||||
}
|
||||
/// \endcond
|
||||
|
||||
@@ -146,7 +142,7 @@ public:
|
||||
label.
|
||||
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` (default value is
|
||||
algorithm. Possible values are `Parallel_tag` (default value if
|
||||
%CGAL is linked with TBB) or `Sequential_tag` (default value
|
||||
otherwise).
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/blocked_range.h>
|
||||
#include <tbb/scalable_allocator.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
#include <tbb/task_group.h>
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/blocked_range.h>
|
||||
#include <tbb/scalable_allocator.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
namespace CGAL {
|
||||
@@ -69,7 +70,7 @@ private:
|
||||
PointMap m_point_map;
|
||||
const NeighborQuery& m_neighbor_query;
|
||||
float& m_mean_range;
|
||||
tbb::mutex& m_mutex;
|
||||
std::mutex& m_mutex;
|
||||
|
||||
public:
|
||||
|
||||
@@ -78,7 +79,7 @@ private:
|
||||
PointMap point_map,
|
||||
const NeighborQuery& neighbor_query,
|
||||
float& mean_range,
|
||||
tbb::mutex& mutex)
|
||||
std::mutex& mutex)
|
||||
: m_eigen (eigen), m_input (input), m_point_map (point_map),
|
||||
m_neighbor_query (neighbor_query), m_mean_range (mean_range), m_mutex (mutex)
|
||||
{ }
|
||||
@@ -120,7 +121,7 @@ private:
|
||||
const FaceListGraph& m_input;
|
||||
const NeighborQuery& m_neighbor_query;
|
||||
float& m_mean_range;
|
||||
tbb::mutex& m_mutex;
|
||||
std::mutex& m_mutex;
|
||||
|
||||
public:
|
||||
|
||||
@@ -128,7 +129,7 @@ private:
|
||||
const FaceListGraph& input,
|
||||
const NeighborQuery& neighbor_query,
|
||||
float& mean_range,
|
||||
tbb::mutex& mutex)
|
||||
std::mutex& mutex)
|
||||
: m_eigen (eigen), m_input (input),
|
||||
m_neighbor_query (neighbor_query), m_mean_range (mean_range), m_mutex (mutex)
|
||||
{ }
|
||||
@@ -225,7 +226,7 @@ public:
|
||||
is `CGAL::Point_3`.
|
||||
\tparam NeighborQuery model of `NeighborQuery`
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
algorithm. Possible values are `Parallel_tag` (default value if %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted if Eigen 3 (or greater)
|
||||
@@ -241,10 +242,8 @@ public:
|
||||
typename NeighborQuery,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename ConcurrencyTag,
|
||||
#elif defined(CGAL_LINKED_WITH_TBB)
|
||||
typename ConcurrencyTag = CGAL::Parallel_tag,
|
||||
#else
|
||||
typename ConcurrencyTag = CGAL::Sequential_tag,
|
||||
typename ConcurrencyTag = CGAL::Parallel_if_available_tag,
|
||||
#endif
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename DiagonalizeTraits>
|
||||
@@ -271,7 +270,7 @@ public:
|
||||
#else
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
tbb::mutex mutex;
|
||||
std::mutex mutex;
|
||||
Compute_eigen_values<PointRange, PointMap, NeighborQuery, DiagonalizeTraits>
|
||||
f(out, input, point_map, neighbor_query, out.m_content->mean_range, mutex);
|
||||
tbb::parallel_for(tbb::blocked_range<size_t>(0, input.size ()), f);
|
||||
@@ -309,7 +308,7 @@ public:
|
||||
\tparam FaceListGraph model of `FaceListGraph`.
|
||||
\tparam NeighborQuery model of `NeighborQuery`
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
algorithm. Possible values are `Parallel_tag` (default value if %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted: if Eigen 3 (or greater)
|
||||
@@ -324,10 +323,8 @@ public:
|
||||
typename NeighborQuery,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename ConcurrencyTag,
|
||||
#elif defined(CGAL_LINKED_WITH_TBB)
|
||||
typename ConcurrencyTag = CGAL::Parallel_tag,
|
||||
#else
|
||||
typename ConcurrencyTag = CGAL::Sequential_tag,
|
||||
typename ConcurrencyTag = CGAL::Parallel_if_available_tag,
|
||||
#endif
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename DiagonalizeTraits>
|
||||
@@ -361,7 +358,7 @@ public:
|
||||
#else
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
tbb::mutex mutex;
|
||||
std::mutex mutex;
|
||||
Compute_eigen_values_graph<FaceListGraph, NeighborQuery, DiagonalizeTraits>
|
||||
f(out, input, neighbor_query, out.m_content->mean_range, mutex);
|
||||
|
||||
@@ -395,7 +392,7 @@ public:
|
||||
`RandomAccessIterator` and its value type is the key type of
|
||||
`PointMap`.
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
algorithm. Possible values are `Parallel_tag` (default value if %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted: if Eigen 3 (or greater)
|
||||
@@ -408,10 +405,8 @@ public:
|
||||
template <typename ClusterRange,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename ConcurrencyTag,
|
||||
#elif defined(CGAL_LINKED_WITH_TBB)
|
||||
typename ConcurrencyTag = CGAL::Parallel_tag,
|
||||
#else
|
||||
typename ConcurrencyTag = CGAL::Sequential_tag,
|
||||
typename ConcurrencyTag = CGAL::Parallel_if_available_tag,
|
||||
#endif
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename DiagonalizeTraits>
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
#ifdef CGAL_LINKED_WITH_TBB
|
||||
#include <tbb/task_group.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
namespace CGAL {
|
||||
@@ -79,7 +79,7 @@ namespace Classification {
|
||||
is `GeomTraits::Point_3`.
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
computation of `CGAL::Classification::Local_eigen_analysis`
|
||||
objects. Possible values are `Parallel_tag` (default value is %CGAL
|
||||
objects. Possible values are `Parallel_tag` (default value if %CGAL
|
||||
is linked with TBB) or `Sequential_tag` (default value otherwise).
|
||||
\tparam DiagonalizeTraits model of `DiagonalizeTraits` used for
|
||||
matrix diagonalization. It can be omitted: if Eigen 3 (or greater)
|
||||
@@ -93,10 +93,8 @@ template <typename GeomTraits,
|
||||
typename PointMap,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename ConcurrencyTag,
|
||||
#elif defined(CGAL_LINKED_WITH_TBB)
|
||||
typename ConcurrencyTag = CGAL::Parallel_tag,
|
||||
#else
|
||||
typename ConcurrencyTag = CGAL::Sequential_tag,
|
||||
typename ConcurrencyTag = CGAL::Parallel_if_available_tag,
|
||||
#endif
|
||||
typename DiagonalizeTraits = CGAL::Default_diagonalize_traits<float,3> >
|
||||
class Mesh_feature_generator
|
||||
|
||||
@@ -90,10 +90,8 @@ template <typename GeomTraits,
|
||||
typename PointMap,
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename ConcurrencyTag,
|
||||
#elif defined(CGAL_LINKED_WITH_TBB)
|
||||
typename ConcurrencyTag = CGAL::Parallel_tag,
|
||||
#else
|
||||
typename ConcurrencyTag = CGAL::Sequential_tag,
|
||||
typename ConcurrencyTag = CGAL::Parallel_if_available_tag,
|
||||
#endif
|
||||
#if defined(DOXYGEN_RUNNING)
|
||||
typename DiagonalizeTraits>
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/blocked_range.h>
|
||||
#include <tbb/scalable_allocator.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
#define CLASSIFICATION_TRAINING_QUICK_ESTIMATION
|
||||
@@ -72,9 +72,9 @@ private:
|
||||
std::vector<std::size_t>& m_true_positives;
|
||||
std::vector<std::size_t>& m_false_positives;
|
||||
std::vector<std::size_t>& m_false_negatives;
|
||||
std::vector<tbb::mutex>& m_tp_mutex;
|
||||
std::vector<tbb::mutex>& m_fp_mutex;
|
||||
std::vector<tbb::mutex>& m_fn_mutex;
|
||||
std::vector<std::mutex>& m_tp_mutex;
|
||||
std::vector<std::mutex>& m_fp_mutex;
|
||||
std::vector<std::mutex>& m_fn_mutex;
|
||||
|
||||
|
||||
public:
|
||||
@@ -85,9 +85,9 @@ private:
|
||||
std::vector<std::size_t>& true_positives,
|
||||
std::vector<std::size_t>& false_positives,
|
||||
std::vector<std::size_t>& false_negatives,
|
||||
std::vector<tbb::mutex>& tp_mutex,
|
||||
std::vector<tbb::mutex>& fp_mutex,
|
||||
std::vector<tbb::mutex>& fn_mutex)
|
||||
std::vector<std::mutex>& tp_mutex,
|
||||
std::vector<std::mutex>& fp_mutex,
|
||||
std::vector<std::mutex>& fn_mutex)
|
||||
: m_training_set (training_set)
|
||||
, m_classifier (classifier)
|
||||
, m_label (label)
|
||||
@@ -901,9 +901,9 @@ private:
|
||||
#else
|
||||
if (boost::is_convertible<ConcurrencyTag,Parallel_tag>::value)
|
||||
{
|
||||
std::vector<tbb::mutex> tp_mutex (m_labels.size());
|
||||
std::vector<tbb::mutex> fp_mutex (m_labels.size());
|
||||
std::vector<tbb::mutex> fn_mutex (m_labels.size());
|
||||
std::vector<std::mutex> tp_mutex (m_labels.size());
|
||||
std::vector<std::mutex> fp_mutex (m_labels.size());
|
||||
std::vector<std::mutex> fn_mutex (m_labels.size());
|
||||
Compute_iou f(training_sets[j], *this, j,
|
||||
true_positives, false_positives, false_negatives,
|
||||
tp_mutex, fp_mutex, fn_mutex);
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
#include <tbb/parallel_for.h>
|
||||
#include <tbb/blocked_range.h>
|
||||
#include <tbb/scalable_allocator.h>
|
||||
#include <tbb/mutex.h>
|
||||
#include <mutex>
|
||||
#endif // CGAL_LINKED_WITH_TBB
|
||||
|
||||
namespace CGAL {
|
||||
@@ -327,7 +327,7 @@ namespace internal {
|
||||
suboptimal results.
|
||||
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` or `Sequential_tag`.
|
||||
algorithm. Possible values are `Parallel_if_available_tag`, `Parallel_tag` or `Sequential_tag`.
|
||||
|
||||
\tparam ItemRange model of `ConstRange`. Its iterator type is
|
||||
`RandomAccessIterator`. Its value type depends on the data that is
|
||||
@@ -417,7 +417,7 @@ namespace internal {
|
||||
efficiency and better quality results.
|
||||
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` or `Sequential_tag`.
|
||||
algorithm. Possible values are `Parallel_if_available_tag`, `Parallel_tag` or `Sequential_tag`.
|
||||
\tparam ItemRange model of `ConstRange`. Its iterator type is
|
||||
`RandomAccessIterator`.
|
||||
\tparam ItemMap model of `ReadablePropertyMap` whose key
|
||||
@@ -495,7 +495,7 @@ namespace internal {
|
||||
results.
|
||||
|
||||
\tparam ConcurrencyTag enables sequential versus parallel
|
||||
algorithm. Possible values are `Parallel_tag` or `Sequential_tag`.
|
||||
algorithm. Possible values are `Parallel_if_available_tag`, `Parallel_tag` or `Sequential_tag`.
|
||||
\tparam ItemRange model of `ConstRange`. Its iterator type is
|
||||
`RandomAccessIterator`.
|
||||
\tparam ItemMap model of `ReadablePropertyMap` whose key
|
||||
|
||||
@@ -5,7 +5,6 @@ cmake_minimum_required(VERSION 3.1...3.15)
|
||||
project( Classification_Tests )
|
||||
|
||||
|
||||
|
||||
# CGAL and its components
|
||||
find_package( CGAL QUIET COMPONENTS )
|
||||
|
||||
@@ -22,88 +21,39 @@ if ( NOT Boost_FOUND )
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(Classification_dependencies_met TRUE)
|
||||
|
||||
find_package( Boost OPTIONAL_COMPONENTS serialization iostreams )
|
||||
|
||||
if( WIN32 )
|
||||
# to avoid a warning with old cmake
|
||||
set(_Boost_BZIP2_HEADERS "boost/iostreams/filter/bzip2.hpp")
|
||||
set(_Boost_ZLIB_HEADERS "boost/iostreams/filter/zlib.hpp")
|
||||
find_package( Boost OPTIONAL_COMPONENTS bzip2 zlib)
|
||||
else()
|
||||
find_package(ZLIB QUIET)
|
||||
if (NOT Boost_SERIALIZATION_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost Serialization, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
if (NOT Boost_IOSTREAMS_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost IO Streams, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
# Use Eigen
|
||||
find_package(Eigen3 3.1.0) #(requires 3.1.0 or greater)
|
||||
if (EIGEN3_FOUND)
|
||||
include( ${EIGEN3_USE_FILE} )
|
||||
find_package(Eigen3 3.1.0 REQUIRED) #(3.1.0 or greater)
|
||||
if (NOT EIGEN3_FOUND)
|
||||
message(STATUS "This project requires the Eigen library, and will not be compiled.")
|
||||
set(Classification_dependencies_met FALSE)
|
||||
endif()
|
||||
|
||||
find_package( TBB )
|
||||
find_package(TBB QUIET)
|
||||
|
||||
# include for local directory
|
||||
include_directories( BEFORE include )
|
||||
|
||||
# include for local package
|
||||
|
||||
# Creating entries for all C++ files with "main" routine
|
||||
# ##########################################################
|
||||
|
||||
#add_definitions("-DCGAL_DO_NOT_USE_BOYKOV_KOLMOGOROV_MAXFLOW_SOFTWARE")
|
||||
|
||||
# Classification requires some C++11 features
|
||||
set(needed_cxx_features cxx_rvalue_references cxx_variadic_templates)
|
||||
|
||||
# Libraries and flags
|
||||
set(classification_linked_libraries)
|
||||
|
||||
if (Boost_SERIALIZATION_FOUND AND Boost_IOSTREAMS_FOUND)
|
||||
if(TARGET Boost::serialization AND TARGET Boost::iostreams)
|
||||
set(classification_linked_libraries Boost::serialization Boost::iostreams)
|
||||
else()
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${Boost_SERIALIZATION_LIBRARY}
|
||||
${Boost_IOSTREAMS_LIBRARY})
|
||||
endif()
|
||||
else()
|
||||
if (NOT Boost_SERIALIZATION_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost Serialization, and will not be compiled.")
|
||||
endif()
|
||||
if (NOT Boost_IOSTREAMS_FOUND)
|
||||
message(STATUS "NOTICE: This project requires Boost IO Streams, and will not be compiled.")
|
||||
endif()
|
||||
if (NOT Classification_dependencies_met)
|
||||
return()
|
||||
endif()
|
||||
|
||||
if( WIN32 )
|
||||
if (Boost_ZLIB_FOUND AND Boost_BZIP2_FOUND)
|
||||
set(classification_linked_libraries ${classification_linked_libraries}
|
||||
${Boost_ZLIB_LIBRARY} ${Boost_BZIP2_LIBRARY})
|
||||
else()
|
||||
message(STATUS "NOTICE: This project requires Boost ZLIB and Boost BZIP2, and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
else()
|
||||
if(ZLIB_FOUND)
|
||||
set(classification_linked_libraries ${classification_linked_libraries} ZLIB::ZLIB)
|
||||
else()
|
||||
message(STATUS "NOTICE: This project requires ZLIB, and will not be compiled.")
|
||||
return()
|
||||
endif()
|
||||
endif()
|
||||
create_single_source_cgal_program( "test_classification_point_set.cpp" )
|
||||
create_single_source_cgal_program( "test_classification_io.cpp" )
|
||||
|
||||
create_single_source_cgal_program( "test_classification_point_set.cpp" CXX_FEATURES ${needed_cxx_features} )
|
||||
if(TARGET test_classification_point_set)
|
||||
target_link_libraries(test_classification_point_set PUBLIC ${classification_linked_libraries})
|
||||
if (TBB_FOUND)
|
||||
CGAL_target_use_TBB( test_classification_point_set )
|
||||
foreach(target test_classification_point_set test_classification_io)
|
||||
CGAL_target_use_Eigen(${target})
|
||||
CGAL_target_use_Boost_IOStreams(${target})
|
||||
CGAL_target_use_Boost_Serialization(${target})
|
||||
if(TBB_FOUND)
|
||||
CGAL_target_use_TBB(${target})
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
create_single_source_cgal_program( "test_classification_io.cpp" CXX_FEATURES ${needed_cxx_features} )
|
||||
if(TARGET test_classification_io)
|
||||
target_link_libraries(test_classification_io PUBLIC ${classification_linked_libraries})
|
||||
if (TBB_FOUND)
|
||||
CGAL_target_use_TBB( test_classification_io )
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@@ -41,6 +41,9 @@
|
||||
#include <deque>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
|
||||
#include <CGAL/config.h>
|
||||
|
||||
#if defined( __INTEL_COMPILER )
|
||||
@@ -55,6 +58,16 @@ _Pragma("GCC diagnostic ignored \"-Warray-bounds\"")
|
||||
#endif
|
||||
|
||||
namespace CGAL {
|
||||
// functions to allow the call to next/opposite by ADL
|
||||
template <typename G, typename Desc>
|
||||
auto CM_ADL_next(Desc&& d, G&& g) {
|
||||
return next(std::forward<Desc>(d), std::forward<G>(g));
|
||||
}
|
||||
|
||||
template <typename G, typename Desc>
|
||||
auto CM_ADL_opposite(Desc&& d, G&& g) {
|
||||
return opposite(std::forward<Desc>(d), std::forward<G>(g));
|
||||
}
|
||||
|
||||
/** @file Combinatorial_map.h
|
||||
* Definition of generic dD Combinatorial map.
|
||||
@@ -199,18 +212,27 @@ namespace CGAL {
|
||||
CGAL_assertion(number_of_darts()==0);
|
||||
}
|
||||
|
||||
/** Copy the given combinatorial map into *this.
|
||||
/** Copy the given combinatorial map 'amap' into *this.
|
||||
* Note that both CMap can have different dimensions and/or non void attributes.
|
||||
* @param amap the combinatorial map to copy.
|
||||
* @post *this is valid.
|
||||
*/
|
||||
template <typename CMap2, typename Converters, typename DartInfoConverter,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2,
|
||||
typename Converters, typename DartInfoConverter,
|
||||
typename PointConverter>
|
||||
void copy(const CMap2& amap, const Converters& converters,
|
||||
void copy(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>& amap,
|
||||
const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter,
|
||||
const PointConverter& pointconverter,
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle>* dart_mapping=nullptr)
|
||||
boost::unordered_map
|
||||
<typename Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>::
|
||||
Dart_const_handle, Dart_handle>* origin_to_copy=NULL,
|
||||
boost::unordered_map
|
||||
<Dart_handle, typename Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>::Dart_const_handle>* copy_to_origin=NULL)
|
||||
{
|
||||
typedef Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2> CMap2;
|
||||
this->clear();
|
||||
|
||||
this->mnb_used_marks = amap.mnb_used_marks;
|
||||
@@ -232,81 +254,113 @@ namespace CGAL {
|
||||
// Create an mapping between darts of the two maps (originals->copies).
|
||||
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||
// iterators...
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle> local_dartmap;
|
||||
if (dart_mapping==nullptr)
|
||||
{ dart_mapping=&local_dartmap; }
|
||||
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle>
|
||||
local_dartmap;
|
||||
if (origin_to_copy==NULL) // Used local_dartmap if user does not provides its own unordered_map
|
||||
{ origin_to_copy=&local_dartmap; }
|
||||
|
||||
Dart_handle new_dart;
|
||||
for (typename CMap2::Dart_const_range::const_iterator
|
||||
it=amap.darts().begin(), itend=amap.darts().end();
|
||||
it!=itend; ++it)
|
||||
{
|
||||
(*dart_mapping)[it]=mdarts.emplace();
|
||||
init_dart((*dart_mapping)[it], amap.get_marks(it));
|
||||
internal::Copy_dart_info_functor<CMap2, Refs, DartInfoConverter>::run
|
||||
(amap, static_cast<Refs&>(*this), it, (*dart_mapping)[it],
|
||||
dartinfoconverter);
|
||||
new_dart=mdarts.emplace();
|
||||
init_dart(new_dart, amap.get_marks(it));
|
||||
|
||||
(*origin_to_copy)[it]=new_dart;
|
||||
if (copy_to_origin!=NULL) { (*copy_to_origin)[new_dart]=it; }
|
||||
|
||||
internal::Copy_dart_info_functor<Refs2, Refs, DartInfoConverter>::run
|
||||
(static_cast<const Refs2&>(amap), static_cast<Refs&>(*this),
|
||||
it, new_dart, dartinfoconverter);
|
||||
}
|
||||
|
||||
unsigned int min_dim=(dimension<amap.dimension?dimension:amap.dimension);
|
||||
|
||||
typename boost::unordered_map<typename CMap2::Dart_const_handle,Dart_handle>
|
||||
::iterator dartmap_iter, dartmap_iter_end=dart_mapping->end();
|
||||
for (dartmap_iter=dart_mapping->begin(); dartmap_iter!=dartmap_iter_end;
|
||||
::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end();
|
||||
for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end;
|
||||
++dartmap_iter)
|
||||
{
|
||||
for (unsigned int i=0; i<=min_dim; i++)
|
||||
{
|
||||
if (!amap.is_free(dartmap_iter->first,i) &&
|
||||
(dartmap_iter->first)<(amap.beta(dartmap_iter->first,i)))
|
||||
is_free(dartmap_iter->second,i))
|
||||
{
|
||||
basic_link_beta(dartmap_iter->second,
|
||||
(*dart_mapping)[amap.beta(dartmap_iter->first,i)], i);
|
||||
(*origin_to_copy)[amap.beta(dartmap_iter->first,i)], i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Copy attributes */
|
||||
for (dartmap_iter=dart_mapping->begin(); dartmap_iter!=dartmap_iter_end;
|
||||
for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end;
|
||||
++dartmap_iter)
|
||||
{
|
||||
Helper::template Foreach_enabled_attributes
|
||||
< internal::Copy_attributes_functor <CMap2, Refs, Converters,
|
||||
< internal::Copy_attributes_functor <Refs2, Refs, Converters,
|
||||
PointConverter> >::
|
||||
run(amap, static_cast<Refs&>(*this),
|
||||
run(static_cast<const Refs2&>(amap), static_cast<Refs&>(*this),
|
||||
dartmap_iter->first, dartmap_iter->second,
|
||||
converters, pointconverter);
|
||||
}
|
||||
|
||||
CGAL_assertion (is_valid () == 1);
|
||||
CGAL_assertion (is_valid());
|
||||
}
|
||||
|
||||
template <typename CMap2>
|
||||
void copy(const CMap2& amap,
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle>* dart_mapping=nullptr)
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2>
|
||||
void copy(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>& amap,
|
||||
boost::unordered_map
|
||||
<typename Combinatorial_map_base<d2, Refs2, Items2, Alloc2,
|
||||
Storage2>::Dart_const_handle, Dart_handle>* origin_to_copy=NULL,
|
||||
boost::unordered_map
|
||||
<Dart_handle, typename Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>::Dart_const_handle>* copy_to_origin=NULL)
|
||||
|
||||
{
|
||||
std::tuple<> converters;
|
||||
Default_converter_dart_info<CMap2, Refs> dartinfoconverter;
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> pointconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter, dart_mapping);
|
||||
CGAL::cpp11::tuple<> converters;
|
||||
Default_converter_dart_info<Refs2, Refs> dartinfoconverter;
|
||||
Default_converter_cmap_0attributes_with_point<Refs2, Refs> pointconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter,
|
||||
origin_to_copy, copy_to_origin);
|
||||
}
|
||||
|
||||
template <typename CMap2, typename Converters>
|
||||
void copy(const CMap2& amap, const Converters& converters,
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle>* dart_mapping=nullptr)
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters>
|
||||
void copy(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap,
|
||||
const Converters& converters,
|
||||
boost::unordered_map
|
||||
<typename Combinatorial_map_base<d2, Refs2, Items2, Alloc2,
|
||||
Storage2>::Dart_const_handle, Dart_handle>* origin_to_copy=NULL,
|
||||
boost::unordered_map
|
||||
<Dart_handle, typename Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>::Dart_const_handle>* copy_to_origin=NULL)
|
||||
{
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> pointconverter;
|
||||
Default_converter_dart_info<CMap2, Refs> dartinfoconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter, dart_mapping);
|
||||
Default_converter_cmap_0attributes_with_point<Refs2, Refs> pointconverter;
|
||||
Default_converter_dart_info<Refs2, Refs> dartinfoconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter,
|
||||
origin_to_copy, copy_to_origin);
|
||||
}
|
||||
|
||||
template <typename CMap2, typename Converters, typename DartInfoConverter>
|
||||
void copy(const CMap2& amap, const Converters& converters,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2,
|
||||
typename Converters, typename DartInfoConverter>
|
||||
void copy(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap,
|
||||
const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter,
|
||||
boost::unordered_map<typename CMap2::Dart_const_handle, Dart_handle>* dart_mapping=nullptr)
|
||||
boost::unordered_map
|
||||
<typename Combinatorial_map_base<d2, Refs2, Items2, Alloc2,
|
||||
Storage2>::Dart_const_handle, Dart_handle>* origin_to_copy=NULL,
|
||||
boost::unordered_map
|
||||
<Dart_handle, typename Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>::Dart_const_handle>* copy_to_origin=NULL)
|
||||
{
|
||||
Default_converter_cmap_0attributes_with_point<CMap2, Refs> pointconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter, dart_mapping);
|
||||
Default_converter_cmap_0attributes_with_point<Refs2, Refs> pointconverter;
|
||||
copy(amap, converters, dartinfoconverter, pointconverter,
|
||||
origin_to_copy, copy_to_origin);
|
||||
}
|
||||
|
||||
// Copy constructor from a map having exactly the same type.
|
||||
@@ -314,25 +368,37 @@ namespace CGAL {
|
||||
{ copy(amap); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2>
|
||||
Combinatorial_map_base(const CMap2& amap)
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2>
|
||||
Combinatorial_map_base(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap)
|
||||
{ copy(amap); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2, typename Converters>
|
||||
Combinatorial_map_base(const CMap2& amap, Converters& converters)
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters>
|
||||
Combinatorial_map_base(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap,
|
||||
const Converters& converters)
|
||||
{ copy(amap, converters); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2, typename Converters, typename DartInfoConverter>
|
||||
Combinatorial_map_base(const CMap2& amap, Converters& converters,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters, typename DartInfoConverter>
|
||||
Combinatorial_map_base(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap,
|
||||
const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter)
|
||||
{ copy(amap, converters, dartinfoconverter); }
|
||||
|
||||
// "Copy constructor" from a map having different type.
|
||||
template <typename CMap2, typename Converters, typename DartInfoConverter,
|
||||
typename PointConverter>
|
||||
Combinatorial_map_base(const CMap2& amap, Converters& converters,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2,
|
||||
typename Converters, typename DartInfoConverter,
|
||||
typename PointConverter>
|
||||
Combinatorial_map_base(const Combinatorial_map_base<d2, Refs2, Items2,
|
||||
Alloc2, Storage2>& amap,
|
||||
const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter,
|
||||
const PointConverter& pointconverter)
|
||||
{ copy(amap, converters, dartinfoconverter, pointconverter); }
|
||||
@@ -385,6 +451,62 @@ namespace CGAL {
|
||||
}
|
||||
}
|
||||
|
||||
/** Import the given hds which should be a model of an halfedge graph. */
|
||||
template<class HEG>
|
||||
void import_from_halfedge_graph(const HEG& heg,
|
||||
boost::unordered_map
|
||||
<typename boost::graph_traits<HEG>::halfedge_descriptor,
|
||||
Dart_handle>* origin_to_copy=NULL,
|
||||
boost::unordered_map
|
||||
<Dart_handle,
|
||||
typename boost::graph_traits<HEG>::halfedge_descriptor>*
|
||||
copy_to_origin=NULL)
|
||||
|
||||
{
|
||||
// Create an mapping between darts of the two maps (originals->copies).
|
||||
// (here we cannot use CGAL::Unique_hash_map because it does not provide
|
||||
// iterators...
|
||||
boost::unordered_map
|
||||
<typename boost::graph_traits<HEG>::halfedge_descriptor,
|
||||
Dart_handle> local_dartmap;
|
||||
if (origin_to_copy==NULL) // Used local_dartmap if user does not provides its own unordered_map
|
||||
{ origin_to_copy=&local_dartmap; }
|
||||
|
||||
Dart_handle new_dart;
|
||||
for (typename boost::graph_traits<HEG>::halfedge_iterator
|
||||
it=halfedges(heg).begin(), itend=halfedges(heg).end();
|
||||
it!=itend; ++it)
|
||||
{
|
||||
if (!CGAL::is_border(*it, heg))
|
||||
{
|
||||
new_dart=mdarts.emplace();
|
||||
(*origin_to_copy)[*it]=new_dart;
|
||||
if (copy_to_origin!=NULL) { (*copy_to_origin)[new_dart]=*it; }
|
||||
}
|
||||
}
|
||||
|
||||
typename boost::unordered_map
|
||||
<typename boost::graph_traits<HEG>::halfedge_descriptor,
|
||||
Dart_handle>::iterator dartmap_iter, dartmap_iter_end=origin_to_copy->end();
|
||||
for (dartmap_iter=origin_to_copy->begin(); dartmap_iter!=dartmap_iter_end;
|
||||
++dartmap_iter)
|
||||
{
|
||||
basic_link_beta(dartmap_iter->second,
|
||||
(*origin_to_copy)[CM_ADL_next(dartmap_iter->first, heg)],
|
||||
1);
|
||||
|
||||
if (!CGAL::is_border(CM_ADL_opposite(dartmap_iter->first, heg), heg) &&
|
||||
(dartmap_iter->first)<CM_ADL_opposite(dartmap_iter->first, heg))
|
||||
{
|
||||
basic_link_beta(dartmap_iter->second,
|
||||
(*origin_to_copy)
|
||||
[CM_ADL_opposite(dartmap_iter->first, heg)], 2);
|
||||
}
|
||||
}
|
||||
|
||||
CGAL_assertion (is_valid());
|
||||
}
|
||||
|
||||
/** Clear the combinatorial map. Remove all darts and all attributes.
|
||||
* Note that reserved marks are not free.
|
||||
*/
|
||||
@@ -498,6 +620,16 @@ namespace CGAL {
|
||||
{ return mdarts.iterator_to(adart); }
|
||||
Dart_const_handle dart_handle(const Dart& adart) const
|
||||
{ return mdarts.iterator_to(adart); }
|
||||
Dart_handle dart_handle(size_type i)
|
||||
{
|
||||
CGAL_assertion(darts().is_used(i));
|
||||
return mdarts.iterator_to(darts()[i]);
|
||||
}
|
||||
Dart_const_handle dart_handle(size_type i) const
|
||||
{
|
||||
CGAL_assertion(darts().is_used(i));
|
||||
return mdarts.iterator_to(darts()[i]);
|
||||
}
|
||||
|
||||
/** Return the highest dimension for which dh is not free.
|
||||
* @param dh a dart handle
|
||||
@@ -673,6 +805,11 @@ namespace CGAL {
|
||||
Dart_const_handle next(Dart_const_handle ADart) const
|
||||
{ return this->template beta<1>(ADart); }
|
||||
|
||||
Dart_handle opposite2(Dart_handle ADart)
|
||||
{ return this->template beta<2>(ADart); }
|
||||
Dart_const_handle opposite2(Dart_const_handle ADart) const
|
||||
{ return this->template beta<2>(ADart); }
|
||||
|
||||
template<unsigned int dim>
|
||||
Dart_handle opposite(Dart_handle ADart)
|
||||
{ return this->template beta<dim>(ADart); }
|
||||
@@ -950,6 +1087,27 @@ namespace CGAL {
|
||||
mnb_times_reserved_marks[amark]=0;
|
||||
}
|
||||
|
||||
template <unsigned int i, unsigned int d=dimension>
|
||||
bool belong_to_same_cell(Dart_const_handle adart1,
|
||||
Dart_const_handle adart2) const
|
||||
{ return CGAL::belong_to_same_cell<Self, i, d>(*this, adart1, adart2); }
|
||||
|
||||
template <unsigned int i, unsigned int d=dimension>
|
||||
bool is_whole_cell_unmarked(Dart_const_handle adart, size_type amark) const
|
||||
{ return CGAL::is_whole_cell_unmarked<Self, i, d>(*this, adart, amark); }
|
||||
|
||||
template <unsigned int i, unsigned int d=dimension>
|
||||
bool is_whole_cell_marked(Dart_const_handle adart, size_type amark) const
|
||||
{ return CGAL::is_whole_cell_marked<Self, i, d>(*this, adart, amark); }
|
||||
|
||||
template <unsigned int i, unsigned int d=dimension>
|
||||
size_type mark_cell(Dart_const_handle adart, size_type amark) const
|
||||
{ return CGAL::mark_cell<Self, i, d>(*this, adart, amark); }
|
||||
|
||||
template <unsigned int i, unsigned int d=dimension>
|
||||
size_type unmark_cell(Dart_const_handle adart, size_type amark) const
|
||||
{ return CGAL::unmark_cell<Self, i, d>(*this, adart, amark); }
|
||||
|
||||
/** Test if this map is without boundary for a given dimension.
|
||||
* @param i the dimension.
|
||||
* @return true iff all the darts are not i-free.
|
||||
@@ -2300,6 +2458,30 @@ namespace CGAL {
|
||||
run(*this, adart, amark);
|
||||
}
|
||||
|
||||
/// Keep the biggest connected component.
|
||||
/// @return the size (in number of darts) of the biggest cc.
|
||||
std::size_t keep_biggest_connected_component()
|
||||
{
|
||||
std::map<std::size_t, Dart_handle> ccs;
|
||||
|
||||
size_type treated=get_new_mark();
|
||||
for (auto it=darts().begin(), itend=darts().end(); it!=itend; ++it)
|
||||
{
|
||||
if (!is_marked(it, treated))
|
||||
{ ccs[mark_cell<dimension+1>(it, treated)]=it; }
|
||||
}
|
||||
|
||||
if (ccs.size()>1)
|
||||
{ // Here all darts are marked
|
||||
this->template unmark_cell<dimension+1>(ccs.rbegin()->second, treated); // Unmark the biggest cc
|
||||
erase_marked_darts(treated);
|
||||
}
|
||||
|
||||
free_mark(treated);
|
||||
|
||||
return ccs.rbegin()->first;
|
||||
}
|
||||
|
||||
/** Count the marked cells (at least one marked dart).
|
||||
* @param amark the mark to consider.
|
||||
* @param avector containing the dimensions of the cells to count.
|
||||
@@ -2433,6 +2615,64 @@ namespace CGAL {
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
/// @return the positive turn between the two given darts.
|
||||
// @pre beta1(d1) and d2 must belong to the same vertex.
|
||||
std::size_t positive_turn(Dart_const_handle d1, Dart_const_handle d2) const
|
||||
{
|
||||
CGAL_assertion((!this->template is_free<1>(d1)));
|
||||
/* CGAL_assertion((belong_to_same_cell<0>(this->template beta<1>(d1),
|
||||
d2))); */
|
||||
|
||||
if (d2==beta<2>(d1)) { return 0; }
|
||||
|
||||
Dart_const_handle dd1=d1;
|
||||
std::size_t res=1;
|
||||
while (beta<1>(dd1)!=d2)
|
||||
{
|
||||
if (this->template is_free<2>(beta<1>(dd1)))
|
||||
{ return std::numeric_limits<std::size_t>::max(); }
|
||||
|
||||
++res;
|
||||
dd1=beta<1, 2>(dd1);
|
||||
|
||||
CGAL_assertion(!this->template is_free<1>(dd1));
|
||||
CGAL_assertion(beta<1>(dd1)==d2 || dd1!=d1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// @return the negative turn between the two given darts.
|
||||
// @pre beta1(d1) and d2 must belong to the same vertex.
|
||||
std::size_t negative_turn(Dart_const_handle d1, Dart_const_handle d2) const
|
||||
{
|
||||
CGAL_assertion((!this->template is_free<1>(d1)));
|
||||
/* CGAL_assertion((belong_to_same_cell<0>(this->template beta<1>(d1),
|
||||
d2))); */
|
||||
|
||||
if (d2==beta<2>(d1)) { return 0; }
|
||||
|
||||
if (this->template is_free<2>(d1) || this->template is_free<2>(d2))
|
||||
{ return std::numeric_limits<std::size_t>::max(); }
|
||||
|
||||
d1=beta<2>(d1);
|
||||
d2=beta<2>(d2);
|
||||
Dart_const_handle dd1=d1;
|
||||
std::size_t res=1;
|
||||
while (beta<0>(dd1)!=d2)
|
||||
{
|
||||
if (this->template is_free<2>(beta<0>(dd1)))
|
||||
{ return std::numeric_limits<std::size_t>::max(); }
|
||||
|
||||
++res;
|
||||
dd1=beta<0, 2>(dd1);
|
||||
|
||||
CGAL_assertion(!this->template is_free<0>(dd1));
|
||||
CGAL_assertion(beta<0>(dd1)==d2 || dd1!=d1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/** Erase marked darts from the map.
|
||||
* Marked darts are unlinked before to be removed, thus surviving darts
|
||||
* are correctly linked, but the map is not necessarily valid depending
|
||||
@@ -3513,12 +3753,12 @@ namespace CGAL {
|
||||
!is_face_combinatorial_polygon(d4, 3) ) return false;
|
||||
|
||||
// TODO do better with marks (?).
|
||||
if ( belong_to_same_cell<Self,2,1>(*this, d1, d2) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d3) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d4) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d3) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d4) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d3, d4) ) return false;
|
||||
if ( belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ) return false;
|
||||
|
||||
if ( beta(d1,1,2)!=beta(d3,0) ||
|
||||
beta(d4,0,2)!=beta(d3,1) ||
|
||||
@@ -3611,21 +3851,21 @@ namespace CGAL {
|
||||
!is_face_combinatorial_polygon(d6, 4) ) return false;
|
||||
|
||||
// TODO do better with marks.
|
||||
if ( belong_to_same_cell<Self,2,1>(*this, d1, d2) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d3) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d4) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d5) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d1, d6) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d3) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d4) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d5) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d2, d6) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d3, d4) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d3, d5) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d3, d6) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d4, d5) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d4, d6) ||
|
||||
belong_to_same_cell<Self,2,1>(*this, d5, d6) )
|
||||
if ( belong_to_same_cell<2,1>(d1, d2) ||
|
||||
belong_to_same_cell<2,1>(d1, d3) ||
|
||||
belong_to_same_cell<2,1>(d1, d4) ||
|
||||
belong_to_same_cell<2,1>(d1, d5) ||
|
||||
belong_to_same_cell<2,1>(d1, d6) ||
|
||||
belong_to_same_cell<2,1>(d2, d3) ||
|
||||
belong_to_same_cell<2,1>(d2, d4) ||
|
||||
belong_to_same_cell<2,1>(d2, d5) ||
|
||||
belong_to_same_cell<2,1>(d2, d6) ||
|
||||
belong_to_same_cell<2,1>(d3, d4) ||
|
||||
belong_to_same_cell<2,1>(d3, d5) ||
|
||||
belong_to_same_cell<2,1>(d3, d6) ||
|
||||
belong_to_same_cell<2,1>(d4, d5) ||
|
||||
belong_to_same_cell<2,1>(d4, d6) ||
|
||||
belong_to_same_cell<2,1>(d5, d6) )
|
||||
return false;
|
||||
|
||||
if ( beta(d1,2) !=beta(d4,1,1) ||
|
||||
@@ -3781,7 +4021,7 @@ namespace CGAL {
|
||||
return this->template beta<1>(adart);
|
||||
}
|
||||
|
||||
/** Insert a vertex in the given 2-cell which is splitted in triangles,
|
||||
/** Insert a vertex in the given 2-cell which is split in triangles,
|
||||
* once for each inital edge of the facet.
|
||||
* @param adart a dart of the facet to triangulate.
|
||||
* @param update_attributes a boolean to update the enabled attributes
|
||||
@@ -4213,7 +4453,7 @@ namespace CGAL {
|
||||
if ( od==null_handle ) return false;
|
||||
|
||||
// of and *it must belong to the same vertex of the same volume
|
||||
if ( !belong_to_same_cell<Self, 0, 2>(*this, od, *it) )
|
||||
if ( !belong_to_same_cell<0, 2>(od, *it) )
|
||||
return false;
|
||||
}
|
||||
prec = *it;
|
||||
@@ -4223,7 +4463,7 @@ namespace CGAL {
|
||||
od = other_extremity(prec);
|
||||
if ( od==null_handle ) return false;
|
||||
|
||||
if (!belong_to_same_cell<Self, 0, 2>(*this, od, *afirst))
|
||||
if (!belong_to_same_cell<0, 2>(od, *afirst))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
@@ -4437,24 +4677,33 @@ namespace CGAL {
|
||||
Combinatorial_map(const Self & amap) : Base(amap)
|
||||
{}
|
||||
|
||||
template < class CMap >
|
||||
Combinatorial_map(const CMap & amap) : Base(amap)
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2>
|
||||
Combinatorial_map(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>&
|
||||
amap) : Base(amap)
|
||||
{}
|
||||
|
||||
template < class CMap, typename Converters >
|
||||
Combinatorial_map(const CMap & amap, const Converters& converters) :
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters>
|
||||
Combinatorial_map(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>&
|
||||
amap, const Converters& converters) :
|
||||
Base(amap, converters)
|
||||
{}
|
||||
|
||||
template < class CMap, typename Converters, typename DartInfoConverter >
|
||||
Combinatorial_map(const CMap & amap, const Converters& converters,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters,
|
||||
typename DartInfoConverter>
|
||||
Combinatorial_map(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>&
|
||||
amap, const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter) :
|
||||
Base(amap, converters, dartinfoconverter)
|
||||
{}
|
||||
|
||||
template < class CMap, typename Converters, typename DartInfoConverter,
|
||||
typename PointConverter >
|
||||
Combinatorial_map(const CMap & amap, const Converters& converters,
|
||||
template <unsigned int d2, typename Refs2, typename Items2, typename Alloc2,
|
||||
typename Storage2, typename Converters,
|
||||
typename DartInfoConverter, typename PointConverter >
|
||||
Combinatorial_map(const Combinatorial_map_base<d2, Refs2, Items2, Alloc2, Storage2>&
|
||||
amap, const Converters& converters,
|
||||
const DartInfoConverter& dartinfoconverter,
|
||||
const PointConverter& pointconverter) :
|
||||
Base(amap, converters, dartinfoconverter, pointconverter)
|
||||
|
||||
@@ -194,7 +194,7 @@ namespace CGAL
|
||||
typename Map::size_type amark)
|
||||
{
|
||||
return CGAL::is_whole_orbit_unmarked<Map,
|
||||
typename Map::template Dart_of_cell_range<i,d>::iterator>
|
||||
typename Map::template Dart_of_cell_range<i,d>::const_iterator>
|
||||
(amap, adart, amark);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ insert_cell_0_in_cell_1( CMap& amap, typename CMap::Dart_handle adart,
|
||||
return amap.insert_cell_0_in_cell_1(adart, ah, update_attributes);
|
||||
}
|
||||
|
||||
/** Insert a vertex in the given 2-cell which is splitted in triangles,
|
||||
/** Insert a vertex in the given 2-cell which is split in triangles,
|
||||
* once for each inital edge of the facet.
|
||||
* @param amap the used combinatorial map.
|
||||
* @param adart a dart of the facet to triangulate.
|
||||
|
||||
@@ -106,7 +106,7 @@ namespace CGAL {
|
||||
{
|
||||
return ( ((*this==mmap->null_handle) && (aiterator==mmap->null_handle)) ||
|
||||
(mfirst_dart == aiterator.mfirst_dart &&
|
||||
static_cast<const Base&>(*this)==
|
||||
static_cast<const Base&>(*this)==
|
||||
static_cast<const Base&>(aiterator)) );
|
||||
}
|
||||
|
||||
|
||||
@@ -127,6 +127,8 @@ namespace CGAL {
|
||||
CGAL_assertion(i <= dimension);
|
||||
return dh->mf[i]==null_dart_handle;
|
||||
}
|
||||
bool is_perforated(Dart_const_handle /*dh*/) const
|
||||
{ return false; }
|
||||
|
||||
/// Set simultaneously all the marks of this dart to a given value.
|
||||
void set_dart_marks(Dart_const_handle ADart,
|
||||
|
||||
@@ -0,0 +1,941 @@
|
||||
// Copyright (c) 2019 CNRS and LIRIS' Establishments (France).
|
||||
// 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) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
#ifndef CGAL_FACE_GRAPH_WRAPPER_H
|
||||
#define CGAL_FACE_GRAPH_WRAPPER_H 1
|
||||
|
||||
#include <CGAL/Functors_for_face_graph_wrapper.h>
|
||||
#include <CGAL/Iterators_for_face_graph_wrapper.h>
|
||||
#include <CGAL/internal/Combinatorial_map_internal_functors.h>
|
||||
#include <CGAL/Polyhedron_3_fwd.h>
|
||||
#include <CGAL/Surface_mesh/Surface_mesh_fwd.h>
|
||||
#include <bitset>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
// Forward declarations of all classes model of Face_graph
|
||||
template <unsigned int d, typename Refs, typename Items, typename Alloc,
|
||||
typename Storage>
|
||||
class Combinatorial_map_base;
|
||||
|
||||
template <unsigned int d, typename Refs, typename Items, typename Alloc,
|
||||
typename Storage>
|
||||
class Generalized_map_base;
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Refs, typename Storage>
|
||||
class Linear_cell_complex_base;
|
||||
|
||||
template <unsigned int d, typename Items, typename Alloc,
|
||||
typename Storage>
|
||||
class Combinatorial_map;
|
||||
|
||||
template <unsigned int d, typename Items, typename Alloc,
|
||||
typename Storage>
|
||||
class Generalized_map;
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Storage>
|
||||
class Linear_cell_complex_for_combinatorial_map;
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Storage>
|
||||
class Linear_cell_complex_for_generalized_map;
|
||||
|
||||
namespace Surface_mesh_topology
|
||||
{
|
||||
template <typename Items, typename Alloc, typename Storage>
|
||||
class Polygonal_schema_with_combinatorial_map;
|
||||
|
||||
template <typename Items, typename Alloc, typename Storage>
|
||||
class Polygonal_schema_with_generalized_map;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** Class Face_graph_wrapper: to wrap any model of FaceGraph into a
|
||||
* Combinatorial map. For now, only for const models, i.e. does not support
|
||||
* modification operators.
|
||||
*/
|
||||
template<typename HEG_>
|
||||
class Face_graph_wrapper
|
||||
{
|
||||
public:
|
||||
typedef HEG_ HEG;
|
||||
typedef Face_graph_wrapper<HEG> Self;
|
||||
typedef std::size_t size_type;
|
||||
|
||||
struct Dart_container
|
||||
{
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_iterator iterator;
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_iterator const_iterator; // TODO ?
|
||||
// typedef My_halfedge_iterator<HEG> iterator;
|
||||
// typedef My_halfedge_iterator<HEG> const_iterator; // TODO ?
|
||||
};
|
||||
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_handle;
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
|
||||
typedef Dart_handle Null_handle_type;
|
||||
// typedef CGAL::Void* Null_handle_type;
|
||||
static const Null_handle_type null_handle; //=Dart_handle();
|
||||
static const Null_handle_type null_dart_handle; //=Dart_handle();
|
||||
|
||||
/// Number of marks
|
||||
static const size_type NB_MARKS = 32;
|
||||
static const size_type INVALID_MARK = NB_MARKS;
|
||||
|
||||
/// The dimension of the combinatorial map.
|
||||
static const unsigned int dimension=2;
|
||||
static const unsigned int ambient_dimension=3;
|
||||
|
||||
typedef typename boost::graph_traits<HEG>::vertex_descriptor vertex_descriptor;
|
||||
typedef typename boost::graph_traits<HEG>::edge_descriptor edge_descriptor;
|
||||
typedef typename boost::graph_traits<HEG>::face_descriptor face_descriptor;
|
||||
typedef boost::undirected_tag directed_category;
|
||||
typedef boost::disallow_parallel_edge_tag edge_parallel_category;
|
||||
|
||||
struct SM_graph_traversal_category : public virtual boost::bidirectional_graph_tag,
|
||||
public virtual boost::vertex_list_graph_tag,
|
||||
public virtual boost::edge_list_graph_tag
|
||||
{};
|
||||
typedef SM_graph_traversal_category traversal_category;
|
||||
|
||||
|
||||
Face_graph_wrapper(const HEG& f) : m_fg(f),
|
||||
mdarts(*this),
|
||||
m_nb_darts(0),
|
||||
mnb_used_marks(0)
|
||||
|
||||
{
|
||||
mmask_marks.reset();
|
||||
|
||||
for (size_type i=0; i<NB_MARKS; ++i)
|
||||
{
|
||||
mfree_marks_stack[i] =i;
|
||||
mindex_marks[i] =i;
|
||||
mnb_marked_darts[i] =0;
|
||||
mnb_times_reserved_marks[i]=0;
|
||||
}
|
||||
|
||||
// Store locally the number of darts: the HEG must not be modified
|
||||
m_nb_darts=darts().size();
|
||||
|
||||
m_all_marks=get(CGAL::dynamic_halfedge_property_t<std::bitset<NB_MARKS> >(), m_fg);
|
||||
for (typename Dart_range::const_iterator it(darts().begin()),
|
||||
itend(darts().end()); it!=itend; ++it)
|
||||
{ put(m_all_marks, it, std::bitset<NB_MARKS>()); }
|
||||
}
|
||||
|
||||
const HEG& get_fg() const
|
||||
{ return m_fg; }
|
||||
|
||||
template<unsigned int i>
|
||||
bool is_free(Dart_const_handle /* dh */) const
|
||||
{ return false; } // Not possible to have a free dart with an HEG.
|
||||
bool is_free(Dart_const_handle /*dh*/, unsigned int /*i*/) const
|
||||
{ return false; } // Not possible to have a free dart with an HEG.
|
||||
|
||||
bool is_perforated(Dart_const_handle dh) const
|
||||
{ return is_border(dh, m_fg); }
|
||||
|
||||
Dart_const_handle get_beta(Dart_const_handle ADart, int B1) const
|
||||
{
|
||||
CGAL_assertion(B1>=0 && B1<=static_cast<int>(dimension));
|
||||
if (B1==1) return Get_beta<HEG, 1>::value(m_fg, ADart);
|
||||
if (B1==2) return Get_beta<HEG, 2>::value(m_fg, ADart);
|
||||
return Get_beta<HEG, 0>::value(m_fg, ADart);
|
||||
}
|
||||
template<int B1>
|
||||
Dart_const_handle get_beta(Dart_const_handle ADart) const
|
||||
{
|
||||
CGAL_assertion(B1>=0 && B1<=static_cast<int>(dimension));
|
||||
return Get_beta<HEG, B1>::value(m_fg, ADart);
|
||||
}
|
||||
|
||||
bool is_empty() const
|
||||
{ return number_of_darts()==0; }
|
||||
|
||||
/* ?? bool is_dart_used(Dart_const_handle dh) const
|
||||
{ return true; ?? } */
|
||||
|
||||
int highest_nonfree_dimension(Dart_const_handle /* dh */) const
|
||||
{ return 2; }
|
||||
|
||||
Dart_const_handle previous(Dart_const_handle ADart) const
|
||||
{ return get_beta<0>(ADart); }
|
||||
Dart_const_handle next(Dart_const_handle ADart) const
|
||||
{ return get_beta<1>(ADart); }
|
||||
Dart_const_handle opposite(Dart_const_handle dh) const
|
||||
{ return get_beta<2>(dh); }
|
||||
Dart_const_handle opposite2(Dart_const_handle dh) const
|
||||
{ return get_beta<2>(dh); }
|
||||
Dart_const_handle other_extremity(Dart_const_handle dh) const
|
||||
{ return get_beta<1>(dh); }
|
||||
|
||||
template<unsigned int dim>
|
||||
Dart_const_handle opposite(Dart_const_handle ADart) const
|
||||
{ return this->template get_beta<dim>(ADart); }
|
||||
Dart_const_handle other_orientation(Dart_const_handle ADart) const
|
||||
{ return ADart; }
|
||||
|
||||
bool is_previous_exist(Dart_const_handle) const
|
||||
{ return true; }
|
||||
bool is_next_exist(Dart_const_handle) const
|
||||
{ return true; }
|
||||
template<unsigned int dim>
|
||||
bool is_opposite_exist(Dart_const_handle /* ADart */) const
|
||||
{ return true; }
|
||||
|
||||
template<typename ...Betas>
|
||||
Dart_handle beta(Dart_handle ADart, Betas... betas)
|
||||
{ return CGAL::internal::Beta_functor<Self, Dart_handle, Betas...>::
|
||||
run(*this, ADart, betas...); }
|
||||
template<typename ...Betas>
|
||||
Dart_const_handle beta(Dart_const_handle ADart, Betas... betas) const
|
||||
{ return CGAL::internal::Beta_functor<const Self, Dart_const_handle, Betas...>::
|
||||
run(*this, ADart, betas...); }
|
||||
template<int... Betas>
|
||||
Dart_handle beta(Dart_handle ADart)
|
||||
{ return CGAL::internal::Beta_functor_static<Self, Dart_handle, Betas...>::
|
||||
run(*this, ADart); }
|
||||
template<int... Betas>
|
||||
Dart_const_handle beta(Dart_const_handle ADart) const
|
||||
{ return CGAL::internal::Beta_functor_static<const Self, Dart_const_handle, Betas...>::
|
||||
run(*this, ADart); }
|
||||
|
||||
size_type number_of_darts() const
|
||||
{ return m_nb_darts; }
|
||||
|
||||
size_type number_of_halfedges() const
|
||||
{ return number_of_darts(); }
|
||||
|
||||
size_type number_of_used_marks() const
|
||||
{ return mnb_used_marks; }
|
||||
|
||||
bool is_reserved(size_type amark) const
|
||||
{
|
||||
CGAL_assertion(amark<NB_MARKS);
|
||||
return (mnb_times_reserved_marks[amark]!=0);
|
||||
}
|
||||
|
||||
size_type number_of_marked_darts(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
return mnb_marked_darts[amark];
|
||||
}
|
||||
|
||||
size_type number_of_unmarked_darts(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
return number_of_darts() - number_of_marked_darts(amark);
|
||||
}
|
||||
|
||||
bool is_whole_map_unmarked(size_type amark) const
|
||||
{ return number_of_marked_darts(amark)==0; }
|
||||
|
||||
bool is_whole_map_marked(size_type amark) const
|
||||
{ return number_of_marked_darts(amark)==number_of_darts(); }
|
||||
|
||||
class Exception_no_more_available_mark {};
|
||||
|
||||
size_type get_new_mark() const
|
||||
{
|
||||
if (mnb_used_marks==NB_MARKS)
|
||||
{
|
||||
std::cerr << "Not enough Boolean marks: "
|
||||
"increase NB_MARKS in item class." << std::endl;
|
||||
std::cerr << " (exception launched)" << std::endl;
|
||||
throw Exception_no_more_available_mark();
|
||||
}
|
||||
|
||||
size_type m=mfree_marks_stack[mnb_used_marks];
|
||||
mused_marks_stack[mnb_used_marks]=m;
|
||||
|
||||
mindex_marks[m]=mnb_used_marks;
|
||||
mnb_times_reserved_marks[m]=1;
|
||||
|
||||
++mnb_used_marks;
|
||||
CGAL_assertion(is_whole_map_unmarked(m));
|
||||
|
||||
return m;
|
||||
}
|
||||
|
||||
void share_a_mark(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
++mnb_times_reserved_marks[amark];
|
||||
}
|
||||
|
||||
size_type get_number_of_times_mark_reserved(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( amark<NB_MARKS );
|
||||
return mnb_times_reserved_marks[amark];
|
||||
}
|
||||
|
||||
void negate_mark(size_type amark) const
|
||||
{
|
||||
CGAL_assertion(is_reserved(amark));
|
||||
|
||||
mnb_marked_darts[amark]=number_of_darts()-mnb_marked_darts[amark];
|
||||
mmask_marks.flip(amark);
|
||||
}
|
||||
|
||||
void mark_null_dart( size_type /*amark*/) const
|
||||
{}
|
||||
|
||||
bool get_dart_mark(Dart_const_handle ADart, size_type amark) const
|
||||
{
|
||||
return get(m_all_marks, ADart)[amark];
|
||||
}
|
||||
void set_dart_mark(Dart_const_handle ADart, size_type amark, bool avalue) const
|
||||
{
|
||||
const_cast<std::bitset<NB_MARKS>& >(get(m_all_marks, ADart)).set(amark, avalue);
|
||||
}
|
||||
|
||||
void flip_dart_mark(Dart_const_handle ADart, size_type amark) const
|
||||
{ set_dart_mark(ADart, amark, !get_dart_mark(ADart, amark)); }
|
||||
|
||||
bool is_marked(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
CGAL_assertion(is_reserved(amark));
|
||||
return get_dart_mark(adart, amark)!=mmask_marks[amark];
|
||||
}
|
||||
|
||||
void set_mark_to(Dart_const_handle adart, size_type amark,
|
||||
bool astate) const
|
||||
{
|
||||
CGAL_assertion(is_reserved(amark));
|
||||
|
||||
if (is_marked(adart, amark)!=astate)
|
||||
{
|
||||
if (astate) ++mnb_marked_darts[amark];
|
||||
else --mnb_marked_darts[amark];
|
||||
|
||||
flip_dart_mark(adart, amark);
|
||||
}
|
||||
}
|
||||
|
||||
void mark(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
CGAL_assertion(is_reserved(amark));
|
||||
|
||||
if (is_marked(adart, amark)) return;
|
||||
|
||||
++mnb_marked_darts[amark];
|
||||
flip_dart_mark(adart, amark);
|
||||
}
|
||||
|
||||
void unmark(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
CGAL_assertion( adart!=this->null_dart_handle );
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
|
||||
if (!is_marked(adart, amark)) return;
|
||||
|
||||
--mnb_marked_darts[amark];
|
||||
flip_dart_mark(adart, amark);
|
||||
}
|
||||
|
||||
void unmark_all(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
|
||||
if ( is_whole_map_marked(amark) )
|
||||
{
|
||||
negate_mark(amark);
|
||||
}
|
||||
else if ( !is_whole_map_unmarked(amark) )
|
||||
{
|
||||
for (typename Dart_range::const_iterator it(darts().begin()),
|
||||
itend(darts().end()); it!=itend; ++it)
|
||||
unmark(*it, amark);
|
||||
}
|
||||
CGAL_assertion(is_whole_map_unmarked(amark));
|
||||
}
|
||||
|
||||
void free_mark(size_type amark) const
|
||||
{
|
||||
CGAL_assertion( is_reserved(amark) );
|
||||
|
||||
if ( mnb_times_reserved_marks[amark]>1 )
|
||||
{
|
||||
--mnb_times_reserved_marks[amark];
|
||||
return;
|
||||
}
|
||||
|
||||
unmark_all(amark);
|
||||
|
||||
// 1) We remove amark from the array mused_marks_stack by
|
||||
// replacing it with the last mark in this array.
|
||||
mused_marks_stack[mindex_marks[amark]] =
|
||||
mused_marks_stack[--mnb_used_marks];
|
||||
mindex_marks[mused_marks_stack[mnb_used_marks]] =
|
||||
mindex_marks[amark];
|
||||
|
||||
// 2) We add amark in the array mfree_marks_stack and update its index.
|
||||
mfree_marks_stack[ mnb_used_marks ]=amark;
|
||||
mindex_marks[amark] = mnb_used_marks;
|
||||
|
||||
mnb_times_reserved_marks[amark]=0;
|
||||
}
|
||||
|
||||
bool is_without_boundary(unsigned int i) const
|
||||
{
|
||||
CGAL_assertion(1<=i && i<=dimension);
|
||||
if (i==1) return true;
|
||||
|
||||
for ( typename Dart_range::const_iterator it(darts().begin()),
|
||||
itend(darts().end()); it!=itend; ++it)
|
||||
{ if (is_perforated(it)) return false; }
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_without_boundary() const
|
||||
{ return is_without_boundary(2); }
|
||||
|
||||
//**************************************************************************
|
||||
// Dart_of_cell_range
|
||||
template<unsigned int i>
|
||||
struct Dart_of_cell_range
|
||||
{
|
||||
typedef CGAL::FGW_cell_iterator<Self, i> iterator;
|
||||
typedef CGAL::FGW_cell_iterator<Self, i> const_iterator;
|
||||
Dart_of_cell_range(const Self &amap, Dart_handle adart) : mmap(amap),
|
||||
m_initdart(adart),
|
||||
msize(0)
|
||||
{}
|
||||
const_iterator begin() const { return const_iterator(mmap, m_initdart); }
|
||||
const_iterator end() const { return const_iterator(mmap, m_initdart, mmap.null_handle); }
|
||||
size_type size() const
|
||||
{
|
||||
if (msize==0)
|
||||
{
|
||||
for (const_iterator it=begin(), itend=end(); it!=itend; ++it)
|
||||
{ ++msize; }
|
||||
}
|
||||
return msize;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{ return mmap.is_empty(); }
|
||||
private:
|
||||
const Self & mmap;
|
||||
Dart_handle m_initdart;
|
||||
mutable typename Self::size_type msize;
|
||||
};
|
||||
//**************************************************************************
|
||||
// Dart_of_cell_const_range
|
||||
/* template<unsigned int i,int dim=Self::dimension>
|
||||
struct Dart_of_cell_const_range // TODO REMOVE ??
|
||||
{}; */
|
||||
//--------------------------------------------------------------------------
|
||||
template<unsigned int i>
|
||||
Dart_of_cell_range<i> darts_of_cell(Dart_handle adart)
|
||||
{ return Dart_of_cell_range<i>(*this,adart); }
|
||||
//--------------------------------------------------------------------------
|
||||
template<unsigned int i>
|
||||
Dart_of_cell_range<i> darts_of_cell(Dart_const_handle adart) const
|
||||
{ return Dart_of_cell_range<i>(*this,adart); } // Before it was Dart_of_cell_const_range<i>
|
||||
//**************************************************************************
|
||||
// Dart_range
|
||||
struct Dart_range {
|
||||
typedef CGAL::FGW_dart_iterator_basic_of_all<Self> iterator;
|
||||
typedef CGAL::FGW_dart_iterator_basic_of_all<Self> const_iterator;
|
||||
Dart_range(const Self &amap) : mmap(amap), msize(0)
|
||||
{}
|
||||
iterator begin() { return iterator(mmap); }
|
||||
iterator end() { return iterator(mmap,mmap.null_handle); }
|
||||
const_iterator begin() const { return const_iterator(mmap); }
|
||||
const_iterator end() const { return const_iterator(mmap,mmap.null_handle); }
|
||||
size_type size() const
|
||||
{
|
||||
if (msize==0)
|
||||
{ msize=halfedges(mmap.get_fg()).size(); }
|
||||
return msize;
|
||||
}
|
||||
bool empty() const
|
||||
{ return mmap.is_empty(); }
|
||||
|
||||
size_type capacity() const
|
||||
{ return num_halfedges(mmap.get_fg()); }
|
||||
|
||||
bool is_used(size_type i) const
|
||||
{
|
||||
for (typename boost::template graph_traits<typename Self::HEG>::halfedge_iterator
|
||||
it=halfedges(mmap.get_fg()).begin(),
|
||||
itend=halfedges(mmap.get_fg()).end(); it!=itend; ++it)
|
||||
{
|
||||
if (i==0) { return !is_border(*it, mmap.get_fg()); }
|
||||
--i;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
const Self & mmap;
|
||||
mutable typename Self::size_type msize;
|
||||
};
|
||||
//**************************************************************************
|
||||
// Dart_const_range // TODO REMOVE ?
|
||||
/* struct Dart_const_range {
|
||||
typedef CGAL::FGW_dart_iterator_basic_of_all<Self, true> const_iterator;
|
||||
Dart_const_range(const Self &amap) : mmap(amap), msize(0)
|
||||
{}
|
||||
const_iterator begin() const { return const_iterator(mmap); }
|
||||
const_iterator end() const { return const_iterator(mmap,mmap.null_handle); }
|
||||
size_type size() const
|
||||
{
|
||||
if (msize==0)
|
||||
{
|
||||
for (const_iterator it=begin(), itend=end(); it!=itend; ++it)
|
||||
{ ++msize; }
|
||||
}
|
||||
return msize;
|
||||
}
|
||||
|
||||
bool empty() const
|
||||
{ return mmap.is_empty(); }
|
||||
private:
|
||||
const Self & mmap;
|
||||
mutable typename Self::size_type msize;
|
||||
};*/
|
||||
//**************************************************************************
|
||||
Dart_range& darts()
|
||||
{ return mdarts; }
|
||||
//--------------------------------------------------------------------------
|
||||
const Dart_range& darts() const
|
||||
{ return mdarts; } // Before it was Dart_const_range(*this)
|
||||
//**************************************************************************
|
||||
Dart_handle dart_handle(size_type i)
|
||||
{
|
||||
CGAL_assertion(darts().is_used(i));
|
||||
for (typename boost::template graph_traits<typename Self::HEG>::halfedge_iterator
|
||||
it=halfedges(get_fg()).begin(),
|
||||
itend=halfedges(get_fg()).end(); it!=itend; ++it)
|
||||
{
|
||||
if (i==0) { return *it; }
|
||||
--i;
|
||||
}
|
||||
CGAL_assertion(false);
|
||||
return Dart_handle();
|
||||
}
|
||||
Dart_const_handle dart_handle(size_type i) const
|
||||
{
|
||||
CGAL_assertion(darts().is_used(i));
|
||||
for (typename boost::template graph_traits<typename Self::HEG>::halfedge_iterator
|
||||
it=halfedges(get_fg()).begin(),
|
||||
itend=halfedges(get_fg()).end(); it!=itend; ++it)
|
||||
{
|
||||
if (i==0) { return *it; }
|
||||
--i;
|
||||
}
|
||||
CGAL_assertion(false);
|
||||
return Dart_const_handle();
|
||||
}
|
||||
|
||||
template <unsigned int i>
|
||||
bool belong_to_same_cell(Dart_const_handle adart1,
|
||||
Dart_const_handle adart2) const
|
||||
{
|
||||
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart1).begin(),
|
||||
itend=darts_of_cell<i>(adart1).end(); it!=itend; ++it)
|
||||
{ if (*it==adart2) { return true; } }
|
||||
return false;
|
||||
}
|
||||
|
||||
template <unsigned int i>
|
||||
bool is_whole_cell_unmarked(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
|
||||
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
|
||||
{ if (is_marked(*it, amark)) { return false; } }
|
||||
return true;
|
||||
}
|
||||
|
||||
template <unsigned int i>
|
||||
bool is_whole_cell_marked(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
|
||||
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
|
||||
{ if (!is_marked(*it, amark)) { return false; } }
|
||||
return true;
|
||||
}
|
||||
|
||||
template <unsigned int i>
|
||||
size_type mark_cell(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
size_type res=0;
|
||||
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
|
||||
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
|
||||
{ mark(*it, amark); ++res; }
|
||||
return res;
|
||||
}
|
||||
|
||||
size_type mark_cell(Dart_const_handle adart, unsigned int i, size_type amark) const
|
||||
{
|
||||
if (i==0) { return mark_cell<0>(adart, amark); }
|
||||
else if (i==1) { return mark_cell<1>(adart, amark); }
|
||||
else if (i==2) { return mark_cell<2>(adart, amark); }
|
||||
return mark_cell<3>(adart, amark);
|
||||
}
|
||||
|
||||
template <unsigned int i>
|
||||
size_type unmark_cell(Dart_const_handle adart, size_type amark) const
|
||||
{
|
||||
size_type res=0;
|
||||
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
|
||||
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
|
||||
{ unmark(*it, amark); ++res; }
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<unsigned int>
|
||||
count_marked_cells(size_type amark, const std::vector<unsigned int>& acells) const
|
||||
{
|
||||
std::vector<unsigned int> res(dimension+2);
|
||||
std::vector<size_type> marks(dimension+2);
|
||||
|
||||
// Initialization of the result
|
||||
for (unsigned int i=0; i<dimension+2; ++i)
|
||||
{
|
||||
res[i]=0;
|
||||
marks[i]=INVALID_MARK;
|
||||
}
|
||||
|
||||
// Mark reservation
|
||||
for (unsigned int i=0; i<acells.size(); ++i)
|
||||
{
|
||||
CGAL_assertion(acells[i]<=dimension+1);
|
||||
if (marks[acells[i]]==INVALID_MARK )
|
||||
{
|
||||
marks[acells[i]]=get_new_mark();
|
||||
assert(is_whole_map_unmarked(marks[acells[i]]));
|
||||
}
|
||||
}
|
||||
|
||||
// Counting and marking cells
|
||||
for (typename Dart_range::const_iterator it(darts().begin()),
|
||||
itend(darts().end()); it!=itend; ++it)
|
||||
{
|
||||
if (is_marked(*it, amark))
|
||||
{
|
||||
for (unsigned int i=0; i<acells.size(); ++i)
|
||||
{
|
||||
if (!is_marked(*it, marks[acells[i]]))
|
||||
{
|
||||
mark_cell(*it, acells[i], marks[acells[i]]);
|
||||
++res[acells[i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unmarking darts
|
||||
std::vector<size_type> tounmark;
|
||||
for (unsigned int i=0; i<acells.size(); ++i)
|
||||
{
|
||||
if (is_whole_map_marked(marks[acells[i]]) ||
|
||||
is_whole_map_unmarked(marks[acells[i]]))
|
||||
{ free_mark(marks[acells[i]]); }
|
||||
else
|
||||
{ tounmark.push_back(marks[acells[i]]); }
|
||||
}
|
||||
|
||||
if (tounmark.size()>0)
|
||||
{
|
||||
for (typename Dart_range::const_iterator it(darts().begin()),
|
||||
itend(darts().end()); it!=itend; ++it)
|
||||
{
|
||||
for (unsigned int i=0; i<tounmark.size(); ++i)
|
||||
{ unmark(*it, tounmark[i]); }
|
||||
}
|
||||
for (unsigned int i=0; i<tounmark.size(); ++i)
|
||||
{
|
||||
CGAL_assertion(is_whole_map_unmarked(tounmark[i]));
|
||||
free_mark(tounmark[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<unsigned int>
|
||||
count_cells(const std::vector<unsigned int>& acells) const
|
||||
{
|
||||
std::vector<unsigned int> res;
|
||||
size_type m=get_new_mark();
|
||||
negate_mark(m); // We mark all the cells.
|
||||
|
||||
res=count_marked_cells(m, acells);
|
||||
|
||||
negate_mark(m); // We unmark the cells
|
||||
free_mark(m);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> count_all_cells() const
|
||||
{
|
||||
std::vector<unsigned int> dim(dimension+2);
|
||||
|
||||
for ( unsigned int i=0; i<=dimension+1; ++i)
|
||||
{ dim[i]=i; }
|
||||
|
||||
return count_cells(dim);
|
||||
}
|
||||
|
||||
std::ostream& display_characteristics(std::ostream & os) const
|
||||
{
|
||||
std::vector<unsigned int> cells(dimension+2);
|
||||
for ( unsigned int i=0; i<=dimension+1; ++i)
|
||||
{ cells[i]=i; }
|
||||
|
||||
std::vector<unsigned int> res=count_cells(cells);
|
||||
|
||||
os<<"#Darts="<<number_of_darts();
|
||||
for (unsigned int i=0; i<=dimension; ++i)
|
||||
os<<", #"<<i<<"-cells="<<res[i];
|
||||
os<<", #ccs="<<res[dimension+1];
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
protected:
|
||||
const HEG& m_fg;
|
||||
Dart_range mdarts;
|
||||
std::size_t m_nb_darts;
|
||||
|
||||
/// Number of times each mark is reserved. 0 if the mark is free.
|
||||
mutable size_type mnb_times_reserved_marks[NB_MARKS];
|
||||
|
||||
/// Mask marks to know the value of unmark dart, for each index i.
|
||||
mutable std::bitset<NB_MARKS> mmask_marks;
|
||||
|
||||
/// Number of used marks.
|
||||
mutable size_type mnb_used_marks;
|
||||
|
||||
/// Index of each mark, in mfree_marks_stack or in mfree_marks_stack.
|
||||
mutable size_type mindex_marks[NB_MARKS];
|
||||
|
||||
/// "Stack" of free marks.
|
||||
mutable size_type mfree_marks_stack[NB_MARKS];
|
||||
|
||||
/// "Stack" of used marks.
|
||||
mutable size_type mused_marks_stack[NB_MARKS];
|
||||
|
||||
/// Number of marked darts for each used marks.
|
||||
mutable size_type mnb_marked_darts[NB_MARKS];
|
||||
|
||||
/// Array of property maps; one for each reserved mark.
|
||||
typedef typename boost::property_map
|
||||
<HEG, CGAL::dynamic_halfedge_property_t<std::bitset<NB_MARKS> > >::const_type MarkPMap;
|
||||
mutable MarkPMap m_all_marks;
|
||||
};
|
||||
|
||||
/// null_handle
|
||||
// template <typename HEG>
|
||||
// const typename Face_graph_wrapper<HEG>::Null_handle_type
|
||||
// Face_graph_wrapper<HEG>::null_handle=nullptr;
|
||||
template <typename HEG>
|
||||
const typename Face_graph_wrapper<HEG>::Null_handle_type
|
||||
Face_graph_wrapper<HEG>::null_handle=typename Face_graph_wrapper<HEG>::Dart_handle();
|
||||
|
||||
/// null_dart_handle
|
||||
// template <typename HEG>
|
||||
// const typename Face_graph_wrapper<HEG>::Null_handle_type
|
||||
// Face_graph_wrapper<HEG>::null_dart_handle=nullptr;
|
||||
template <typename HEG>
|
||||
const typename Face_graph_wrapper<HEG>::Null_handle_type
|
||||
Face_graph_wrapper<HEG>::null_dart_handle=typename Face_graph_wrapper<HEG>::Dart_handle();
|
||||
|
||||
template<class Base, class HEG>
|
||||
struct Get_map
|
||||
{
|
||||
typedef Face_graph_wrapper<HEG> type;
|
||||
typedef const Face_graph_wrapper<HEG> storage_type;
|
||||
Get_map(const HEG& heg): m_map(heg) {}
|
||||
static const HEG& get_mesh(const storage_type& amap)
|
||||
{ return amap.get_fg(); }
|
||||
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, typename Refs, typename Items, typename Alloc,
|
||||
typename Storage, class Map>
|
||||
struct Get_map<CGAL::Combinatorial_map_base<d, Refs, Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, typename Refs, typename Items, typename Alloc,
|
||||
typename Storage, class Map>
|
||||
struct Get_map<CGAL::Generalized_map_base<d, Refs, Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Refs, typename Storage, class LCC>
|
||||
struct Get_map<CGAL::Linear_cell_complex_base<d, d2, Traits, Items, Alloc,
|
||||
Map, Refs, Storage>, LCC>
|
||||
{
|
||||
typedef LCC type;
|
||||
typedef const LCC& storage_type;
|
||||
Get_map(const LCC& heg): m_map(heg) {}
|
||||
static const LCC& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, typename Items, typename Alloc,
|
||||
typename Storage, class Map>
|
||||
struct Get_map<CGAL::Combinatorial_map<d, Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <typename Items, typename Alloc, typename Storage, class Map>
|
||||
struct Get_map<CGAL::Surface_mesh_topology::
|
||||
Polygonal_schema_with_combinatorial_map<Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, typename Items, typename Alloc,
|
||||
typename Storage, class Map>
|
||||
struct Get_map<CGAL::Generalized_map<d, Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <typename Items, typename Alloc, typename Storage, class Map>
|
||||
struct Get_map<CGAL::Surface_mesh_topology::
|
||||
Polygonal_schema_with_generalized_map<Items, Alloc, Storage>, Map>
|
||||
{
|
||||
typedef Map type;
|
||||
typedef const Map& storage_type;
|
||||
Get_map(const Map& heg): m_map(heg) {}
|
||||
static const Map& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Storage, class LCC>
|
||||
struct Get_map<CGAL::Linear_cell_complex_for_combinatorial_map
|
||||
<d, d2, Traits, Items, Alloc, Map, Storage>, LCC>
|
||||
{
|
||||
typedef LCC type;
|
||||
typedef const LCC& storage_type;
|
||||
Get_map(const LCC& heg): m_map(heg) {}
|
||||
static const LCC& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template <unsigned int d, unsigned int d2, typename Traits, typename Items,
|
||||
typename Alloc,
|
||||
template<unsigned int,class,class,class,class>
|
||||
class Map, typename Storage, class LCC>
|
||||
struct Get_map<CGAL::Linear_cell_complex_for_generalized_map
|
||||
<d, d2, Traits, Items, Alloc, Map, Storage>, LCC>
|
||||
{
|
||||
typedef LCC type;
|
||||
typedef const LCC& storage_type;
|
||||
Get_map(const LCC& heg): m_map(heg) {}
|
||||
static const LCC& get_mesh(storage_type& amap)
|
||||
{ return amap; }
|
||||
storage_type m_map;
|
||||
};
|
||||
|
||||
template<class Mesh_>
|
||||
struct Get_traits
|
||||
{
|
||||
typedef Mesh_ Mesh;
|
||||
typedef typename Mesh::Traits Kernel;
|
||||
typedef typename Mesh::Point Point;
|
||||
typedef typename Mesh::Vector Vector;
|
||||
|
||||
template<class Dart_handle>
|
||||
static const Point& get_point(const Mesh& m, Dart_handle dh)
|
||||
{ return m.point(dh); }
|
||||
};
|
||||
|
||||
template<class P>
|
||||
struct Get_traits<CGAL::Surface_mesh<P> >
|
||||
{
|
||||
typedef CGAL::Surface_mesh<P> Mesh;
|
||||
typedef typename CGAL::Kernel_traits<P>::Kernel Kernel;
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Vector_3 Vector;
|
||||
|
||||
template<class Dart_handle>
|
||||
static const Point& get_point(const Mesh& m, Dart_handle dh)
|
||||
{ return m.point(m.source(dh)); }
|
||||
};
|
||||
|
||||
template<class PolyhedronTraits_3,
|
||||
class PolyhedronItems_3,
|
||||
template<class T, class I, class A> class T_HDS,
|
||||
class Alloc>
|
||||
struct Get_traits<CGAL::Polyhedron_3<PolyhedronTraits_3,
|
||||
PolyhedronItems_3, T_HDS, Alloc> >
|
||||
{
|
||||
typedef CGAL::Polyhedron_3<PolyhedronTraits_3, PolyhedronItems_3,
|
||||
T_HDS, Alloc> Mesh;
|
||||
typedef PolyhedronTraits_3 Kernel;
|
||||
typedef typename Kernel::Point_3 Point;
|
||||
typedef typename Kernel::Vector_3 Vector;
|
||||
|
||||
template<class Dart_handle>
|
||||
static const Point& get_point(const Mesh& /*m*/, Dart_handle dh)
|
||||
{ return dh->opposite()->vertex()->point(); }
|
||||
};
|
||||
|
||||
} // Namespace CGAL
|
||||
|
||||
#endif // CGAL_FACE_GRAPH_WRAPPER_H //
|
||||
// EOF //
|
||||
@@ -0,0 +1,87 @@
|
||||
// Copyright (c) 2019 CNRS and LIRIS' Establishments (France).
|
||||
// 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) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
#ifndef CGAL_FUNCTORS_FOR_FACE_GRAPH_WRAPPER_H
|
||||
#define CGAL_FUNCTORS_FOR_FACE_GRAPH_WRAPPER_H 1
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <CGAL/Iterators_for_face_graph_wrapper.h>
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/** This file contains the following functors for Face_graph_wrapper:
|
||||
* Is_free<typename HEG, unsigned int i>::
|
||||
operator() (const HEG& heg, Dart_const_handle dh)
|
||||
* Get_beta<typename HEG, unsigned int i>::
|
||||
operator() (const HEG& heg, Dart_const_handle dh)
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
namespace CGAL
|
||||
{
|
||||
/// Is_free
|
||||
//template<typename HEG, unsigned int i>
|
||||
//struct Is_free
|
||||
//{
|
||||
// typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
|
||||
// static bool value(const HEG& /*heg*/, Dart_const_handle /*dh*/)
|
||||
// { CGAL_static_assertion(i==0 || i==1); return false; }
|
||||
//};
|
||||
//template<typename HEG>
|
||||
//struct Is_free<HEG, 2>
|
||||
//{
|
||||
// typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
// static bool value(const HEG& heg, Dart_const_handle dh)
|
||||
// { return is_border(opposite(dh, heg), heg); }
|
||||
//};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Get_beta
|
||||
template<typename HEG, unsigned int i>
|
||||
struct Get_beta
|
||||
{
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
|
||||
static Dart_const_handle value(const HEG& /*heg*/, Dart_const_handle /*dh*/)
|
||||
{ /* CGAL_static_assertion(false);*/
|
||||
std::cout<<"ERROR Get_beta<HEG, "<<i<<">"<<std::endl;
|
||||
CGAL_assertion(false);
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
template<typename HEG>
|
||||
struct Get_beta<HEG, 0>
|
||||
{
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
static Dart_const_handle value(const HEG& heg, Dart_const_handle dh)
|
||||
{ return prev(dh, heg); }
|
||||
};
|
||||
template<typename HEG>
|
||||
struct Get_beta<HEG, 1>
|
||||
{
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
static Dart_const_handle value(const HEG& heg, Dart_const_handle dh)
|
||||
{ return next(dh, heg); }
|
||||
};
|
||||
template<typename HEG>
|
||||
struct Get_beta<HEG, 2>
|
||||
{
|
||||
typedef typename boost::graph_traits<HEG>::halfedge_descriptor Dart_const_handle;
|
||||
static Dart_const_handle value(const HEG& heg, Dart_const_handle dh)
|
||||
{
|
||||
//if (Is_free<HEG, 2>::value(heg, dh)) return Dart_const_handle();
|
||||
return opposite(dh, heg);
|
||||
}
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_FUNCTORS_FOR_FACE_GRAPH_WRAPPER_H //
|
||||
// EOF //
|
||||
@@ -0,0 +1,332 @@
|
||||
// Copyright (c) 2019 CNRS and LIRIS' Establishments (France).
|
||||
// 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) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
|
||||
//
|
||||
#ifndef CGAL_ITERATORS_FOR_FACE_GRAPH_WRAPPER_H
|
||||
#define CGAL_ITERATORS_FOR_FACE_GRAPH_WRAPPER_H 1
|
||||
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
#include <CGAL/boost/graph/helpers.h>
|
||||
#include <stack>
|
||||
|
||||
namespace CGAL
|
||||
{
|
||||
|
||||
//****************************************************************************
|
||||
/* Class CMap_dart_iterator_basic_of_all: to iterate onto all the
|
||||
* darts of the face graph.
|
||||
*/
|
||||
template <typename Map_,bool Const=false>
|
||||
class FGW_dart_iterator_basic_of_all
|
||||
{
|
||||
public:
|
||||
typedef FGW_dart_iterator_basic_of_all Self;
|
||||
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
public:
|
||||
/// Main constructor.
|
||||
FGW_dart_iterator_basic_of_all(const Map& amap):
|
||||
mmap(amap),
|
||||
m_it(halfedges(amap.get_fg()).begin())
|
||||
{
|
||||
/*if (m_it!=halfedges(amap.get_fg()).end() &&
|
||||
is_border(*m_it, amap.get_fg()))
|
||||
{ operator++(0); } */
|
||||
}
|
||||
|
||||
/// Constructor with a dart in parameter (for end iterator).
|
||||
FGW_dart_iterator_basic_of_all(const Map& amap, Dart_handle /*adart*/):
|
||||
mmap(amap),
|
||||
m_it(halfedges(amap.get_fg()).end())
|
||||
{}
|
||||
|
||||
FGW_dart_iterator_basic_of_all(const FGW_dart_iterator_basic_of_all& other):
|
||||
mmap(other.mmap),
|
||||
m_it(other.m_it)
|
||||
{}
|
||||
|
||||
operator Dart_handle() const
|
||||
{ return operator*(); }
|
||||
|
||||
bool operator==(const Self& other) const
|
||||
{ return &mmap==&(other.mmap) && m_it==other.m_it; }
|
||||
|
||||
bool operator!=(const Self& other) const
|
||||
{ return !(operator==(other)); }
|
||||
|
||||
/// Prefix ++ operator.
|
||||
Self& operator++()
|
||||
{
|
||||
CGAL_assertion(m_it!=halfedges(this->mmap.get_fg()).end());
|
||||
|
||||
//do
|
||||
{
|
||||
++m_it;
|
||||
}
|
||||
/*while(m_it!=halfedges(this->mmap.get_fg()).end() &&
|
||||
is_border(*m_it, this->mmap.get_fg())); */
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix ++ operator.
|
||||
Self operator++(int)
|
||||
{ Self res=*this; operator ++(); return res; }
|
||||
|
||||
Dart_handle operator*() const
|
||||
{
|
||||
CGAL_assertion(m_it!=halfedges(this->mmap.get_fg()).end());
|
||||
return *m_it;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map& mmap;
|
||||
typename boost::graph_traits<typename Map_::HEG>::halfedge_iterator m_it;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template <typename Map_>
|
||||
class FGW_basis_for_cell_iterator
|
||||
{
|
||||
public:
|
||||
typedef FGW_basis_for_cell_iterator Self;
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
/// Main constructor.
|
||||
FGW_basis_for_cell_iterator(const Map& amap, Dart_handle adart):
|
||||
mmap(amap),
|
||||
m_firstdart(adart),
|
||||
m_curdart(adart)
|
||||
{}
|
||||
|
||||
/// Constructor with two darts in parameter (for end iterator).
|
||||
FGW_basis_for_cell_iterator(const Map& amap, Dart_handle adart,
|
||||
Dart_handle /* d2 */):
|
||||
mmap(amap),
|
||||
m_firstdart(adart),
|
||||
m_curdart(Dart_handle())
|
||||
{}
|
||||
|
||||
bool operator==(const Self& other) const
|
||||
{ return &mmap==&(other.mmap) && m_firstdart==other.m_firstdart &&
|
||||
m_curdart==other.m_curdart; }
|
||||
|
||||
bool operator!=(const Self& other) const
|
||||
{ return !(this->operator==(other)); }
|
||||
|
||||
operator Dart_handle() const
|
||||
{ return operator*(); }
|
||||
|
||||
Dart_handle operator*() const
|
||||
{
|
||||
CGAL_assertion(m_curdart!=Dart_handle());
|
||||
return m_curdart;
|
||||
}
|
||||
|
||||
protected:
|
||||
const Map& mmap;
|
||||
Dart_handle m_firstdart, m_curdart;
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename HEG, unsigned int i>
|
||||
class FGW_cell_iterator
|
||||
{};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// Vertex iterator
|
||||
template<typename Map_>
|
||||
class FGW_cell_iterator<Map_, 0>: public FGW_basis_for_cell_iterator<Map_> // Vertex
|
||||
{
|
||||
public:
|
||||
typedef FGW_cell_iterator Self;
|
||||
typedef FGW_basis_for_cell_iterator<Map_> Base;
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart) : Base(amap, adart),
|
||||
m_second_way(false)
|
||||
{}
|
||||
|
||||
/// Constructor with two darts in parameter (for end iterator).
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart,
|
||||
Dart_handle d2): Base(amap, adart, d2)
|
||||
{}
|
||||
|
||||
/// Prefix ++ operator.
|
||||
Self& operator++()
|
||||
{
|
||||
if (!m_second_way)
|
||||
{
|
||||
if (this->mmap.template is_free<2>(this->m_curdart))
|
||||
{
|
||||
m_second_way=true;
|
||||
this->m_curdart=this->mmap.template beta<0>(this->m_firstdart);
|
||||
if (this->mmap.template is_free<2>(this->m_curdart))
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
else { this->m_curdart=this->mmap.template beta<2>(this->m_curdart); }
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_curdart=this->mmap.template beta<2, 1>(this->m_curdart);
|
||||
if (this->m_curdart==this->m_firstdart)
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->m_curdart=this->mmap.template beta<0>(this->m_curdart);
|
||||
if (this->mmap.template is_free<2>(this->m_curdart))
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
else { this->m_curdart=this->mmap.template beta<2>(this->m_curdart); }
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix ++ operator.
|
||||
Self operator++(int)
|
||||
{ Self res=*this; operator ++(); return res; }
|
||||
|
||||
protected:
|
||||
/// True if we already found a border dart, and thus turn in the second way
|
||||
bool m_second_way;
|
||||
};
|
||||
template<typename Map_>
|
||||
class FGW_cell_iterator<Map_, 1>: public FGW_basis_for_cell_iterator<Map_> // Edge
|
||||
{
|
||||
public:
|
||||
typedef FGW_cell_iterator Self;
|
||||
typedef FGW_basis_for_cell_iterator<Map_> Base;
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart) : Base(amap, adart)
|
||||
{}
|
||||
|
||||
/// Constructor with two darts in parameter (for end iterator).
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart,
|
||||
Dart_handle d2): Base(amap, adart, d2)
|
||||
{}
|
||||
|
||||
/// Prefix ++ operator.
|
||||
Self& operator++()
|
||||
{
|
||||
if (this->m_curdart==this->m_firstdart)
|
||||
{
|
||||
if (this->mmap.template is_free<2>(this->m_curdart))
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
else { this->m_curdart=this->mmap.template beta<2>(this->m_curdart); }
|
||||
}
|
||||
else
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix ++ operator.
|
||||
Self operator++(int)
|
||||
{ Self res=*this; operator ++(); return res; }
|
||||
};
|
||||
template<typename Map_>
|
||||
class FGW_cell_iterator<Map_, 2>: public FGW_basis_for_cell_iterator<Map_> // Face
|
||||
{
|
||||
public:
|
||||
typedef FGW_cell_iterator Self;
|
||||
typedef FGW_basis_for_cell_iterator<Map_> Base;
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart) : Base(amap, adart)
|
||||
{}
|
||||
|
||||
/// Constructor with two darts in parameter (for end iterator).
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart,
|
||||
Dart_handle d2): Base(amap, adart, d2)
|
||||
{}
|
||||
|
||||
/// Prefix ++ operator.
|
||||
Self& operator++()
|
||||
{
|
||||
this->m_curdart=this->mmap.template beta<1>(this->m_curdart);
|
||||
if (this->m_curdart==this->m_firstdart)
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix ++ operator.
|
||||
Self operator++(int)
|
||||
{ Self res=*this; operator ++(); return res; }
|
||||
};
|
||||
template<typename Map_>
|
||||
class FGW_cell_iterator<Map_, 3>: public FGW_basis_for_cell_iterator<Map_> // CC
|
||||
{
|
||||
public:
|
||||
typedef FGW_cell_iterator Self;
|
||||
typedef FGW_basis_for_cell_iterator<Map_> Base;
|
||||
typedef Map_ Map;
|
||||
typedef typename Map::Dart_handle Dart_handle;
|
||||
typedef typename Map::size_type size_type;
|
||||
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart) : Base(amap, adart)
|
||||
{ m_mark=this->mmap.get_new_mark(); }
|
||||
|
||||
/// Constructor with two darts in parameter (for end iterator).
|
||||
FGW_cell_iterator(const Map& amap, Dart_handle adart,
|
||||
Dart_handle d2): Base(amap, adart, d2)
|
||||
{ m_mark=this->mmap.get_new_mark(); }
|
||||
|
||||
~FGW_cell_iterator()
|
||||
{ this->mmap.free_mark(m_mark); }
|
||||
|
||||
/// Prefix ++ operator.
|
||||
Self& operator++()
|
||||
{
|
||||
if (!this->mmap.is_marked(this->mmap.template beta<1>(this->m_curdart), m_mark))
|
||||
{
|
||||
m_to_treat.push(this->mmap.template beta<1>(this->m_curdart));
|
||||
this->mmap.mark(this->mmap.template beta<1>(this->m_curdart), m_mark);
|
||||
}
|
||||
if (!this->mmap.template is_free<2>(this->m_curdart) &&
|
||||
!this->mmap.is_marked(this->mmap.template beta<2>(this->m_curdart), m_mark))
|
||||
{
|
||||
m_to_treat.push(this->mmap.template beta<2>(this->m_curdart));
|
||||
this->mmap.mark(this->mmap.template beta<2>(this->m_curdart), m_mark);
|
||||
}
|
||||
|
||||
if (m_to_treat.empty())
|
||||
{ this->m_curdart=Dart_handle(); }
|
||||
else
|
||||
{ this->m_curdart=m_to_treat.top(); m_to_treat.pop(); }
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Postfix ++ operator.
|
||||
Self operator++(int)
|
||||
{ Self res=*this; operator ++(); return res; }
|
||||
|
||||
protected:
|
||||
typename Map_::size_type m_mark;
|
||||
std::stack<Dart_handle> m_to_treat;
|
||||
};
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
} // namespace CGAL
|
||||
|
||||
#endif // CGAL_ITERATORS_FOR_FACE_GRAPH_WRAPPER_H //
|
||||
// EOF //
|
||||
@@ -1,5 +1,6 @@
|
||||
Algebraic_foundations
|
||||
Arithmetic_kernel
|
||||
BGL
|
||||
Cartesian_kernel
|
||||
Circulator
|
||||
Combinatorial_map
|
||||
@@ -17,5 +18,7 @@ Kernel_d
|
||||
Modular_arithmetic
|
||||
Number_types
|
||||
Profiling_tools
|
||||
Property_map
|
||||
STL_Extension
|
||||
Stream_support
|
||||
Random_numbers
|
||||
|
||||
@@ -16,6 +16,11 @@ if ( CGAL_FOUND )
|
||||
create_single_source_cgal_program( "${cppfile}" )
|
||||
endforeach()
|
||||
|
||||
find_package( OpenMesh QUIET )
|
||||
if (TARGET OpenMesh::OpenMesh)
|
||||
target_link_libraries(Combinatorial_map_copy_test PRIVATE OpenMesh::OpenMesh)
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
message(STATUS "This program requires the CGAL library, and will not be compiled.")
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
#include <CGAL/Combinatorial_map.h>
|
||||
#include <CGAL/Cell_attribute.h>
|
||||
#include "Combinatorial_map_test_iterators.h"
|
||||
#include <CGAL/HalfedgeDS_default.h>
|
||||
#if CGAL_USE_OPENMESH
|
||||
# include <OpenMesh/Core/IO/MeshIO.hh>
|
||||
# include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
# include <CGAL/boost/graph/graph_traits_TriMesh_ArrayKernelT.h>
|
||||
typedef OpenMesh::TriMesh_ArrayKernelT</* MyTraits*/> OpenMesh_mesh;
|
||||
#endif // CGAL_USE_OPENMESH
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -152,6 +159,10 @@ typedef CGAL::Combinatorial_map<4, Map_dart_items_4> Map8;
|
||||
// info=char, int, int, int, int, double
|
||||
typedef CGAL::Combinatorial_map<4, Map_dart_max_items_4> Map9;
|
||||
|
||||
struct Traits { typedef int Point_2; typedef int Point_3; };
|
||||
typedef CGAL::HalfedgeDS_default<Traits> HDS;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
template<typename Map, unsigned int i, typename Attr=typename Map::
|
||||
template Attribute_type<i>::type>
|
||||
struct CreateAttributes
|
||||
@@ -579,6 +590,31 @@ bool testCopy()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool testImportFromHalfedge()
|
||||
{
|
||||
bool res=true;
|
||||
|
||||
HDS hds;
|
||||
CGAL::HalfedgeDS_decorator<HDS> decorator(hds);
|
||||
decorator.create_loop();
|
||||
decorator.create_segment();
|
||||
|
||||
Map1 map1; map1.import_from_halfedge_graph(hds);
|
||||
Map2 map2; map2.import_from_halfedge_graph(hds);
|
||||
Map3 map3; map3.import_from_halfedge_graph(hds);
|
||||
|
||||
#if CGAL_USE_OPENMESH
|
||||
{
|
||||
// test the compilation, with an empty mesh
|
||||
OpenMesh_mesh hds;
|
||||
Map1 map1; map1.import_from_halfedge_graph(hds);
|
||||
Map2 map2; map2.import_from_halfedge_graph(hds);
|
||||
Map3 map3; map3.import_from_halfedge_graph(hds);
|
||||
}
|
||||
#endif // CGAL_USE_OPENMESH
|
||||
return res; // TODO compare number of darts/cells
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
std::cout<<"Combinatorial map copy test (v1)."<<std::flush;
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
#include <CGAL/Combinatorial_map.h>
|
||||
#include <CGAL/Cell_attribute.h>
|
||||
#include <CGAL/Face_graph_wrapper.h>
|
||||
#include <CGAL/Simple_cartesian.h>
|
||||
#include <CGAL/Surface_mesh.h>
|
||||
#include <CGAL/Polyhedron_3.h>
|
||||
#include <CGAL/IO/Polyhedron_iostream.h>
|
||||
|
||||
#include "Combinatorial_map_2_test.h"
|
||||
#include "Combinatorial_map_3_test.h"
|
||||
@@ -193,8 +198,64 @@ bool test_get_new_mark()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool test_face_graph_wrapper()
|
||||
{
|
||||
bool res=true;
|
||||
|
||||
typedef CGAL::Surface_mesh<CGAL::Simple_cartesian<double>::Point_3> SMesh;
|
||||
SMesh m;
|
||||
std::ifstream in1("data/head.off");
|
||||
if (in1.fail())
|
||||
{
|
||||
std::cout<<"Error: impossible to open 'data/head.off'"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
in1>>m;
|
||||
|
||||
CGAL::Face_graph_wrapper<SMesh> fgw1(m);
|
||||
std::vector<unsigned int> cells=fgw1.count_all_cells();
|
||||
if (cells[0]!=1487 || cells[1]!=4406 || cells[2]!=2921 ||
|
||||
fgw1.number_of_darts()!=8812)
|
||||
{
|
||||
std::cout<<"Error: incorrect number of cells in test_face_graph_wrapper "
|
||||
<<"for Surface_mesh: "
|
||||
<<cells[0]<<", "<<cells[1]<<", "<<cells[2]<<", "<<fgw1.number_of_darts()
|
||||
<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
|
||||
typedef CGAL::Polyhedron_3<CGAL::Simple_cartesian<double> > Polyhedron;
|
||||
Polyhedron p;
|
||||
std::ifstream in2("data/head.off");
|
||||
if (in2.fail())
|
||||
{
|
||||
std::cout<<"Error: impossible to open 'data/head.off'"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
in2>>p;
|
||||
CGAL::Face_graph_wrapper<Polyhedron> fgw2(p);
|
||||
cells=fgw2.count_all_cells();
|
||||
if (cells[0]!=1487 || cells[1]!=4406 || cells[2]!=2921 ||
|
||||
fgw2.number_of_darts()!=8812)
|
||||
{
|
||||
std::cout<<"Error: incorrect number of cells in test_face_graph_wrapper "
|
||||
<<"for Polyhedron."
|
||||
<<cells[0]<<", "<<cells[1]<<", "<<cells[2]<<", "<<fgw2.number_of_darts()
|
||||
<<std::endl;
|
||||
res=false;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
if (!test_face_graph_wrapper())
|
||||
{
|
||||
std::cout<<"ERROR during test_face_graph_wrapper."<<std::endl;
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
if ( !test_get_new_mark() )
|
||||
{
|
||||
std::cout<<"ERROR during test_get_new_mark."<<std::endl;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -12,12 +12,12 @@ cyclic sequence of extreme points is cut into a linear sequence.
|
||||
\pre The source range [`first`,`beyond`) does not contain `result`.
|
||||
|
||||
The default traits class `Default_traits` is the kernel in which the
|
||||
value type of `InputIterator` is defined.
|
||||
value type of `ForwardIterator` is defined.
|
||||
|
||||
\cgalHeading{Requirements}
|
||||
|
||||
<OL>
|
||||
<LI>The value type of `InputIterator` and
|
||||
<LI>The value type of `ForwardIterator` and
|
||||
`OutputIterator` is equivalent to `Traits::Point_2`.
|
||||
<LI>`Traits` defines the following subset of types from
|
||||
the concept `ConvexHullTraits_2` and their corresponding member
|
||||
@@ -46,10 +46,10 @@ 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 ForwardIterator, class OutputIterator, class Traits>
|
||||
OutputIterator
|
||||
ch_jarvis( InputIterator first,
|
||||
InputIterator beyond,
|
||||
ch_jarvis( ForwardIterator first,
|
||||
ForwardIterator beyond,
|
||||
OutputIterator result,
|
||||
const Traits & ch_traits = Default_traits);
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ is a kernel with exact predicates but inexact constructions
|
||||
(in practice we check `R::Has_filtered_predicates_tag` is `Tag_true` and `R::FT` is a floating point type),
|
||||
then the default traits class of `::convex_hull_3()` is `Convex_hull_traits_3<R>`, and `R` otherwise.
|
||||
|
||||
\attention The user must include the header file of the `Polygon_mesh` type.
|
||||
\attention The user must include the header file of the `PolygonMesh` type.
|
||||
|
||||
\cgalHeading{Implementation}
|
||||
|
||||
@@ -34,6 +34,36 @@ Barnard <I>et al.</I> \cgalCite{bdh-qach-96}.
|
||||
template <class InputIterator, class PolygonMesh, class Traits>
|
||||
void convex_hull_3(InputIterator first, InputIterator last, PolygonMesh& pm, const Traits& ch_traits = Default_traits);
|
||||
|
||||
|
||||
/*!
|
||||
\ingroup PkgConvexHull3Functions
|
||||
* \brief computes the convex hull of the points associated to the vertices of `g`.
|
||||
* The polygon mesh `pm` is cleared, then
|
||||
* the convex hull is stored in `pm`. Note that the convex hull will be triangulated,
|
||||
* that is `pm` will contain only triangular faces.
|
||||
* if the convex hull is a point or a segment, endpoints will be added in `pm` as isolated vertices.
|
||||
*
|
||||
* \tparam VertexListGraph a model of `VertexListGraph`.
|
||||
* \tparam PolygonMesh must be a model of `MutableFaceGraph`.
|
||||
* \tparam NamedParameters a sequence of named parameters
|
||||
*
|
||||
* \param g the graph
|
||||
* \param pm the `PolygonMesh` that will contain the convex hull
|
||||
* \param np optional sequence of named parameters among the ones listed below
|
||||
*
|
||||
* \cgalNamedParamsBegin
|
||||
* \cgalParamBegin{vertex_point_map} the property map with the points associated to the vertices of `g`.
|
||||
* If this parameter is omitted, an internal property map for
|
||||
* `CGAL::vertex_point_t` must be available in `VertexListGraph`
|
||||
* \cgalParamEnd
|
||||
* \cgalNamedParamsEnd
|
||||
* \attention The user must include the header file of the `PolygonMesh` and `VertexListGraph` types.
|
||||
*/
|
||||
template <class VertexListGraph, class PolygonMesh, class NamedParameters>
|
||||
void convex_hull_3(const VertexListGraph& g,
|
||||
PolygonMesh& pm,
|
||||
const NamedParameters& np);
|
||||
|
||||
/*!
|
||||
\ingroup PkgConvexHull3Functions
|
||||
|
||||
@@ -47,7 +77,7 @@ that is the polygon mesh will contain only triangular facets.
|
||||
\tparam Traits must be model of the concept `ConvexHullTraits_3`.
|
||||
For the purposes of checking the postcondition that the convex hull
|
||||
is valid, `Traits` must also be a model of the concept
|
||||
`IsStronglyConvexTraits_3`. Furthermore, `Traits` must define a type `Polygon_mesh` that is a model of
|
||||
`IsStronglyConvexTraits_3`. Furthermore, `Traits` must define a type `PolygonMesh` that is a model of
|
||||
`MutableFaceGraph`.
|
||||
|
||||
If the kernel `R` of the points determined by the value type of `InputIterator`
|
||||
@@ -55,7 +85,7 @@ is a kernel with exact predicates but inexact constructions
|
||||
(in practice we check `R::Has_filtered_predicates_tag` is `Tag_true` and `R::FT` is a floating point type),
|
||||
then the default traits class of `convex_hull_3()` is `Convex_hull_traits_3<R>`, and `R` otherwise.
|
||||
|
||||
\attention The user must include the header file of the `Polygon_mesh` type.
|
||||
\attention The user must include the header file of the `PolygonMesh` type.
|
||||
*/
|
||||
|
||||
template <class InputIterator, class Traits>
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS}
|
||||
|
||||
PROJECT_NAME = "CGAL ${CGAL_DOC_VERSION} - 3D Convex Hulls"
|
||||
|
||||
\# macros to be used inside the code
|
||||
ALIASES += "cgalNamedParamsBegin=<dl class=\"params\"><dt>Named Parameters</dt><dd> <table class=\"params\">"
|
||||
ALIASES += "cgalNamedParamsEnd=</table> </dd> </dl>"
|
||||
ALIASES += "cgalParamBegin{1}=<tr><td class=\"paramname\">\ref BGL_\1 \"\1\"</td><td>"
|
||||
ALIASES += "cgalParamEnd=</td></tr>"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user