Make the code matching the submission

- rename first_intersection_and_primitive to first_intersection
 - update examples and test
 - switch on the function doc
 - add implementation for first_intersected_primitive
This commit is contained in:
Sébastien Loriot 2016-04-25 12:38:43 +02:00
parent e2ed883dfc
commit 03f9c56c76
8 changed files with 113204 additions and 62 deletions

View File

@ -75,7 +75,7 @@ the corresponding intersection object, and stops after the first
encountered intersection. Note that the traversal order of the tree is encountered intersection. Note that the traversal order of the tree is
such that first herein does not refer to any particular ordering of such that first herein does not refer to any particular ordering of
the intersections with respect to the query. the intersections with respect to the query.
- Function `AABB_tree::first_intersected_primitive(Ray_3)` returns - Function `AABB_tree::first_intersected_primitive()` returns
the intersecting primitive id (if any) of the corresponding the intersecting primitive id (if any) of the corresponding
intersection object that is closest to the source of the ray. intersection object that is closest to the source of the ray.
@ -86,8 +86,8 @@ intersection objects with the input primitives.
- Function `AABB_tree::any_intersection()` detects and constructs the first - Function `AABB_tree::any_intersection()` detects and constructs the first
encountered intersection and constructs the corresponding object. This encountered intersection and constructs the corresponding object. This
function is fast as it stops after the first encountered intersection. function is fast as it stops after the first encountered intersection.
- Function `AABB_tree::first_intersection(Ray_3)` detects and constructs - Function `AABB_tree::first_intersection()` detects and constructs
the intersectin object that is closest to the source of the ray. the intersection object that is closest to the source of the ray.
\b Distance. An AABB tree computes the closest point from a \b Distance. An AABB tree computes the closest point from a

View File

@ -86,7 +86,7 @@ int main()
Point inside(0.1, 0.1, 0.1); Point inside(0.1, 0.1, 0.1);
Ray ray(inside,r); Ray ray(inside,r);
tree.first_intersection_and_primitive(ray); tree.first_intersection(ray);
return EXIT_SUCCESS; return EXIT_SUCCESS;
} }

View File

@ -1,17 +1,15 @@
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
#include <CGAL/AABB_tree.h>
#include <CGAL/AABB_traits.h>
#include <CGAL/AABB_face_graph_triangle_primitive.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/point_generators_3.h>
#include <algorithm> #include <algorithm>
#include <iterator> #include <iterator>
#include <boost/functional/value_factory.hpp> #include <boost/functional/value_factory.hpp>
#include <boost/timer/timer.hpp> #include <boost/timer/timer.hpp>
#include <CGAL/Simple_cartesian.h>
#include <CGAL/BVH_tree.h>
#include <CGAL/BVH_bbox_traits_3.h>
#include <CGAL/boost/graph/graph_traits_Polyhedron_3.h>
#include <CGAL/BVH_face_graph_triangle_primitive.h>
#include <CGAL/algorithm.h>
#include <CGAL/point_generators_3.h>
#include <CGAL/Exact_predicates_exact_constructions_kernel.h>
typedef CGAL::Epeck K; typedef CGAL::Epeck K;
typedef K::FT FT; typedef K::FT FT;
@ -20,9 +18,9 @@ typedef K::Vector_3 Vector;
typedef K::Segment_3 Segment; typedef K::Segment_3 Segment;
typedef K::Ray_3 Ray; typedef K::Ray_3 Ray;
typedef CGAL::Polyhedron_3<K> Polyhedron; typedef CGAL::Polyhedron_3<K> Polyhedron;
typedef CGAL::BVH_face_graph_triangle_primitive<Polyhedron> Primitive; typedef CGAL::AABB_face_graph_triangle_primitive<Polyhedron> Primitive;
typedef CGAL::BVH_bbox_traits_3<K, Primitive> Traits; typedef CGAL::AABB_traits<K, Primitive> Traits;
typedef CGAL::BVH_tree<Traits> Tree; typedef CGAL::AABB_tree<Traits> Tree;
typedef Tree::Primitive_id Primitive_id; typedef Tree::Primitive_id Primitive_id;
int main() int main()
@ -41,11 +39,11 @@ int main()
std::vector<Point> v1, v2; std::vector<Point> v1, v2;
v1.reserve(NB_RAYS); v2.reserve(NB_RAYS); v1.reserve(NB_RAYS); v2.reserve(NB_RAYS);
const float r = 2.0; const float rad = 2.0;
// Generate NB_RAYS*2 points that lie on a sphere of radius r. // Generate NB_RAYS*2 points that lie on a sphere of radius r.
CGAL::Random rand = CGAL::Random(23); // fix the seed to yield the same results each run CGAL::Random rand = CGAL::Random(23); // fix the seed to yield the same results each run
CGAL::cpp11::copy_n(CGAL::Random_points_on_sphere_3<Point>(r, rand), NB_RAYS, std::back_inserter(v1)); CGAL::cpp11::copy_n(CGAL::Random_points_on_sphere_3<Point>(rad, rand), NB_RAYS, std::back_inserter(v1));
CGAL::cpp11::copy_n(CGAL::Random_points_on_sphere_3<Point>(r, rand), NB_RAYS, std::back_inserter(v2)); CGAL::cpp11::copy_n(CGAL::Random_points_on_sphere_3<Point>(rad, rand), NB_RAYS, std::back_inserter(v2));
// Generate NB_RAYS using v1 as source and v2 as target. // Generate NB_RAYS using v1 as source and v2 as target.
std::vector<Ray> rays; std::vector<Ray> rays;
@ -53,12 +51,16 @@ int main()
std::transform(v1.begin(), v1.end(), v2.begin(), std::transform(v1.begin(), v1.end(), v2.begin(),
std::back_inserter(rays), boost::value_factory<Ray>()); std::back_inserter(rays), boost::value_factory<Ray>());
std::vector< boost::optional<Tree::template Intersection_and_primitive_id<Ray>::Type > >
intersections;
// Calculate intersections between rays and primitives. // Calculate intersections between rays and primitives.
std::vector< boost::optional<Tree::template Intersection_and_primitive_id<Ray>::Type > >
first_intersections;
for(std::vector<Ray>::iterator it = rays.begin(); it != rays.end(); ++it)
first_intersections.push_back(tree.first_intersection(*it));
//alternative if we are only intersected by the primitives
std::vector< boost::optional<Tree::Primitive_id> > intersected_primitives;
for(std::vector<Ray>::iterator it = rays.begin(); it != rays.end(); ++it) { for(std::vector<Ray>::iterator it = rays.begin(); it != rays.end(); ++it) {
prims2.push_back(tree.ray_intersection(*it, polyhedron.facets_begin())); intersected_primitives.push_back(tree.first_intersected_primitive(*it));
} }
return 0; return 0;

View File

@ -402,37 +402,51 @@ public:
}; };
// Returns the intersection and primitive id closest to the source point of the ray /// Returns the intersection and primitive id closest to the source point of the ray
// query. /// query.
// \tparam Ray must be the same as `AABBTraits::Ray_3` and /// \tparam Ray must be the same as `AABBTraits::Ray_3` and
// `do_intersect` predicates and intersections for it must be /// `do_intersect` predicates and intersections for it must be
// defined. /// defined.
// \tparam Skip a functor with an operator /// \tparam Skip a functor with an operator
// `bool operator()(const Primitive_id& id) const` /// `bool operator()(const Primitive_id& id) const`
// that returns `true` in order to skip the primitive. /// that returns `true` in order to skip the primitive.
// Defaults to a functor that always returns `false`. /// Defaults to a functor that always returns `false`.
// ///
// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to /// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to
// call this member function. /// call this member function.
template<typename Ray, typename SkipFunctor = False_functor> template<typename Ray, typename SkipFunctor>
boost::optional< typename Intersection_and_primitive_id<Ray>::Type > boost::optional< typename Intersection_and_primitive_id<Ray>::Type >
first_intersection_and_primitive(const Ray& query, const SkipFunctor& skip = SkipFunctor()) const; first_intersection(const Ray& query, const SkipFunctor& skip) const;
// Returns the primitive id closest to the source point of the ray template<typename Ray>
// query. boost::optional< typename Intersection_and_primitive_id<Ray>::Type >
// \tparam Ray must be the same as `AABBTraits::Ray_3` and first_intersection(const Ray& query) const
// `do_intersect` predicates and intersections for it must be {
// defined. return first_intersection(query, False_functor());
// \tparam Skip a functor with an operator }
// `bool operator()(const Primitive_id& id) const`
// that returns `true` in order to skip the primitive. /// Returns the primitive id closest to the source point of the ray
// Defaults to a functor that always returns `false`. /// query.
// /// \tparam Ray must be the same as `AABBTraits::Ray_3` and
// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to /// `do_intersect` predicates and intersections for it must be
// call this member function. /// defined.
template<typename Ray, typename SkipFunctor = False_functor> /// \tparam Skip a functor with an operator
/// `bool operator()(const Primitive_id& id) const`
/// that returns `true` in order to skip the primitive.
/// Defaults to a functor that always returns `false`.
///
/// `AABBTraits` must be a model of `AABBRayIntersectionTraits` to
/// call this member function.
template<typename Ray, typename SkipFunctor>
boost::optional<Primitive_id> boost::optional<Primitive_id>
first_intersected_primitive(const Ray& query, const SkipFunctor& skip = SkipFunctor()) const; first_intersected_primitive(const Ray& query, const SkipFunctor& skip) const;
template<typename Ray>
boost::optional<Primitive_id>
first_intersected_primitive(const Ray& query) const
{
return first_intersected_primitive(query, False_functor());
}
///@} ///@}
/// \name Distance Queries /// \name Distance Queries

View File

@ -187,7 +187,7 @@ private:
template<typename AABBTraits> template<typename AABBTraits>
template<typename Ray, typename SkipFunctor> template<typename Ray, typename SkipFunctor>
boost::optional< typename AABB_tree<AABBTraits>::template Intersection_and_primitive_id<Ray>::Type > boost::optional< typename AABB_tree<AABBTraits>::template Intersection_and_primitive_id<Ray>::Type >
AABB_tree<AABBTraits>::first_intersection_and_primitive(const Ray& query, AABB_tree<AABBTraits>::first_intersection(const Ray& query,
const SkipFunctor& skip) const { const SkipFunctor& skip) const {
CGAL_static_assertion_msg((boost::is_same<Ray, typename AABBTraits::Ray_3>::value), CGAL_static_assertion_msg((boost::is_same<Ray, typename AABBTraits::Ray_3>::value),
"Ray and Ray_3 must be the same type"); "Ray and Ray_3 must be the same type");
@ -213,10 +213,16 @@ AABB_tree<AABBTraits>::first_intersection_and_primitive(const Ray& query,
template<typename AABBTraits> template<typename AABBTraits>
template<typename Ray, typename SkipFunctor> template<typename Ray, typename SkipFunctor>
boost::optional<typename AABB_tree<AABBTraits>::Primitive_id> boost::optional<typename AABB_tree<AABBTraits>::Primitive_id>
first_intersected_primitive(const Ray& query, AABB_tree<AABBTraits>::first_intersected_primitive(const Ray& query,
const SkipFunctor& skip = SkipFunctor()) const const SkipFunctor& skip) const
{ {
boost::optional<
typename AABB_tree<AABBTraits>::
template Intersection_and_primitive_id<Ray>::Type > res =
first_intersection(query, skip);
if ( (bool) res )
return boost::make_optional( res->second );
return boost::none;
} }
} }

View File

@ -77,11 +77,13 @@ int main()
// polyhedron.make_tetrahedron(p, q, r, s); // polyhedron.make_tetrahedron(p, q, r, s);
} }
std::ifstream in("../bunny00.off"); std::ifstream in("data/bunny00.off");
if(in) if(in)
in >> polyhedron; in >> polyhedron;
else else{
std::cout << "error reading bunny" << std::endl; std::cout << "error reading bunny" << std::endl;
return 1;
}
Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron); Tree tree(faces(polyhedron).first, faces(polyhedron).second, polyhedron);
Tree::Bounding_box bbox = tree.bbox(); Tree::Bounding_box bbox = tree.bbox();
@ -132,7 +134,7 @@ int main()
} }
for(std::vector<Ray>::iterator it = rays.begin(); it != rays.end(); ++it) { for(std::vector<Ray>::iterator it = rays.begin(); it != rays.end(); ++it) {
primitives2.push_back(tree.ray_intersection(*it)); primitives2.push_back(tree.first_intersection(*it));
} }
CGAL_assertion_msg(primitives1.size() == primitives2.size(), "Different amount of primitives intersected."); CGAL_assertion_msg(primitives1.size() == primitives2.size(), "Different amount of primitives intersected.");
CGAL_assertion_msg(std::equal(primitives1.begin(), primitives1.end(), primitives2.begin()), CGAL_assertion_msg(std::equal(primitives1.begin(), primitives1.end(), primitives2.begin()),

File diff suppressed because it is too large Load Diff

View File

@ -149,9 +149,9 @@ and <code>src/</code> directories).
<!-- Spatial Searching and Sorting --> <!-- Spatial Searching and Sorting -->
<h3>3D Fast Intersection and Distance Computation</h3> <h3>3D Fast Intersection and Distance Computation</h3>
<ul> <ul>
<li>Add the functions <code>AABB_tree::first_intersection_and_primitive(Ray_3)</code> <li>Add the functions <code>AABB_tree::first_intersection()</code>
and <code>AABB_tree::first_intersected_primitive(Ray_3)</code> that computes and <code>AABB_tree::first_intersected_primitive()</code> that computes
the intersection which is closest to the source of the ray</li> the intersection which is closest to the source of a ray</li>
</ul> </ul>
<!-- Geometric Optimization --> <!-- Geometric Optimization -->
<!-- Interpolation --> <!-- Interpolation -->