diff --git a/AABB_tree/examples/AABB_tree/AABB_cached_bbox_example.cpp b/AABB_tree/examples/AABB_tree/AABB_cached_bbox_example.cpp new file mode 100644 index 00000000000..95f20cb189e --- /dev/null +++ b/AABB_tree/examples/AABB_tree/AABB_cached_bbox_example.cpp @@ -0,0 +1,93 @@ +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef K::FT FT; +typedef K::Point_3 Point_3; +typedef CGAL::Bbox_3 Bbox_3; +typedef CGAL::Surface_mesh Surface_mesh; +typedef CGAL::Polyhedron_3 Polyhedron_3; +typedef CGAL::Timer Timer; + + +template +void triangle_mesh(char* fname) +{ + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree; + + TriangleMesh tmesh; + std::ifstream in(fname); + in >> tmesh; + Timer t; + t.start(); + Tree tree(faces(tmesh).first, faces(tmesh).second, tmesh); + tree.build(); + std::cout << t.time() << " sec." << std::endl; + std::cout << "Closest point to ORIGIN:" << tree.closest_point(CGAL::ORIGIN) << std::endl; +} + + +Bbox_3 bbox(boost::graph_traits::face_descriptor fd, + const Surface_mesh& p) +{ + boost::graph_traits::halfedge_descriptor hd = halfedge(fd,p); + Bbox_3 res = p.point(source(hd,p)).bbox(); + res += p.point(target(hd,p)).bbox(); + res += p.point(target(next(hd,p),p)).bbox(); + return res; +} + + +void surface_mesh_cache_bbox(char* fname) +{ + typedef boost::graph_traits::face_descriptor face_descriptor; + typedef Surface_mesh::Property_map Bbox_pmap; + typedef CGAL::AABB_face_graph_triangle_primitive Primitive; + typedef CGAL::AABB_traits Traits; + typedef CGAL::AABB_tree Tree; + + Surface_mesh tmesh; + std::ifstream in(fname); + in >> tmesh; + + Timer t; + t.start(); + Bbox_pmap bb = tmesh.add_property_map("f:bbox",Bbox_3()).first; + + BOOST_FOREACH(face_descriptor fd, faces(tmesh)){ + put(bb, fd, bbox(fd,tmesh)); + } + Traits traits(bb); + Tree tree(traits); + tree.insert(faces(tmesh).first, faces(tmesh).second, tmesh); + tree.build(); + tmesh.remove_property_map(bb); + + std::cout << t.time() << " sec."<< std::endl; + std::cout << "Closest point to ORIGIN:" << tree.closest_point(CGAL::ORIGIN) << std::endl; +} + + +int main(int argc, char* argv[]) +{ + std::cout << "Polyhedron_3" << std::endl; + triangle_mesh(argv[1]); + + std::cout << "Surface_mesh" << std::endl; + triangle_mesh(argv[1]); + + std::cout << "Surface_mesh with cached Bbox_3" << std::endl; + surface_mesh_cache_bbox(argv[1]); + + return EXIT_SUCCESS; +} diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 24dd6e0bdb7..51082d19c0f 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -24,7 +24,6 @@ #include - #include #include #include @@ -188,15 +187,18 @@ struct AABB_traits_base_2{ /// \tparam Primitive provide the type of primitives stored in the AABB_tree. /// It is a model of the concept `AABBPrimitive` or `AABBPrimitiveWithSharedData`. /// -/// If the argument GeomTraits is a model of the concept \ref -/// AABBRayIntersectionGeomTraits, this class is also a model of \ref -/// AABBRayIntersectionTraits. +/// \tparam BboxMap must be a property map.................... +/// +/// If the argument `GeomTraits` is a model of the concept \ref +/// `AABBRayIntersectionGeomTraits`, this class is also a model of \ref +/// `AABBRayIntersectionTraits`. /// /// \sa `AABBTraits` /// \sa `AABB_tree` /// \sa `AABBPrimitive` /// \sa `AABBPrimitiveWithSharedData` -template + + template class AABB_traits: public internal::AABB_tree::AABB_traits_base, public internal::AABB_tree::AABB_traits_base_2 @@ -205,7 +207,7 @@ class AABB_traits: public: typedef GeomTraits Geom_traits; - typedef AABB_traits AT; + typedef AABB_traits AT; // AABBTraits concept types typedef typename GeomTraits::FT FT; typedef AABBPrimitive Primitive; @@ -254,8 +256,14 @@ public: typedef typename GeomTraits::Construct_max_vertex_3 Construct_max_vertex_3; typedef typename GeomTraits::Construct_iso_cuboid_3 Construct_iso_cuboid_3; + BboxMap bbm; + /// Default constructor. - AABB_traits() { }; + AABB_traits() { } + + AABB_traits(BboxMap bbm) + : bbm(bbm) + {} typedef typename GeomTraits::Compute_squared_distance_3 Squared_distance; @@ -276,9 +284,9 @@ public: */ class Sort_primitives { - const AABB_traits& m_traits; + const AABB_traits& m_traits; public: - Sort_primitives(const AABB_traits& traits) + Sort_primitives(const AABB_traits& traits) : m_traits(traits) {} template @@ -314,31 +322,32 @@ public: * @return the bounding box of the primitives of the iterator range */ class Compute_bbox { - const AABB_traits& m_traits; + const AABB_traits& m_traits; public: - Compute_bbox(const AABB_traits& traits) + Compute_bbox(const AABB_traits& traits) :m_traits (traits) {} - + template typename AT::Bounding_box operator()(ConstPrimitiveIterator first, ConstPrimitiveIterator beyond) const - { - typename AT::Bounding_box bbox = compute_bbox(*first,m_traits); - for(++first; first != beyond; ++first) + { + typename AT::Bounding_box bbox = m_traits.compute_bbox(*first,m_traits.bbm); + for(++first; first != beyond; ++first) { - bbox = bbox + compute_bbox(*first,m_traits); + bbox = bbox + m_traits.compute_bbox(*first,m_traits.bbm); } - return bbox; - } + return bbox; + } + }; Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);} class Do_intersect { - const AABB_traits& m_traits; + const AABB_traits& m_traits; public: - Do_intersect(const AABB_traits& traits) + Do_intersect(const AABB_traits& traits) :m_traits(traits) {} template @@ -357,9 +366,9 @@ public: Do_intersect do_intersect_object() const {return Do_intersect(*this);} class Intersection { - const AABB_traits& m_traits; + const AABB_traits& m_traits; public: - Intersection(const AABB_traits& traits) + Intersection(const AABB_traits& traits) :m_traits(traits) {} #if CGAL_INTERSECTION_VERSION < 2 template @@ -394,9 +403,9 @@ public: class Closest_point { typedef typename AT::Point_3 Point; typedef typename AT::Primitive Primitive; - const AABB_traits& m_traits; + const AABB_traits& m_traits; public: - Closest_point(const AABB_traits& traits) + Closest_point(const AABB_traits& traits) : m_traits(traits) {} @@ -450,12 +459,18 @@ private: * @param pr the primitive * @return the bounding box of the primitive \c pr */ - static Bounding_box compute_bbox (const Primitive& pr, - const AABB_traits& traits) + template + Bounding_box compute_bbox(const Primitive& pr, const PM&)const { - return internal::Primitive_helper::get_datum(pr,traits).bbox(); + return get(bbm, pr.id()); } + Bounding_box compute_bbox(const Primitive& pr, const Default&)const + { + return internal::Primitive_helper::get_datum(pr,*this).bbox(); + } + + typedef enum { CGAL_AXIS_X = 0, CGAL_AXIS_Y = 1, CGAL_AXIS_Z = 2} Axis; @@ -463,17 +478,17 @@ private: static Axis longest_axis(const Bounding_box& bbox); /// Comparison functions - static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) { return GeomTraits().less_x_3_object()( internal::Primitive_helper::get_reference_point(pr1,traits), internal::Primitive_helper::get_reference_point(pr2,traits) ); } - static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) { return GeomTraits().less_y_3_object()( internal::Primitive_helper::get_reference_point(pr1,traits), internal::Primitive_helper::get_reference_point(pr2,traits) ); } - static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) { return GeomTraits().less_z_3_object()( internal::Primitive_helper::get_reference_point(pr1,traits), internal::Primitive_helper::get_reference_point(pr2,traits) ); @@ -485,9 +500,9 @@ private: //------------------------------------------------------- // Private methods //------------------------------------------------------- -template -typename AABB_traits::Axis -AABB_traits::longest_axis(const Bounding_box& bbox) + template + typename AABB_traits::Axis + AABB_traits::longest_axis(const Bounding_box& bbox) { const double dx = bbox.xmax() - bbox.xmin(); const double dy = bbox.ymax() - bbox.ymin();