Add a template argument to AABB_traits for a face->bbox property map

This commit is contained in:
Andreas Fabri 2017-05-19 16:55:58 +02:00
parent ceec6140ba
commit aefd26b080
2 changed files with 141 additions and 33 deletions

View File

@ -0,0 +1,93 @@
#include <iostream>
#include <fstream>
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/Polyhedron_3.h>
#include <CGAL/Surface_mesh.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/Timer.h>
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<Point_3> Surface_mesh;
typedef CGAL::Polyhedron_3<K> Polyhedron_3;
typedef CGAL::Timer Timer;
template <typename TriangleMesh>
void triangle_mesh(char* fname)
{
typedef CGAL::AABB_face_graph_triangle_primitive<TriangleMesh> Primitive;
typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::AABB_tree<Traits> 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<Surface_mesh>::face_descriptor fd,
const Surface_mesh& p)
{
boost::graph_traits<Surface_mesh>::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<Surface_mesh>::face_descriptor face_descriptor;
typedef Surface_mesh::Property_map<face_descriptor,Bbox_3> Bbox_pmap;
typedef CGAL::AABB_face_graph_triangle_primitive<Surface_mesh> Primitive;
typedef CGAL::AABB_traits<K, Primitive,Bbox_pmap> Traits;
typedef CGAL::AABB_tree<Traits> Tree;
Surface_mesh tmesh;
std::ifstream in(fname);
in >> tmesh;
Timer t;
t.start();
Bbox_pmap bb = tmesh.add_property_map<face_descriptor,Bbox_3>("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<Polyhedron_3>(argv[1]);
std::cout << "Surface_mesh" << std::endl;
triangle_mesh<Surface_mesh>(argv[1]);
std::cout << "Surface_mesh with cached Bbox_3" << std::endl;
surface_mesh_cache_bbox(argv[1]);
return EXIT_SUCCESS;
}

View File

@ -24,7 +24,6 @@
#include <CGAL/license/AABB_tree.h> #include <CGAL/license/AABB_tree.h>
#include <CGAL/Bbox_3.h> #include <CGAL/Bbox_3.h>
#include <CGAL/intersections.h> #include <CGAL/intersections.h>
#include <CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h> #include <CGAL/internal/AABB_tree/Has_nested_type_Shared_data.h>
@ -188,15 +187,18 @@ struct AABB_traits_base_2<GeomTraits,true>{
/// \tparam Primitive provide the type of primitives stored in the AABB_tree. /// \tparam Primitive provide the type of primitives stored in the AABB_tree.
/// It is a model of the concept `AABBPrimitive` or `AABBPrimitiveWithSharedData`. /// It is a model of the concept `AABBPrimitive` or `AABBPrimitiveWithSharedData`.
/// ///
/// If the argument GeomTraits is a model of the concept \ref /// \tparam BboxMap must be a property map....................
/// AABBRayIntersectionGeomTraits, this class is also a model of \ref ///
/// AABBRayIntersectionTraits. /// If the argument `GeomTraits` is a model of the concept \ref
/// `AABBRayIntersectionGeomTraits`, this class is also a model of \ref
/// `AABBRayIntersectionTraits`.
/// ///
/// \sa `AABBTraits` /// \sa `AABBTraits`
/// \sa `AABB_tree` /// \sa `AABB_tree`
/// \sa `AABBPrimitive` /// \sa `AABBPrimitive`
/// \sa `AABBPrimitiveWithSharedData` /// \sa `AABBPrimitiveWithSharedData`
template<typename GeomTraits, typename AABBPrimitive>
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
class AABB_traits: class AABB_traits:
public internal::AABB_tree::AABB_traits_base<AABBPrimitive>, public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
public internal::AABB_tree::AABB_traits_base_2<GeomTraits> public internal::AABB_tree::AABB_traits_base_2<GeomTraits>
@ -205,7 +207,7 @@ class AABB_traits:
public: public:
typedef GeomTraits Geom_traits; typedef GeomTraits Geom_traits;
typedef AABB_traits<GeomTraits, AABBPrimitive> AT; typedef AABB_traits<GeomTraits, AABBPrimitive, BboxMap> AT;
// AABBTraits concept types // AABBTraits concept types
typedef typename GeomTraits::FT FT; typedef typename GeomTraits::FT FT;
typedef AABBPrimitive Primitive; typedef AABBPrimitive Primitive;
@ -254,8 +256,14 @@ public:
typedef typename GeomTraits::Construct_max_vertex_3 Construct_max_vertex_3; typedef typename GeomTraits::Construct_max_vertex_3 Construct_max_vertex_3;
typedef typename GeomTraits::Construct_iso_cuboid_3 Construct_iso_cuboid_3; typedef typename GeomTraits::Construct_iso_cuboid_3 Construct_iso_cuboid_3;
BboxMap bbm;
/// Default constructor. /// Default constructor.
AABB_traits() { }; AABB_traits() { }
AABB_traits(BboxMap bbm)
: bbm(bbm)
{}
typedef typename GeomTraits::Compute_squared_distance_3 Squared_distance; typedef typename GeomTraits::Compute_squared_distance_3 Squared_distance;
@ -276,9 +284,9 @@ public:
*/ */
class Sort_primitives class Sort_primitives
{ {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits; const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
public: public:
Sort_primitives(const AABB_traits<GeomTraits,AABBPrimitive>& traits) Sort_primitives(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
: m_traits(traits) {} : m_traits(traits) {}
template<typename PrimitiveIterator> template<typename PrimitiveIterator>
@ -314,31 +322,32 @@ public:
* @return the bounding box of the primitives of the iterator range * @return the bounding box of the primitives of the iterator range
*/ */
class Compute_bbox { class Compute_bbox {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits; const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public: public:
Compute_bbox(const AABB_traits<GeomTraits,AABBPrimitive>& traits) Compute_bbox(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
:m_traits (traits) {} :m_traits (traits) {}
template<typename ConstPrimitiveIterator> template<typename ConstPrimitiveIterator>
typename AT::Bounding_box operator()(ConstPrimitiveIterator first, typename AT::Bounding_box operator()(ConstPrimitiveIterator first,
ConstPrimitiveIterator beyond) const ConstPrimitiveIterator beyond) const
{ {
typename AT::Bounding_box bbox = compute_bbox(*first,m_traits); typename AT::Bounding_box bbox = m_traits.compute_bbox(*first,m_traits.bbm);
for(++first; first != beyond; ++first) 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);} Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);}
class Do_intersect { class Do_intersect {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits; const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public: public:
Do_intersect(const AABB_traits<GeomTraits,AABBPrimitive>& traits) Do_intersect(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
:m_traits(traits) {} :m_traits(traits) {}
template<typename Query> template<typename Query>
@ -357,9 +366,9 @@ public:
Do_intersect do_intersect_object() const {return Do_intersect(*this);} Do_intersect do_intersect_object() const {return Do_intersect(*this);}
class Intersection { class Intersection {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits; const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
public: public:
Intersection(const AABB_traits<GeomTraits,AABBPrimitive>& traits) Intersection(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
:m_traits(traits) {} :m_traits(traits) {}
#if CGAL_INTERSECTION_VERSION < 2 #if CGAL_INTERSECTION_VERSION < 2
template<typename Query> template<typename Query>
@ -394,9 +403,9 @@ public:
class Closest_point { class Closest_point {
typedef typename AT::Point_3 Point; typedef typename AT::Point_3 Point;
typedef typename AT::Primitive Primitive; typedef typename AT::Primitive Primitive;
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits; const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public: public:
Closest_point(const AABB_traits<GeomTraits,AABBPrimitive>& traits) Closest_point(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
: m_traits(traits) {} : m_traits(traits) {}
@ -450,12 +459,18 @@ private:
* @param pr the primitive * @param pr the primitive
* @return the bounding box of the primitive \c pr * @return the bounding box of the primitive \c pr
*/ */
static Bounding_box compute_bbox (const Primitive& pr, template <typename PM>
const AABB_traits<GeomTraits,AABBPrimitive>& traits) Bounding_box compute_bbox(const Primitive& pr, const PM&)const
{ {
return internal::Primitive_helper<AT>::get_datum(pr,traits).bbox(); return get(bbm, pr.id());
} }
Bounding_box compute_bbox(const Primitive& pr, const Default&)const
{
return internal::Primitive_helper<AT>::get_datum(pr,*this).bbox();
}
typedef enum { CGAL_AXIS_X = 0, typedef enum { CGAL_AXIS_X = 0,
CGAL_AXIS_Y = 1, CGAL_AXIS_Y = 1,
CGAL_AXIS_Z = 2} Axis; CGAL_AXIS_Z = 2} Axis;
@ -463,17 +478,17 @@ private:
static Axis longest_axis(const Bounding_box& bbox); static Axis longest_axis(const Bounding_box& bbox);
/// Comparison functions /// Comparison functions
static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive>& traits) static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
{ {
return GeomTraits().less_x_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits), return GeomTraits().less_x_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) ); internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
} }
static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive>& traits) static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
{ {
return GeomTraits().less_y_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits), return GeomTraits().less_y_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) ); internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
} }
static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive>& traits) static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
{ {
return GeomTraits().less_z_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits), return GeomTraits().less_z_3_object()( internal::Primitive_helper<AT>::get_reference_point(pr1,traits),
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) ); internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
@ -485,9 +500,9 @@ private:
//------------------------------------------------------- //-------------------------------------------------------
// Private methods // Private methods
//------------------------------------------------------- //-------------------------------------------------------
template<typename GT, typename P> template<typename GT, typename P, typename B>
typename AABB_traits<GT,P>::Axis typename AABB_traits<GT,P,B>::Axis
AABB_traits<GT,P>::longest_axis(const Bounding_box& bbox) AABB_traits<GT,P,B>::longest_axis(const Bounding_box& bbox)
{ {
const double dx = bbox.xmax() - bbox.xmin(); const double dx = bbox.xmax() - bbox.xmin();
const double dy = bbox.ymax() - bbox.ymin(); const double dy = bbox.ymax() - bbox.ymin();