From 0e883861b5ccce4f9bb1dd506985289a9d29fe82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Philipp=20M=C3=B6ller?= Date: Fri, 23 Oct 2015 12:38:26 +0200 Subject: [PATCH] Move Intersection_distance into its own base This is necessary so that we only define it if the GeomTraits meet the necessary requirements. --- AABB_tree/include/CGAL/AABB_traits.h | 83 ++++++++++++++++------------ 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 20b228cd744..fa3a22302e5 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -91,6 +92,51 @@ struct AABB_traits_base{ const typename Primitive::Shared_data& shared_data() const {return m_primitive_data;} }; +// AABB_traits_base_2 brings in the Intersection_distance predicate, +// if GeomTraits is a model RayIntersectionGeomTraits. +template ::value> +struct AABB_traits_base_2; + +template +struct AABB_traits_base_2{}; + +template +struct AABB_traits_base_2{ + typedef typename GeomTraits::Ray_3 Ray_3; + typedef typename GeomTraits::FT FT; + // defining Bounding_box here is a hack. Otherwise we would need to + // use CRTP to get access to the derived class, which would bloat + // the code even more. + typedef typename CGAL::Bbox_3 Bounding_box; + + struct Intersection_distance { + boost::optional operator()(const Ray_3& ray, const Bounding_box& bbox) { + FT t_near = -DBL_MAX; // std::numeric_limits::lowest(); C++1903 + FT t_far = DBL_MAX; + + for(int i = 0; i < 3; i++) { + if(ray.direction().delta(i) == 0) { + if((ray.source()[i] < box.min(i)) || (ray.source()[i] > box.max(i))) { + return boost::none; + } + } else { + FT t1 = (box.min(i) - ray.source()[i]) / ray.direction().delta(i); + FT t2 = (box.max(i) - ray.source()[i]) / ray.direction().delta(i); + + t_near = (std::max)(t_near, (std::min)(t1, t2)); + t_far = (std::min)(t_far, (std::max)(t1, t2)); + } + } + + if(t_far > t_near && t_far > 0) { + return t_near; + } else { + return boost::none; + } + } + }; + + Intersection_distance intersection_distance_object const { return Intersection_distance(); } } } //end of namespace internal::AABB_tree /// \addtogroup PkgAABB_tree @@ -114,7 +160,8 @@ struct AABB_traits_base{ /// \sa `AABBPrimitiveWithSharedData` template class AABB_traits: - public internal::AABB_tree::AABB_traits_base + public internal::AABB_tree::AABB_traits_base, + public internal::AABB_tree::AABB_traits_base_2 { typedef typename CGAL::Object Object; public: @@ -300,40 +347,6 @@ public: Intersection intersection_object() const {return Intersection(*this);} - class Intersection_distance { - const AABB_traits& m_traits; - public: - Intersection_distane(const AABB_traits& traits) - : m_traits(traits) {} - - template - boost::optional operator()(const Ray& ray, const Bounding_box& bbox) { - FT t_near = -DBL_MAX; // std::numeric_limits::lowest(); C++1903 - FT t_far = DBL_MAX; - - for(int i = 0; i < 3; i++) { - if(ray.direction().delta(i) == 0) { - if((ray.source()[i] < box.min(i)) || (ray.source()[i] > box.max(i))) { - return boost::none; - } - } else { - FT t1 = (box.min(i) - ray.source()[i]) / ray.direction().delta(i); - FT t2 = (box.max(i) - ray.source()[i]) / ray.direction().delta(i); - - t_near = (std::max)(t_near, (std::min)(t1, t2)); - t_far = (std::min)(t_far, (std::max)(t1, t2)); - } - } - - if(t_far > t_near && t_far > 0) { - return t_near; - } else { - return boost::none; - } - } - }; - - Intersection_distance intersection_distance_object const { return Intersection_distance(*this); } // This should go down to the GeomTraits, i.e. the kernel class Closest_point {