mirror of https://github.com/CGAL/cgal
Merge pull request #8052 from afabri/Polygon-exact_area-GF
Polygon: Avoid stackoverflow when summing exact numbers
This commit is contained in:
commit
8cab90ed8b
|
|
@ -108,11 +108,26 @@ template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value||std::is_e
|
|||
template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value||std::is_enum<T>::value, T> exact (T d){return d;}
|
||||
template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value||std::is_enum<T>::value, int> depth(T){return -1;}
|
||||
|
||||
template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value, Quotient<T>> approx(Quotient<T> d){return d;}
|
||||
template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value, Quotient<T>> exact (Quotient<T> d){return d;}
|
||||
template<class T>inline std::enable_if_t<std::is_arithmetic<T>::value, int> depth(Quotient<T>){return -1;}
|
||||
|
||||
// For tag classes: Return_base_tag, Homogeneous_tag, Null_vector, Origin
|
||||
template<class T>inline std::enable_if_t<std::is_empty<T>::value, T> exact(T){return {};}
|
||||
template<class T>inline std::enable_if_t<std::is_empty<T>::value, T> approx(T){return {};}
|
||||
template<class T>inline std::enable_if_t<std::is_empty<T>::value, int> depth(T){return -1;}
|
||||
|
||||
namespace internal{
|
||||
template <typename AT, typename ET, typename E2A>
|
||||
struct Evaluate<Lazy<AT,ET,E2A>>
|
||||
{
|
||||
void operator()(const Lazy<AT,ET,E2A>& l)
|
||||
{
|
||||
exact(l);
|
||||
}
|
||||
};
|
||||
} // internal namespace
|
||||
|
||||
// For an iterator, exact/approx applies to the objects it points to
|
||||
template <class T, class=std::enable_if_t<is_iterator_type<T,std::input_iterator_tag>::value>>
|
||||
auto exact(T const& t) {return make_transforming_iterator(t,[](auto const&u)->decltype(auto){return CGAL::exact(u);});}
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include <CGAL/squared_distance_3.h>
|
||||
#include <CGAL/Polygon_mesh_processing/measure.h>
|
||||
#include <CGAL/number_utils.h>
|
||||
#include <CGAL/Default.h>
|
||||
|
||||
#ifdef CGAL_EIGEN3_ENABLED
|
||||
#include <CGAL/Eigen_solver_traits.h>
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ Cartesian_kernel
|
|||
Circulator
|
||||
Distance_2
|
||||
Distance_3
|
||||
Filtered_kernel
|
||||
Heat_method_3
|
||||
Installation
|
||||
Interval_support
|
||||
|
|
|
|||
|
|
@ -266,6 +266,17 @@ class Is_valid
|
|||
};
|
||||
};
|
||||
|
||||
namespace internal
|
||||
{
|
||||
// utility class to be used for calling exact(Lazy) when doing accumulation with EPECK
|
||||
template <class NT>
|
||||
struct Evaluate
|
||||
{
|
||||
void operator()(const NT&)
|
||||
{}
|
||||
};
|
||||
} // internal namespace
|
||||
|
||||
} //namespace CGAL
|
||||
|
||||
#endif // CGAL_UTILS_CLASSES_H
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <CGAL/enum.h>
|
||||
#include <CGAL/Bbox_2.h>
|
||||
#include <CGAL/Polygon_2/polygon_assertions.h>
|
||||
#include <CGAL/utils_classes.h>
|
||||
|
||||
///
|
||||
namespace CGAL {
|
||||
|
|
@ -142,6 +143,7 @@ area_2( ForwardIterator first, ForwardIterator last,
|
|||
const PolygonTraits& traits)
|
||||
{
|
||||
typedef typename PolygonTraits::FT FT;
|
||||
internal::Evaluate<FT> evaluate;
|
||||
result = FT(0);
|
||||
// check if the polygon is empty
|
||||
if (first == last) return;
|
||||
|
|
@ -153,6 +155,7 @@ area_2( ForwardIterator first, ForwardIterator last,
|
|||
ForwardIterator third = second;
|
||||
while (++third != last) {
|
||||
result = result + compute_area_2(*first, *second, *third);
|
||||
evaluate(result);
|
||||
second = third;
|
||||
}
|
||||
}
|
||||
|
|
@ -179,6 +182,7 @@ polygon_area_2( ForwardIterator first, ForwardIterator last,
|
|||
const PolygonTraits& traits)
|
||||
{
|
||||
typedef typename PolygonTraits::FT FT;
|
||||
internal::Evaluate<FT> evaluate;
|
||||
FT result = FT(0);
|
||||
// check if the polygon is empty
|
||||
if (first == last) return result;
|
||||
|
|
@ -190,6 +194,7 @@ polygon_area_2( ForwardIterator first, ForwardIterator last,
|
|||
ForwardIterator third = second;
|
||||
while (++third != last) {
|
||||
result = result + compute_area_2(*first, *second, *third);
|
||||
evaluate(result);
|
||||
second = third;
|
||||
}
|
||||
return result;
|
||||
|
|
|
|||
|
|
@ -23,9 +23,7 @@
|
|||
#include <CGAL/boost/graph/properties.h>
|
||||
#include <CGAL/Named_function_parameters.h>
|
||||
#include <CGAL/Polygon_mesh_processing/internal/named_params_helper.h>
|
||||
|
||||
|
||||
#include <CGAL/Lazy.h> // needed for CGAL::exact(FT)/CGAL::exact(Lazy_exact_nt<T>)
|
||||
#include <CGAL/utils_classes.h>
|
||||
|
||||
#include <boost/container/small_vector.hpp>
|
||||
#include <boost/graph/graph_traits.hpp>
|
||||
|
|
@ -261,12 +259,14 @@ face_border_length(typename boost::graph_traits<PolygonMesh>::halfedge_descripto
|
|||
const PolygonMesh& pmesh,
|
||||
const NamedParameters& np = parameters::default_values())
|
||||
{
|
||||
typename GetGeomTraits<PolygonMesh, NamedParameters>::type::FT result = 0;
|
||||
using FT = typename GetGeomTraits<PolygonMesh, NamedParameters>::type::FT;
|
||||
::CGAL::internal::Evaluate<FT> evaluate;
|
||||
FT result = 0;
|
||||
|
||||
for(typename boost::graph_traits<PolygonMesh>::halfedge_descriptor haf : halfedges_around_face(h, pmesh))
|
||||
{
|
||||
result += edge_length(haf, pmesh, np);
|
||||
exact(result);
|
||||
evaluate(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -559,11 +559,14 @@ area(FaceRange face_range,
|
|||
{
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
|
||||
typename GetGeomTraits<TriangleMesh, CGAL_NP_CLASS>::type::FT result = 0;
|
||||
using FT = typename GetGeomTraits<TriangleMesh, CGAL_NP_CLASS>::type::FT;
|
||||
FT result = 0;
|
||||
::CGAL::internal::Evaluate<FT> evaluate;
|
||||
|
||||
for(face_descriptor f : face_range)
|
||||
{
|
||||
result += face_area(f, tmesh, np);
|
||||
exact(result);
|
||||
evaluate(result);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -676,7 +679,10 @@ volume(const TriangleMesh& tmesh,
|
|||
|
||||
typedef typename boost::graph_traits<TriangleMesh>::face_descriptor face_descriptor;
|
||||
|
||||
typename GetGeomTraits<TriangleMesh, CGAL_NP_CLASS>::type::FT volume = 0;
|
||||
using FT = typename GetGeomTraits<TriangleMesh, CGAL_NP_CLASS>::type::FT;
|
||||
::CGAL::internal::Evaluate<FT> evaluate;
|
||||
|
||||
FT volume = 0;
|
||||
typename CGAL::Kernel_traits<typename property_map_value<TriangleMesh,
|
||||
CGAL::vertex_point_t>::type>::Kernel::Compute_volume_3 cv3;
|
||||
|
||||
|
|
@ -686,7 +692,7 @@ volume(const TriangleMesh& tmesh,
|
|||
get(vpm, target(halfedge(f, tmesh), tmesh)),
|
||||
get(vpm, target(next(halfedge(f, tmesh), tmesh), tmesh)),
|
||||
get(vpm, target(prev(halfedge(f, tmesh), tmesh), tmesh)));
|
||||
exact(volume);
|
||||
evaluate(volume);
|
||||
}
|
||||
|
||||
return volume;
|
||||
|
|
|
|||
Loading…
Reference in New Issue