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> // Author: Marc Glisse <marc.glisse@inria.fr>
#ifndef CGAL_GMPXX_ARITHMETIC_KERNEL_H #ifndef CGAL_BOOST_MP_ARITHMETIC_KERNEL_H
#define CGAL_GMPXX_ARITHMETIC_KERNEL_H #define CGAL_BOOST_MP_ARITHMETIC_KERNEL_H
#include <CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h> #include <CGAL/Arithmetic_kernel/Arithmetic_kernel_base.h>
#include <CGAL/Get_arithmetic_kernel.h> #include <CGAL/Get_arithmetic_kernel.h>

View File

@ -129,7 +129,7 @@ configure()
rm -rf CMakeCache.txt CMakeFiles/ rm -rf CMakeCache.txt CMakeFiles/
if [ -f "$INIT_FILE" ] if [ -f "$INIT_FILE" ]
then 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_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \ -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS -I../../include" \
-DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \

View File

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

View File

@ -76,10 +76,10 @@ public:
using parameters::is_default_parameter; using parameters::is_default_parameter;
using parameters::get_parameter; using parameters::get_parameter;
const bool is_vnm_requested = !(is_default_parameter<NamedParameters, internal_np::vertex_normal_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>()); 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>()); 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>()); 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_normal> vertex_normals;
std::vector<Vertex_color> vertex_colors; std::vector<Vertex_color> vertex_colors;

View File

@ -122,10 +122,10 @@ public:
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(CGAL::vertex_point, g)); 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_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>()); 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>()); 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>()); 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); VNM vnm = get_parameter(np, internal_np::vertex_normal_map);
VTM vtm = get_parameter(np, internal_np::vertex_texture_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()); 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()); 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_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>(); 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); VIMap vim = CGAL::get_initialized_vertex_index_map(g, np);
Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), Vpm vpm = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, g)); get_const_property_map(boost::vertex_point, g));

View File

@ -10,175 +10,156 @@
#define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H #define CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H
#include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h> #include <CGAL/boost/graph/internal/initialized_index_maps_helpers.h>
#include <CGAL/Named_function_parameters.h>
#include <CGAL/boost/graph/properties.h> #include <CGAL/boost/graph/properties.h>
#include <CGAL/Dynamic_property_map.h> #include <CGAL/Dynamic_property_map.h>
#include <CGAL/iterator.h>
#include <CGAL/Kernel_traits.h> #include <CGAL/Kernel_traits.h>
#include <CGAL/Origin.h> #include <CGAL/Origin.h>
#include <CGAL/iterator.h> #include <CGAL/Named_function_parameters.h>
#include <CGAL/property_map.h> #include <CGAL/property_map.h>
#include <boost/mpl/if.hpp> #include <boost/mpl/if.hpp>
#include <boost/mpl/has_xxx.hpp> #include <boost/mpl/has_xxx.hpp>
#include <boost/type_traits/is_same.hpp> #include <boost/type_traits/is_same.hpp>
#include <fstream>
#include <iterator>
#include <type_traits> #include <type_traits>
namespace CGAL { namespace CGAL {
namespace parameters // forward declarations to avoid dependency to Solver_interface
template <typename FT, unsigned int dim>
class Default_diagonalize_traits;
class Eigen_svd;
class Lapack_svd;
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
>::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
>::type const_type;
type get_pmap(const PropertyTag& p, PolygonMesh& pmesh)
{ {
template <class Parameter, class NamedParameters> return get_impl(p, pmesh, Has_internal_pmap());
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;
class Eigen_svd;
class Lapack_svd;
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
>::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
>::type const_type;
type get_pmap(const PropertyTag& p, PolygonMesh& pmesh)
{
return get_impl(p, pmesh, Has_internal_pmap());
}
const_type get_const_pmap(const PropertyTag& p, const PolygonMesh& pmesh)
{
return get_const_pmap_impl(p, pmesh, Has_internal_pmap());
}
private:
type get_impl(const PropertyTag&, PolygonMesh&, CGAL::Tag_false)
{
return type(); //boost::cgal_no_property::type
}
type get_impl(const PropertyTag& p, PolygonMesh& pmesh, CGAL::Tag_true)
{
return get(p, pmesh);
}
const_type get_const_pmap_impl(const PropertyTag&
, const PolygonMesh&, CGAL::Tag_false)
{
return const_type(); //boost::cgal_no_property::type
}
const_type get_const_pmap_impl(const PropertyTag& p
, const PolygonMesh& pmesh, CGAL::Tag_true)
{
return get(p, pmesh);
}
};
template<typename PolygonMesh, typename PropertyTag>
typename property_map_selector<PolygonMesh, PropertyTag>::type
get_property_map(const PropertyTag& p, PolygonMesh& pmesh)
{
property_map_selector<PolygonMesh, PropertyTag> pms;
return pms.get_pmap(p, pmesh);
} }
template<typename PolygonMesh, typename PropertyTag> const_type get_const_pmap(const PropertyTag& p, const PolygonMesh& pmesh)
typename property_map_selector<PolygonMesh, PropertyTag>::const_type
get_const_property_map(const PropertyTag& p, const PolygonMesh& pmesh)
{ {
property_map_selector<PolygonMesh, PropertyTag> pms; return get_const_pmap_impl(p, pmesh, Has_internal_pmap());
return pms.get_const_pmap(p, pmesh);
} }
// Shortcut for accessing the value type of the property map private:
template <class Graph, class Property> type get_impl(const PropertyTag&, PolygonMesh&, CGAL::Tag_false)
class property_map_value {
typedef typename boost::property_map<Graph, Property>::const_type PMap;
public:
typedef typename boost::property_traits<PMap>::value_type type;
};
template<typename PolygonMesh,
typename NamedParameters = parameters::Default_named_parameters >
class GetVertexPointMap
{ {
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::const_type return type(); //boost::cgal_no_property::type
DefaultVPMap_const; }
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::type type get_impl(const PropertyTag& p, PolygonMesh& pmesh, CGAL::Tag_true)
DefaultVPMap;
public:
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,
NamedParameters,
DefaultVPMap_const
> ::type const_type;
};
template<typename PolygonMesh, typename NamedParameters>
class GetK
{ {
typedef typename boost::property_traits< return get(p, pmesh);
typename GetVertexPointMap<PolygonMesh, NamedParameters>::type }
>::value_type Point;
public:
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
};
template<typename PolygonMesh, const_type get_const_pmap_impl(const PropertyTag&
typename NamedParametersGT = parameters::Default_named_parameters, , const PolygonMesh&, CGAL::Tag_false)
typename NamedParametersVPM = NamedParametersGT >
class GetGeomTraits
{ {
typedef typename CGAL::graph_has_property<PolygonMesh, boost::vertex_point_t>::type return const_type(); //boost::cgal_no_property::type
Has_internal_pmap; }
const_type get_const_pmap_impl(const PropertyTag& p
, const PolygonMesh& pmesh, CGAL::Tag_true)
{
return get(p, pmesh);
}
};
typedef typename internal_np::Lookup_named_param_def < template<typename PolygonMesh, typename PropertyTag>
internal_np::vertex_point_t, typename property_map_selector<PolygonMesh, PropertyTag>::type
NamedParametersVPM, get_property_map(const PropertyTag& p, PolygonMesh& pmesh)
internal_np::Param_not_found {
> ::type NP_vpm; property_map_selector<PolygonMesh, PropertyTag> pms;
return pms.get_pmap(p, pmesh);
}
struct Fake_GT {};//to be used if there is no internal vertex_point_map in PolygonMesh template<typename PolygonMesh, typename PropertyTag>
typename property_map_selector<PolygonMesh, PropertyTag>::const_type
get_const_property_map(const PropertyTag& p, const PolygonMesh& pmesh)
{
property_map_selector<PolygonMesh, PropertyTag> pms;
return pms.get_const_pmap(p, pmesh);
}
typedef typename boost::mpl::if_c<Has_internal_pmap::value || !boost::is_same<internal_np::Param_not_found, NP_vpm>::value, // Shortcut for accessing the value type of the property map
typename GetK<PolygonMesh, NamedParametersVPM>::Kernel, template <class Graph, class Property>
Fake_GT>::type DefaultKernel; class property_map_value
{
typedef typename boost::property_map<Graph, Property>::const_type PMap;
public: public:
typedef typename internal_np::Lookup_named_param_def < typedef typename boost::property_traits<PMap>::value_type type;
internal_np::geom_traits_t, };
NamedParametersGT,
DefaultKernel template <typename PolygonMesh,
> ::type type; typename NamedParameters = parameters::Default_named_parameters>
}; class GetVertexPointMap
{
typedef typename property_map_selector<PolygonMesh, boost::vertex_point_t>::const_type
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,
NamedParameters,
DefaultVPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_point_t,
NamedParameters,
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;
public:
typedef typename CGAL::Kernel_traits<Point>::Kernel Kernel;
};
template <typename PolygonMesh,
typename NamedParametersGT = parameters::Default_named_parameters,
typename NamedParametersVPM = NamedParametersGT>
class GetGeomTraits
{
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,
NamedParametersVPM,
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,
typename GetK<PolygonMesh, NamedParametersVPM>::Kernel,
Fake_GT>::type DefaultKernel;
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::geom_traits_t,
NamedParametersGT,
DefaultKernel>::type type;
};
// Define the following structs: // Define the following structs:
// //
@ -189,7 +170,7 @@ namespace CGAL {
#define CGAL_DEF_GET_INDEX_TYPE(CTYPE, DTYPE, STYPE) \ #define CGAL_DEF_GET_INDEX_TYPE(CTYPE, DTYPE, STYPE) \
template <typename Graph, \ template <typename Graph, \
typename NamedParameters = parameters::Default_named_parameters> \ typename NamedParameters = parameters::Default_named_parameters> \
struct GetInitialized##CTYPE##IndexMap \ struct GetInitialized##CTYPE##IndexMap \
: public BGL::internal::GetInitializedIndexMap<internal_np::DTYPE##_index_t, \ : public BGL::internal::GetInitializedIndexMap<internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \ boost::DTYPE##_index_t, \
@ -224,7 +205,7 @@ typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \ CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::const_type \ Graph, NamedParameters>::const_type \
get_initialized_##DTYPE##_index_map(const Graph& g, \ get_initialized_##DTYPE##_index_map(const Graph& g, \
const NamedParameters& np = parameters::default_values()) \ const NamedParameters& np = parameters::default_values()) \
{ \ { \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \ typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \ boost::DTYPE##_index_t, \
@ -234,7 +215,7 @@ get_initialized_##DTYPE##_index_map(const Graph& g,
} \ } \
/* same as above, non-const version*/ \ /* same as above, non-const version*/ \
template <typename Graph, \ template <typename Graph, \
typename NamedParameters = parameters::Default_named_parameters, \ typename NamedParameters = parameters::Default_named_parameters, \
/*otherwise compilers will try to use 'Graph := const PM' and things will go badly*/ \ /*otherwise compilers will try to use 'Graph := const PM' and things will go badly*/ \
std::enable_if_t< \ std::enable_if_t< \
!std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \ !std::is_const<typename std::remove_reference<Graph>::type>::value, int> = 0> \
@ -243,7 +224,7 @@ typename BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_
CGAL::dynamic_##DTYPE##_property_t<STYPE>, \ CGAL::dynamic_##DTYPE##_property_t<STYPE>, \
Graph, NamedParameters>::type \ Graph, NamedParameters>::type \
get_initialized_##DTYPE##_index_map(Graph& g, \ get_initialized_##DTYPE##_index_map(Graph& g, \
const NamedParameters& np = parameters::default_values()) \ const NamedParameters& np = parameters::default_values()) \
{ \ { \
typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \ typedef BGL::internal::GetInitializedIndexMap<CGAL::internal_np::DTYPE##_index_t, \
boost::DTYPE##_index_t, \ boost::DTYPE##_index_t, \
@ -259,263 +240,244 @@ CGAL_DEF_GET_INITIALIZED_INDEX_MAP(face, typename boost::graph_traits<Graph>::fa
#undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP #undef CGAL_DEF_GET_INITIALIZED_INDEX_MAP
namespace internal { namespace internal {
BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_iterator, iterator, false)
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>
class GetPointMap
{
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Point;
typedef typename CGAL::Identity_property_map<Point> DefaultPMap;
typedef typename CGAL::Identity_property_map<const Point> DefaultConstPMap;
public:
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,
DefaultPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,
DefaultConstPMap>::type const_type;
};
// to please compiler instantiating non valid overloads
template<typename PointRange, typename NamedParameters>
class GetPointMap<PointRange, NamedParameters, false>
{
struct Dummy_point{};
public:
typedef typename CGAL::Identity_property_map<Dummy_point> type;
typedef typename CGAL::Identity_property_map<const Dummy_point> const_type;
};
template <class PointRange, class NamedParameters, typename NP_TAG = internal_np::point_t>
struct Point_set_processing_3_np_helper
{
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Value_type;
typedef CGAL::Identity_property_map<Value_type> DefaultPMap;
typedef CGAL::Identity_property_map<const Value_type> DefaultConstPMap;
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,
DefaultPMap>::type Point_map;
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
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,
NamedParameters,
Default_geom_traits>::type Geom_traits;
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,
NamedParameters,
DummyNormalMap>::type Normal_map;
static Point_map get_point_map(PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Point_map>(parameters::get_parameter(np, internal_np::point_map));
} }
template<typename PointRange, static Point_map get_point_map(const NamedParameters& np)
typename NamedParameters = parameters::Default_named_parameters,
bool has_nested_iterator = internal::Has_nested_type_iterator<PointRange>::value,
typename NP_TAG = internal_np::point_t
>
class GetPointMap
{ {
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Point; return parameters::choose_parameter<Point_map>(parameters::get_parameter(np, internal_np::point_map));
typedef typename CGAL::Identity_property_map<Point> DefaultPMap; }
typedef typename CGAL::Identity_property_map<const Point> DefaultConstPMap;
public: static Const_point_map get_const_point_map(const PointRange&, const NamedParameters& np)
typedef typename internal_np::Lookup_named_param_def< {
NP_TAG, return parameters::choose_parameter<Const_point_map>(parameters::get_parameter(np, internal_np::point_map));
NamedParameters, }
DefaultPMap
> ::type type;
typedef typename internal_np::Lookup_named_param_def< static Normal_map get_normal_map(const PointRange&, const NamedParameters& np)
NP_TAG, {
NamedParameters, return parameters::choose_parameter<Normal_map>(parameters::get_parameter(np, internal_np::normal_map));
DefaultConstPMap }
> ::type const_type;
static Normal_map get_normal_map(const NamedParameters& np)
{
return parameters::choose_parameter<Normal_map>(parameters::get_parameter(np, internal_np::normal_map));
}
static Geom_traits get_geom_traits(const PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Geom_traits>(parameters::get_parameter(np, internal_np::geom_traits));
}
static constexpr bool has_normal_map()
{
return !boost::is_same< typename internal_np::Get_param<typename NamedParameters::base, internal_np::normal_t>::type,
internal_np::Param_not_found> ::value;
}
};
namespace Point_set_processing_3 {
template <typename ValueType>
struct Fake_point_range
{
struct iterator
{
typedef ValueType value_type;
typedef std::ptrdiff_t difference_type;
typedef ValueType* pointer;
typedef ValueType reference;
typedef std::random_access_iterator_tag iterator_category;
};
};
template<typename PlaneRange, typename NamedParameters>
class GetPlaneMap
{
typedef typename PlaneRange::iterator::value_type Plane;
typedef typename CGAL::Identity_property_map<Plane> DefaultPMap;
typedef typename CGAL::Identity_property_map<const Plane> DefaultConstPMap;
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::plane_t,
NamedParameters,
DefaultPMap>::type type;
typedef typename internal_np::Lookup_named_param_def<internal_np::plane_t,
NamedParameters,
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,
NamedParameters,
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;
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::point_is_constrained_t,
NamedParameters,
Default_map>::type type;
};
template<typename PointRange, typename NamedParameters>
class GetAdjacencies
{
public:
typedef Emptyset_iterator Empty;
typedef typename internal_np::Lookup_named_param_def<internal_np::adjacencies_t,
NamedParameters,
Empty>::type type;
};
} // namespace Point_set_processing_3
template<typename NamedParameters, typename DefaultSolver>
class GetSolver
{
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::sparse_linear_solver_t,
NamedParameters,
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,
NamedParameters,
Default_diagonalize_traits<FT, dim> >::type type;
};
template<typename NamedParameters>
class GetSvdTraits
{
struct DummySvdTraits
{
typedef double FT;
typedef int Vector;
typedef int Matrix;
static FT solve (const Matrix&, Vector&) { return 0.; }
}; };
// to please compiler instantiating non valid overloads public:
template<typename PointRange, typename NamedParameters> typedef DummySvdTraits NoTraits;
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;
};
template <class PointRange, class NamedParameters, typename NP_TAG = internal_np::point_t> typedef typename internal_np::Lookup_named_param_def<internal_np::svd_traits_t,
struct Point_set_processing_3_np_helper NamedParameters,
{
typedef typename std::iterator_traits<typename PointRange::iterator>::value_type Value_type;
typedef CGAL::Identity_property_map<Value_type> DefaultPMap;
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
typedef typename internal_np::Lookup_named_param_def<NP_TAG,
NamedParameters,DefaultConstPMap> ::type Const_point_map; // public
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,
NamedParameters,
Default_geom_traits
> ::type Geom_traits; // public
typedef typename Geom_traits::FT FT; // public
typedef Constant_property_map<Value_type, typename Geom_traits::Vector_3> DummyNormalMap;
typedef typename internal_np::Lookup_named_param_def<
internal_np::normal_t,
NamedParameters,
DummyNormalMap
> ::type Normal_map; // public
static Point_map get_point_map(PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Point_map>(parameters::get_parameter(np, internal_np::point_map));
}
static Point_map get_point_map(const NamedParameters& np)
{
return parameters::choose_parameter<Point_map>(parameters::get_parameter(np, internal_np::point_map));
}
static Const_point_map get_const_point_map(const PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Const_point_map>(parameters::get_parameter(np, internal_np::point_map));
}
static Normal_map get_normal_map(const PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Normal_map>(parameters::get_parameter(np, internal_np::normal_map));
}
static Normal_map get_normal_map(const NamedParameters& np)
{
return parameters::choose_parameter<Normal_map>(parameters::get_parameter(np, internal_np::normal_map));
}
static Geom_traits get_geom_traits(const PointRange&, const NamedParameters& np)
{
return parameters::choose_parameter<Geom_traits>(parameters::get_parameter(np, internal_np::geom_traits));
}
static constexpr bool has_normal_map()
{
return !boost::is_same< typename internal_np::Get_param<typename NamedParameters::base, internal_np::normal_t>::type,
internal_np::Param_not_found> ::value;
}
};
namespace Point_set_processing_3 {
template <typename ValueType>
struct Fake_point_range
{
struct iterator
{
typedef ValueType value_type;
typedef std::ptrdiff_t difference_type;
typedef ValueType* pointer;
typedef ValueType reference;
typedef std::random_access_iterator_tag iterator_category;
};
};
template<typename PlaneRange, typename NamedParameters>
class GetPlaneMap
{
typedef typename PlaneRange::iterator::value_type Plane;
typedef typename CGAL::Identity_property_map<Plane> DefaultPMap;
typedef typename CGAL::Identity_property_map<const Plane> DefaultConstPMap;
public:
typedef typename internal_np::Lookup_named_param_def<
internal_np::plane_t,
NamedParameters,
DefaultPMap
> ::type type;
typedef typename internal_np::Lookup_named_param_def<
internal_np::plane_t,
NamedParameters,
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,
NamedParameters,
DummyPlaneIndexMap//default
> ::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;
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::point_is_constrained_t,
NamedParameters,
Default_map //default
> ::type type;
};
template<typename PointRange, typename NamedParameters>
class GetAdjacencies
{
public:
typedef Emptyset_iterator Empty;
typedef typename internal_np::Lookup_named_param_def <
internal_np::adjacencies_t,
NamedParameters,
Empty//default
> ::type type;
};
} // namespace Point_set_processing_3
template<typename NamedParameters, typename DefaultSolver>
class GetSolver
{
public:
typedef typename internal_np::Lookup_named_param_def <
internal_np::sparse_linear_solver_t,
NamedParameters,
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,
NamedParameters,
Default_diagonalize_traits<FT, dim>
> ::type type;
};
template<typename NamedParameters>
class GetSvdTraits
{
struct DummySvdTraits
{
typedef double FT;
typedef int Vector;
typedef int Matrix;
static FT solve (const Matrix&, Vector&) { return 0.; }
};
public:
typedef DummySvdTraits NoTraits;
typedef typename internal_np::Lookup_named_param_def <
internal_np::svd_traits_t,
NamedParameters,
#if defined(CGAL_EIGEN3_ENABLED) #if defined(CGAL_EIGEN3_ENABLED)
Eigen_svd Eigen_svd
#elif defined(CGAL_LAPACK_ENABLED) #elif defined(CGAL_LAPACK_ENABLED)
Lapack_svd Lapack_svd
#else #else
NoTraits NoTraits
#endif #endif
> ::type type; >::type type;
}; };
template<typename NamedParameters> template<typename NamedParameters>
class GetImplementationTag class GetImplementationTag
{
public:
typedef typename internal_np::Lookup_named_param_def<internal_np::implementation_tag_t,
NamedParameters,
Alpha_expansion_boost_adjacency_list_tag>::type type;
};
template<typename NP>
void set_stream_precision_from_NP(std::ostream& os, const NP& np)
{
using parameters::get_parameter;
using parameters::choose_parameter;
using parameters::is_default_parameter;
if(!is_default_parameter<NP, internal_np::stream_precision_t>::value)
{ {
public: const int precision = choose_parameter<int>(get_parameter(np,
typedef typename internal_np::Lookup_named_param_def < internal_np::stream_precision));
internal_np::implementation_tag_t, os.precision(precision);
NamedParameters,
Alpha_expansion_boost_adjacency_list_tag
>::type type;
};
template<typename NP>
void set_stream_precision_from_NP(std::ostream& os, const NP& np)
{
using parameters::get_parameter;
using parameters::choose_parameter;
using parameters::is_default_parameter;
if(!is_default_parameter<NP, internal_np::stream_precision_t>())
{
const int precision = choose_parameter<int>(get_parameter(np,
internal_np::stream_precision));
os.precision(precision);
}
} }
} //namespace CGAL }
} // namespace CGAL
#endif // CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H #endif // CGAL_BOOST_GRAPH_NAMED_PARAMETERS_HELPERS_H

View File

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

View File

@ -4,7 +4,6 @@
project(Barycentric_coordinates_2_Examples) project(Barycentric_coordinates_2_Examples)
cmake_minimum_required(VERSION 3.1...3.23) cmake_minimum_required(VERSION 3.1...3.23)
set(CMAKE_CXX_STANDARD 14)
find_package(CGAL REQUIRED COMPONENTS Core) 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) ); 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 = (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 weights.
return boost::optional<OutputIterator>(output); return boost::optional<OutputIterator>(output);
@ -277,6 +278,7 @@ private:
++output; ++output;
} }
*output = weight[n-1] * inverted_dh_denominator; *output = weight[n-1] * inverted_dh_denominator;
++output;
// Return coordinates. // Return coordinates.
return boost::optional<OutputIterator>(output); return boost::optional<OutputIterator>(output);
@ -333,6 +335,7 @@ private:
++output; ++output;
} }
*output = weight[n-1] * inverted_dh_denominator; *output = weight[n-1] * inverted_dh_denominator;
++output;
// Return coordinates. // Return coordinates.
return boost::optional<OutputIterator>(output); return boost::optional<OutputIterator>(output);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ namespace CGAL {
\ingroup PkgBoundingVolumesRef \ingroup PkgBoundingVolumesRef
The class `Min_ellipse_2_traits_2` is a traits class for `CGAL::Min_ellipse_2<Traits>` 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`. The template parameter `K` must be a model for `Kernel`.

View File

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

View File

@ -2,11 +2,11 @@
\ingroup PkgBoundingVolumesConcepts \ingroup PkgBoundingVolumesConcepts
\cgalConcept \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 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 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 has no bounded side, its boundary is \f$ \{p\}\f$, and its unbounded side
equals \f$ \E^2 \setminus \{p\}\f$. equals \f$ \E^2 \setminus \{p\}\f$.
@ -42,21 +42,21 @@ typedef unspecified_type Distance;
void set(); 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); void set( const Point& p);
/*! /*!
sets `circle` to the circle with diameter equal to the segment 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. called with two equal points.
*/ */
void set( const Point& p, const Point& q); void set( const Point& p, const Point& q);
/*! /*!
sets `circle` to the circle through `p`,`q`,`r`. The algorithm sets `circle` to the circle through `p`, `q`, and `r`. The algorithm
guarantees that `set` is never called with three collinear points. guarantees that `set()` is never called with three collinear points.
*/ */
void set( const Point& p, const Point& q, const Point& r); void set( const Point& p, const Point& q, const Point& r);

View File

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

View File

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

View File

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

View File

@ -92,17 +92,11 @@ if(LEDA_FOUND)
target_link_libraries(test_LEDA_IO ${LEDA_LIBRARIES}) target_link_libraries(test_LEDA_IO ${LEDA_LIBRARIES})
endif() endif()
if("$ENV{CMAKE_GENERATOR}" STREQUAL "") if("$ENV{INIT_FILE}" STREQUAL "")
set(GENERATOR )
else()
set(GENERATOR $ENV{CMAKE_GENERATOR})
endif()
if("$ENV{INIT_FILE}" STREQUAL "")
set(INIT_FILE ) set(INIT_FILE )
else() else()
set(INIT_FILE -C$ENV{INIT_FILE}) set(INIT_FILE -C$ENV{INIT_FILE})
endif() endif()
function(CGAL_installation_test_find_package_version mode) function(CGAL_installation_test_find_package_version mode)
set(EXACT) set(EXACT)
@ -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) 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} 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}) cgal_setup_test_properties(test_find_package_version_${mode})
set_property(TEST 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 #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) 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 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" "${CMAKE_BINARY_DIR}/test_config_file"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_3") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_3")
list(APPEND test_config_lst "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) if(CGAL_Qt5_FOUND)
#configure cgal for a non standard install with qt5 #configure cgal for a non standard install with qt5
add_test(NAME config_non_standard_cgal_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}" "${CGAL_SOURCE_DIR}"
WORKING_DIRECTORY "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build_qt5") WORKING_DIRECTORY "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build_qt5")
#install cgal in the non standard place #install cgal in the non standard place
@ -233,7 +227,7 @@ if(CGAL_Qt5_FOUND)
#test CGAL_DIR=non standard place with cgal_qt5 #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) 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 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" "${CMAKE_BINARY_DIR}/test_config_file_qt5"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_4") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_4")
list(APPEND test_config_lst "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 #test CGAL_DIR=non standard build
get_filename_component(CGAL_DIR_CORRECT_PATH "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build/CGALConfig.cmake" DIRECTORY) get_filename_component(CGAL_DIR_CORRECT_PATH "${NON_STANDARD_INSTALL_PREFIX}/non_standard_build/CGALConfig.cmake" DIRECTORY)
add_test(NAME test_config_file_5 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" "${CMAKE_BINARY_DIR}/test_config_file"
WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_5") WORKING_DIRECTORY "${CMAKE_BINARY_DIR}/build-test_config_file_5")
list(APPEND test_config_lst "test_config_file_5") list(APPEND test_config_lst "test_config_file_5")

View File

@ -26,7 +26,7 @@ touch ../$ERRORFILE
echo "Configuring... " echo "Configuring... "
mkdir build_dir mkdir build_dir
cd 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 \ -DCGAL_DIR="$CGAL_RELEASE_DIR" -DBUILD_TESTING=ON -DWITH_tests=ON \
..' ; then ..' ; then

View File

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

View File

@ -1264,7 +1264,7 @@ vertices/second
View of 3d image mesh generation result (size = 4). View of 3d image mesh generation result (size = 4).
\cgalFigureEnd \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 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} is 0.78mm x 0.78mm x 1.6mm. \cgalFigureRef{figuremesh_3_benchmark_3d_image}
shows the mesh obtained for size set to 4. shows the mesh obtained for size set to 4.

View File

@ -304,14 +304,14 @@ struct Polyline_visitor
template <typename Kernel> template <typename Kernel>
struct Angle_tester 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() Angle_tester()
: m_angle_sq_cosine(0) : m_angle_sq_cosine(0)
{} {}
Angle_tester(const double angle_deg)//angle given in degrees for readability 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> template <typename vertex_descriptor, typename Graph>

View File

@ -26,7 +26,7 @@ configure()
{ {
echo "Configuring... " 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" \ -DCGAL_DIR="$CGAL_DIR" \
.' ; then .' ; then

View File

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

View File

@ -50,30 +50,30 @@ typedef unspecified_type Exact_integer;
#else // not DOXYGEN_RUNNING #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; typedef mpz_class Exact_integer;
#elif defined(CGAL_USE_GMP)
#elif CGAL_USE_GMP #if defined(CGAL_USE_BOOST_MP)
# ifdef CGAL_USE_BOOST_MP typedef BOOST_gmp_arithmetic_kernel::Integer Exact_integer;
typedef boost::multiprecision::mpz_int Exact_integer; #else
# else
typedef Gmpz Exact_integer; typedef Gmpz Exact_integer;
# endif #endif
#elif defined(CGAL_USE_LEDA)
#elif CGAL_USE_LEDA
typedef leda_integer Exact_integer; typedef leda_integer Exact_integer;
#elif defined(CGAL_USE_BOOST_MP)
#elif CGAL_USE_CORE typedef BOOST_cpp_arithmetic_kernel::Integer Exact_integer;
#elif defined(CGAL_USE_CORE)
typedef CORE::BigInt Exact_integer; typedef CORE::BigInt Exact_integer;
#else
#elif defined CGAL_USE_BOOST_MP #error "ERROR: Cannot determine a BigInt type!"
typedef boost::multiprecision::cpp_int Exact_integer;
#endif // CGAL_USE_CORE #endif // CGAL_USE_CORE
#endif // BOOST_VERSION > 107800
#endif // not DOXYGEN_RUNNING #endif // not DOXYGEN_RUNNING
} /* end namespace CGAL */ } /* end namespace CGAL */

View File

@ -40,7 +40,7 @@
# include <CGAL/leda_real.h> # include <CGAL/leda_real.h>
#endif #endif
#ifdef CGAL_USE_CORE #ifdef CGAL_USE_CORE
// # include <CGAL/CORE_Expr.h> // # include <CGAL/CORE_Expr.h>
namespace CORE { namespace CORE {
class Expr; class Expr;
} }
@ -54,23 +54,39 @@ namespace CGAL { namespace internal {
// It should support the built-in types. // It should support the built-in types.
template < typename > template < typename >
struct Exact_field_selector 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 #ifdef CGAL_USE_GMPXX
{ typedef mpq_class Type; }; { typedef mpq_class Type; };
#elif defined(CGAL_USE_GMP) #elif defined(CGAL_USE_GMP)
# if defined(CGAL_USE_BOOST_MP) #if defined(CGAL_USE_BOOST_MP)
{ typedef boost::multiprecision::mpq_rational Type; }; { typedef BOOST_gmp_arithmetic_kernel::Rational Type; };
# else #else
{ typedef Gmpq Type; }; { typedef Gmpq Type; };
# endif #endif
#elif defined(CGAL_USE_LEDA) #elif defined(CGAL_USE_LEDA)
{ typedef leda_rational Type; }; { 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 // 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. // 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; }; { typedef BOOST_cpp_arithmetic_kernel::Rational Type; };
#endif
#else #else
{ typedef Quotient<MP_Float> Type; }; { typedef Quotient<MP_Float> Type; };
#endif #endif
#endif // BOOST_VERSION > 107800
// By default, a field is a safe choice of ring. // By default, a field is a safe choice of ring.
template < typename T > template < typename T >

View File

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

View File

@ -13,6 +13,7 @@
#define CGAL_BOOST_MP_H #define CGAL_BOOST_MP_H
#include <CGAL/config.h> #include <CGAL/config.h>
#include <CGAL/number_utils.h>
// It is easier to disable this number type completely for old versions. // 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 // 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) (!defined _MSC_VER || BOOST_VERSION >= 107000)
#define CGAL_USE_BOOST_MP 1 #define CGAL_USE_BOOST_MP 1
#include <CGAL/Quotient.h>
#include <CGAL/functional.h> // *ary_function #include <CGAL/functional.h> // *ary_function
#include <CGAL/number_type_basic.h> #include <CGAL/number_type_basic.h>
#include <CGAL/Modular_traits.h> #include <CGAL/Modular_traits.h>
@ -139,6 +141,227 @@ struct Algebraic_structure_traits<boost::multiprecision::detail::expression<T1,T
// Real_embeddable_traits // 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> template <class NT>
struct RET_boost_mp_base struct RET_boost_mp_base
: public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > { : public INTERN_RET::Real_embeddable_traits_base< NT , CGAL::Tag_true > {
@ -192,24 +415,41 @@ struct RET_boost_mp_base
struct To_interval struct To_interval
: public CGAL::cpp98::unary_function< Type, std::pair< double, double > > { : public CGAL::cpp98::unary_function< Type, std::pair< double, double > > {
std::pair<double, double> std::pair<double, double>
operator()(const Type& x) const { operator()(const Type& x) const {
// See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better
// assume the conversion is within 1 ulp // See if https://github.com/boostorg/multiprecision/issues/108 suggests anything better
// adding IA::smallest() doesn't work because inf-e=inf, even rounded down. // assume the conversion is within 1 ulp
double i = x.template convert_to<double>(); // adding IA::smallest() doesn't work because inf-e=inf, even rounded down.
double s = i;
double inf = std::numeric_limits<double>::infinity(); // We must use to_nearest here.
int cmp = x.compare(i); double i;
if (cmp > 0) { const double inf = std::numeric_limits<double>::infinity();
s = nextafter(s, +inf); {
CGAL_assertion(x.compare(s) < 0); 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());
} }
else if (cmp < 0) { }
i = nextafter(i, -inf); double s = i;
CGAL_assertion(x.compare(i) > 0); CGAL_assertion(CGAL::abs(i) != inf && CGAL::abs(s) != inf);
}
return std::pair<double, double> (i, s); // 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);
}
else if (cmp < 0) {
i = nextafter(i, -inf);
CGAL_assertion(x.compare(i) > 0);
}
return std::pair<double, double>(i, s);
} }
}; };
}; };
@ -219,11 +459,30 @@ struct RET_boost_mp;
template <class NT> template <class NT>
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_integer> > 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> template <class NT>
struct RET_boost_mp <NT, boost::mpl::int_<boost::multiprecision::number_kind_rational> > 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 #ifdef CGAL_USE_MPFR
// Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary. // Because of these full specializations, things get instantiated more eagerly. Make them artificially partial if necessary.
@ -607,6 +866,25 @@ namespace internal {
#endif #endif
} // namespace internal } // 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 } //namespace CGAL
#include <CGAL/BOOST_MP_arithmetic_kernel.h> #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 # 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("Quotient_new.cpp")
create_single_source_cgal_program("test_nt_Coercion_traits.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 const unsigned int seed = choose_parameter(get_parameter(np, internal_np::random_seed), -1); // undocumented
CGAL::Random fixed_seed_rng(seed); 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; CGAL::get_default_random() : fixed_seed_rng;
#ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG #ifdef CGAL_OPTIMAL_BOUNDING_BOX_DEBUG

View File

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

View File

@ -39,8 +39,6 @@ bool write_OFF_PSP(std::ostream& os,
const PointRange& points, const PointRange& points,
const CGAL_NP_CLASS& np = CGAL::parameters::default_values()) 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; using CGAL::parameters::is_default_parameter;
// basic geometric types // 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::Const_point_map PointMap;
typedef typename NP_helper::Normal_map NormalMap; 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); PointMap point_map = NP_helper::get_const_point_map(points, np);
NormalMap normal_map = NP_helper::get_normal_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. // or vertex j is in the k-neighborhood of vertex i.
Riemannian_graph riemannian_graph; 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, riemannian_graph = create_riemannian_graph(points,
point_map, normal_map, index_map, point_map, normal_map, index_map,
Default_constrained_map<typename PointRange::iterator> Default_constrained_map<typename PointRange::iterator>

View File

@ -235,7 +235,7 @@ public:
typedef typename Point_set_processing_3::GetPlaneIndexMap<NamedParameters>::type PlaneIndexMap; 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(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"); "Error: no plane index map");
PointMap point_map = NP_helper::get_const_point_map(points, np); 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_vector_map default_fvmap;
Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal), Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal),
Default_map(default_fvmap)); 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 #ifdef CGAL_PMP_COMPUTE_NORMAL_DEBUG_PP
std::cout << "<----- compute vertex normal at " << get(vpmap, v) 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_dmap>::type Face_normal_map;
Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal), Face_normal_map face_normals = choose_parameter(get_parameter(np, internal_np::face_normal),
get(Face_normal_tag(), pmesh)); 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) if(must_compute_face_normals)
compute_face_normals(pmesh, face_normals, np); 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)) for(vertex_descriptor v: vertices(pmesh))
if (!keep_vertex[v]) if (!keep_vertex[v])
vertices_to_remove.push_back(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) for (vertex_descriptor v : vertices_to_remove)
remove_vertex(v, pmesh); remove_vertex(v, pmesh);
else else
@ -1014,7 +1014,7 @@ void split_connected_components_impl(FIMap fim,
get(CGAL::dynamic_face_property_t<faces_size_type>(), tm)); get(CGAL::dynamic_face_property_t<faces_size_type>(), tm));
faces_size_type nb_patches = 0; 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( nb_patches = CGAL::Polygon_mesh_processing::connected_components(
tm, pidmap, CGAL::parameters::face_index_map(fim) 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))); User_visitor uv(choose_parameter<User_visitor>(get_parameter(np1, internal_np::visitor)));
static const bool handle_non_manifold_features = static const bool handle_non_manifold_features =
!parameters::Is_default<internal_np::non_manifold_feature_map_t, NamedParameters1>::value || !parameters::is_default_parameter<NamedParameters1, internal_np::non_manifold_feature_map_t>::value ||
!parameters::Is_default<internal_np::non_manifold_feature_map_t, NamedParameters2>::value; !parameters::is_default_parameter<NamedParameters2, internal_np::non_manifold_feature_map_t>::value;
// surface intersection algorithm call // surface intersection algorithm call
typedef Corefinement::No_extra_output_from_corefinement<TriangleMesh> Ob; 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(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; use_rs = false;
} }
@ -463,7 +463,7 @@ struct Triangle_structure_sampler_for_triangle_mesh
pmap = choose_parameter(get_parameter(np, internal_np::vertex_point), pmap = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(vertex_point, tm)); 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)); rnd = CGAL::Random(choose_parameter(get_parameter(np, internal_np::random_seed),0));
min_sq_edge_length = (std::numeric_limits<double>::max)(); 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; using parameters::is_default_parameter;
min_sq_edge_length = (std::numeric_limits<double>::max)(); 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)); 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); 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; 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()) if(visitor.stop())
return 0; 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)); get_property_map(vertex_point, tm_B));
internal::Snapping_default_visitor<PolygonMesh> default_visitor; 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(); visitor.start_vertex_vertex_phase();
if(visitor.stop()) if(visitor.stop())

View File

@ -218,7 +218,7 @@ void isotropic_remeshing(const FaceRange& faces
#endif #endif
static const bool need_aabb_tree = 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; typedef typename GetGeomTraits<PM, NamedParameters>::type GT;
GT gt = choose_parameter<GT>(get_parameter(np, internal_np::geom_traits)); 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( FPMap fpmap = choose_parameter(
get_parameter(np, internal_np::face_patch), get_parameter(np, internal_np::face_patch),
internal::Connected_components_pmap<PM, FIMap>(faces, pmesh, ecmap, fimap, 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) #if !defined(CGAL_NO_PRECONDITIONS)
|| protect // face patch map is used to identify patch border edges to check protected edges are short enough || protect // face patch map is used to identify patch border edges to check protected edges are short enough
#endif #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)); 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 // 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_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>(); 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); 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), VPM vpmap = choose_parameter(get_parameter(np, internal_np::vertex_point),
get_const_property_map(boost::vertex_point, tmesh)); 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); const unsigned int maximum_number = choose_parameter(get_parameter(np, internal_np::maximum_number), 0);
if(do_limit && maximum_number == 0) if(do_limit && maximum_number == 0)
{ {

View File

@ -404,7 +404,7 @@ public:
else else
deg_faces.insert(f); 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); init(epsilon);
else else
{ {
@ -513,7 +513,7 @@ public:
deg_faces.insert(f); 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); init(epsilon);
else else
{ {
@ -597,8 +597,10 @@ public:
env_faces.emplace_back(face); 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); init(epsilon);
}
else else
{ {
std::vector<double> epsilon_values; 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); bool do_project = choose_parameter(get_parameter(np, internal_np::do_project), false);
// check is a parameter has been given by the user // 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()); 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 (see \ref PkgSolverInterface). It should be noted that GLPK only manages to solve small problems, i.e., objects
with reasonably simple structure. with reasonably simple structure.
In case you are reconstructing more complex objects, you may need to consider more efficient open source 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>). <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. 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." DESCRIPTION "A library for image processing."
PURPOSE "Can be used for I/O (DICOM, VTU, VTP.") 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) target_link_libraries(triangulation_3_io_plugin PUBLIC scene_triangulation_3_item)
if(VTK_FOUND) if(VTK_FOUND)

View File

@ -168,7 +168,7 @@ void Polyhedron_demo_join_and_split_polyhedra_plugin::on_actionSplitPolyhedra_tr
scene->addItem(group); scene->addItem(group);
for(FaceGraph& poly : new_polyhedra) 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->setName(tr("%1 - CC %2").arg(item->name()).arg(cc));
new_item->setColor(color_map[cc]); new_item->setColor(color_map[cc]);
++cc; ++cc;

View File

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

View File

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

View File

@ -26,7 +26,7 @@ configure()
{ {
echo "Configuring... " 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" \ -DCGAL_DIR="$CGAL_DIR" \
.' ; then .' ; 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); 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>()) || 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>()) || !(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>()) || !(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>())) !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value))
{ {
return CGAL::IO::internal::read_OFF_BGL(in, P, np); return CGAL::IO::internal::read_OFF_BGL(in, P, np);
} }
CGAL::scan_OFF(in, P, verbose); 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); Def_VPM def_vpm = get_property_map(CGAL::vertex_point, P);
VPM vpm = choose_parameter(get_parameter(np, internal_np::vertex_point), 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::get_parameter;
using parameters::is_default_parameter; using parameters::is_default_parameter;
if(!(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_color_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>()) || !(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>()) || !(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>())) !(is_default_parameter<CGAL_NP_CLASS, internal_np::vertex_texture_map_t>::value))
{ {
return CGAL::IO::internal::write_OFF_BGL(out, P, np); 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[1],
eigen_vectors[2]); eigen_vectors[2]);
plane = Plane(c,normal); 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 } // end regular case
} }

View File

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

View File

@ -80,7 +80,6 @@ REFERENCE_PLATFORMS_DIR="must_be_set_in_.autocgalrc"
ACTUAL_DIR=`pwd` ACTUAL_DIR=`pwd`
RSH="rsh" RSH="rsh"
NICE_OPTIONS="-19" NICE_OPTIONS="-19"
CMAKE_GENERATOR=""
USE_TARGZ="n" USE_TARGZ="n"
USE_TARBZ="n" USE_TARBZ="n"
PLATFORMS="" PLATFORMS=""
@ -506,16 +505,12 @@ build_cgal_on_host()
cat >> "${CGAL_BINARY_DIR}/localbuildscript" <<EOF cat >> "${CGAL_BINARY_DIR}/localbuildscript" <<EOF
CGAL_BINARY_DIR='${CGAL_BINARY_DIR}'; CGAL_BINARY_DIR='${CGAL_BINARY_DIR}';
if [ -z "\$CMAKE_GENERATOR" ]; then
CMAKE_GENERATOR='${CMAKE_GENERATOR}';
fi
MAKE_CMD='${MAKE_CMD}'; MAKE_CMD='${MAKE_CMD}';
export CMAKE_GENERATOR;
export MAKE_CMD; export MAKE_CMD;
export CGAL_BINARY_DIR; export CGAL_BINARY_DIR;
cd '${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 \\ VERBOSE=1 \\
../../..; ../../..;
${MAKE_CMD} VERBOSE=ON -k -fMakefile ; ${MAKE_CMD} VERBOSE=ON -k -fMakefile ;
@ -604,14 +599,10 @@ else
fi fi
CGAL_TEST_HOST='${HOST}'; CGAL_TEST_HOST='${HOST}';
CGAL_TEST_PLATFORM='${PLATFORM}'; CGAL_TEST_PLATFORM='${PLATFORM}';
if [ -z "\$CMAKE_GENERATOR" ]; then
CMAKE_GENERATOR='${CMAKE_GENERATOR}';
fi
MAKE_CMD='${MAKE_CMD}' MAKE_CMD='${MAKE_CMD}'
export CGAL_TESTER CGAL_TESTER_NAME CGAL_TESTER_ADDRESS; export CGAL_TESTER CGAL_TESTER_NAME CGAL_TESTER_ADDRESS;
export CGAL_DIR; export CGAL_DIR;
export CGAL_TEST_HOST CGAL_TEST_PLATFORM; export CGAL_TEST_HOST CGAL_TEST_PLATFORM;
export CMAKE_GENERATOR;
export MAKE_CMD; export MAKE_CMD;
EOF EOF
@ -884,43 +875,6 @@ else
done done
fi 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 # Make that file writable (lockfile create read-only files
chmod u+w "$LOCK_FILE" chmod u+w "$LOCK_FILE"
# Put the PID of current process in the lock file # Put the PID of current process in the lock file

View File

@ -80,7 +80,7 @@ configure()
{ {
echo "Configuring... " 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" \ -DCGAL_DIR="$CGAL_DIR" \
--no-warn-unused-cli \ --no-warn-unused-cli \
.' ; then .' ; then

View File

@ -201,7 +201,7 @@ for i in `echo $nps`; do
echo " CGAL::parameters::${i}(A()).${i}(A());" >> main.cpp echo " CGAL::parameters::${i}(A()).${i}(A());" >> main.cpp
done done
echo "}" >> main.cpp 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" echo "ERROR: At least one documented named parameter does not exist"
cd - cd -
rm -r $tmp_dir rm -r $tmp_dir

View File

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

View File

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

View File

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

View File

@ -293,10 +293,10 @@ namespace Planes {
using parameters::get_parameter; using parameters::get_parameter;
using parameters::choose_parameter; using parameters::choose_parameter;
using parameters::is_default_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"); "Error: no plane index map");
const PlaneIndexMap index_map = const PlaneIndexMap index_map =

View File

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

View File

@ -25,7 +25,7 @@ configure()
{ {
echo "Configuring... " 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" \ -DCGAL_DIR="$CGAL_DIR" \
.' ; then .' ; then

View File

@ -273,7 +273,7 @@ namespace CGAL {
/// classes, i.e., `CGAL::GLPK_mixed_integer_program_traits` or /// classes, i.e., `CGAL::GLPK_mixed_integer_program_traits` or
/// `CGAL::SCIP_mixed_integer_program_traits`. Alternatively, use /// `CGAL::SCIP_mixed_integer_program_traits`. Alternatively, use
/// `CGAL::Mixed_integer_program_traits` as a base to derive a new model /// `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 /// <a href = "https://www.gurobi.com/"> Gurobi </a> for better
/// performance). /// performance).
/// ///

View File

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

View File

@ -53,13 +53,13 @@ template<typename PolygonMesh,
class GetVertexColorMap class GetVertexColorMap
{ {
typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Vertex_index, typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Vertex_index,
CGAL::IO::Color> DefaultMap; CGAL::IO::Color> DefaultMap;
typedef DefaultMap DefaultMap_const; typedef DefaultMap DefaultMap_const;
public: public:
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_color_map_t, typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_color_map_t,
NamedParameters, DefaultMap>::type type; NamedParameters, DefaultMap>::type type;
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_color_map_t, typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_color_map_t,
NamedParameters, DefaultMap_const>::type const_type; NamedParameters, DefaultMap_const>::type const_type;
}; };
template<typename PolygonMesh, typename K, template<typename PolygonMesh, typename K,
@ -67,8 +67,8 @@ template<typename PolygonMesh, typename K,
class GetVertexTextureMap class GetVertexTextureMap
{ {
typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Vertex_index, typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Vertex_index,
typename K::Point_2> DefaultMap; typename K::Point_2> DefaultMap;
typedef DefaultMap DefaultMap_const; typedef DefaultMap DefaultMap_const;
public: public:
typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_texture_map_t, typedef typename internal_np::Lookup_named_param_def<internal_np::vertex_texture_map_t,
@ -82,7 +82,7 @@ template<typename PolygonMesh,
class GetFaceColorMap class GetFaceColorMap
{ {
typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Face_index, typedef typename PolygonMesh::template Property_map<typename PolygonMesh::Face_index,
CGAL::IO::Color> DefaultMap; CGAL::IO::Color> DefaultMap;
typedef DefaultMap DefaultMap_const; typedef DefaultMap DefaultMap_const;
public: public:
@ -100,9 +100,9 @@ bool read_OFF_with_or_without_fcolors(std::istream& is,
{ {
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Face_index Face_index; typedef typename Mesh::Face_index Face_index;
typedef CGAL::IO::Color Color; typedef CGAL::IO::Color Color;
typedef typename GetFaceColorMap<Mesh, CGAL_NP_CLASS>::type FCM; typedef typename GetFaceColorMap<Mesh, CGAL_NP_CLASS>::type FCM;
using parameters::choose_parameter; using parameters::choose_parameter;
using parameters::is_default_parameter; using parameters::is_default_parameter;
@ -110,7 +110,7 @@ bool read_OFF_with_or_without_fcolors(std::istream& is,
typename Mesh::template Property_map<Face_index, Color> fcm; 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()) if(!is_fcm_requested && scanner.has_colors())
{ {
bool created; bool created;
@ -139,7 +139,7 @@ bool read_OFF_with_or_without_vtextures(std::istream& is,
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::Vertex_index Vertex_index;
typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K; typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K;
typedef typename K::Point_2 Texture; typedef typename K::Point_2 Texture;
typedef typename GetVertexTextureMap<Mesh, K, CGAL_NP_CLASS>::type VTM; typedef typename GetVertexTextureMap<Mesh, K, CGAL_NP_CLASS>::type VTM;
@ -149,7 +149,7 @@ bool read_OFF_with_or_without_vtextures(std::istream& is,
typename Mesh::template Property_map<Vertex_index, Texture> vtm; 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()) if(!is_vtm_requested && scanner.has_textures())
{ {
bool created; 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; 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()) if(!is_vcm_requested && scanner.has_colors())
{ {
bool created; 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; 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()) if(!is_vnm_requested && scanner.has_normals())
{ {
bool created; bool created;
@ -324,10 +324,6 @@ bool read_OFF(std::istream& is,
Surface_mesh<Point>& sm, Surface_mesh<Point>& sm,
const CGAL_NP_CLASS& np = parameters::default_values()) 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(); std::streampos pos = is.tellg();
CGAL::File_scanner_OFF scanner(is, false); CGAL::File_scanner_OFF scanner(is, false);
is.seekg(pos); is.seekg(pos);
@ -388,13 +384,11 @@ bool write_OFF_with_or_without_fcolors(std::ostream& os,
{ {
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Face_index Face_index; typedef typename Mesh::Face_index Face_index;
typedef CGAL::IO::Color Color; typedef CGAL::IO::Color Color;
using parameters::choose_parameter;
using parameters::is_default_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; typename Mesh::template Property_map<Face_index, Color> fcolors;
bool has_internal_fcolors; bool has_internal_fcolors;
@ -414,14 +408,12 @@ bool write_OFF_with_or_without_vtextures(std::ostream& os,
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::Vertex_index Vertex_index;
typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K; typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K;
typedef typename K::Point_2 Texture; typedef typename K::Point_2 Texture;
using parameters::choose_parameter;
using parameters::is_default_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; typename Mesh::template Property_map<Vertex_index, Texture> vtextures;
bool has_internal_vtextures; bool has_internal_vtextures;
@ -440,13 +432,11 @@ bool write_OFF_with_or_without_vcolors(std::ostream& os,
{ {
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::Vertex_index Vertex_index;
typedef CGAL::IO::Color Color; typedef CGAL::IO::Color Color;
using parameters::choose_parameter;
using parameters::is_default_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; typename Mesh::template Property_map<Vertex_index, Color> vcolors;
bool has_internal_vcolors; bool has_internal_vcolors;
@ -466,14 +456,12 @@ bool write_OFF_with_or_without_vnormals(std::ostream& os,
typedef Surface_mesh<Point> Mesh; typedef Surface_mesh<Point> Mesh;
typedef typename Mesh::Vertex_index Vertex_index; typedef typename Mesh::Vertex_index Vertex_index;
typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K; typedef typename GetK<Surface_mesh<Point>, CGAL_NP_CLASS>::Kernel K;
typedef typename K::Vector_3 Normal; typedef typename K::Vector_3 Normal;
using parameters::choose_parameter;
using parameters::is_default_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; typename Mesh::template Property_map<Vertex_index, Normal> vnormals;
bool has_internal_vnormals; bool has_internal_vnormals;
@ -559,11 +547,9 @@ bool write_OFF(std::ostream& os,
const Surface_mesh<Point>& sm, const Surface_mesh<Point>& sm,
const CGAL_NP_CLASS& np = parameters::default_values()) const CGAL_NP_CLASS& np = parameters::default_values())
{ {
using parameters::choose_parameter;
using parameters::is_default_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) if(has_vpoints)
return internal::write_OFF_with_or_without_vnormals(os, sm, np); return internal::write_OFF_with_or_without_vnormals(os, sm, np);

View File

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

View File

@ -341,7 +341,7 @@ public:
{ {
typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base; typedef Properties::Property_map_base<I, T, Property_map<I, T> > Base;
typedef typename Base::reference reference; typedef typename Base::reference reference;
Property_map() : Base() {} Property_map() = default;
Property_map(const Base& pm): Base(pm) {} 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. /// Copy constructor: copies `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh(const Surface_mesh& rhs) { *this = rhs; } 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. /// assigns `rhs` to `*this`. Performs a deep copy of all properties.
Surface_mesh& operator=(const Surface_mesh& rhs); 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. /// assigns `rhs` to `*this`. Does not copy custom properties.
Surface_mesh& assign(const Surface_mesh& rhs); Surface_mesh& assign(const Surface_mesh& rhs);

View File

@ -230,6 +230,40 @@ void properties () {
assert(created == false); 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() int main()
{ {
@ -244,6 +278,7 @@ int main()
border_vertex_check(); border_vertex_check();
point_position_accessor(); point_position_accessor();
properties(); properties();
move();
std::cout << "done" << std::endl; std::cout << "done" << std::endl;
return 0; return 0;
} }

View File

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

View File

@ -3,5 +3,6 @@
\example Surface_mesh_skeletonization/MCF_Skeleton_example.cpp \example Surface_mesh_skeletonization/MCF_Skeleton_example.cpp
\example Surface_mesh_skeletonization/segmentation_example.cpp \example Surface_mesh_skeletonization/segmentation_example.cpp
\example Surface_mesh_skeletonization/MCF_Skeleton_sm_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 \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) find_package(Eigen3 3.2.0) #(requires 3.2.0 or greater)
include(CGAL_Eigen3_support) 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) if(TARGET CGAL::Eigen3_support)
create_single_source_cgal_program("simple_mcfskel_example.cpp") create_single_source_cgal_program("simple_mcfskel_example.cpp")
create_single_source_cgal_program("simple_mcfskel_sm_example.cpp") create_single_source_cgal_program("simple_mcfskel_sm_example.cpp")
@ -28,6 +36,11 @@ if(TARGET CGAL::Eigen3_support)
segmentation_example) segmentation_example)
target_link_libraries(${target} PUBLIC CGAL::Eigen3_support) target_link_libraries(${target} PUBLIC CGAL::Eigen3_support)
endforeach() 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() else()
message( message(
STATUS 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 rm CMakeCache.txt
if [ -f "$INIT_FILE" ] if [ -f "$INIT_FILE" ]
then 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_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \ -DCGAL_CXX_FLAGS:STRING="$CGAL_CXX_FLAGS $TESTSUITE_CXXFLAGS" \
-DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \ -DCGAL_EXE_LINKER_FLAGS="$CGAL_EXE_LINKER_FLAGS $TESTSUITE_LDFLAGS" \
@ -43,7 +43,7 @@ configure()
echo " ERROR: configuration" >> $ERRORFILE echo " ERROR: configuration" >> $ERRORFILE
fi fi
else 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_DIR="$CGAL_DIR" \
-DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \ -DCGAL_CXX_FLAGS:STRING="$TESTSUITE_CXXFLAGS" \
-DCGAL_EXE_LINKER_FLAGS="$TESTSUITE_LDFLAGS" \ -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) if(!is)
return 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); tr._tds.set_dimension(d);
V.resize(n+1);
std::vector< Vertex_handle > V(n+1);
V[0] = tr.infinite_vertex(); // the infinite vertex is numbered 0 V[0] = tr.infinite_vertex(); // the infinite vertex is numbered 0
for(std::size_t i=1; i <= n; i++) 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) include(${CGAL_MODULES_DIR}/CGAL_add_test.cmake)
cgal_add_compilation_test( Triangulation_on_sphere_2_Demo ) cgal_add_compilation_test( Triangulation_on_sphere_2_Demo )
else() 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() endif()

View File

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

View File

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