Merge branch 'master' into pr/lrineau/6558

This commit is contained in:
Laurent Rineau 2022-05-06 16:25:32 +02:00
commit 734c96e951
84 changed files with 1955 additions and 647 deletions

View File

@ -9,8 +9,8 @@
//
// Author: Marc Glisse <marc.glisse@inria.fr>
#ifndef CGAL_GMPXX_ARITHMETIC_KERNEL_H
#define CGAL_GMPXX_ARITHMETIC_KERNEL_H
#ifndef CGAL_BOOST_MP_ARITHMETIC_KERNEL_H
#define CGAL_BOOST_MP_ARITHMETIC_KERNEL_H
#include <CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h>
#include <CGAL/Get_arithmetic_kernel.h>

View File

@ -129,7 +129,7 @@ configure()
rm -rf CMakeCache.txt CMakeFiles/
if [ -f "$INIT_FILE" ]
then
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \
-DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \

View File

@ -758,7 +758,7 @@ user might encounter.
- `CGAL::alpha_expansion_graphcut()`
\cgalCRPSection{I/O Functions}
- `CGAL::IO::read_polygon_mesh()`
- \link PkgBGLIOFct `CGAL::IO::read_polygon_mesh()` \endlink
- `CGAL::IO::write_polygon_mesh()`
- \link PkgBGLIoFuncsSTL I/O for STL files \endlink
- \link PkgBGLIoFuncsPLY I/O for PLY files \endlink

View File

@ -76,10 +76,10 @@ public:
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool is_vnm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>());
const bool is_vcm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_color_map_t>());
const bool is_vtm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_texture_map_t>());
const bool is_fcm_requested = !(is_default_parameter<NamedParameters, internal_np::face_color_map_t>());
const bool is_vnm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>::value);
const bool is_vcm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_color_map_t>::value);
const bool is_vtm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_texture_map_t>::value);
const bool is_fcm_requested = !(is_default_parameter<NamedParameters, internal_np::face_color_map_t>::value);
std::vector<Vertex_normal> vertex_normals;
std::vector<Vertex_color> vertex_colors;

View File

@ -122,10 +122,10 @@ public:
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(CGAL::vertex_point, g));
const bool has_vertex_normals = !(is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>());
const bool has_vertex_colors = !(is_default_parameter<NamedParameters, internal_np::vertex_color_map_t>());
const bool has_vertex_textures = !(is_default_parameter<NamedParameters, internal_np::vertex_texture_map_t>());
const bool has_face_colors = !(is_default_parameter<NamedParameters, internal_np::face_color_map_t>());
const bool has_vertex_normals = !(is_default_parameter<NamedParameters, internal_np::vertex_normal_map_t>::value);
const bool has_vertex_colors = !(is_default_parameter<NamedParameters, internal_np::vertex_color_map_t>::value);
const bool has_vertex_textures = !(is_default_parameter<NamedParameters, internal_np::vertex_texture_map_t>::value);
const bool has_face_colors = !(is_default_parameter<NamedParameters, internal_np::face_color_map_t>::value);
VNM vnm = get_parameter(np, internal_np::vertex_normal_map);
VTM vtm = get_parameter(np, internal_np::vertex_texture_map);

View File

@ -326,8 +326,8 @@ bool write_PLY(std::ostream& os,
VCM vcm = choose_parameter(get_parameter(np, internal_np::vertex_color_map), VCM());
FCM fcm = choose_parameter(get_parameter(np, internal_np::face_color_map), FCM());
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>();
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>();
bool has_vcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value;
bool has_fcolor = !is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value;
VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, g));

View File

@ -10,37 +10,24 @@
#define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
#include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/properties.h>
#include <CGAL/Dynamic_property_map.h>
#include <CGAL/iterator.h>
#include <CGAL/Kernel_traits.h>
#include <CGAL/Origin.h>
#include <CGAL/iterator.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/property_map.h>
#include <boost/mpl/if.hpp>
#include <boost/mpl/has_xxx.hpp>
#include <boost/type_traits/is_same.hpp>
#include <fstream>
#include <iterator>
#include <type_traits>
namespace CGAL {
namespace parameters
{
template <class Parameter, class NamedParameters>
struct Is_default
{
typedef typename internal_np::Lookup_named_param_def <
Parameter,
NamedParameters,
internal_np::Param_not_found > ::type NP_type;
static const bool value = boost::is_same<NP_type, internal_np::Param_not_found>::value;
typedef CGAL::Boolean_tag<value> type;
};
} // end of parameters namespace
// forward declarations to avoid dependency to Solver_interface
template <typename FT, unsigned int dim>
class Default_diagonalize_traits;
@ -49,20 +36,19 @@ namespace CGAL {
struct Alpha_expansion_boost_adjacency_list_tag;
//
//helper classes
template<typename PolygonMesh, typename PropertyTag>
class property_map_selector
{
public:
typedef typename graph_has_property<PolygonMesh, PropertyTag>::type Has_internal_pmap;
typedef typename boost::mpl::if_c< Has_internal_pmap::value
, typename boost::property_map<PolygonMesh, PropertyTag>::type
, typename boost::cgal_no_property::type
typedef typename boost::mpl::if_c<Has_internal_pmap::value,
typename boost::property_map<PolygonMesh, PropertyTag>::type,
typename boost::cgal_no_property::type
>::type type;
typedef typename boost::mpl::if_c< Has_internal_pmap::value
, typename boost::property_map<PolygonMesh, PropertyTag>::const_type
, typename boost::cgal_no_property::const_type
typedef typename boost::mpl::if_c<Has_internal_pmap::value,
typename boost::property_map<PolygonMesh, PropertyTag>::const_type,
typename boost::cgal_no_property::const_type
>::type const_type;
type get_pmap(const PropertyTag& p, PolygonMesh& pmesh)
@ -115,8 +101,10 @@ namespace CGAL {
// Shortcut for accessing the value type of the property map
template <class Graph, class Property>
class property_map_value {
class property_map_value
{
typedef typename boost::property_map<Graph, Property>::const_type PMap;
public:
typedef typename boost::property_traits<PMap>::value_type type;
};
@ -129,25 +117,22 @@ namespace CGAL {
DefaultVPMap_const;
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::type
DefaultVPMap;
public:
typedef typename internal_np::Lookup_named_param_def<
internal_np::vertex_point_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
DefaultVPMap
> ::type type;
typedef typename internal_np::Lookup_named_param_def<
internal_np::vertex_point_t,
DefaultVPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
DefaultVPMap_const
> ::type const_type;
DefaultVPMap_const>::type const_type;
};
template<typename PolygonMesh, typename NamedParameters>
class GetK
{
typedef typename boost::property_traits<
typename GetVertexPointMap<PolygonMesh, NamedParameters>::type
>::value_type Point;
typename GetVertexPointMap<PolygonMesh, NamedParameters>::type>::value_type Point;
public:
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
};
@ -157,27 +142,23 @@ namespace CGAL {
typename NamedParametersVPM = NamedParametersGT>
class GetGeomTraits
{
typedef typename CGAL::graph_has_property<PolygonMesh, boost::vertex_point_t>::type
Has_internal_pmap;
typedef typename CGAL::graph_has_property<PolygonMesh, boost::vertex_point_t>::type Has_internal_pmap;
typedef typename internal_np::Lookup_named_param_def <
internal_np::vertex_point_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParametersVPM,
internal_np::Param_not_found
> ::type NP_vpm;
internal_np::Param_not_found>::type NP_vpm;
struct Fake_GT {}; // to be used if there is no internal vertex_point_map in PolygonMesh
typedef typename boost::mpl::if_c<Has_internal_pmap::value || !boost::is_same<internal_np::Param_not_found, NP_vpm>::value,
typedef typename boost::mpl::if_c<Has_internal_pmap::value ||
!boost::is_same<internal_np::Param_not_found, NP_vpm>::value,
typename GetK<PolygonMesh, NamedParametersVPM>::Kernel,
Fake_GT>::type DefaultKernel;
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::geom_traits_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::geom_traits_t,
NamedParametersGT,
DefaultKernel
> ::type type;
DefaultKernel>::type type;
};
// Define the following structs:
@ -260,14 +241,15 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
#undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP
namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
}
} // namespace internal
template<typename PointRange,
typename NamedParameters = parameters::Default_named_parameters,
bool has_nested_iterator = internal::Has_nested_type_iterator<PointRange>::value,
typename NP_TAG = internal_np::point_t
>
typename NP_TAG = internal_np::point_t>
class GetPointMap
{
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Point;
@ -275,17 +257,13 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef typename CGAL::Identity_property_map<const Point> DefaultConstPMap;
public:
typedef typename internal_np::Lookup_named_param_def<
NP_TAG,
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,
DefaultPMap
> ::type type;
DefaultPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<
NP_TAG,
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,
DefaultConstPMap
> ::type const_type;
DefaultConstPMap>::type const_type;
};
// to please compiler instantiating non valid overloads
@ -293,6 +271,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
class GetPointMap<PointRange, NamedParameters, false>
{
struct Dummy_point{};
public:
typedef typename CGAL::Identity_property_map<Dummy_point> type;
typedef typename CGAL::Identity_property_map<const Dummy_point> const_type;
@ -306,28 +285,26 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef CGAL::Identity_property_map<const Value_type> DefaultConstPMap;
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,DefaultPMap> ::type Point_map; // public
NamedParameters,
DefaultPMap>::type Point_map;
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,DefaultConstPMap> ::type Const_point_map; // public
NamedParameters,
DefaultConstPMap>::type Const_point_map;
typedef typename boost::property_traits<Point_map>::value_type Point;
typedef typename Kernel_traits<Point>::Kernel Default_geom_traits;
typedef typename internal_np::Lookup_named_param_def <
internal_np::geom_traits_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::geom_traits_t,
NamedParameters,
Default_geom_traits
> ::type Geom_traits; // public
Default_geom_traits>::type Geom_traits;
typedef typename Geom_traits::FT FT; // public
typedef typename Geom_traits::FT FT;
typedef Constant_property_map<Value_type, typename Geom_traits::Vector_3> DummyNormalMap;
typedef typename internal_np::Lookup_named_param_def<
internal_np::normal_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::normal_t,
NamedParameters,
DummyNormalMap
> ::type Normal_map; // public
DummyNormalMap>::type Normal_map;
static Point_map get_point_map(PointRange&, const NamedParameters& np)
{
@ -367,6 +344,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
};
namespace Point_set_processing_3 {
template <typename ValueType>
struct Fake_point_range
{
@ -388,43 +366,36 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
typedef typename CGAL::Identity_property_map<const Plane> DefaultConstPMap;
public:
typedef typename internal_np::Lookup_named_param_def<
internal_np::plane_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::plane_t,
NamedParameters,
DefaultPMap
> ::type type;
DefaultPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<
internal_np::plane_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::plane_t,
NamedParameters,
DefaultConstPMap
> ::type const_type;
DefaultConstPMap>::type const_type;
};
template<typename NamedParameters>
class GetPlaneIndexMap
{
typedef Constant_property_map<std::size_t, int> DummyPlaneIndexMap;
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::plane_index_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::plane_index_t,
NamedParameters,
DummyPlaneIndexMap//default
> ::type type;
DummyPlaneIndexMap>::type type;
};
template<typename PointRange, typename NamedParameters>
class GetIsConstrainedMap
{
typedef Static_boolean_property_map<
typename std::iterator_traits<typename PointRange::iterator>::value_type,
false> Default_map;
typename std::iterator_traits<typename PointRange::iterator>::value_type, false> Default_map;
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::point_is_constrained_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::point_is_constrained_t,
NamedParameters,
Default_map //default
> ::type type;
Default_map>::type type;
};
template<typename PointRange, typename NamedParameters>
@ -432,11 +403,9 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
{
public:
typedef Emptyset_iterator Empty;
typedef typename internal_np::Lookup_named_param_def <
internal_np::adjacencies_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::adjacencies_t,
NamedParameters,
Empty//default
> ::type type;
Empty>::type type;
};
} // namespace Point_set_processing_3
@ -445,22 +414,18 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
class GetSolver
{
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::sparse_linear_solver_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::sparse_linear_solver_t,
NamedParameters,
DefaultSolver
> ::type type;
DefaultSolver>::type type;
};
template<typename NamedParameters, typename FT, unsigned int dim = 3>
class GetDiagonalizeTraits
{
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::diagonalize_traits_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::diagonalize_traits_t,
NamedParameters,
Default_diagonalize_traits<FT, dim>
> ::type type;
Default_diagonalize_traits<FT, dim> >::type type;
};
template<typename NamedParameters>
@ -477,8 +442,7 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
public:
typedef DummySvdTraits NoTraits;
typedef typename internal_np::Lookup_named_param_def <
internal_np::svd_traits_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::svd_traits_t,
NamedParameters,
#if defined(CGAL_EIGEN3_ENABLED)
Eigen_svd
@ -494,11 +458,9 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
class GetImplementationTag
{
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::implementation_tag_t,
typedef typename internal_np::Lookup_named_param_def<internal_np::implementation_tag_t,
NamedParameters,
Alpha_expansion_boost_adjacency_list_tag
>::type type;
Alpha_expansion_boost_adjacency_list_tag>::type type;
};
template<typename NP>
@ -508,14 +470,14 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
using parameters::choose_parameter;
using parameters::is_default_parameter;
if(!is_default_parameter<NP, internal_np::stream_precision_t>())
if(!is_default_parameter<NP, internal_np::stream_precision_t>::value)
{
const int precision = choose_parameter<int>(get_parameter(np,
internal_np::stream_precision));
os.precision(precision);
}
}
} // namespace CGAL
#endif // CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H

View File

@ -4,7 +4,6 @@
project(Barycentric_coordinates_2_Benchmarks)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)
include(${CGAL_USE_FILE})

View File

@ -4,7 +4,6 @@
project(Barycentric_coordinates_2_Examples)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -217,6 +217,7 @@ private:
CGAL_precondition( A[n-2] != FT(0) && A[n-1] != FT(0) );
*output = (r[0]*A[n-2] - r[n-1]*B[n-1] + r[n-2]*A[n-1]) / (A[n-2] * A[n-1]);
++output;
// Return weights.
return boost::optional<OutputIterator>(output);
@ -277,6 +278,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_dh_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);
@ -333,6 +335,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_dh_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);

View File

@ -489,6 +489,7 @@ private:
++output;
}
*output = coordinate[0];
++output;
// Return computed coordinates.
if(success) return boost::optional<OutputIterator>(output);

View File

@ -290,6 +290,7 @@ private:
CGAL_precondition( r[n-1] != FT(0) );
*output = (t[n-2] + t[n-1]) / r[n-1];
++output;
// Return weights.
return boost::optional<OutputIterator>(output);
@ -364,6 +365,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_mv_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);
@ -432,6 +434,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_mv_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);

View File

@ -211,6 +211,7 @@ private:
CGAL_precondition( A[n-2] != FT(0) && A[n-1] != FT(0) );
*output = C[n-1] / (A[n-2] * A[n-1]);
++output;
// Return weights.
return boost::optional<OutputIterator>(output);
@ -261,6 +262,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_wp_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);
@ -314,6 +316,7 @@ private:
++output;
}
*output = weight[n-1] * inverted_wp_denominator;
++output;
// Return coordinates.
return boost::optional<OutputIterator>(output);

View File

@ -337,6 +337,7 @@ namespace Barycentric_coordinates {
*output = b_first;
++output;
*output = FT(1) - b_first;
++output;
// Output both coordinates.
return boost::optional<OutputIterator>(output);

View File

@ -368,6 +368,7 @@ namespace Barycentric_coordinates {
// Compute the last = third coordinate, using the partition of unity property.
*output = FT(1) - b_first - b_second;
++output;
// Output all coordinates.
return boost::optional<OutputIterator>(output);

View File

@ -4,7 +4,6 @@
project(Barycentric_coordinates_2_Tests)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -5,7 +5,7 @@ namespace CGAL {
\ingroup PkgBoundingVolumesRef
The class `Min_ellipse_2_traits_2` is a traits class for `CGAL::Min_ellipse_2<Traits>`
using the two-di-men-sional \cgal kernel.
using the two-dimensional \cgal kernel.
The template parameter `K` must be a model for `Kernel`.

View File

@ -5,8 +5,8 @@ namespace CGAL {
\ingroup PkgBoundingVolumesRef
The class `Min_quadrilateral_default_traits_2` is a traits class for the
functions `min_rectangle_2`, `min_parallelogram_2` and
`min_strip_2` using a two-dimensional \cgal kernel.
functions `min_rectangle_2()`, `min_parallelogram_2()` and
`min_strip_2()` using a two-dimensional \cgal kernel.
\tparam K must be a model for `Kernel`.

View File

@ -2,11 +2,11 @@
\ingroup PkgBoundingVolumesConcepts
\cgalConcept
An object of the class `Circle` is a circle in two-dimensional
An object `circle` of the class `Circle` is a circle in the two-dimensional
Euclidean plane \f$ \E^2\f$. Its boundary splits the plane into a bounded
and an unbounded side. By definition, an empty `Circle` has no
and an unbounded side. By definition, an empty `circle` has no
boundary and no bounded side, i.e.\ its unbounded side equals the
whole plane \f$ \E^2\f$. A `Circle` containing exactly one point \f$ p\f$
whole plane \f$ \E^2\f$. A `circle` containing exactly one point \f$ p\f$
has no bounded side, its boundary is \f$ \{p\}\f$, and its unbounded side
equals \f$ \E^2 \setminus \{p\}\f$.
@ -42,21 +42,21 @@ typedef unspecified_type Distance;
void set();
/**
* sets `circle` to the circle containing exactly \f$ \{\mbox{`p` }\}\f$.
* sets `circle` to the circle containing exactly `p`.
*/
void set( const Point& p);
/*!
sets `circle` to the circle with diameter equal to the segment
connecting `p` and `q`. The algorithm guarantees that `set` is never
connecting `p` and `q`. The algorithm guarantees that `set()` is never
called with two equal points.
*/
void set( const Point& p, const Point& q);
/*!
sets `circle` to the circle through `p`,`q`,`r`. The algorithm
guarantees that `set` is never called with three collinear points.
sets `circle` to the circle through `p`, `q`, and `r`. The algorithm
guarantees that `set()` is never called with three collinear points.
*/
void set( const Point& p, const Point& q, const Point& r);

View File

@ -4,3 +4,5 @@ STL_Extension
Algebraic_foundations
Circulator
Stream_support
Matrix_search
Polytope_distance_d

View File

@ -18,6 +18,7 @@
#include <CGAL/memory.h>
#include <iostream>
#include <limits>
namespace CGAL {

View File

@ -487,11 +487,11 @@ namespace cpp11{
// http://clang.llvm.org/docs/AttributeReference.html#statement-attributes
// See for gcc:
// https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
#if __cpp_attributes >= 200809 && __has_cpp_attribute(fallthrough)
#if __cplusplus > 201402L && __has_cpp_attribute(fallthrough)
# define CGAL_FALLTHROUGH [[fallthrough]]
#elif __cpp_attributes >= 200809 && __has_cpp_attribute(gnu::fallthrough)
#elif __has_cpp_attribute(gnu::fallthrough)
# define CGAL_FALLTHROUGH [[gnu::fallthrough]]
#elif __cpp_attributes >= 200809 && __has_cpp_attribute(clang::fallthrough)
#elif __has_cpp_attribute(clang::fallthrough)
# define CGAL_FALLTHROUGH [[clang::fallthrough]]
#elif __has_attribute(fallthrough) && ! __clang__
# define CGAL_FALLTHROUGH __attribute__ ((fallthrough))

View File

@ -92,12 +92,6 @@ if(LEDA_FOUND)
target_link_libraries(test_LEDA_IO ${LEDA_LIBRARIES})
endif()
if("$ENV{CMAKE_GENERATOR}" STREQUAL "")
set(GENERATOR )
else()
set(GENERATOR $ENV{CMAKE_GENERATOR})
endif()
if("$ENV{INIT_FILE}" STREQUAL "")
set(INIT_FILE )
else()
@ -131,7 +125,7 @@ function(CGAL_installation_test_find_package_version mode)
configure_file(test_find_package.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/test_find_package_version_${mode}/CMakeLists.txt)
add_test(NAME test_find_package_version_${mode}
COMMAND ${CMAKE_COMMAND} ${GENERATOR} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release ${CMAKE_CURRENT_BINARY_DIR}/test_find_package_version_${mode}
COMMAND ${CMAKE_COMMAND} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release ${CMAKE_CURRENT_BINARY_DIR}/test_find_package_version_${mode}
)
cgal_setup_test_properties(test_find_package_version_${mode})
set_property(TEST test_find_package_version_${mode}
@ -215,7 +209,7 @@ add_test(NAME install_non_standard_cgal
#test CGAL_DIR=non standard place without cgal_qt5
get_filename_component(CGAL_DIR_CORRECT_PATH "${NON_STANDARD_INSTALL_PREFIX}/non_standard_install/lib/cmake/CGAL/CGALConfig.cmake" DIRECTORY)
add_test(NAME test_config_file_3
COMMAND ${CMAKE_COMMAND} ${GENERATOR} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
COMMAND ${CMAKE_COMMAND} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
"${CMAKE_BINARY_DIR}/test_config_file"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_3")
list(APPEND test_config_lst "test_config_file_3")
@ -223,7 +217,7 @@ list(APPEND test_config_lst "test_config_file_3")
if(CGAL_Qt5_FOUND)
#configure cgal for a non standard install with qt5
add_test(NAME config_non_standard_cgal_qt5
COMMAND ${CMAKE_COMMAND} ${GENERATOR} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${NON_STANDARD_INSTALL_PREFIX}/non_standard_install_qt5 -DCGAL_INSTALL_LIB_DIR=lib
COMMAND ${CMAKE_COMMAND} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=${NON_STANDARD_INSTALL_PREFIX}/non_standard_install_qt5 -DCGAL_INSTALL_LIB_DIR=lib
"${CGAL_SOURCE_DIR}"
WORKING_DIRECTORY "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build_qt5")
#install cgal in the non standard place
@ -233,7 +227,7 @@ if(CGAL_Qt5_FOUND)
#test CGAL_DIR=non standard place with cgal_qt5
get_filename_component(CGAL_DIR_CORRECT_PATH "${NON_STANDARD_INSTALL_PREFIX}/non_standard_install_qt5/lib/cmake/CGAL/CGALConfig.cmake" DIRECTORY)
add_test(NAME test_config_file_4
COMMAND ${CMAKE_COMMAND} ${GENERATOR} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
COMMAND ${CMAKE_COMMAND} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
"${CMAKE_BINARY_DIR}/test_config_file_qt5"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_4")
list(APPEND test_config_lst "test_config_file_4")
@ -242,7 +236,7 @@ endif()#CGAL_Qt5_FOUND
#test CGAL_DIR=non standard build
get_filename_component(CGAL_DIR_CORRECT_PATH "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build/CGALConfig.cmake" DIRECTORY)
add_test(NAME test_config_file_5
COMMAND ${CMAKE_COMMAND} ${GENERATOR} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
COMMAND ${CMAKE_COMMAND} ${INIT_FILE} -DCMAKE_BUILD_TYPE=Release -DCGAL_DIR=${CGAL_DIR_CORRECT_PATH} -DCGAL_GIVEN_DIR=${CGAL_DIR_CORRECT_PATH}
"${CMAKE_BINARY_DIR}/test_config_file"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_5")
list(APPEND test_config_lst "test_config_file_5")

View File

@ -26,7 +26,7 @@ touch ../$ERRORFILE
echo "Configuring... "
mkdir build_dir
cd build_dir
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_RELEASE_DIR" -DBUILD_TESTING=ON -DWITH_tests=ON \
..' ; then

View File

@ -343,8 +343,8 @@ public:
if(tet.is_degenerate())
continue;
P l0 = tet0 + CGAL::cross_product(V(tet0, tet1), V(tet0, tet2));
P l1 = tet2 + CGAL::cross_product(V(tet2, tet1), V(tet2, tet0));
P l0 = tet0 - CGAL::cross_product(V(tet0, tet1), V(tet0, tet2));
P l1 = tet3 + CGAL::cross_product(V(tet3, tet1), V(tet3, tet2));
assert(tet.has_on_unbounded_side(l0) && tet.has_on_unbounded_side(l1));
@ -363,6 +363,7 @@ public:
// No intersection
Tr tr(p(0,0,0), p(1,0,1), p(1,1,0));
check_no_intersection(L(p(5,0,0), p(5,1,0)), tr);
// on edge

View File

@ -1264,7 +1264,7 @@ vertices/second
View of 3d image mesh generation result (size = 4).
\cgalFigureEnd
We mesh image number 2 from the 3D-IRCADb-01 (available at <A href="https://www.ircad.fr/softwares/3Dircadb/3Dircadb1/index.php">https://www.ircad.fr/softwares/3Dircadb/3Dircadb1/index.php</A>) public database.
We mesh image number 2 from the 3D-IRCADb-01 (available at <A href="https://www.ircad.fr/research/data-sets/liver-segmentation-3d-ircadb-01/">https://www.ircad.fr/research/data-sets/liver-segmentation-3d-ircadb-01/</A>) public database.
The size of this image is 512x512x172 voxels (about 45M voxels). The size of the voxels
is 0.78mm x 0.78mm x 1.6mm. \cgalFigureRef{figuremesh_3_benchmark_3d_image}
shows the mesh obtained for size set to 4.

View File

@ -304,14 +304,14 @@ struct Polyline_visitor
template <typename Kernel>
struct Angle_tester
{
const double m_angle_sq_cosine;// squared cosine of `std:min(90, angle_deg)`
const double m_angle_sq_cosine;// squared cosine of `std:max(90, angle_deg)`
Angle_tester()
: m_angle_sq_cosine(0)
{}
Angle_tester(const double angle_deg)//angle given in degrees for readability
: m_angle_sq_cosine(CGAL::square(std::cos((std::min)(90.,angle_deg) * CGAL_PI / 180.)))
: m_angle_sq_cosine(CGAL::square(std::cos((std::max)(90.,angle_deg) * CGAL_PI / 180.)))
{}
template <typename vertex_descriptor, typename Graph>

View File

@ -26,7 +26,7 @@ configure()
{
echo "Configuring... "
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
.' ; then

View File

@ -1,6 +1,5 @@
#include <boost/config.hpp>
//#define BOOST_RESULT_OF_USE_DECLTYPE 1
#include <CGAL/Epick_d.h>
#include <CGAL/Epeck_d.h>
#include <typeinfo>

View File

@ -50,30 +50,30 @@ typedef unspecified_type Exact_integer;
#else // not DOXYGEN_RUNNING
#if CGAL_USE_GMPXX
#if ( (defined(CGAL_TEST_SUITE) && CGAL_VERSION_NR == 1050500900) || defined(CGAL_FORCE_USE_BOOST_MP))\
&& BOOST_VERSION > 107800 && defined(CGAL_USE_BOOST_MP)
// use boost-mp by default in the testsuite until 5.5-beta is out
typedef BOOST_cpp_arithmetic_kernel::Integer Exact_integer;
#else // BOOST_VERSION > 107800
#ifdef CGAL_USE_GMPXX
typedef mpz_class Exact_integer;
#elif CGAL_USE_GMP
# ifdef CGAL_USE_BOOST_MP
typedef boost::multiprecision::mpz_int Exact_integer;
#elif defined(CGAL_USE_GMP)
#if defined(CGAL_USE_BOOST_MP)
typedef BOOST_gmp_arithmetic_kernel::Integer Exact_integer;
#else
typedef Gmpz Exact_integer;
#endif
#elif CGAL_USE_LEDA
#elif defined(CGAL_USE_LEDA)
typedef leda_integer Exact_integer;
#elif CGAL_USE_CORE
#elif defined(CGAL_USE_BOOST_MP)
typedef BOOST_cpp_arithmetic_kernel::Integer Exact_integer;
#elif defined(CGAL_USE_CORE)
typedef CORE::BigInt Exact_integer;
#elif defined CGAL_USE_BOOST_MP
typedef boost::multiprecision::cpp_int Exact_integer;
#else
#error "ERROR: Cannot determine a BigInt type!"
#endif // CGAL_USE_CORE
#endif // BOOST_VERSION > 107800
#endif // not DOXYGEN_RUNNING
} /* end namespace CGAL */

View File

@ -54,23 +54,39 @@ namespace CGAL { namespace internal {
// It should support the built-in types.
template < typename >
struct Exact_field_selector
#if ( (defined(CGAL_TEST_SUITE) && CGAL_VERSION_NR == 1050500900) || defined(CGAL_FORCE_USE_BOOST_MP))\
&& BOOST_VERSION > 107800 && defined(CGAL_USE_BOOST_MP)
// use boost-mp by default in the testsuite until 5.5-beta is out
// Boost
{ typedef BOOST_cpp_arithmetic_kernel::Rational Type; };
#else // BOOST_VERSION > 107800
#ifdef CGAL_USE_GMPXX
{ typedef mpq_class Type; };
#elif defined(CGAL_USE_GMP)
#if defined(CGAL_USE_BOOST_MP)
{ typedef boost::multiprecision::mpq_rational Type; };
{ typedef BOOST_gmp_arithmetic_kernel::Rational Type; };
#else
{ typedef Gmpq Type; };
#endif
#elif defined(CGAL_USE_LEDA)
{ typedef leda_rational Type; };
#elif 0 && defined(CGAL_USE_BOOST_MP)
#elif defined(CGAL_USE_BOOST_MP)
// See the discussion in https://github.com/CGAL/cgal/pull/3614
// This is disabled for now because cpp_rational is even slower than Quotient<MP_Float>. Quotient<cpp_int> will be a good candidate after some polishing.
// In fact, the new version of cpp_rational from here: https://github.com/boostorg/multiprecision/pull/366
// is much better than Quotient<cpp_int> because it is using smart gcd and is well-supported
// while Quotient does not. Though, we can still use it if needed.
#if BOOST_VERSION <= 107800
// See this comment: https://github.com/CGAL/cgal/pull/5937#discussion_r721533675
{ typedef Quotient<boost::multiprecision::cpp_int> Type; };
#else
{ typedef BOOST_cpp_arithmetic_kernel::Rational Type; };
#endif
#else
{ typedef Quotient<MP_Float> Type; };
#endif
#endif // BOOST_VERSION > 107800
// By default, a field is a safe choice of ring.
template < typename T >

View File

@ -33,6 +33,9 @@
#include <CGAL/Kernel/mpl.h>
#include <boost/operators.hpp>
#ifdef CGAL_USE_BOOST_MP
#include <boost/multiprecision/cpp_int.hpp>
#endif // CGAL_USE_BOOST_MP
namespace CGAL {
@ -46,6 +49,15 @@ template < typename NT >
inline void
simplify_quotient(NT &, NT &) {}
#ifdef CGAL_USE_BOOST_MP
inline void
simplify_quotient(boost::multiprecision::cpp_int & a, boost::multiprecision::cpp_int & b) {
const boost::multiprecision::cpp_int r = boost::multiprecision::gcd(a, b);
a /= r;
b /= r;
}
#endif // CGAL_USE_BOOST_MP
// This one should be replaced by some functor or tag.
// Meanwhile, the class is specialized for Gmpz, mpz_class, leda_integer.
template < typename NT >
@ -687,7 +699,7 @@ template < class NT > class Real_embeddable_traits_quotient_base< Quotient<NT> >
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
public:
std::pair<double, double> operator()( const Type& x ) const {
Interval_nt<> quot =
const Interval_nt<> quot =
Interval_nt<>(CGAL_NTS to_interval(x.numerator())) /
Interval_nt<>(CGAL_NTS to_interval(x.denominator()));
return std::make_pair(quot.inf(), quot.sup());

View File

@ -13,6 +13,7 @@
#define CGAL_BOOST_MP_H
#include <CGAL/config.h>
#include <CGAL/number_utils.h>
// It is easier to disable this number type completely for old versions.
// Before 1.63, I/O is broken. Again, disabling the whole file is just the
@ -23,6 +24,7 @@
(!defined _MSC_VER || BOOST_VERSION >= 107000)
#define CGAL_USE_BOOST_MP 1
#include <CGAL/Quotient.h>
#include <CGAL/functional.h> // *ary_function
#include <CGAL/number_type_basic.h>
#include <CGAL/Modular_traits.h>
@ -139,6 +141,227 @@ struct Algebraic_structure_traits<boost::multiprecision::detail::expression<T1,T
// Real_embeddable_traits
namespace Boost_MP_internal {
// here we know that `intv` contains int64 numbers such that their msb is std::numeric_limits<double>::digits-1
// TODO: possibly return denormals sometimes...
inline
std::pair<double,double> shift_positive_interval( const std::pair<double,double>& intv, const int e ) {
CGAL_assertion(intv.first > 0.0);
CGAL_assertion(intv.second > 0.0);
CGAL_assertion_code(
union {
#ifdef CGAL_LITTLE_ENDIAN
struct { uint64_t man:52; uint64_t exp:11; uint64_t sig:1; } s;
#else /* CGAL_BIG_ENDIAN */
//WARNING: untested!
struct { uint64_t sig:1; uint64_t exp:11; uint64_t man:52; } s;
#endif
double d;
} conv;
conv.d = intv.first;
)
// Check that the exponent of intv.inf is 52, which corresponds to a 53 bit integer
CGAL_assertion(conv.s.exp - ((1 << (11 - 1)) - 1) == std::numeric_limits<double>::digits - 1);
typedef std::numeric_limits<double> limits;
// warning: min_exponent and max_exponent are 1 more than what the name suggests
if (e < limits::min_exponent - limits::digits)
return {0, (limits::min)()};
if (e > limits::max_exponent - limits::digits)
return {(limits::max)(), limits::infinity()}; // intv is positive
const double scale = std::ldexp(1.0, e); // ldexp call is exact
return { scale * intv.first, scale * intv.second }; // cases that would require a rounding mode have been handled above
}
// This function checks if the computed interval is correct and if it is tight.
template<typename Type>
bool are_bounds_correct( const double l, const double u, const Type& x ) {
typedef std::numeric_limits<double> limits;
const double inf = std::numeric_limits<double>::infinity();
if ( u!=l && (l==-inf || u==inf
|| (u==0 && l >= -(limits::min)())
|| (l==0 && u <= (limits::min)())) )
{
return x > Type((limits::max)()) ||
x < Type(-(limits::max)()) ||
(x > Type(-(limits::min)()) && x < Type((limits::min)()));
}
if (!(u == l || u == std::nextafter(l, +inf))) return false;
//TODO: Type(nextafter(l,inf))>x && Type(nextafter(u,-inf))<x
const Type lb(l), ub(u);
const bool are_bounds_respected = (lb <= x && x <= ub);
return are_bounds_respected;
}
// This one returns zero length interval that is inf = sup.
inline
std::pair<double, double> get_0ulp_interval( const int shift, const uint64_t p ) {
const double pp_dbl = static_cast<double>(p);
const std::pair<double,double> intv(pp_dbl, pp_dbl);
return shift_positive_interval(intv, -shift);
}
// This one returns 1 unit length interval.
inline
std::pair<double, double> get_1ulp_interval( const int shift, const uint64_t p ) {
const double pp_dbl = static_cast<double>(p);
const double qq_dbl = pp_dbl+1;
const std::pair<double,double> intv(pp_dbl, qq_dbl);
return shift_positive_interval(intv, -shift);
}
template<typename ET>
std::pair<double, double> to_interval( ET x, int extra_shift = 0 );
// This is a version of to_interval that converts a rational type into a
// double tight interval.
template<typename Type, typename ET>
std::pair<double, double> to_interval( ET xnum, ET xden ) {
CGAL_assertion(!CGAL::is_zero(xden));
CGAL_assertion_code(const Type input(xnum, xden));
double l = 0.0, u = 0.0;
if (CGAL::is_zero(xnum)) { // return [0.0, 0.0]
CGAL_assertion(are_bounds_correct(l, u, input));
return std::make_pair(l, u);
}
CGAL_assertion(!CGAL::is_zero(xnum));
// Handle signs.
bool change_sign = false;
const bool is_num_pos = CGAL::is_positive(xnum);
const bool is_den_pos = CGAL::is_positive(xden);
if (!is_num_pos && !is_den_pos) {
xnum = -xnum;
xden = -xden;
} else if (!is_num_pos && is_den_pos) {
change_sign = true;
xnum = -xnum;
} else if (is_num_pos && !is_den_pos) {
change_sign = true;
xden = -xden;
}
CGAL_assertion(CGAL::is_positive(xnum) && CGAL::is_positive(xden));
const int64_t num_dbl_digits = std::numeric_limits<double>::digits - 1;
const int64_t msb_num = static_cast<int64_t>(boost::multiprecision::msb(xnum));
const int64_t msb_den = static_cast<int64_t>(boost::multiprecision::msb(xden));
#if 0 // Optimisation for the case of input that are double
// An alternative strategy would be to convert numerator and denominator to
// intervals, then divide. However, this would require setting the rounding
// mode (and dividing intervals is not completely free). An important
// special case is when the rational is exactly equal to a double
// (fit_in_double). Then the denominator is a power of 2, so we can skip
// the division and it becomes unnecessary to set the rounding mode, we
// just need to modify the exponent correction for the denominator.
if(msb_den == static_cast<int64_t>(lsb(xden))) {
std::tie(l,u)=to_interval(xnum, msb_den);
if (change_sign) {
CGAL_assertion(are_bounds_correct(-u, -l, input));
return {-u, -l};
}
CGAL_assertion(are_bounds_correct(l, u, input));
return {u, l};
}
#endif
const int64_t msb_diff = msb_num - msb_den;
// Shift so the division result has at least 53 (and at most 54) bits
int shift = static_cast<int>(num_dbl_digits - msb_diff + 1);
CGAL_assertion(shift == num_dbl_digits - msb_diff + 1);
if (shift > 0) {
xnum <<= +shift;
} else if (shift < 0) {
xden <<= -shift;
}
CGAL_assertion(num_dbl_digits + 1 ==
static_cast<int64_t>(boost::multiprecision::msb(xnum)) -
static_cast<int64_t>(boost::multiprecision::msb(xden)));
ET p, r;
boost::multiprecision::divide_qr(xnum, xden, p, r);
uint64_t uip = static_cast<uint64_t>(p);
const int64_t p_bits = static_cast<int64_t>(boost::multiprecision::msb(p));
bool exact = r.is_zero();
if (p_bits > num_dbl_digits) { // case 54 bits
exact &= ((uip & 1) == 0);
uip>>=1;
--shift;
}
std::tie(l, u) = exact ? get_0ulp_interval(shift, uip) : get_1ulp_interval(shift, uip);
if (change_sign) {
const double t = l;
l = -u;
u = -t;
}
CGAL_assertion(are_bounds_correct(l, u, input));
return std::make_pair(l, u);
}
// This is a version of to_interval that converts an integer type into a
// double tight interval.
template<typename ET>
std::pair<double, double> to_interval( ET x, int extra_shift) {
CGAL_assertion_code(const ET input = x);
double l = 0.0, u = 0.0;
if (CGAL::is_zero(x)) { // return [0.0, 0.0]
CGAL_assertion(are_bounds_correct(l, u, input));
return std::make_pair(l, u);
}
CGAL_assertion(!CGAL::is_zero(x));
bool change_sign = false;
const bool is_pos = CGAL::is_positive(x);
if (!is_pos) {
change_sign = true;
x = -x;
}
CGAL_assertion(CGAL::is_positive(x));
const int64_t n = static_cast<int64_t>(boost::multiprecision::msb(x)) + 1;
const int64_t num_dbl_digits = std::numeric_limits<double>::digits;
if (n > num_dbl_digits) {
const int64_t mindig = static_cast<int64_t>(boost::multiprecision::lsb(x));
int e = static_cast<int>(n - num_dbl_digits);
x >>= e;
if (n - mindig > num_dbl_digits)
std::tie(l, u) = get_1ulp_interval(-e+extra_shift, static_cast<uint64_t>(x));
else
std::tie(l, u) = get_0ulp_interval(-e+extra_shift, static_cast<uint64_t>(x));
} else {
l = u = extra_shift==0 ? static_cast<double>(static_cast<uint64_t>(x))
: std::ldexp(static_cast<double>(static_cast<uint64_t>(x)),-extra_shift);
}
if (change_sign) {
const double t = l;
l = -u;
u = -t;
}
CGAL_assertion(extra_shift != 0 || are_bounds_correct(l, u, input));
return std::make_pair(l, u);
}
} // Boost_MP_internal
template <class NT>
struct RET_boost_mp_base
: public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > {
@ -192,15 +415,32 @@ struct RET_boost_mp_base
struct To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
std::pair<double, double>
operator()(const Type& x) const {
// See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better
// assume the conversion is within 1 ulp
// adding IA::smallest() doesn't work because inf-e=inf, even rounded down.
double i = x.template convert_to<double>();
// We must use to_nearest here.
double i;
const double inf = std::numeric_limits<double>::infinity();
{
Protect_FPU_rounding<true> P(CGAL_FE_TONEAREST);
i = static_cast<double>(x);
if (i == +inf) {
return std::make_pair((std::numeric_limits<double>::max)(), i);
} else if (i == -inf) {
return std::make_pair(i, std::numeric_limits<double>::lowest());
}
}
double s = i;
double inf = std::numeric_limits<double>::infinity();
int cmp = x.compare(i);
CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf);
// Throws uncaught exception: Cannot convert a non-finite number to an integer.
// We can catch it earlier by using the CGAL_assertion() one line above.
const int cmp = x.compare(i);
if (cmp > 0) {
s = nextafter(s, +inf);
CGAL_assertion(x.compare(s) < 0);
@ -219,11 +459,30 @@ struct RET_boost_mp;
template <class NT>
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_integer> >
: RET_boost_mp_base <NT> {};
: RET_boost_mp_base <NT> {
typedef NT Type;
struct To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
std::pair<double, double> operator()( const Type& x ) const {
return Boost_MP_internal::to_interval(x);
}
};
};
template <class NT>
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rational> >
: RET_boost_mp_base <NT> {};
: RET_boost_mp_base <NT> {
typedef NT Type;
struct To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
std::pair<double, double> operator()( const Type& x ) const {
return Boost_MP_internal::to_interval<Type>(
boost::multiprecision::numerator(x), boost::multiprecision::denominator(x));
}
};
};
#ifdef CGAL_USE_MPFR
// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary.
@ -607,6 +866,25 @@ namespace internal {
#endif
} // namespace internal
#ifdef CGAL_USE_BOOST_MP
template< > class Real_embeddable_traits< Quotient<boost::multiprecision::cpp_int> >
: public INTERN_QUOTIENT::Real_embeddable_traits_quotient_base< Quotient<boost::multiprecision::cpp_int> > {
public:
typedef Quotient<boost::multiprecision::cpp_int> Type;
class To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
public:
std::pair<double, double> operator()( const Type& x ) const {
return Boost_MP_internal::to_interval<Type>(x.num, x.den);
}
};
};
#endif // CGAL_USE_BOOST_MP
} //namespace CGAL
#include <CGAL/BOOST_MP_arithmetic_kernel.h>

View File

@ -88,3 +88,8 @@ endif()#NOT CGAL_DISABLE_GMP
# all the programs below will be linked against MPFI in case it is present
create_single_source_cgal_program("Quotient_new.cpp")
create_single_source_cgal_program("test_nt_Coercion_traits.cpp")
find_package(Boost)
if(Boost_FOUND)
create_single_source_cgal_program("to_interval_test_boost.cpp")
endif()

View File

@ -0,0 +1,867 @@
// STL.
#include <array>
#include <limits>
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
// Boost.
#include <boost/type_index.hpp>
// Kernels.
#include <CGAL/Simple_cartesian.h>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
// CGAL.
#include <CGAL/Random.h>
#include <CGAL/Quotient.h>
#include <CGAL/Exact_integer.h>
#include <CGAL/Exact_rational.h>
#include <CGAL/Lazy_exact_nt.h>
#ifdef CGAL_USE_BOOST_MP
#if false // https://github.com/boostorg/multiprecision/issues/370
void test_boost_eval_lehmer() {
const boost::multiprecision::cpp_int a("500000000000000052504760255204421627079393309355027816932345132815919505535709229444276879024105562954502314530690391078574434507015318513443905076213688875017942541908041275407131568575177172639474548726709751235383681696449966404295647940685784470144122251803020020951078103818191513659921807053133698549053838430992170843235673537548059987539601671975279280846041564435631581262016246808786828637048154067265620710396778995313534536353760281048487250661054626168637371167135426013683337484254647996964562455566714879467026196409913165805735073230830136024016362543811769017875638974011487488573436");
const boost::multiprecision::cpp_int b("1500000000000000157514280765613264881238179928065083450797035398447758516607127688332830637072316688863506943592071173235723303521045955540331715228641066625053827625724123826221394705725531517918423646180129253706151045089349899212886943822057353410432366755409060062853234311454574540979765421159386595647161515292215193506006556519037965168192736708179557957863203557666055574947146355487693991882510747766220045897624670399027877365714431356466054500731862264092476764347207739651025585146903094168986610767496468412336047796468657032646893153521091155634158263410282629846280069312485301157888001");
const boost::multiprecision::cpp_int r = boost::multiprecision::gcd(a, b);
}
#endif // issue 370
void test_minimal_boost_gcd() {
boost::multiprecision::cpp_int u = 1;
for (unsigned i = 1; i <= 50; ++i) {
u *= i;
}
std::cout << "u: " << u << std::endl;
boost::multiprecision::cpp_int v = 1;
for (unsigned i = 1; i <= 100; ++i) {
v *= i;
}
std::cout << "v: " << v << std::endl;
// const auto r = boost::multiprecision::gcd(u, v); // fail
const boost::multiprecision::cpp_int r = boost::multiprecision::gcd(u, v); // pass
std::cout << "r: " << r << std::endl;
u = u / r;
v = v / r;
std::cout << "new u: " << u << std::endl;
std::cout << "new v: " << v << std::endl;
}
#if false // _MM_ROUND_UP is not available on all platforms
void test_minimal_nextafter() {
_MM_SET_ROUNDING_MODE(_MM_ROUND_UP); // fail
// _MM_SET_ROUNDING_MODE(_MM_ROUND_NEAREST); // pass
const boost::multiprecision::cpp_int x("1312729512902970206056841780066779136");
double i = x.template convert_to<double>();
double s = i;
const double inf = std::numeric_limits<double>::infinity();
assert(i != inf && s != inf);
const int cmp = x.compare(i);
if (cmp > 0) {
s = nextafter(s, +inf);
assert(x.compare(s) < 0);
} else if (cmp < 0) {
i = nextafter(i, -inf);
assert(x.compare(i) > 0);
}
}
#endif // test_minimal_nextafter
void test_to_interval_boost() {
using NT = boost::multiprecision::cpp_int;
using Quotient = CGAL::Quotient<NT>;
using Traits = CGAL::Real_embeddable_traits<Quotient>;
using Interval = typename Traits::To_interval;
NT n, d;
Quotient x;
double i, s;
n = NT("-15284404573383541");
d = NT("4503599627370496");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: -3.3938195750112902793" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: -3.3938195750112898352" << std::endl;
std::cout << std::endl;
// Results for current tight using cpp_rational.
assert(i == -3.3938195750112902793);
assert(s == -3.3938195750112898352);
}
// In assert, we use values from impl2.
void test_to_interval_tight_rational_1() {
// In green, we compare to impl2.
#define TESTCASE_RAT_10 // pass all three
#define TESTCASE_RAT_11 // impl1: fails tightness (sup is larger, s = 9.3488310472396616291)
#define TESTCASE_RAT_12 // pass all three
#define TESTCASE_RAT_13 // pass all three
#define TESTCASE_RAT_14 // pass all three
#define TESTCASE_RAT_15 // pass all three
#define TESTCASE_RAT_16 // pass all three
#define TESTCASE_RAT_17 // pass all three
#define TESTCASE_RAT_18 // pass all three
#define TESTCASE_RAT_19 // pass all three
using NT = boost::multiprecision::cpp_int;
using Quotient = CGAL::Quotient<NT>;
using Traits = CGAL::Real_embeddable_traits<Quotient>;
using Interval = typename Traits::To_interval;
// std::cout << std::endl;
// std::cout << boost::typeindex::type_id<Quotient>() << std::endl;
// std::cout << std::endl;
// std::cout << boost::typeindex::type_id<typename Traits::Type>() << std::endl;
// std::cout << std::endl;
NT n, d;
Quotient x;
double i, s;
std::cout << std::endl;
std::cout << "- T1 testing tight interval for rationals ..." << std::endl;
std::cout << std::endl;
#ifdef TESTCASE_RAT_10 // small numbers
std::cout << "=============" << std::endl;
std::cout << "CASE0 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("39792587355159975");
d = NT("140737488355328");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 282.7433388230813307" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 282.74333882308138755" << std::endl;
std::cout << std::endl;
assert(i == 282.7433388230813307);
assert(s == 282.74333882308138755);
#endif
#ifdef TESTCASE_RAT_11 // large numbers
std::cout << "=============" << std::endl;
std::cout << "CASE1 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
d = NT("82634630175374856683315372867724319098240552701588533218371381248009342768269285501674184091886435054368116496214846441734481770666205690731018817430937185570378353100803926136323598244976110318516454816403989543192819758059431171537258117598056453283568595627159988837663160716950017789671313834717457946818990093589809113731838629064768225280");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 9.3488310472396563" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 9.3488310472396580764" << std::endl;
std::cout << std::endl;
// Results for current tight using cpp_rational.
assert(i == 9.3488310472396563);
assert(s == 9.3488310472396580764);
#endif
#ifdef TESTCASE_RAT_12
std::cout << "=============" << std::endl;
std::cout << "CASE2 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
d = NT("1");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 1.7976931348623157081e+308" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: inf" << std::endl;
std::cout << std::endl;
assert(i == std::numeric_limits<double>::max());
assert(s == std::numeric_limits<double>::infinity());
#endif
#ifdef TESTCASE_RAT_13
std::cout << "=============" << std::endl;
std::cout << "CASE3 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("1");
d = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.0 or higher" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.0 or higher" << std::endl;
std::cout << std::endl;
assert(i >= 0.0 && i <= std::numeric_limits<double>::min() * 2.0);
assert(s >= 0.0 && s <= std::numeric_limits<double>::min() * 2.0);
assert(i <= s);
#endif
#ifdef TESTCASE_RAT_14
std::cout << "=============" << std::endl;
std::cout << "CASE4 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("10");
d = NT("10");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 1" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 1" << std::endl;
std::cout << std::endl;
assert(i == 1.0);
assert(s == 1.0);
#endif
#ifdef TESTCASE_RAT_15
std::cout << "=============" << std::endl;
std::cout << "CASE5 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = NT("1");
d = NT("6");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.16666666666666665741" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.16666666666666668517" << std::endl;
std::cout << std::endl;
assert(i == 0.16666666666666665741);
assert(s == 0.16666666666666668517);
#endif
#ifdef TESTCASE_RAT_16
std::cout << "=============" << std::endl;
std::cout << "CASE6 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = +NT("6");
d = +NT("3");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: " << 6.0 / 3.0 << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: " << 6.0 / 3.0 << std::endl;
std::cout << std::endl;
assert(i == 2.0);
assert(s == 2.0);
#endif
#ifdef TESTCASE_RAT_17
std::cout << "=============" << std::endl;
std::cout << "CASE7 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = -NT("1");
d = -NT("2");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: " << 1.0 / 2.0 << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: " << 1.0 / 2.0 << std::endl;
std::cout << std::endl;
assert(i == 1.0 / 2.0);
assert(s == 1.0 / 2.0);
#endif
#ifdef TESTCASE_RAT_18
std::cout << "=============" << std::endl;
std::cout << "CASE8 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = -NT("1");
d = +NT("3");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: -0.33333333333333337034" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: -0.33333333333333331483" << std::endl;
std::cout << std::endl;
assert(i == -0.33333333333333337034);
assert(s == -0.33333333333333331483);
#endif
#ifdef TESTCASE_RAT_19 // small numbers, num > 0 and den < 0
std::cout << "=============" << std::endl;
std::cout << "CASE9 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
n = +NT("39792587355159975");
d = -NT("140737488355328");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: -282.74333882308138755" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: -282.7433388230813307" << std::endl;
std::cout << std::endl;
assert(i == -282.74333882308138755);
assert(s == -282.7433388230813307);
#endif
std::cout << "---SUCCESS ALL---" << std::endl;
std::cout << std::endl;
}
// In assert, we use values from impl2.
void test_to_interval_tight_rational_2() {
// In green, we compare to impl2.
#define TESTCASE_RAT_20 // pass all three
#define TESTCASE_RAT_21 // impl1: fails tightness (sup is larger, s = 0.43464565325999998668)
#define TESTCASE_RAT_22 // pass all three
#define TESTCASE_RAT_23 // pass all three
#define TESTCASE_RAT_24 // pass all three
#define TESTCASE_RAT_25 // pass all three
#define TESTCASE_RAT_26 // pass all three
#define TESTCASE_RAT_27 // pass all three
#define TESTCASE_RAT_28 // pass all three
#define TESTCASE_RAT_29 // pass all three
#define TESTCASE_RAT_210 // impl1, impl3: fails tightness (sup is larger, s = 5.9425938166208590782e+26)
#define TESTCASE_RAT_211 // impl1, impl3: fails tightness (inf is smaller, i = 3602879701896396.5, sup is larger, s = 3602879701896398)
using NT = boost::multiprecision::cpp_int;
using Quotient = CGAL::Quotient<NT>;
using Traits = CGAL::Real_embeddable_traits<Quotient>;
using Interval = typename Traits::To_interval;
NT n, d;
Quotient x;
double i, s;
std::cout << std::endl;
std::cout << "- T2 testing tight interval for rationals ..." << std::endl;
std::cout << std::endl;
#ifdef TESTCASE_RAT_20
std::cout << "TEST 0" << std::endl; // num, case 2
n = NT("-15284404573383541");
d = NT("4503599627370496");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: -3.3938195750112902793" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: -3.3938195750112898352" << std::endl;
std::cout << std::endl;
assert(i == -3.3938195750112902793);
assert(s == -3.3938195750112898352);
#endif
#ifdef TESTCASE_RAT_21
std::cout << "TEST 1" << std::endl; // num, case 4
const double nn = 0.43464565326;
x = Quotient(nn);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.43464565325999998668" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.43464565325999998668" << std::endl;
std::cout << std::endl;
assert(i == 0.43464565325999998668);
assert(s == 0.43464565325999998668);
assert(i == s);
#endif
#ifdef TESTCASE_RAT_22
std::cout << "TEST 2" << std::endl; // num, case 4
n = NT("1");
d = NT("2");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.5" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.5" << std::endl;
std::cout << std::endl;
assert(i == 0.5);
assert(s == 0.5);
#endif
#ifdef TESTCASE_RAT_23
std::cout << "TEST 3" << std::endl; // shift = 0
n = NT("7725371961607115");
d = NT("1");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 7725371961607115" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 7725371961607115" << std::endl;
std::cout << std::endl;
assert(i == 7725371961607115);
assert(s == 7725371961607115);
#endif
#ifdef TESTCASE_RAT_24
std::cout << "TEST 4" << std::endl;
n = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
d = NT("1");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 1.7976931348623157081e+308" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: inf" << std::endl;
std::cout << std::endl;
assert(i == std::numeric_limits<double>::max());
assert(s == std::numeric_limits<double>::infinity());
#endif
#ifdef TESTCASE_RAT_25
std::cout << "TEST 5" << std::endl;
n = NT("1");
d = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.0 or higher" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.0 or higher" << std::endl;
std::cout << std::endl;
assert(i >= 0.0 && i <= std::numeric_limits<double>::min() * 2.0);
assert(s >= 0.0 && s <= std::numeric_limits<double>::min() * 2.0);
assert(i <= s);
#endif
#ifdef TESTCASE_RAT_26
std::cout << "TEST 6" << std::endl; // case shift > 0 && p_bits = 51, subcase1
n = NT("1");
d = NT("10");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.099999999999999991673" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.10000000000000000555" << std::endl;
std::cout << std::endl;
assert(i == 0.099999999999999991673);
assert(s == 0.10000000000000000555);
#endif
#ifdef TESTCASE_RAT_27
std::cout << "TEST 7" << std::endl; // non representable double
n = NT("1");
d = NT("3");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0.33333333333333331483" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0.33333333333333337034" << std::endl;
std::cout << std::endl;
assert(i == 0.33333333333333331483);
assert(s == 0.33333333333333337034);
#endif
#ifdef TESTCASE_RAT_28
std::cout << "TEST 8" << std::endl; // fails assertion (q_bits == num_dbl_digits || r != 0)
n = NT("21");
d = NT("3");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 7" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 7" << std::endl;
std::cout << std::endl;
assert(i == 7);
assert(s == 7);
#endif
#ifdef TESTCASE_RAT_29
std::cout << "TEST 9" << std::endl; // case shift > 0 && p_bits = 51, subcase3
n = NT("17");
d = NT("3");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 5.6666666666666660745" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 5.6666666666666669627" << std::endl;
std::cout << std::endl;
assert(i == 5.6666666666666660745);
assert(s == 5.6666666666666669627);
#endif
#ifdef TESTCASE_RAT_210
std::cout << "TEST 10" << std::endl; // case shift < 0 && p_bits = 51
n = NT("7725371961607115475320817955");
d = NT("13");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 5.9425938166208577038e+26" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 5.942593816620858391e+26" << std::endl;
std::cout << std::endl;
assert(i == 5.9425938166208577038e+26);
assert(s == 5.942593816620858391e+26);
#endif
#ifdef TESTCASE_RAT_211
std::cout << "TEST 11" << std::endl; // case shift = 0 && p_bits = 51 && cmp = 0, subcase3
n = NT("36028797018963975");
d = NT("10");
x = Quotient(n, d);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 3602879701896397.5" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 3602879701896397.5" << std::endl;
std::cout << std::endl;
assert(i == 3602879701896397.5);
assert(s == 3602879701896397.5);
#endif
std::cout << "---SUCCESS ALL---" << std::endl;
std::cout << std::endl;
}
void test_to_interval_tight_integer() {
#define TESTCASE_INT_0
#define TESTCASE_INT_1
#define TESTCASE_INT_2
#define TESTCASE_INT_3
using NT = boost::multiprecision::cpp_int;
using Traits = CGAL::Real_embeddable_traits<NT>;
using Interval = typename Traits::To_interval;
// std::cout << std::endl;
// std::cout << boost::typeindex::type_id<NT>() << std::endl;
// std::cout << std::endl;
// std::cout << boost::typeindex::type_id<typename Traits::Type>() << std::endl;
// std::cout << std::endl;
NT x;
double i, s;
std::cout << std::endl;
std::cout << "- T testing tight interval for integers ..." << std::endl;
std::cout << std::endl;
#ifdef TESTCASE_INT_0
std::cout << "=============" << std::endl;
std::cout << "CASE0 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
x = NT("0");
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 0" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 0" << std::endl;
std::cout << std::endl;
assert(i == 0.0);
assert(s == 0.0);
#endif
#ifdef TESTCASE_INT_1
std::cout << "=============" << std::endl;
std::cout << "CASE1 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
x = NT("5");
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 5" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: 5" << std::endl;
std::cout << std::endl;
assert(i == 5.0);
assert(s == 5.0);
#endif
#ifdef TESTCASE_INT_2
std::cout << "=============" << std::endl;
std::cout << "CASE2 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
x = NT(-12);
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: -12" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: -12" << std::endl;
std::cout << std::endl;
assert(i == -12.0);
assert(s == -12.0);
#endif
#ifdef TESTCASE_INT_3
std::cout << "=============" << std::endl;
std::cout << "CASE3 RESULT:" << std::endl;
std::cout << "=============" << std::endl;
x = NT("772537196160711547532081795586792063331305895970601529435744397743492241616327030886637827664482971614281724796166908515292029740442872965475211471498392497954317530347232852540146110053764627070672243390766540271554856759037331142360111552286202392826786995364211101723592791550906796165626083442695020580821188398298798456115881346136681033873");
std::tie(i, s) = Interval()(x);
std::cout << std::endl;
std::cout << "inf: " << i << std::endl;
std::cout << "ref: 1.7976931348623157081e+308" << std::endl;
std::cout << "sup: " << s << std::endl;
std::cout << "ref: inf" << std::endl;
std::cout << std::endl;
assert(i == std::numeric_limits<double>::max());
assert(s == std::numeric_limits<double>::infinity());
#endif
std::cout << "---SUCCESS ALL---" << std::endl;
std::cout << std::endl;
}
void test_shift_positive() {
{
double d = (1LL << 53) - 1;
auto shift = std::numeric_limits<double>::max_exponent - (std::numeric_limits<double>::digits);
auto r = CGAL::Boost_MP_internal::shift_positive_interval({d,d},shift);
d = ldexp(d,shift);
assert(!isinf(d));
assert(r.first == d && d == r.second);
}
{
double d = (1LL << 52);
auto shift = std::numeric_limits<double>::max_exponent - std::numeric_limits<double>::digits + 1;
auto r = CGAL::Boost_MP_internal::shift_positive_interval({d,d},shift);
d = ldexp(d,shift);
assert(d >= (std::numeric_limits<double>::max)());
assert(r.first <= d && d <= r.second);
}
{
double d = (1LL << 53) - 1;
auto shift = std::numeric_limits<double>::min_exponent - std::numeric_limits<double>::digits - 1;
auto r = CGAL::Boost_MP_internal::shift_positive_interval({d,d},shift);
d = ldexp(d,shift);
assert(d <= (std::numeric_limits<double>::min)());
assert(r.first <= d && d <= r.second);
}
{
double d = (1LL << 53) - 2;
auto shift = std::numeric_limits<double>::min_exponent - std::numeric_limits<double>::digits - 1;
auto r = CGAL::Boost_MP_internal::shift_positive_interval({d,d},shift);
d = ldexp(d,shift);
assert(d < (std::numeric_limits<double>::min)());
assert(r.first <= d && d <= r.second);
}
{
double d = (1LL << 52);
auto shift = std::numeric_limits<double>::min_exponent - std::numeric_limits<double>::digits;
auto r = CGAL::Boost_MP_internal::shift_positive_interval({d,d},shift);
d = ldexp(d,shift);
assert(d == (std::numeric_limits<double>::min)());
assert(r.first == d && d == r.second);
}
}
#endif // CGAL_USE_BOOST_MP
int main() {
#ifdef CGAL_USE_BOOST_MP
test_shift_positive();
#endif
// Make sure we have the same seed.
CGAL::get_default_random() = CGAL::Random(0);
std::cout.precision(20);
#ifdef CGAL_USE_BOOST_MP
#if false
test_boost_eval_lehmer();
test_minimal_nextafter();
#endif
test_minimal_boost_gcd();
test_to_interval_boost();
// Test rational types.
test_to_interval_tight_rational_1();
test_to_interval_tight_rational_2();
// Test integer types.
test_to_interval_tight_integer();
#endif // CGAL_USE_BOOST_MP
return EXIT_SUCCESS;
}

View File

@ -351,7 +351,7 @@ void oriented_bounding_box(const PointRange& points,
const unsigned int seed = choose_parameter(get_parameter(np, internal_np::random_seed), -1); // undocumented
CGAL::Random fixed_seed_rng(seed);
CGAL::Random& rng = is_default_parameter<NamedParameters,internal_np::random_seed_t>() ?
CGAL::Random& rng = is_default_parameter<NamedParameters, internal_np::random_seed_t>::value ?
CGAL::get_default_random() : fixed_seed_rng;
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG

View File

@ -4,9 +4,6 @@
cmake_minimum_required(VERSION 3.1...3.23)
project(Orthtree_benchmarks)
# TODO: I shouldn't leave this here
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED QUIET OPTIONAL_COMPONENTS Core)
create_single_source_cgal_program("construction.cpp")

View File

@ -39,8 +39,6 @@ bool write_OFF_PSP(std::ostream& os,
const PointRange& points,
const CGAL_NP_CLASS& np = CGAL::parameters::default_values())
{
using CGAL::parameters::choose_parameter;
using CGAL::parameters::get_parameter;
using CGAL::parameters::is_default_parameter;
// basic geometric types
@ -48,7 +46,7 @@ bool write_OFF_PSP(std::ostream& os,
typedef typename NP_helper::Const_point_map PointMap;
typedef typename NP_helper::Normal_map NormalMap;
const bool has_normals = !(is_default_parameter<CGAL_NP_CLASS, internal_np::normal_t>());
const bool has_normals = !(is_default_parameter<CGAL_NP_CLASS, internal_np::normal_t>::value);
PointMap point_map = NP_helper::get_const_point_map(points, np);
NormalMap normal_map = NP_helper::get_normal_map(points, np);

View File

@ -665,7 +665,7 @@ mst_orient_normals(
// or vertex j is in the k-neighborhood of vertex i.
Riemannian_graph riemannian_graph;
if (is_default_parameter<NamedParameters, internal_np::point_is_constrained_t>())
if (is_default_parameter<NamedParameters, internal_np::point_is_constrained_t>::value)
riemannian_graph = create_riemannian_graph(points,
point_map, normal_map, index_map,
Default_constrained_map<typename PointRange::iterator>

View File

@ -235,7 +235,7 @@ public:
typedef typename Point_set_processing_3::GetPlaneIndexMap<NamedParameters>::type PlaneIndexMap;
CGAL_static_assertion_msg(NP_helper::has_normal_map(), "Error: no normal map");
CGAL_static_assertion_msg((!is_default_parameter<NamedParameters, internal_np::plane_index_t>()),
CGAL_static_assertion_msg((!is_default_parameter<NamedParameters, internal_np::plane_index_t>::value),
"Error: no plane index map");
PointMap point_map = NP_helper::get_const_point_map(points, np);

View File

@ -685,7 +685,7 @@ compute_vertex_normal(typename boost::graph_traits<PolygonMesh>::vertex_descript
Face_vector_map default_fvmap;
Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal),
Default_map(default_fvmap));
const bool must_compute_face_normals = is_default_parameter<NamedParameters, internal_np::face_normal_t>();
const bool must_compute_face_normals = is_default_parameter<NamedParameters, internal_np::face_normal_t>::value;
#ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP
std::cout << "<----- compute vertex normal at " << get(vpmap, v)
@ -802,7 +802,7 @@ void compute_vertex_normals(const PolygonMesh& pmesh,
Face_normal_dmap>::type Face_normal_map;
Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal),
get(Face_normal_tag(), pmesh));
const bool must_compute_face_normals = is_default_parameter<NamedParameters, internal_np::face_normal_t>();
const bool must_compute_face_normals = is_default_parameter<NamedParameters, internal_np::face_normal_t>::value;
if(must_compute_face_normals)
compute_face_normals(pmesh, face_normals, np);

View File

@ -731,7 +731,7 @@ void keep_or_remove_connected_components(PolygonMesh& pmesh
for(vertex_descriptor v: vertices(pmesh))
if (!keep_vertex[v])
vertices_to_remove.push_back(v);
if ( is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_is_constrained_t>() )
if ( is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_is_constrained_t>::value )
for (vertex_descriptor v : vertices_to_remove)
remove_vertex(v, pmesh);
else
@ -1014,7 +1014,7 @@ void split_connected_components_impl(FIMap fim,
get(CGAL::dynamic_face_property_t<faces_size_type>(), tm));
faces_size_type nb_patches = 0;
if(is_default_parameter<NamedParameters, internal_np::face_patch_t>())
if(is_default_parameter<NamedParameters, internal_np::face_patch_t>::value)
{
nb_patches = CGAL::Polygon_mesh_processing::connected_components(
tm, pidmap, CGAL::parameters::face_index_map(fim)

View File

@ -737,8 +737,8 @@ corefine( TriangleMesh& tm1,
User_visitor uv(choose_parameter<User_visitor>(get_parameter(np1, internal_np::visitor)));
static const bool handle_non_manifold_features =
!parameters::Is_default<internal_np::non_manifold_feature_map_t, NamedParameters1>::value ||
!parameters::Is_default<internal_np::non_manifold_feature_map_t, NamedParameters2>::value;
!parameters::is_default_parameter<NamedParameters1, internal_np::non_manifold_feature_map_t>::value ||
!parameters::is_default_parameter<NamedParameters2, internal_np::non_manifold_feature_map_t>::value;
// surface intersection algorithm call
typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob;

View File

@ -230,7 +230,7 @@ struct Triangle_structure_sampler_base
if(use_gs || use_ms)
{
if(is_default_parameter<NamedParameters, internal_np::random_uniform_sampling_t>())
if(is_default_parameter<NamedParameters, internal_np::random_uniform_sampling_t>::value)
use_rs = false;
}
@ -463,7 +463,7 @@ struct Triangle_structure_sampler_for_triangle_mesh
pmap = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, tm));
if(!(is_default_parameter<NamedParameters, internal_np::random_seed_t>()))
if(!(is_default_parameter<NamedParameters, internal_np::random_seed_t>::value))
rnd = CGAL::Random(choose_parameter(get_parameter(np, internal_np::random_seed),0));
min_sq_edge_length = (std::numeric_limits<double>::max)();
@ -644,7 +644,7 @@ struct Triangle_structure_sampler_for_triangle_soup
using parameters::is_default_parameter;
min_sq_edge_length = (std::numeric_limits<double>::max)();
if(!(is_default_parameter<NamedParameters, internal_np::random_seed_t>()))
if(!(is_default_parameter<NamedParameters, internal_np::random_seed_t>::value))
rnd = CGAL::Random(choose_parameter(get_parameter(np, internal_np::random_seed),0));
}

View File

@ -1107,7 +1107,7 @@ std::size_t snap_non_conformal(HalfedgeRange& halfedge_range_A,
const bool is_second_mesh_fixed = choose_parameter(get_parameter(np_B, internal_np::do_lock_mesh), false);
internal::Snapping_default_visitor<TriangleMesh> default_visitor;
Visitor& visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor);
Visitor visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor);
if(visitor.stop())
return 0;

View File

@ -738,7 +738,7 @@ std::size_t snap_vertices_two_way(const HalfedgeRange_A& halfedge_range_A,
get_property_map(vertex_point, tm_B));
internal::Snapping_default_visitor<PolygonMesh> default_visitor;
Visitor& visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor);
Visitor visitor = choose_parameter(get_parameter_reference(np_A, internal_np::visitor), default_visitor);
visitor.start_vertex_vertex_phase();
if(visitor.stop())

View File

@ -218,7 +218,7 @@ void isotropic_remeshing(const FaceRange& faces
#endif
static const bool need_aabb_tree =
parameters::is_default_parameter<NamedParameters, internal_np::projection_functor_t>();
parameters::is_default_parameter<NamedParameters, internal_np::projection_functor_t>::value;
typedef typename GetGeomTraits<PM, NamedParameters>::type GT;
GT gt = choose_parameter<GT>(get_parameter(np, internal_np::geom_traits));
@ -255,7 +255,7 @@ void isotropic_remeshing(const FaceRange& faces
FPMap fpmap = choose_parameter(
get_parameter(np, internal_np::face_patch),
internal::Connected_components_pmap<PM, FIMap>(faces, pmesh, ecmap, fimap,
parameters::is_default_parameter<NamedParameters, internal_np::face_patch_t>() && (need_aabb_tree
parameters::is_default_parameter<NamedParameters, internal_np::face_patch_t>::value && (need_aabb_tree
#if !defined(CGAL_NO_PRECONDITIONS)
|| protect // face patch map is used to identify patch border edges to check protected edges are short enough
#endif

View File

@ -177,8 +177,8 @@ std::size_t remove_connected_components_of_negligible_size(TriangleMesh& tmesh,
FT volume_threshold = choose_parameter(get_parameter(np, internal_np::volume_threshold), FT(-1));
// If no threshold is provided, compute it as a % of the bbox
const bool is_default_area_threshold = is_default_parameter<NamedParameters, internal_np::area_threshold_t>();
const bool is_default_volume_threshold = is_default_parameter<NamedParameters, internal_np::volume_threshold_t>();
const bool is_default_area_threshold = is_default_parameter<NamedParameters, internal_np::area_threshold_t>::value;
const bool is_default_volume_threshold = is_default_parameter<NamedParameters, internal_np::volume_threshold_t>::value;
const bool dry_run = choose_parameter(get_parameter(np, internal_np::dry_run), false);

View File

@ -249,7 +249,7 @@ self_intersections_impl(const FaceRange& face_range,
VPM vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, tmesh));
const bool do_limit = !(is_default_parameter<NamedParameters, internal_np::maximum_number_t>());
const bool do_limit = !(is_default_parameter<NamedParameters, internal_np::maximum_number_t>::value);
const unsigned int maximum_number = choose_parameter(get_parameter(np, internal_np::maximum_number), 0);
if(do_limit && maximum_number == 0)
{

View File

@ -404,7 +404,7 @@ public:
else
deg_faces.insert(f);
}
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>())
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>::value)
init(epsilon);
else
{
@ -513,7 +513,7 @@ public:
deg_faces.insert(f);
}
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>())
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>::value)
init(epsilon);
else
{
@ -597,8 +597,10 @@ public:
env_faces.emplace_back(face);
}
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>())
if (is_default_parameter<NamedParameters, internal_np::face_epsilon_map_t>::value)
{
init(epsilon);
}
else
{
std::vector<double> epsilon_values;

View File

@ -45,7 +45,7 @@ void my_function_with_named_parameters(PolygonMesh& mesh, const NamedParameters&
bool do_project = choose_parameter(get_parameter(np, internal_np::do_project), false);
// check is a parameter has been given by the user
constexpr bool do_project_is_default = is_default_parameter<NamedParameters, internal_np::do_project_t>();
constexpr bool do_project_is_default = is_default_parameter<NamedParameters, internal_np::do_project_t>::value;
VCM vcm_np = choose_parameter(get_parameter(np, internal_np::vertex_is_constrained), Default_VCM());

View File

@ -208,7 +208,7 @@ The current implementation incorporates two open source solvers: \ref thirdparty
(see \ref PkgSolverInterface). It should be noted that GLPK only manages to solve small problems, i.e., objects
with reasonably simple structure.
In case you are reconstructing more complex objects, you may need to consider more efficient open source
solvers (e.g., <a href = "https://projects.coin-or.org/Cbc">CBC</a>) or even commercial solvers (e.g.,
solvers (e.g., <a href = "https://github.com/coin-or/Cbc">CBC</a>) or even commercial solvers (e.g.,
<a href = "https://www.gurobi.com/">Gurobi</a>, <a href = "https://www.ibm.com/analytics/cplex-optimizer">CPLEX</a>).
The following table gives a rough idea of the performance of some solvers.

View File

@ -50,7 +50,7 @@ set_package_properties(
DESCRIPTION "A library for image processing."
PURPOSE "Can be used for I/O (DICOM, VTU, VTP.")
polyhedron_demo_plugin(triangulation_3_io_plugin triangulation_3_io_plugin KEYWORDS IO)
polyhedron_demo_plugin(triangulation_3_io_plugin triangulation_3_io_plugin KEYWORDS Viewer)
target_link_libraries(triangulation_3_io_plugin PUBLIC scene_triangulation_3_item)
if(VTK_FOUND)

View File

@ -168,7 +168,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_tr
scene->addItem(group);
for(FaceGraph& poly : new_polyhedra)
{
Scene_facegraph_item* new_item=new Scene_facegraph_item(poly);
Scene_facegraph_item* new_item=new Scene_facegraph_item(std::move(poly));
new_item->setName(tr("%1 - CC %2").arg(item->name()).arg(cc));
new_item->setColor(color_map[cc]);
++cc;

View File

@ -51,6 +51,7 @@
#include "id_printing.h"
#include <unordered_map>
#include <functional>
#include <utility>
#endif
typedef CGAL::Three::Triangle_container Tri;
@ -350,11 +351,16 @@ Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh* sm)
standard_constructor(sm);
}
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh sm)
Scene_surface_mesh_item::Scene_surface_mesh_item(const SMesh& sm)
{
standard_constructor(new SMesh(sm));
}
Scene_surface_mesh_item::Scene_surface_mesh_item(SMesh&& sm)
{
standard_constructor(new SMesh(std::move(sm)));
}
Scene_surface_mesh_item*
Scene_surface_mesh_item::clone() const
{ return new Scene_surface_mesh_item(*this); }

View File

@ -48,7 +48,8 @@ public:
Scene_surface_mesh_item();
// Takes ownership of the argument.
Scene_surface_mesh_item(SMesh*);
Scene_surface_mesh_item(SMesh);
Scene_surface_mesh_item(const SMesh&);
Scene_surface_mesh_item(SMesh&&);
Scene_surface_mesh_item(const Scene_surface_mesh_item& other);
~Scene_surface_mesh_item();

View File

@ -26,7 +26,7 @@ configure()
{
echo "Configuring... "
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
.' ; then

View File

@ -66,17 +66,17 @@ bool read_OFF(std::istream& in,
const bool verbose = choose_parameter(get_parameter(np, internal_np::verbose), true);
if(!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>()))
if(!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value))
{
return CGAL::IO::internal::read_OFF_BGL(in, P, np);
}
CGAL::scan_OFF(in, P, verbose);
if(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_point_t>())
if(!parameters::is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_point_t>::value)
{
Def_VPM def_vpm = get_property_map(CGAL::vertex_point, P);
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
@ -132,10 +132,10 @@ bool write_OFF(std::ostream& out,
using parameters::get_parameter;
using parameters::is_default_parameter;
if(!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>()) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>()))
if(!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value) ||
!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value))
{
return CGAL::IO::internal::write_OFF_BGL(out, P, np);
}

View File

@ -723,7 +723,11 @@ fitting_plane_3(typename DiagonalizeTraits::Covariance_matrix& covariance, // co
eigen_vectors[1],
eigen_vectors[2]);
plane = Plane(c,normal);
return FT(1) - eigen_values[0] / eigen_values[1];
if (eigen_values[1] == 0)
return FT(0); // line case
else
return FT(1) - eigen_values[0] / eigen_values[1]; // regular case
} // end regular case
}

View File

@ -16,8 +16,11 @@
#include <CGAL/basic.h>
#endif
#include <CGAL/tags.h>
#include <boost/type_traits/is_same.hpp>
#include <boost/mpl/if.hpp>
#include <type_traits>
#include <utility>
@ -356,12 +359,17 @@ const T& choose_parameter(const T& t)
return t;
}
template <class NP, class TAG>
constexpr bool is_default_parameter()
template <class NamedParameters, class Parameter>
struct is_default_parameter
{
return std::is_same< typename internal_np::Get_param<typename NP::base, TAG>::type,
internal_np::Param_not_found> ::value;
}
typedef typename internal_np::Lookup_named_param_def<Parameter,
NamedParameters,
internal_np::Param_not_found>::type NP_type;
static const bool value = boost::is_same<NP_type, internal_np::Param_not_found>::value;
typedef CGAL::Boolean_tag<value> type;
};
} // end of parameters namespace

View File

@ -80,7 +80,6 @@ REFERENCE_PLATFORMS_DIR="must_be_set_in_.autocgalrc"
ACTUAL_DIR=`pwd`
RSH="rsh"
NICE_OPTIONS="-19"
CMAKE_GENERATOR=""
USE_TARGZ="n"
USE_TARBZ="n"
PLATFORMS=""
@ -506,16 +505,12 @@ build_cgal_on_host()
cat >> "${CGAL_BINARY_DIR}/localbuildscript" <<EOF
CGAL_BINARY_DIR='${CGAL_BINARY_DIR}';
if [ -z "\$CMAKE_GENERATOR" ]; then
CMAKE_GENERATOR='${CMAKE_GENERATOR}';
fi
MAKE_CMD='${MAKE_CMD}';
export CMAKE_GENERATOR;
export MAKE_CMD;
export CGAL_BINARY_DIR;
cd '${CGAL_BINARY_DIR}';
cmake \${INIT_FILE:+"-C\${INIT_FILE}"} '${CMAKE_GENERATOR}' -DRUNNING_CGAL_AUTO_TEST=TRUE \\
cmake \${INIT_FILE:+"-C\${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \\
VERBOSE=1 \\
../../..;
${MAKE_CMD} VERBOSE=ON -k -fMakefile ;
@ -604,14 +599,10 @@ else
fi
CGAL_TEST_HOST='${HOST}';
CGAL_TEST_PLATFORM='${PLATFORM}';
if [ -z "\$CMAKE_GENERATOR" ]; then
CMAKE_GENERATOR='${CMAKE_GENERATOR}';
fi
MAKE_CMD='${MAKE_CMD}'
export CGAL_TESTER CGAL_TESTER_NAME CGAL_TESTER_ADDRESS;
export CGAL_DIR;
export CGAL_TEST_HOST CGAL_TEST_PLATFORM;
export CMAKE_GENERATOR;
export MAKE_CMD;
EOF
@ -884,43 +875,6 @@ else
done
fi
# Detects cygwin
if uname | grep -q "CYGWIN"; then
JOM="`which jom`"
if [ -e "$JOM" ]; then
CMAKE_GENERATOR='-GNMake Makefiles JOM'
MAKE_CMD='jom'
log "${ACTUAL_LOGFILE}" "Cygwin detected, jom detected, using jom"
else
CMAKE_GENERATOR='-GNMake Makefiles'
MAKE_CMD='nmake'
log "${ACTUAL_LOGFILE}" "Cygwin detected, using nmake"
fi
IS_CYGWIN='y'
else
log "${ACTUAL_LOGFILE}" "Non-cygwin linux detected, using system make."
MAKE_CMD='make'
fi
if [ -z "$IS_CYGWIN" ]; then
# Acquire lock
lockfile -r 1 "$LOCK_FILE";
if [ ${?} != 0 ]; then
PID=`cat "$LOCK_FILE"`
if kill -0 "$PID"; then
log "${ACTUAL_LOGFILE}" "COULD NOT ACQUIRE LOCK! LOCKING PROCESS PID=$PID";
exit 1;
else
# The locking process has died without erasing the lock file
rm -f "$LOCK_FILE"
lockfile -r 1 "$LOCK_FILE";
if [ ${?} != 0 ]; then
log "${ACTUAL_LOGFILE}" "COULD NOT ACQUIRE LOCK!";
exit 1
fi
fi
fi
# Make that file writable (lockfile create read-only files
chmod u+w "$LOCK_FILE"
# Put the PID of current process in the lock file

View File

@ -80,7 +80,7 @@ configure()
{
echo "Configuring... "
if eval 'cmake ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
--no-warn-unused-cli \
.' ; then

View File

@ -201,7 +201,7 @@ for i in `echo $nps`; do
echo " CGAL::parameters::${i}(A()).${i}(A());" >> main.cpp
done
echo "}" >> main.cpp
if ! g++ -DCGAL_NO_STATIC_ASSERTION_TESTS -I$git_dir/STL_Extension/include main.cpp; then
if ! g++ -DCGAL_NO_STATIC_ASSERTION_TESTS -I$git_dir/STL_Extension/include -I$git_dir/Stream_support/include -I$git_dir/Installation/include main.cpp; then
echo "ERROR: At least one documented named parameter does not exist"
cd -
rm -r $tmp_dir

View File

@ -295,7 +295,6 @@ EOF
add_test( "$BASE" \${CMAKE_CTEST_COMMAND}
--build-and-test "\${CMAKE_CURRENT_SOURCE_DIR}"
"\${CMAKE_CURRENT_BINARY_DIR}"
--build-generator "\${CMAKE_GENERATOR}"
--build-makeprogram "\${CMAKE_MAKE_PROGRAM}"
--build-target $BASE
--build-no-clean

View File

@ -4,7 +4,6 @@
project(Shape_regularization_Benchmarks)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -4,7 +4,6 @@
project(Shape_regularization_Examples)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -293,10 +293,10 @@ namespace Planes {
using parameters::get_parameter;
using parameters::choose_parameter;
using parameters::is_default_parameter;
using PlaneIndexMap = typename CGAL::Point_set_processing_3::
GetPlaneIndexMap<NamedParameters>::type;
CGAL_static_assertion_msg((!is_default_parameter<NamedParameters, internal_np::plane_index_t>()),
using PlaneIndexMap = typename CGAL::Point_set_processing_3::GetPlaneIndexMap<NamedParameters>::type;
CGAL_static_assertion_msg((!is_default_parameter<NamedParameters, internal_np::plane_index_t>::value),
"Error: no plane index map");
const PlaneIndexMap index_map =

View File

@ -4,7 +4,6 @@
project(Shape_regularization_Tests)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -25,7 +25,7 @@ configure()
{
echo "Configuring... "
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
.' ; then

View File

@ -273,7 +273,7 @@ namespace CGAL {
/// classes, i.e., `CGAL::GLPK_mixed_integer_program_traits` or
/// `CGAL::SCIP_mixed_integer_program_traits`. Alternatively, use
/// `CGAL::Mixed_integer_program_traits` as a base to derive a new model
/// (using e.g., <a href = "https://projects.coin-or.org/Cbc"> CBC </a>,
/// (using e.g., <a href = "https://github.com/coin-or/Cbc"> CBC </a>,
/// <a href = "https://www.gurobi.com/"> Gurobi </a> for better
/// performance).
///

View File

@ -28,6 +28,7 @@
#include <cstddef>
#include <iostream>
#include <sstream>
#include <vector>
namespace CGAL {

View File

@ -110,7 +110,7 @@ bool read_OFF_with_or_without_fcolors(std::istream& is,
typename Mesh::template Property_map<Face_index, Color> fcm;
bool is_fcm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>());
bool is_fcm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value);
if(!is_fcm_requested && scanner.has_colors())
{
bool created;
@ -149,7 +149,7 @@ bool read_OFF_with_or_without_vtextures(std::istream& is,
typename Mesh::template Property_map<Vertex_index, Texture> vtm;
bool is_vtm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>());
bool is_vtm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value);
if(!is_vtm_requested && scanner.has_textures())
{
bool created;
@ -187,7 +187,7 @@ bool read_OFF_with_or_without_vcolors(std::istream& is,
typename Mesh::template Property_map<Vertex_index, Color> vcm;
bool is_vcm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>());
bool is_vcm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value);
if(!is_vcm_requested && scanner.has_colors())
{
bool created;
@ -226,7 +226,7 @@ bool read_OFF_with_or_without_vnormals(std::istream& is,
typename Mesh::template Property_map<Vertex_index, Normal> vnm;
bool is_vnm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>());
bool is_vnm_requested = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value);
if(!is_vnm_requested && scanner.has_normals())
{
bool created;
@ -324,10 +324,6 @@ bool read_OFF(std::istream& is,
Surface_mesh<Point>& sm,
const CGAL_NP_CLASS& np = parameters::default_values())
{
using parameters::choose_parameter;
using parameters::get_parameter;
using parameters::is_default_parameter;
std::streampos pos = is.tellg();
CGAL::File_scanner_OFF scanner(is, false);
is.seekg(pos);
@ -390,11 +386,9 @@ bool write_OFF_with_or_without_fcolors(std::ostream& os,
typedef typename Mesh::Face_index Face_index;
typedef CGAL::IO::Color Color;
using parameters::choose_parameter;
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool has_fcolors = !(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>());
const bool has_fcolors = !(is_default_parameter<CGAL_NP_CLASS, internal_np::face_color_map_t>::value);
typename Mesh::template Property_map<Face_index, Color> fcolors;
bool has_internal_fcolors;
@ -417,11 +411,9 @@ bool write_OFF_with_or_without_vtextures(std::ostream& os,
typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K;
typedef typename K::Point_2 Texture;
using parameters::choose_parameter;
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool has_vtextures = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>());
const bool has_vtextures = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value);
typename Mesh::template Property_map<Vertex_index, Texture> vtextures;
bool has_internal_vtextures;
@ -442,11 +434,9 @@ bool write_OFF_with_or_without_vcolors(std::ostream& os,
typedef typename Mesh::Vertex_index Vertex_index;
typedef CGAL::IO::Color Color;
using parameters::choose_parameter;
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool has_vcolors = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>());
const bool has_vcolors = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_map_t>::value);
typename Mesh::template Property_map<Vertex_index, Color> vcolors;
bool has_internal_vcolors;
@ -469,11 +459,9 @@ bool write_OFF_with_or_without_vnormals(std::ostream& os,
typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K;
typedef typename K::Vector_3 Normal;
using parameters::choose_parameter;
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool has_vnormals = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>());
const bool has_vnormals = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_normal_map_t>::value);
typename Mesh::template Property_map<Vertex_index, Normal> vnormals;
bool has_internal_vnormals;
@ -559,11 +547,9 @@ bool write_OFF(std::ostream& os,
const Surface_mesh<Point>& sm,
const CGAL_NP_CLASS& np = parameters::default_values())
{
using parameters::choose_parameter;
using parameters::is_default_parameter;
using parameters::get_parameter;
const bool has_vpoints = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_point_t>());
const bool has_vpoints = !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_point_t>::value);
if(has_vpoints)
return internal::write_OFF_with_or_without_vnormals(os, sm, np);

View File

@ -234,7 +234,7 @@ class Property_container
public:
// default constructor
Property_container() : size_(0), capacity_(0) {}
Property_container() = default;
// destructor (deletes all property arrays)
virtual ~Property_container() { clear(); }
@ -242,6 +242,11 @@ public:
// copy constructor: performs deep copy of property arrays
Property_container(const Property_container& _rhs) { operator=(_rhs); }
Property_container(Property_container&& c) noexcept
{
c.swap(*this);
}
// assignment: performs deep copy of property arrays
Property_container& operator=(const Property_container& _rhs)
{
@ -257,6 +262,14 @@ public:
return *this;
}
Property_container& operator=(Property_container&& c) noexcept
{
Property_container tmp(std::move(c));
tmp.swap(*this);
return *this;
}
void transfer(const Property_container& _rhs)
{
for(std::size_t i=0; i<parrays_.size(); ++i){
@ -495,12 +508,13 @@ public:
{
this->parrays_.swap (other.parrays_);
std::swap(this->size_, other.size_);
std::swap(this->capacity_, other.capacity_);
}
private:
std::vector<Base_property_array*> parrays_;
size_t size_;
size_t capacity_;
size_t size_ = 0;
size_t capacity_ = 0;
};
/// @endcond
@ -554,6 +568,20 @@ public:
/// @cond CGAL_DOCUMENT_INTERNALS
Property_map_base(Property_array<T>* p=nullptr) : parray_(p) {}
Property_map_base(Property_map_base&& pm) noexcept
: parray_(std::exchange(pm.parray_, nullptr))
{}
Property_map_base(const Property_map_base& pm)
: parray_(pm.parray_)
{}
Property_map_base& operator=(const Property_map_base& pm)
{
parray_ = pm.parray_;
return *this;
}
void reset()
{
parray_ = nullptr;

View File

@ -341,7 +341,7 @@ public:
{
typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base;
typedef typename Base::reference reference;
Property_map() : Base() {}
Property_map() = default;
Property_map(const Base& pm): Base(pm) {}
};
@ -914,9 +914,58 @@ public:
/// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh(const Surface_mesh& rhs) { *this = rhs; }
Surface_mesh(Surface_mesh&& sm)
: vprops_(std::move(sm.vprops_))
, hprops_(std::move(sm.hprops_))
, eprops_(std::move(sm.eprops_))
, fprops_(std::move(sm.fprops_))
, vconn_(std::move(sm.vconn_))
, hconn_(std::move(sm.hconn_))
, fconn_(std::move(sm.fconn_))
, vremoved_(std::move(sm.vremoved_))
, eremoved_(std::move(sm.eremoved_))
, fremoved_(std::move(sm.fremoved_))
, vpoint_(std::move(sm.vpoint_))
, removed_vertices_(std::exchange(sm.removed_vertices_, 0))
, removed_edges_(std::exchange(sm.removed_edges_, 0))
, removed_faces_(std::exchange(sm.removed_faces_, 0))
, vertices_freelist_(std::exchange(sm.vertices_freelist_,(std::numeric_limits<size_type>::max)()))
, edges_freelist_(std::exchange(sm.edges_freelist_,(std::numeric_limits<size_type>::max)()))
, faces_freelist_(std::exchange(sm.faces_freelist_,(std::numeric_limits<size_type>::max)()))
, garbage_(std::exchange(sm.garbage_, false))
, recycle_(std::exchange(sm.recycle_, true))
, anonymous_property_(std::exchange(sm.anonymous_property_, 0))
{}
/// assigns `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh& operator=(const Surface_mesh& rhs);
Surface_mesh& operator=(Surface_mesh&& sm)
{
vprops_ = std::move(sm.vprops_);
hprops_ = std::move(sm.hprops_);
eprops_ = std::move(sm.eprops_);
fprops_ = std::move(sm.fprops_);
vconn_ = std::move(sm.vconn_);
hconn_ = std::move(sm.hconn_);
fconn_ = std::move(sm.fconn_);
vremoved_ = std::move(sm.vremoved_);
eremoved_ = std::move(sm.eremoved_);
fremoved_ = std::move(sm.fremoved_);
vpoint_ = std::move(sm.vpoint_);
removed_vertices_ = std::exchange(sm.removed_vertices_, 0);
removed_edges_ = std::exchange(sm.removed_edges_, 0);
removed_faces_ = std::exchange(sm.removed_faces_, 0);
vertices_freelist_ = std::exchange(sm.vertices_freelist_, (std::numeric_limits<size_type>::max)());
edges_freelist_ = std::exchange(sm.edges_freelist_,(std::numeric_limits<size_type>::max)());
faces_freelist_ = std::exchange(sm.faces_freelist_,(std::numeric_limits<size_type>::max)());
garbage_ = std::exchange(sm.garbage_, false);
recycle_ = std::exchange(sm.recycle_, true);
anonymous_property_ = std::exchange(sm.anonymous_property_, 0);
return *this;
}
/// assigns `rhs` to `*this`. Does not copy custom properties.
Surface_mesh& assign(const Surface_mesh& rhs);

View File

@ -230,6 +230,40 @@ void properties () {
assert(created == false);
}
void move () {
Surface_fixture f;
auto nf = num_faces(f.m);
// test move-constructor
Sm m2{std::move(f.m)};
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(m2) == nf);
assert(num_faces(f.m) == 0);
// test move-assignment
f.m = std::move(m2);
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == 0);
// test copy-assignment
m2 = f.m;
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == nf);
// test copy-constructor
Sm m3 {f.m};
assert(f.m.is_valid());
assert(m2.is_valid());
assert(num_faces(f.m) == nf);
assert(num_faces(m2) == nf);
}
int main()
{
@ -244,6 +278,7 @@ int main()
border_vertex_check();
point_position_accessor();
properties();
move();
std::cout << "done" << std::endl;
return 0;
}

View File

@ -247,21 +247,21 @@ bool approximate_triangle_mesh(const TriangleMesh &tm, const NamedParameters &np
// get proxy map
approx.proxy_map( get_parameter(np, internal_np::face_proxy_map) );
if (!parameters::is_default_parameter<NamedParameters, internal_np::face_proxy_map_t>()
&& (vl == MAIN_STEPS || vl == VERBOSE))
if (!parameters::is_default_parameter<NamedParameters, internal_np::face_proxy_map_t>::value &&
(vl == MAIN_STEPS || vl == VERBOSE))
std::cout << "Filling face proxy map done." << std::endl;
// get proxies
approx.proxies( get_parameter(np, internal_np::proxies) );
if (!is_default_parameter<NamedParameters,internal_np::proxies_t>()
&& (vl == MAIN_STEPS || vl == VERBOSE))
if (!is_default_parameter<NamedParameters, internal_np::proxies_t>::value &&
(vl == MAIN_STEPS || vl == VERBOSE))
std::cout << "Get proxies done." << std::endl;
// meshing
bool is_manifold = false;
if (!is_default_parameter<NamedParameters, internal_np::anchors_t>()
|| !is_default_parameter<NamedParameters,internal_np::triangles_t>())
if (!is_default_parameter<NamedParameters, internal_np::anchors_t>::value ||
!is_default_parameter<NamedParameters, internal_np::triangles_t>::value)
{
if (vl == VERBOSE) {
const FT subdivision_ratio = choose_parameter(get_parameter(np, internal_np::subdivision_ratio), FT(5.0));
@ -287,15 +287,15 @@ bool approximate_triangle_mesh(const TriangleMesh &tm, const NamedParameters &np
// get anchor points
approx.anchor_points( get_parameter(np, internal_np::anchors) );
if (!is_default_parameter<NamedParameters,internal_np::anchors_t>()
&& (vl == MAIN_STEPS || vl == VERBOSE))
if (!is_default_parameter<NamedParameters,internal_np::anchors_t>::value &&
(vl == MAIN_STEPS || vl == VERBOSE))
std::cout << "Get anchors done." << std::endl;
// get indexed triangles
approx.indexed_triangles( get_parameter(np, internal_np::triangles) );
if (!is_default_parameter<NamedParameters,internal_np::triangles_t>()
&& (vl == MAIN_STEPS || vl == VERBOSE))
if (!is_default_parameter<NamedParameters,internal_np::triangles_t>::value &&
(vl == MAIN_STEPS || vl == VERBOSE))
std::cout << "Get indexed triangles done." << std::endl;
return is_manifold;

View File

@ -3,5 +3,6 @@
\example Surface_mesh_skeletonization/MCF_Skeleton_example.cpp
\example Surface_mesh_skeletonization/segmentation_example.cpp
\example Surface_mesh_skeletonization/MCF_Skeleton_sm_example.cpp
\example Surface_mesh_skeletonization/MCF_Skeleton_om_example.cpp
\example Surface_mesh_skeletonization/simple_mcfskel_sm_example.cpp
*/

View File

@ -9,6 +9,14 @@ find_package(CGAL REQUIRED)
find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater)
include(CGAL_Eigen3_support)
find_package(OpenMesh QUIET)
if(OpenMesh_FOUND)
include(UseOpenMesh)
else()
message(STATUS "Examples that use OpenMesh will not be compiled.")
endif()
if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("simple_mcfskel_example.cpp")
create_single_source_cgal_program("simple_mcfskel_sm_example.cpp")
@ -28,6 +36,11 @@ if(TARGET CGAL::Eigen3_support)
segmentation_example)
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
endforeach()
if(OpenMesh_FOUND)
create_single_source_cgal_program("MCF_Skeleton_om_example.cpp")
target_link_libraries( MCF_Skeleton_om_example PUBLIC CGAL::Eigen3_support PRIVATE ${OPENMESH_LIBRARIES})
endif()
else()
message(
STATUS

View File

@ -0,0 +1,81 @@
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/Mean_curvature_flow_skeletonization.h>
#include <OpenMesh/Core/IO/MeshIO.hh>
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
#include <CGAL/boost/graph/graph_traits_PolyMesh_ArrayKernelT.h>
#include <fstream>
typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel;
typedef Kernel::Point_3 Point;
typedef OpenMesh::PolyMesh_ArrayKernelT</* MyTraits*/> Triangle_mesh;
typedef boost::graph_traits<Triangle_mesh>::vertex_descriptor vertex_descriptor;
typedef CGAL::Mean_curvature_flow_skeletonization<Triangle_mesh> Skeletonization;
typedef Skeletonization::Skeleton Skeleton;
typedef Skeleton::vertex_descriptor Skeleton_vertex;
typedef Skeleton::edge_descriptor Skeleton_edge;
int main(int argc, char* argv[])
{
const std::string filename = (argc > 1) ? argv[1] : CGAL::data_file_path("meshes/elephant.off");
Triangle_mesh tmesh;
OpenMesh::IO::read_mesh(tmesh, filename);
if (!CGAL::is_triangle_mesh(tmesh))
{
std::cout << "Input geometry is not triangulated." << std::endl;
return EXIT_FAILURE;
}
Skeleton skeleton;
Skeletonization mcs(tmesh);
// 1. Contract the mesh by mean curvature flow.
mcs.contract_geometry();
// 2. Collapse short edges and split bad triangles.
mcs.collapse_edges();
mcs.split_faces();
// 3. Fix degenerate vertices.
mcs.detect_degeneracies();
// Perform the above three steps in one iteration.
mcs.contract();
// Iteratively apply step 1 to 3 until convergence.
mcs.contract_until_convergence();
// Convert the contracted mesh into a curve skeleton and
// get the correspondent surface points
mcs.convert_to_skeleton(skeleton);
std::cout << "Number of vertices of the skeleton: " << boost::num_vertices(skeleton) << "\n";
std::cout << "Number of edges of the skeleton: " << boost::num_edges(skeleton) << "\n";
// Output all the edges of the skeleton.
std::ofstream output("skel-sm.polylines.txt");
for(Skeleton_edge e : CGAL::make_range(edges(skeleton)))
{
const Point& s = skeleton[source(e, skeleton)].point;
const Point& t = skeleton[target(e, skeleton)].point;
output << "2 "<< s << " " << t << "\n";
}
output.close();
// Output skeleton points and the corresponding surface points
output.open("correspondance-sm.polylines.txt");
for(Skeleton_vertex v : CGAL::make_range(vertices(skeleton)))
for(vertex_descriptor vd : skeleton[v].vertices)
output << "2 " << skeleton[v].point << " " << get(CGAL::vertex_point, tmesh, vd) << "\n";
return EXIT_SUCCESS;
}

View File

@ -33,7 +33,7 @@ configure()
rm CMakeCache.txt
if [ -f "$INIT_FILE" ]
then
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \
-DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \
@ -43,7 +43,7 @@ configure()
echo " ERROR: configuration" >> $ERRORFILE
fi
else
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} "$CMAKE_GENERATOR" -DRUNNING_CGAL_AUTO_TEST=TRUE \
if eval 'cmake --no-warn-unused-cli ${INIT_FILE:+"-C${INIT_FILE}"} -DRUNNING_CGAL_AUTO_TEST=TRUE \
-DCGAL_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \
-DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \

View File

@ -2388,9 +2388,13 @@ std::istream& operator>> (std::istream& is, Triangulation_3<GT, Tds, Lds>& tr)
if(!is)
return is;
std::vector< Vertex_handle > V;
if(d > 3 || d < -2 || (n+1) > V.max_size()) {
is.setstate(std::ios_base::failbit);
return is;
}
tr._tds.set_dimension(d);
std::vector< Vertex_handle > V(n+1);
V.resize(n+1);
V[0] = tr.infinite_vertex(); // the infinite vertex is numbered 0
for(std::size_t i=1; i <= n; i++)

View File

@ -48,5 +48,5 @@ if(CGAL_Qt5_FOUND AND Qt5_FOUND AND TARGET CGAL::Eigen3_support)
include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
cgal_add_compilation_test( Triangulation_on_sphere_2_Demo )
else()
message(STATUS "NOTICE: This demo requires CGAL, the QGLViewer, OpenGL and Qt4, and will not be compiled.")
message(STATUS "NOTICE: This demo requires CGAL, Qt5 and OpenGL, and will not be compiled.")
endif()

View File

@ -4,7 +4,6 @@
project(Weights_Examples)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)

View File

@ -4,7 +4,6 @@
project(Weights_Tests)
cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core)