mirror of https://github.com/CGAL/cgal
Allow lambdas (or other callables) as MeshDomainField_3
That patch uses C++11 `<type_traits>`, and `boost::callable_traits::is_invocable` that is available only since 1.66. If Boost<1.66, then the previous behavior (testing `Sizing_field::FT`) is kept. Fix issue https://github.com/CGAL/cgal/issues/3005
This commit is contained in:
parent
268cb59ce1
commit
22d6d9ebd8
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) 2019 GeometryFactory Sarl (France).
|
||||
// All rights reserved.
|
||||
//
|
||||
// This file is part of CGAL (www.cgal.org).
|
||||
// You can redistribute it and/or modify it under the terms of the GNU
|
||||
// General Public License as published by the Free Software Foundation,
|
||||
// either version 3 of the License, or (at your option) any later version.
|
||||
//
|
||||
// Licensees holding a valid commercial license may use this file in
|
||||
// accordance with the commercial license agreement provided with the software.
|
||||
//
|
||||
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
||||
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
//
|
||||
// $URL$
|
||||
// $Id$
|
||||
// SPDX-License-Identifier: GPL-3.0+
|
||||
//
|
||||
//
|
||||
// Author(s) : Laurent Rineau
|
||||
//
|
||||
//******************************************************************************
|
||||
// File Description :
|
||||
// Mesh_facet_criteria_3 class.
|
||||
//******************************************************************************
|
||||
|
||||
#ifndef CGAL_MESH_3_IS_MESH_DOMAIN_FIELD_3_H
|
||||
#define CGAL_MESH_3_IS_MESH_DOMAIN_FIELD_3_H
|
||||
|
||||
#include <CGAL/license/Mesh_3.h>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if BOOST_VERSION >= 106600
|
||||
# include <boost/callable_traits/is_invocable.hpp>
|
||||
#else
|
||||
# include <boost/mpl/has_xxx.hpp>
|
||||
#endif
|
||||
|
||||
#include <CGAL/tags.h>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Mesh_3 {
|
||||
#if BOOST_VERSION >= 106600
|
||||
template <typename Tr, typename Type>
|
||||
struct Is_mesh_domain_field_3 :
|
||||
public CGAL::Boolean_tag
|
||||
<
|
||||
boost::callable_traits::is_invocable_r<
|
||||
typename Tr::FT,
|
||||
Type,
|
||||
typename Tr::Bare_point,
|
||||
int,
|
||||
typename Tr::Vertex::Index
|
||||
>::value
|
||||
>
|
||||
{};
|
||||
#else // Boost before 1.66
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(FT)
|
||||
template <typename Tr, typename Type>
|
||||
struct Is_mesh_domain_field_3 : public Boolean_tag<has_FT<Type>::value>
|
||||
{};
|
||||
#endif // Boost before 1.66
|
||||
} // end namespace Mesh_3
|
||||
} // end namespace CGAL
|
||||
|
||||
#endif // CGAL_MESH_3_IS_MESH_DOMAIN_FIELD_3_H
|
||||
|
|
@ -27,6 +27,14 @@
|
|||
|
||||
|
||||
#include <CGAL/Mesh_3/mesh_standard_cell_criteria.h>
|
||||
#include <CGAL/Mesh_3/Is_mesh_domain_field_3.h>
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#if BOOST_VERSION >= 106600
|
||||
# include <boost/callable_traits/is_invocable.hpp>
|
||||
#endif
|
||||
|
||||
#include <type_traits>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -65,13 +73,16 @@ public:
|
|||
init_radius_edge(radius_edge_bound);
|
||||
}
|
||||
|
||||
// Nb: SFINAE (dummy) to avoid wrong matches with built-in numerical types
|
||||
// Nb: SFINAE to avoid wrong matches with built-in numerical types
|
||||
// as int.
|
||||
template <typename Sizing_field>
|
||||
Mesh_cell_criteria_3(const FT& radius_edge_bound,
|
||||
const Sizing_field& radius_bound,
|
||||
typename Sizing_field::FT /*dummy*/ = 0)
|
||||
{
|
||||
typename std::enable_if<
|
||||
Mesh_3::Is_mesh_domain_field_3<Tr,Sizing_field>::value
|
||||
>::type* = 0
|
||||
)
|
||||
{
|
||||
init_radius(radius_bound);
|
||||
|
||||
if ( FT(0) != radius_edge_bound )
|
||||
|
|
|
|||
|
|
@ -30,7 +30,8 @@
|
|||
|
||||
|
||||
#include <CGAL/Mesh_constant_domain_field_3.h>
|
||||
#include <boost/type_traits.hpp>
|
||||
#include <CGAL/Mesh_3/Is_mesh_domain_field_3.h>
|
||||
#include <type_traits>
|
||||
|
||||
namespace CGAL {
|
||||
namespace Mesh_3 {
|
||||
|
|
@ -55,24 +56,22 @@ namespace internal {
|
|||
virtual Sizing_field_interface* clone() const = 0;
|
||||
};
|
||||
|
||||
template < typename Sizing_field >
|
||||
template < typename Sizing_field,
|
||||
typename FT,
|
||||
typename Point_3,
|
||||
typename Index>
|
||||
struct Sizing_field_container
|
||||
: public Sizing_field_interface < typename Sizing_field::FT,
|
||||
typename Sizing_field::Point_3,
|
||||
typename Sizing_field::Index >
|
||||
: public Sizing_field_interface < FT,
|
||||
Point_3,
|
||||
Index >
|
||||
{
|
||||
typedef Sizing_field_interface <
|
||||
typename Sizing_field::FT,
|
||||
typename Sizing_field::Point_3,
|
||||
typename Sizing_field::Index > Base;
|
||||
|
||||
typedef Sizing_field_container<Sizing_field> Self;
|
||||
typedef Sizing_field_interface < FT,
|
||||
Point_3,
|
||||
Index > Base;
|
||||
|
||||
typedef Sizing_field_container<Sizing_field, FT, Point_3, Index> Self;
|
||||
|
||||
public:
|
||||
typedef typename Base::FT FT;
|
||||
typedef typename Base::Point_3 Point_3;
|
||||
typedef typename Base::Index Index;
|
||||
|
||||
Sizing_field_container(const Sizing_field& s) : s_(s) {}
|
||||
virtual ~Sizing_field_container() {}
|
||||
|
||||
|
|
@ -109,23 +108,25 @@ public:
|
|||
/// Constructors
|
||||
Mesh_edge_criteria_3(const FT& value)
|
||||
: p_size_(new Mesh_3::internal::Sizing_field_container<
|
||||
Mesh_constant_domain_field_3<Gt,Index> >(value))
|
||||
Mesh_constant_domain_field_3<Gt,Index> ,
|
||||
FT,
|
||||
Point_3,
|
||||
Index>(value))
|
||||
{}
|
||||
|
||||
// Nb: SFINAE (dummy) to avoid wrong matches with built-in numerical types
|
||||
|
||||
// Nb: SFINAE to avoid wrong matches with built-in numerical types
|
||||
// as int.
|
||||
template < typename Sizing_field >
|
||||
Mesh_edge_criteria_3(const Sizing_field& size,
|
||||
typename Sizing_field::FT /*dummy*/ = 0 )
|
||||
Mesh_edge_criteria_3
|
||||
(
|
||||
const Sizing_field& size,
|
||||
typename std::enable_if<Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field>::value>::type* = 0
|
||||
)
|
||||
{
|
||||
CGAL_static_assertion((boost::is_same<typename Sizing_field::FT,
|
||||
FT>::value));
|
||||
CGAL_static_assertion((boost::is_same<typename Sizing_field::Point_3,
|
||||
Point_3>::value));
|
||||
CGAL_static_assertion((boost::is_same<typename Sizing_field::Index,
|
||||
Index>::value));
|
||||
|
||||
p_size_ = new Mesh_3::internal::Sizing_field_container<Sizing_field>(size);
|
||||
p_size_ = new Mesh_3::internal::Sizing_field_container<Sizing_field,
|
||||
FT,
|
||||
Point_3,
|
||||
Index>(size);
|
||||
}
|
||||
|
||||
Mesh_edge_criteria_3(const Self& rhs)
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <CGAL/Mesh_3/mesh_standard_facet_criteria.h>
|
||||
#include <CGAL/Mesh_facet_topology.h>
|
||||
#include <CGAL/Mesh_3/Is_mesh_domain_field_3.h>
|
||||
|
||||
namespace CGAL {
|
||||
|
||||
|
|
@ -59,83 +60,21 @@ public:
|
|||
/**
|
||||
* @brief Constructor
|
||||
*/
|
||||
Mesh_facet_criteria_3(const FT& angle_bound,
|
||||
const FT& radius_bound,
|
||||
const FT& distance_bound,
|
||||
const Mesh_facet_topology topology =
|
||||
FACET_VERTICES_ON_SURFACE)
|
||||
{
|
||||
if ( FT(0) != angle_bound )
|
||||
init_aspect(angle_bound);
|
||||
|
||||
if ( FT(0) != radius_bound )
|
||||
init_radius_bound(radius_bound);
|
||||
|
||||
if ( FT(0) != distance_bound )
|
||||
init_distance_bound(distance_bound);
|
||||
|
||||
init_topo(topology);
|
||||
}
|
||||
|
||||
// Nb: SFINAE (dummy) to avoid wrong matches with built-in numerical types
|
||||
// as int.
|
||||
template < typename Sizing_field >
|
||||
Mesh_facet_criteria_3(const FT& angle_bound,
|
||||
const Sizing_field& radius_bound,
|
||||
const FT& distance_bound,
|
||||
const Mesh_facet_topology topology =
|
||||
FACET_VERTICES_ON_SURFACE,
|
||||
typename Sizing_field::FT /*dummy*/ = 0)
|
||||
{
|
||||
if ( FT(0) != angle_bound )
|
||||
init_aspect(angle_bound);
|
||||
|
||||
init_radius_field(radius_bound);
|
||||
|
||||
if ( FT(0) != distance_bound )
|
||||
init_distance_bound(distance_bound);
|
||||
|
||||
init_topo(topology);
|
||||
}
|
||||
|
||||
// Nb: SFINAE (dummy) to avoid wrong matches with built-in numerical types
|
||||
// as int.
|
||||
template < typename Sizing_field >
|
||||
Mesh_facet_criteria_3(const FT& angle_bound,
|
||||
const FT& radius_bound,
|
||||
const Sizing_field& distance_bound,
|
||||
const Mesh_facet_topology topology =
|
||||
FACET_VERTICES_ON_SURFACE,
|
||||
typename Sizing_field::FT /*dummy*/ = 0)
|
||||
{
|
||||
if ( FT(0) != angle_bound )
|
||||
init_aspect(angle_bound);
|
||||
|
||||
if ( FT(0) != radius_bound )
|
||||
init_radius_bound(radius_bound);
|
||||
|
||||
init_distance_field(distance_bound);
|
||||
|
||||
init_topo(topology);
|
||||
}
|
||||
|
||||
// Nb: SFINAE (dummy) to avoid wrong matches with built-in numerical types
|
||||
// as int.
|
||||
template < typename Sizing_field, typename Sizing_field2 >
|
||||
Mesh_facet_criteria_3(const FT& angle_bound,
|
||||
const Sizing_field & radius_bound,
|
||||
const Sizing_field2& distance_bound,
|
||||
const Mesh_facet_topology topology =
|
||||
FACET_VERTICES_ON_SURFACE,
|
||||
typename Sizing_field::FT /*dummy*/ = 0,
|
||||
typename Sizing_field2::FT /*dummy*/ = 0)
|
||||
FACET_VERTICES_ON_SURFACE)
|
||||
{
|
||||
if ( FT(0) != angle_bound )
|
||||
init_aspect(angle_bound);
|
||||
|
||||
init_radius_field(radius_bound);
|
||||
init_radius(radius_bound,
|
||||
Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field>());
|
||||
|
||||
init_distance_field(distance_bound);
|
||||
init_distance(distance_bound,
|
||||
Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field2>());
|
||||
|
||||
init_topo(topology);
|
||||
}
|
||||
|
|
@ -169,27 +108,29 @@ private:
|
|||
criteria_.add(new Aspect_criterion(angle_bound));
|
||||
}
|
||||
|
||||
void init_radius_bound(const FT& radius_bound)
|
||||
void init_radius(const FT& radius_bound, Tag_false)
|
||||
{
|
||||
if(FT(0) == radius_bound) return;
|
||||
typedef Mesh_3::Uniform_size_criterion<Tr,Visitor> Uniform_size_criterion;
|
||||
criteria_.add(new Uniform_size_criterion(radius_bound));
|
||||
}
|
||||
|
||||
template <typename Sizing_field>
|
||||
void init_radius_field(const Sizing_field& radius_bound)
|
||||
void init_radius(const Sizing_field& radius_bound, Tag_true)
|
||||
{
|
||||
typedef Mesh_3::Variable_size_criterion<Tr,Visitor,Sizing_field> Variable_size_criterion;
|
||||
criteria_.add(new Variable_size_criterion(radius_bound));
|
||||
}
|
||||
|
||||
void init_distance_bound(const FT& distance_bound)
|
||||
void init_distance(const FT& distance_bound, Tag_false)
|
||||
{
|
||||
if(FT(0) == distance_bound) return;
|
||||
typedef Mesh_3::Uniform_curvature_size_criterion<Tr,Visitor> Criterion;
|
||||
criteria_.add(new Criterion(distance_bound));
|
||||
}
|
||||
|
||||
template <typename Sizing_field>
|
||||
void init_distance_field(const Sizing_field& distance_bound)
|
||||
void init_distance(const Sizing_field& distance_bound, Tag_true)
|
||||
{
|
||||
typedef Mesh_3::Variable_curvature_size_criterion<Tr,
|
||||
Visitor,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@
|
|||
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||
#include <CGAL/make_mesh_3.h>
|
||||
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// Domain
|
||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||
typedef K::FT FT;
|
||||
|
|
@ -42,7 +44,14 @@ FT capsule_function(const Point& p)
|
|||
else if(z < FT(-5)) return base+CGAL::square(z+5);
|
||||
else return base;
|
||||
}
|
||||
|
||||
#if BOOST_VERSION >= 106600
|
||||
auto field = [](const Point& p, const int, const Mesh_domain::Index)
|
||||
{
|
||||
if(p.z() > 2) return 0.025;
|
||||
if(p.z() < -3) return 0.01;
|
||||
else return 1.;
|
||||
};
|
||||
#else
|
||||
struct Field {
|
||||
typedef ::FT FT;
|
||||
|
||||
|
|
@ -52,6 +61,7 @@ struct Field {
|
|||
else return 1;
|
||||
}
|
||||
} field;
|
||||
#endif
|
||||
|
||||
int main()
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue