diff --git a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation.h b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation.h index 48f0475cc27..19b88bed139 100644 --- a/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation.h +++ b/Surface_mesh_segmentation/include/CGAL/Surface_mesh_segmentation.h @@ -250,7 +250,16 @@ Surface_mesh_segmentation::cast_and_return_minimum( { boost::optional min_distance; std::list intersections; +#if 1 + //SL: the difference with all_intersections is that in the traversal traits, we do do_intersect before calling intersection. + typedef std::back_insert_iterator< std::list > + Output_iterator; + Listing_intersection_traits_ray_or_segment_triangle + traversal_traits(std::back_inserter(intersections)); + tree.traversal(ray,traversal_traits); +#else tree.all_intersections(ray, std::back_inserter(intersections)); +#endif Vector min_i_ray; Primitive_id min_id; for(typename std::list::iterator op_it = diff --git a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h index 3bd26908bff..1d59d550a99 100644 --- a/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h +++ b/Surface_mesh_segmentation/include/CGAL/internal/Surface_mesh_segmentation/AABB_traversal_traits.h @@ -1,6 +1,8 @@ #ifndef CGAL_INTERNAL_SURFACE_MESH_SEGMENTATION_AABB_TRAVERSAL_TRAITS_H #define CGAL_INTERNAL_SURFACE_MESH_SEGMENTATION_AABB_TRAVERSAL_TRAITS_H +namespace CGAL +{ /** * @class Closest_intersection_traits @@ -61,7 +63,8 @@ public: return intersected; } //SL: warning this is another requirements for the traits!! - typename AABBTraits::GeomTraits::Segment i_segment; + typedef typename Kernel_traits::Kernel GeomTraits; + typename GeomTraits::Segment i_segment; if(CGAL::assign(i_segment, intersection)) { double distance_1 = (i_segment.source() - query.source()).squared_length(); // source returns closest intersection ? @@ -84,5 +87,54 @@ private: double min_distance; }; +/** + * @class Special case for ray/segemnt-triangle + * the only difference with the offical one (Listing_intersection_traits) is that + * is the do_intersect which is made prior to the intersection call. + */ +template +class Listing_intersection_traits_ray_or_segment_triangle +{ + typedef typename AABBTraits::FT FT; + typedef typename AABBTraits::Point Point; + typedef typename AABBTraits::Primitive Primitive; + typedef typename AABBTraits::Bounding_box Bounding_box; + typedef typename AABBTraits::Primitive::Id Primitive_id; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; + typedef ::CGAL::AABB_node Node; + typedef typename ::CGAL::AABB_tree::size_type size_type; + +public: + Listing_intersection_traits_ray_or_segment_triangle(Output_iterator out_it) + : m_out_it(out_it) {} + + bool go_further() const { + return true; + } + + void intersection(const Query& query, const Primitive& primitive) { + //SL: using Kernel_traits is not bad in this context cause we expect a Ray/Segment from a CGAL Kernel here + typedef typename Kernel_traits::Kernel GeomTraits; + if ( GeomTraits().do_intersect_3_object()(query,primitive.datum()) ) { + boost::optional intersection; + intersection = AABBTraits().intersection_object()(query, primitive); + if(intersection) { + *m_out_it++ = *intersection; + } + } + } + + bool do_intersect(const Query& query, const Node& node) const { + return AABBTraits().do_intersect_object()(query, node.bbox()); + } + +private: + Output_iterator m_out_it; +}; + +} //namespace CGAL #endif + +