diff --git a/AABB_tree/examples/AABB_tree/AABB_indexed_triangle_2_example.cpp b/AABB_tree/examples/AABB_tree/AABB_indexed_triangle_2_example.cpp index 531cafb2f02..14480efece2 100644 --- a/AABB_tree/examples/AABB_tree/AABB_indexed_triangle_2_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_indexed_triangle_2_example.cpp @@ -11,6 +11,8 @@ typedef CGAL::Simple_cartesian K; typedef K::Point_3 Point_3; typedef K::Point_2 Point; +typedef K::Vector_2 Vector; +typedef K::Ray_2 Ray; template struct Projection_xy_point_map { @@ -30,48 +32,13 @@ struct Projection_xy_point_map { } }; -template -struct Projection_xz_point_map { - - typedef typename GeomTraits::Point_3 key_type; - typedef typename GeomTraits::Point_2 value_type; - typedef const value_type& reference; - - typedef boost::readable_property_map_tag category; - typedef Projection_xz_point_map Self; - - Projection_xz_point_map() {} - - inline friend value_type get(Self s, key_type p) - { - return value_type(p.x(), p.z()); - } -}; - -template -struct Projection_yz_point_map { - - typedef typename GeomTraits::Point_3 key_type; - typedef typename GeomTraits::Point_2 value_type; - typedef const value_type& reference; - - typedef boost::readable_property_map_tag category; - typedef Projection_yz_point_map Self; - - Projection_yz_point_map() {} - - inline friend value_type get(Self s, key_type p) - { - return value_type(p.y(), p.z()); - } -}; - typedef std::vector >::iterator IndexIterator; typedef std::vector PointRange; -typedef CGAL::AABB_indexed_triangle_primitive_2> Primitive; +typedef CGAL::AABB_indexed_triangle_primitive_2> Primitive; typedef CGAL::AABB_traits_2 AABB_triangle_traits; typedef CGAL::AABB_tree Tree; typedef Tree::Point_and_primitive_id Point_and_primitive_id; +typedef std::optional::Type> Ray_intersection; int main() @@ -109,5 +76,16 @@ int main() id = tree.closest_point_and_primitive(Point(3.0, 0.5)); std::cout << std::distance(triangles.begin(), id.second) << ". triangle" << std::endl; + Ray ray(Point(5.5, 0.5), Point(1.5, 0.5)); + Ray_intersection intersection = tree.first_intersection(ray); + + if (!intersection) { + std::cout << "Ray does not intersect with triangles although it should!" << std::endl; + return EXIT_FAILURE; + } + else { + std::cout << std::distance(triangles.begin(), intersection->second) << ". triangle" << std::endl; + } + return EXIT_SUCCESS; } diff --git a/AABB_tree/include/CGAL/AABB_traits_2.h b/AABB_tree/include/CGAL/AABB_traits_2.h index 556b1a07935..2d6e366f36b 100644 --- a/AABB_tree/include/CGAL/AABB_traits_2.h +++ b/AABB_tree/include/CGAL/AABB_traits_2.h @@ -38,7 +38,7 @@ namespace internal{ namespace AABB_tree { // AABB_traits_intersection_base brings in the Intersection_distance predicate, // if GeomTraits is a model RayIntersectionGeomTraits. -template ::value> +template ::value> struct AABB_traits_intersection_base_2; template @@ -77,7 +77,7 @@ struct AABB_traits_intersection_base_2{ Cartesian_const_iterator_2 source_iter = construct_cartesian_const_iterator_2(source); Cartesian_const_iterator_2 direction_iter = construct_cartesian_const_iterator_2(direction); - for(int i = 0; i < 3; ++i, ++source_iter, ++direction_iter) { + for(int i = 0; i < 2; ++i, ++source_iter, ++direction_iter) { if(*direction_iter == 0) { if((*source_iter < (bbox.min)(i)) || (*source_iter > (bbox.max)(i))) { return std::nullopt; diff --git a/AABB_tree/include/CGAL/AABB_tree/internal/AABB_ray_intersection.h b/AABB_tree/include/CGAL/AABB_tree/internal/AABB_ray_intersection.h index fd11f41492c..45610d84d9a 100644 --- a/AABB_tree/include/CGAL/AABB_tree/internal/AABB_ray_intersection.h +++ b/AABB_tree/include/CGAL/AABB_tree/internal/AABB_ray_intersection.h @@ -33,10 +33,30 @@ namespace CGAL { +namespace internal { +template +struct Intersection_traits_wrapper {}; + +template +struct Intersection_traits_wrapper { + typedef typename GT::Ray_2 Ray; + typedef typename GT::Vector_2 Vector; +}; + +template +struct Intersection_traits_wrapper { + typedef typename GT::Ray_3 Ray; + typedef typename GT::Vector_3 Vector; +}; +} + template class AABB_ray_intersection { typedef typename AABBTree::AABB_traits AABB_traits; - typedef typename AABB_traits::Ray_3 Ray; + static const int dimension = typename AABB_traits::Point::Ambient_dimension::value; + typedef typename internal::Intersection_traits_wrapper::Ray Ray; + typedef typename internal::Intersection_traits_wrapper::Vector Vector; + typedef typename AABBTree::template Intersection_and_primitive_id::Type Ray_intersection_and_primitive_id; typedef typename Ray_intersection_and_primitive_id::first_type Ray_intersection; public: @@ -167,8 +187,8 @@ private: as_ray_param_visitor(const Ray* ray) : ray(ray), max_i(0) { - typename AABB_traits::Geom_traits::Vector_3 v = ray->to_vector(); - for (int i=1; i<3; ++i) + Vector v = ray->to_vector(); + for (int i=1; i CGAL::abs(v[max_i]) ) max_i = i; } @@ -184,8 +204,8 @@ private: } FT operator()(const Point& point) { - typename AABB_traits::Geom_traits::Vector_3 x(ray->source(), point); - typename AABB_traits::Geom_traits::Vector_3 v = ray->to_vector(); + Vector x(ray->source(), point); + Vector v = ray->to_vector(); return x[max_i] / v[max_i]; } @@ -200,7 +220,7 @@ template std::optional< typename AABB_tree::template Intersection_and_primitive_id::Type > AABB_tree::first_intersection(const Ray& query, const SkipFunctor& skip) const { - static_assert(std::is_same::value, + static_assert(std::is_same::value, "Ray and Ray_3 must be the same type"); switch(size()) // copy-paste from AABB_tree::traversal diff --git a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h index 3d02204b9d0..f77b59d6085 100644 --- a/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h +++ b/AABB_tree/include/CGAL/AABB_tree/internal/Is_ray_intersection_geomtraits.h @@ -24,18 +24,33 @@ namespace CGAL { namespace internal { namespace AABB_tree { -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_ray_3,Ray_3,false) -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_source_3,Construct_source_3,false) -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_vector_3,Construct_vector_3,false) -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_cartesian_const_iterator_3,Construct_cartesian_const_iterator_3,false) -BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_cartesian_const_iterator_3,Cartesian_const_iterator_3,false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_ray_3, Ray_3, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_source_3, Construct_source_3, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_vector_3, Construct_vector_3, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_cartesian_const_iterator_3, Construct_cartesian_const_iterator_3, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_cartesian_const_iterator_3, Cartesian_const_iterator_3, false) + +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_ray_2, Ray_2, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_source_2, Construct_source_2, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_vector_2, Construct_vector_2, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_construct_cartesian_const_iterator_2, Construct_cartesian_const_iterator_2, false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_cartesian_const_iterator_2, Cartesian_const_iterator_2, false) + +template +struct Is_ray_intersection_geomtraits_2 +: std::bool_constant< Has_ray_2::value && + Has_construct_source_2::value && + Has_vector_2::value && + Has_construct_cartesian_const_iterator_2::value && + Has_cartesian_const_iterator_2::value > +{}; template struct Is_ray_intersection_geomtraits -: std::bool_constant< Has_ray_3::value && - Has_construct_source_3::value && - Has_vector_3::value && - Has_construct_cartesian_const_iterator_3::value && +: std::bool_constant< Has_ray_3::value&& + Has_construct_source_3::value&& + Has_vector_3::value&& + Has_construct_cartesian_const_iterator_3::value&& Has_cartesian_const_iterator_3::value > {};