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/Bbox_3.h>
#include <CGAL/intersections.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.
/// 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<typename GeomTraits, typename AABBPrimitive>
template<typename GeomTraits, typename AABBPrimitive, typename BboxMap = Default>
class AABB_traits:
public internal::AABB_tree::AABB_traits_base<AABBPrimitive>,
public internal::AABB_tree::AABB_traits_base_2<GeomTraits>
@ -205,7 +207,7 @@ class AABB_traits:
public:
typedef GeomTraits Geom_traits;
typedef AABB_traits<GeomTraits, AABBPrimitive> AT;
typedef AABB_traits<GeomTraits, AABBPrimitive, BboxMap> 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<GeomTraits,AABBPrimitive>& m_traits;
const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
public:
Sort_primitives(const AABB_traits<GeomTraits,AABBPrimitive>& traits)
Sort_primitives(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
: m_traits(traits) {}
template<typename PrimitiveIterator>
@ -314,31 +322,32 @@ public:
* @return the bounding box of the primitives of the iterator range
*/
class Compute_bbox {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits;
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public:
Compute_bbox(const AABB_traits<GeomTraits,AABBPrimitive>& traits)
Compute_bbox(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
:m_traits (traits) {}
template<typename ConstPrimitiveIterator>
typename AT::Bounding_box operator()(ConstPrimitiveIterator first,
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)
{
bbox = bbox + compute_bbox(*first,m_traits);
bbox = bbox + m_traits.compute_bbox(*first,m_traits.bbm);
}
return bbox;
}
};
Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);}
class Do_intersect {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits;
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public:
Do_intersect(const AABB_traits<GeomTraits,AABBPrimitive>& traits)
Do_intersect(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& traits)
:m_traits(traits) {}
template<typename Query>
@ -357,9 +366,9 @@ public:
Do_intersect do_intersect_object() const {return Do_intersect(*this);}
class Intersection {
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits;
const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& m_traits;
public:
Intersection(const AABB_traits<GeomTraits,AABBPrimitive>& traits)
Intersection(const AABB_traits<GeomTraits,AABBPrimitive,BboxMap>& traits)
:m_traits(traits) {}
#if CGAL_INTERSECTION_VERSION < 2
template<typename Query>
@ -394,9 +403,9 @@ public:
class Closest_point {
typedef typename AT::Point_3 Point;
typedef typename AT::Primitive Primitive;
const AABB_traits<GeomTraits,AABBPrimitive>& m_traits;
const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& m_traits;
public:
Closest_point(const AABB_traits<GeomTraits,AABBPrimitive>& traits)
Closest_point(const AABB_traits<GeomTraits,AABBPrimitive, BboxMap>& 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<GeomTraits,AABBPrimitive>& traits)
template <typename PM>
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,
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<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),
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),
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),
internal::Primitive_helper<AT>::get_reference_point(pr2,traits) );
@ -485,9 +500,9 @@ private:
//-------------------------------------------------------
// Private methods
//-------------------------------------------------------
template<typename GT, typename P>
typename AABB_traits<GT,P>::Axis
AABB_traits<GT,P>::longest_axis(const Bounding_box& bbox)
template<typename GT, typename P, typename B>
typename AABB_traits<GT,P,B>::Axis
AABB_traits<GT,P,B>::longest_axis(const Bounding_box& bbox)
{
const double dx = bbox.xmax() - bbox.xmin();
const double dy = bbox.ymax() - bbox.ymin();