diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 5bfef5a008e..58eb27416b3 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -169,7 +169,11 @@ namespace CGAL { } /// Returns the axis-aligned bounding box of the whole tree. - const Bounding_box& bbox() const { return root_node()->bbox(); } + /// \pre `!empty()` + const Bounding_box& bbox() const { + CGAL_precondition(!empty()); + return root_node()->bbox(); + } /// Returns the number of primitives in the tree. size_type size() const { return m_primitives.size(); } @@ -255,6 +259,7 @@ public: /// `accelerate_distance_queries()` should be called before the /// first distance query, so that an internal secondary search /// structure is build, for improving performance. + /// \pre `!empty()` FT squared_distance(const Point& query) const; /// Returns the point in the union of all input primitives which @@ -264,6 +269,7 @@ public: /// called before the first distance query, so that an internal /// secondary search structure is build, for improving /// performance. + /// \pre `!empty()` Point closest_point(const Point& query) const; @@ -273,6 +279,7 @@ public: /// called before the first distance query, so that an internal /// secondary search structure is build, for improving /// performance. + /// \pre `!empty()` Point_and_primitive_id closest_point_and_primitive(const Point& query) const; @@ -357,17 +364,20 @@ public: /// Returns the minimum squared distance between the query point /// and all input primitives. The internal KD-tree is not used. + /// \pre `!empty()` FT squared_distance(const Point& query, const Point& hint) const; /// Returns the point in the union of all input primitives which /// is closest to the query. In case there are several closest /// points, one arbitrarily chosen closest point is returned. The /// internal KD-tree is not used. + /// \pre `!empty()` Point closest_point(const Point& query, const Point& hint) const; /// Returns a `Point_and_primitive_id` which realizes the /// smallest distance between the query point and all input /// primitives. The internal KD-tree is not used. + /// \pre `!empty()` Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const; ///@} @@ -397,8 +407,6 @@ public: { if(!empty()) root_node()->template traversal(query, traits, m_primitives.size()); - else - std::cerr << "AABB tree traversal with empty tree" << std::endl; } private: @@ -526,21 +534,22 @@ public: { clear_nodes(); - CGAL_assertion(m_primitives.size() > 1); + if(m_primitives.size() > 1) { - // allocates tree nodes - m_p_root_node = new Node[m_primitives.size()-1](); - if(m_p_root_node == NULL) - { - std::cerr << "Unable to allocate memory for AABB tree" << std::endl; - CGAL_assertion(m_p_root_node != NULL); - m_primitives.clear(); - clear(); + // allocates tree nodes + m_p_root_node = new Node[m_primitives.size()-1](); + if(m_p_root_node == NULL) + { + std::cerr << "Unable to allocate memory for AABB tree" << std::endl; + CGAL_assertion(m_p_root_node != NULL); + m_primitives.clear(); + clear(); + } + + // constructs the tree + m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); } - // constructs the tree - m_p_root_node->expand(m_primitives.begin(), m_primitives.end(), m_primitives.size()); - // In case the users has switched on the acceletated distance query // data structure with the default arguments, then it has to be // rebuilt. @@ -575,7 +584,7 @@ public: template bool AABB_tree::accelerate_distance_queries() const { - CGAL_assertion(!m_primitives.empty()); + if(m_primitives.empty()) return true; #ifdef CGAL_HAS_THREADS //this ensures that this function will be done once boost::mutex::scoped_lock scoped_lock(kd_tree_mutex); @@ -686,6 +695,7 @@ public: AABB_tree::closest_point(const Point& query, const Point& hint) const { + CGAL_precondition(!empty()); typename Primitive::Id hint_primitive = m_primitives[0].id(); using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; @@ -700,6 +710,7 @@ public: typename AABB_tree::Point AABB_tree::closest_point(const Point& query) const { + CGAL_precondition(!empty()); const Point_and_primitive_id hint = best_hint(query); return closest_point(query,hint.first); } @@ -710,6 +721,7 @@ public: AABB_tree::squared_distance(const Point& query, const Point& hint) const { + CGAL_precondition(!empty()); const Point closest = this->closest_point(query, hint); return Tr().squared_distance_object()(query, closest); } @@ -719,6 +731,7 @@ public: typename AABB_tree::FT AABB_tree::squared_distance(const Point& query) const { + CGAL_precondition(!empty()); const Point closest = this->closest_point(query); return Tr().squared_distance_object()(query, closest); } @@ -728,6 +741,7 @@ public: typename AABB_tree::Point_and_primitive_id AABB_tree::closest_point_and_primitive(const Point& query) const { + CGAL_precondition(!empty()); return closest_point_and_primitive(query,best_hint(query)); } @@ -737,6 +751,7 @@ public: AABB_tree::closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const { + CGAL_precondition(!empty()); using namespace CGAL::internal::AABB_tree; typedef typename AABB_tree::AABB_traits AABBTraits; Projection_traits projection_traits(hint.first,hint.second); @@ -748,8 +763,8 @@ public: #endif // CGAL_AABB_TREE_H -/***EMACS SETTINGS***/ -/* Local Variables: */ -/* tab-width: 2 */ -/* End: */ - +/***EMACS SETTINGS** */ +/* Local Variables: */ +/* tab-width: 2 */ +/* indent-tabs-mode: t */ +/* End: */ diff --git a/AABB_tree/test/AABB_tree/AABB_test_empty_tree.cpp b/AABB_tree/test/AABB_tree/AABB_test_empty_tree.cpp new file mode 100644 index 00000000000..63b72a7d4e9 --- /dev/null +++ b/AABB_tree/test/AABB_tree/AABB_test_empty_tree.cpp @@ -0,0 +1,57 @@ +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K; + +typedef K::FT FT; +typedef K::Point_3 Point; +typedef K::Plane_3 Plane; +typedef K::Segment_3 Segment; +typedef K::Triangle_3 Triangle; + +typedef std::vector::iterator Iterator; +typedef CGAL::AABB_segment_primitive Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree Tree; + +int main() +{ + Point a(1.0, 0.0, 0.0); + Point b(0.0, 1.0, 0.0); + Point c(0.0, 0.0, 1.0); + Point d(0.0, 0.0, 0.0); + + Tree tree; + Plane plane_query(a,b,d); + Triangle triangle_query(a,b,c); + + // Test calls to all functions but those who have `!empty()` as + // precondition. + CGAL::Emptyset_iterator devnull; + tree.accelerate_distance_queries(); + tree.all_intersections(triangle_query, devnull); + tree.all_intersected_primitives(triangle_query, devnull); + assert(!tree.any_intersected_primitive(triangle_query)); + assert(!tree.any_intersection(triangle_query)); + //Cannot call tree.bbox(); + tree.build(); + tree.clear(); + //Cannot call tree.closest_*(...) + assert(tree.do_intersect(plane_query) == false); + assert(tree.do_intersect(triangle_query) == false); + assert(tree.empty()); + //Do not call tree.insert(...) + assert(tree.number_of_intersected_primitives(plane_query) == 0); + assert(tree.number_of_intersected_primitives(triangle_query) == 0); + // Cannot call tree.rebuild(..) + assert(tree.size() == 0); + // Cannot call tree.squared_distance(..) + + return EXIT_SUCCESS; +}