Merge remote-tracking branch 'cgal/releases/CGAL-4.14-branch'

This commit is contained in:
Sébastien Loriot 2020-03-16 16:19:38 +01:00
commit cf99ea072d
15 changed files with 127 additions and 266 deletions

View File

@ -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.

View File

@ -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>`

View File

@ -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>`

View File

@ -5,5 +5,6 @@ Algebraic_foundations
Circulator
Stream_support
Voronoi_diagram_2
Number_types
TDS_2
Triangulation_2

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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))
{
BOOST_FOREACH(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);
}

View File

@ -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
BOOST_FOREACH(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()

View File

@ -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);

View File

@ -824,7 +824,7 @@ protected:
false> Wrapper;
return Wrapper(image,
transform_fct,
transform_fct(value_outside));
value_outside) ;
}
template <typename FT, typename FT2, typename Functor>

View File

@ -1514,7 +1514,9 @@ private:
// tag patch border halfedges
for(halfedge_descriptor h : halfedges(mesh_))
{
if (status(h)==PATCH && status(opposite(h, mesh_))!=PATCH)
if (status(h) == PATCH
&& ( status(opposite(h, mesh_)) != PATCH
|| get_patch_id(face(h, mesh_)) != get_patch_id(face(opposite(h, mesh_), mesh_))))
{
set_status(h, PATCH_BORDER);
has_border_ = true;

View File

@ -611,7 +611,6 @@ public Q_SLOTS:
}
if (fpmap_valid)
{
PMP::connected_components(pmesh, fpmap, PMP::parameters::edge_is_constrained_map(eif));
poly_item->setItemIsMulticolor(true);
poly_item->show_feature_edges(true);
}

View File

@ -404,30 +404,17 @@ classes:
As mentioned above, performing computations with exact arithmetic
can be very costly. For this reason we have devoted considerable
effort in implementing different kinds of arithmetic filtering
mechanisms. Presently, there two ways of performing arithmetic
filtering for the predicates involved in the computation of
segment Delaunay graphs:
<OL>
<LI>The user can use a kernel with a filtered number type
as the first template parameter in the `Segment_Delaunay_graph_traits_2<K,MTag>`.
<LI>The user can define up to three different kernels `CK`,
effort in implementing arithmetic filtering mechanisms
through special traits classes, `Segment_Delaunay_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>`
and `Segment_Delaunay_graph_filtered_traits_without_intersections_2<CK,CM,EK,EM,FK,FM>`.
These two traits class employ the `Filtered_predicate<EP,FP>` mechanism,
and the user can define up to three different kernels `CK`,
`FK` and `EK` (default values are provided for most
parameters). The first kernel `CK` is used only for
parameters): the first kernel `CK` is used only for
constructions. The second kernel `FK` is the filtering kernel:
the traits class will attempt to compute the predicates using this
kernel. If the filtering kernel fails to successfully compute a
predicate, the exact kernel `EK` will be used. These three
kernels are then used in the
`Segment_Delaunay_graph_filtered_traits_2<CK,CM,EK,EM,FK,FM>` and
`Segment_Delaunay_graph_filtered_traits_without_intersections_2<CK,CM,EK,EM,FK,FM>`
classes, which have been implemented using the
`Filtered_predicate<EP,FP>` mechanism.
</OL>
Our experience so far has shown that for all reasonable and valid
values of the template parameters, the second method for arithmetic
filtering is more efficient among the two.
This approach is also used in the examples.
predicate, the exact kernel `EK` will be used.
Let's consider once more the class
`Segment_Delaunay_graph_traits_2<K,MTag>`.
@ -506,7 +493,7 @@ for inputs consisting of more than about 1,000 sites.
\subsection Segment_Delaunay_graph_2FirstExample First Example using the Filtered Traits
The following example shows how to use the segment Delaunay graph traits
in conjunction with the `Filtered_exact<CT,ET>` mechanism. In
in conjunction with filtered traits mechanisms. In
addition it shows how to use a few of the iterators provided by the
`Segment_Delaunay_graph_2` class in order to count a few
site-related quantities.