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/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 {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -65,12 +73,15 @@ public:
|
||||||
init_radius_edge(radius_edge_bound);
|
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.
|
// as int.
|
||||||
template <typename Sizing_field>
|
template <typename Sizing_field>
|
||||||
Mesh_cell_criteria_3(const FT& radius_edge_bound,
|
Mesh_cell_criteria_3(const FT& radius_edge_bound,
|
||||||
const Sizing_field& radius_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);
|
init_radius(radius_bound);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,8 @@
|
||||||
|
|
||||||
|
|
||||||
#include <CGAL/Mesh_constant_domain_field_3.h>
|
#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 CGAL {
|
||||||
namespace Mesh_3 {
|
namespace Mesh_3 {
|
||||||
|
|
@ -55,24 +56,22 @@ namespace internal {
|
||||||
virtual Sizing_field_interface* clone() const = 0;
|
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
|
struct Sizing_field_container
|
||||||
: public Sizing_field_interface < typename Sizing_field::FT,
|
: public Sizing_field_interface < FT,
|
||||||
typename Sizing_field::Point_3,
|
Point_3,
|
||||||
typename Sizing_field::Index >
|
Index >
|
||||||
{
|
{
|
||||||
typedef Sizing_field_interface <
|
typedef Sizing_field_interface < FT,
|
||||||
typename Sizing_field::FT,
|
Point_3,
|
||||||
typename Sizing_field::Point_3,
|
Index > Base;
|
||||||
typename Sizing_field::Index > Base;
|
|
||||||
|
|
||||||
typedef Sizing_field_container<Sizing_field> Self;
|
typedef Sizing_field_container<Sizing_field, FT, Point_3, Index> Self;
|
||||||
|
|
||||||
public:
|
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) {}
|
Sizing_field_container(const Sizing_field& s) : s_(s) {}
|
||||||
virtual ~Sizing_field_container() {}
|
virtual ~Sizing_field_container() {}
|
||||||
|
|
||||||
|
|
@ -109,23 +108,25 @@ public:
|
||||||
/// Constructors
|
/// Constructors
|
||||||
Mesh_edge_criteria_3(const FT& value)
|
Mesh_edge_criteria_3(const FT& value)
|
||||||
: p_size_(new Mesh_3::internal::Sizing_field_container<
|
: 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.
|
// as int.
|
||||||
template < typename Sizing_field >
|
template < typename Sizing_field >
|
||||||
Mesh_edge_criteria_3(const Sizing_field& size,
|
Mesh_edge_criteria_3
|
||||||
typename Sizing_field::FT /*dummy*/ = 0 )
|
(
|
||||||
|
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,
|
p_size_ = new Mesh_3::internal::Sizing_field_container<Sizing_field,
|
||||||
FT>::value));
|
FT,
|
||||||
CGAL_static_assertion((boost::is_same<typename Sizing_field::Point_3,
|
Point_3,
|
||||||
Point_3>::value));
|
Index>(size);
|
||||||
CGAL_static_assertion((boost::is_same<typename Sizing_field::Index,
|
|
||||||
Index>::value));
|
|
||||||
|
|
||||||
p_size_ = new Mesh_3::internal::Sizing_field_container<Sizing_field>(size);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh_edge_criteria_3(const Self& rhs)
|
Mesh_edge_criteria_3(const Self& rhs)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,7 @@
|
||||||
|
|
||||||
#include <CGAL/Mesh_3/mesh_standard_facet_criteria.h>
|
#include <CGAL/Mesh_3/mesh_standard_facet_criteria.h>
|
||||||
#include <CGAL/Mesh_facet_topology.h>
|
#include <CGAL/Mesh_facet_topology.h>
|
||||||
|
#include <CGAL/Mesh_3/Is_mesh_domain_field_3.h>
|
||||||
|
|
||||||
namespace CGAL {
|
namespace CGAL {
|
||||||
|
|
||||||
|
|
@ -59,83 +60,21 @@ public:
|
||||||
/**
|
/**
|
||||||
* @brief Constructor
|
* @brief Constructor
|
||||||
*/
|
*/
|
||||||
|
template < typename Sizing_field, typename Sizing_field2 >
|
||||||
Mesh_facet_criteria_3(const FT& angle_bound,
|
Mesh_facet_criteria_3(const FT& angle_bound,
|
||||||
const FT& radius_bound,
|
const Sizing_field & radius_bound,
|
||||||
const FT& distance_bound,
|
const Sizing_field2& distance_bound,
|
||||||
const Mesh_facet_topology topology =
|
const Mesh_facet_topology topology =
|
||||||
FACET_VERTICES_ON_SURFACE)
|
FACET_VERTICES_ON_SURFACE)
|
||||||
{
|
{
|
||||||
if ( FT(0) != angle_bound )
|
if ( FT(0) != angle_bound )
|
||||||
init_aspect(angle_bound);
|
init_aspect(angle_bound);
|
||||||
|
|
||||||
if ( FT(0) != radius_bound )
|
init_radius(radius_bound,
|
||||||
init_radius_bound(radius_bound);
|
Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field>());
|
||||||
|
|
||||||
if ( FT(0) != distance_bound )
|
init_distance(distance_bound,
|
||||||
init_distance_bound(distance_bound);
|
Mesh_3::Is_mesh_domain_field_3<Tr, Sizing_field2>());
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
if ( FT(0) != angle_bound )
|
|
||||||
init_aspect(angle_bound);
|
|
||||||
|
|
||||||
init_radius_field(radius_bound);
|
|
||||||
|
|
||||||
init_distance_field(distance_bound);
|
|
||||||
|
|
||||||
init_topo(topology);
|
init_topo(topology);
|
||||||
}
|
}
|
||||||
|
|
@ -169,27 +108,29 @@ private:
|
||||||
criteria_.add(new Aspect_criterion(angle_bound));
|
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;
|
typedef Mesh_3::Uniform_size_criterion<Tr,Visitor> Uniform_size_criterion;
|
||||||
criteria_.add(new Uniform_size_criterion(radius_bound));
|
criteria_.add(new Uniform_size_criterion(radius_bound));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sizing_field>
|
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;
|
typedef Mesh_3::Variable_size_criterion<Tr,Visitor,Sizing_field> Variable_size_criterion;
|
||||||
criteria_.add(new Variable_size_criterion(radius_bound));
|
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;
|
typedef Mesh_3::Uniform_curvature_size_criterion<Tr,Visitor> Criterion;
|
||||||
criteria_.add(new Criterion(distance_bound));
|
criteria_.add(new Criterion(distance_bound));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Sizing_field>
|
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,
|
typedef Mesh_3::Variable_curvature_size_criterion<Tr,
|
||||||
Visitor,
|
Visitor,
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,8 @@
|
||||||
#include <CGAL/Labeled_mesh_domain_3.h>
|
#include <CGAL/Labeled_mesh_domain_3.h>
|
||||||
#include <CGAL/make_mesh_3.h>
|
#include <CGAL/make_mesh_3.h>
|
||||||
|
|
||||||
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
// Domain
|
// Domain
|
||||||
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
typedef CGAL::Exact_predicates_inexact_constructions_kernel K;
|
||||||
typedef K::FT FT;
|
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 if(z < FT(-5)) return base+CGAL::square(z+5);
|
||||||
else return base;
|
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 {
|
struct Field {
|
||||||
typedef ::FT FT;
|
typedef ::FT FT;
|
||||||
|
|
||||||
|
|
@ -52,6 +61,7 @@ struct Field {
|
||||||
else return 1;
|
else return 1;
|
||||||
}
|
}
|
||||||
} field;
|
} field;
|
||||||
|
#endif
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue