From 01d0293bc5abd3a6a1e14e88aa96c6bf8500e7d7 Mon Sep 17 00:00:00 2001 From: Camille Wormser Date: Fri, 8 May 2009 12:59:22 +0000 Subject: [PATCH] Code is now almost up to the specification: Primitive::Id everywhere, the KD-tree uses decorated points to return the Id too. There are just a few boost::optional to add in the traits, where we still use the old bool intersection(..., Result&) approach, and some modernization to do in the distance computation things. Everything compiles. I have removed the funtion closest_primitive from the code and documentation, since it would not be consistent with the rest of the interface, and would not be faster than closest_point_and_primitive. I think we are almost done, not only for the documentation, but for the code too. --- AABB_tree/doc_tex/AABB_tree/interface.tex | 2 +- AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex | 5 -- AABB_tree/include/CGAL/AABB_search_tree.h | 45 +++++++++-- AABB_tree/include/CGAL/AABB_traits.h | 8 +- AABB_tree/include/CGAL/AABB_tree.h | 75 +++++++++---------- 5 files changed, 78 insertions(+), 57 deletions(-) diff --git a/AABB_tree/doc_tex/AABB_tree/interface.tex b/AABB_tree/doc_tex/AABB_tree/interface.tex index 8afd0a27669..e1c56b4170e 100644 --- a/AABB_tree/doc_tex/AABB_tree/interface.tex +++ b/AABB_tree/doc_tex/AABB_tree/interface.tex @@ -24,6 +24,6 @@ Intersections: \item Function \ccc{any_intersection} detects and constructs the first encountered intersection and constructs the corresponding object. This function is fast as it stops at the first encountered intersection. \end{itemize} -\paragraph{Distance.} An AABB tree computes the closest point from a given point query to the input primitives through the function \ccc{closest_point(query,hint)}. In addition, it can compute the id of the closest primitive from a given point query through the functions \ccc{closest_point_and_primitive(query,hint)} and \ccc{closest_primitive(query,hint)}, i.e., the id of the primitive which realizes the minimum distance from the point query. The latter function is a loose version of the former in the sense that it does not return the point on this primitive which is the closest. This is often sufficient in some applications to know which primitive is closer. The hint parameter, which can be omitted, provides a way to indicate an initial first guess. Although this hint can be chosen arbitrarily, the closer from the query the faster. The hint has the same type as the return type. In case a point is provided as a hint (or a point and a primitive), the point must lie on some primitive. Note that this is not always possible without an exact constructions kernel, if the hint is not a vertex. It may then happen that the hint is closer to the query than any of the primitives. In such a case, the hint is returned.\\ +\paragraph{Distance.} An AABB tree computes the closest point from a given point query to the input primitives through the function \ccc{closest_point(query,hint)}. In addition, it can compute the id of the closest primitive from a given point query through the function \ccc{closest_point_and_primitive(query,hint)}, i.e., the id of the primitive which realizes the minimum distance from the point query. The hint parameter, which can be omitted, provides a way to indicate an initial first guess. Although this hint can be chosen arbitrarily, the closer from the query the faster. The hint has the same type as the return type. In case a point is provided as a hint (or a point and a primitive), the point must lie on some primitive. Note that this is not always possible without an exact constructions kernel, if the hint is not a vertex. It may then happen that the hint is closer to the query than any of the primitives. In such a case, the hint is returned.\\ In case the hint is omitted, the AABB tree provides the option to compute one closest hint point by using an internal KD-tree which contains a point sampling of the primitives. This option, which increases the performances is activated if, and only if the construction of the KD-tree has been requested by a call to one of the two \ccc{accelerate_distance_queries} methods. Note that, by default, the method \ccc{reference_point} of the primitives is used to generate the point sampling. However, the user may prefer to provide the point sampling with \ccc{accelerate_distance_queries(InputIterator begin, InputIterator beyond)} rather than relying on the default one which takes one reference point per primitive. If some triangles are very large, it helps inserting more than one sample on these large triangles. Conversely, a sparser sampling with less than one point per primitive is relevant in some cases. For the case where the primitives are the faces of a triangle surface mesh the specified point sampling may be provided as the vertex points of the mesh vertices. \ No newline at end of file diff --git a/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex b/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex index 4c2242b6825..e85fd6276f1 100644 --- a/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex +++ b/AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex @@ -130,11 +130,6 @@ closest_point(const Point& query, const Point& hint);} {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. ÊParameter \ccc{hint} is assumed to be any point located on the input primitives (the closer \ccc{hint} to \ccc{query}, the faster). If \ccc{hint} is closer to \ccc{query} than any of the primitives, \ccc{hint} is returned. Parameter \ccc{hint} can be omitted. If the internal KD-tree data structure has been constructed using function \ccc{accelerate_distance_queries} (see below), it is used to efficiently query the nearest hint point from the query, among a set of hint points stored in the internal KD-tree. Otherwise, the first primitive reference point is chosen as a naive hint point.} -\ccMethod{Primitive::Id -closest_primitive(const Point& query, - const Primitive::Id& hint);} -{Returns the id of the primitive which realizes the smallest distance between the query point and all input primitives. Parameter \ccc{hint} is assumed to be the id of any input primitive (the closer \ccc{hint} to \ccc{query}, the faster). Parameter \ccc{hint} can be omitted. If the internal KD-tree data structure has been constructed using function \ccc{accelerate_distance_queries} (see below), it is used to efficiently query the nearest hint primitive from the query, among a set of hint primitives stored in the internal KD-tree. Otherwise, the first primitive is chosen as a naive hint.} - \ccMethod{Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint);} diff --git a/AABB_tree/include/CGAL/AABB_search_tree.h b/AABB_tree/include/CGAL/AABB_search_tree.h index d4e42bcd182..a97e6a3425d 100644 --- a/AABB_tree/include/CGAL/AABB_search_tree.h +++ b/AABB_tree/include/CGAL/AABB_search_tree.h @@ -25,29 +25,58 @@ namespace CGAL { + template + class Add_decorated_point: public Underlying + { + class Decorated_point: public Underlying::Point_3 + { + public: + Id id; + Decorated_point(): Underlying::Point_3(), id(){} + // Allows the user not to provide the id + // so that we don't break existing code + Decorated_point(const typename Underlying::Point_3& p): Underlying::Point_3(p), id(){} + }; + public: + typedef Decorated_point Point_3; + }; + template class AABB_search_tree { public: typedef typename Traits::FT FT; typedef typename Traits::Point_3 Point; - typedef typename CGAL::Search_traits_3 TreeTraits; + typedef typename Traits::Point_and_primitive_id Point_and_primitive_id; + typedef typename CGAL::Search_traits_3 > TreeTraits; typedef typename CGAL::Orthogonal_k_neighbor_search Neighbor_search; typedef typename Neighbor_search::Tree Tree; private: - Tree m_tree; + Tree* m_tree; public: template - AABB_search_tree(ConstPointIterator begin, ConstPointIterator beyond): - m_tree(begin, beyond){} + AABB_search_tree(ConstPointIterator begin, ConstPointIterator beyond) + { + typedef typename Add_decorated_point::Point_3 Decorated_point; + std::vector points; + while(begin != beyond) { + points.push_back(Decorated_point(begin->first)); + points.back().id = begin->second; + ++begin; + } + m_tree = new Tree(points.begin(), points.end()); + } - ~AABB_search_tree() {} + ~AABB_search_tree() { + delete m_tree; + } // TOFIX: make it const - Point closest_point(const Point& query) + Point_and_primitive_id closest_point(const Point& query) { - Neighbor_search search(m_tree, query, 1); - return search.begin()->first; + typedef typename Add_decorated_point::Point_3 Decorated_point; + Neighbor_search search(*m_tree, query, 1); + return Point_and_primitive_id(static_cast(search.begin()->first), search.begin()->first.id); } }; diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 94378496938..f14754cf981 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -55,8 +55,8 @@ public: typedef typename GeomTraits::Point_3::Point Point; #endif - typedef typename std::pair Object_and_primitive; - typedef typename std::pair Point_and_primitive; + typedef typename std::pair Object_and_primitive_id; + typedef typename std::pair Point_and_primitive_id; // types for search tree // TOFIX: how can we avoid repeating those? @@ -128,7 +128,7 @@ public: template bool intersection(const Query& q, const Primitive& pr, - Object_and_primitive& result) const; + Object_and_primitive_id& result) const; Sphere sphere(const Point& center, const Point& hint) const @@ -215,7 +215,7 @@ template bool AABB_traits::intersection(const Query& query, const P& primitive, - Object_and_primitive& result) const + Object_and_primitive_id& result) const { // TODO: implement a real intersection construction method // do_intersect is needed here because we construct intersection between diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 14e0453599b..7be25dc61bb 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -43,8 +43,8 @@ namespace CGAL { typedef typename AABBTraits::Primitive Primitive; typedef typename AABBTraits::Size_type Size_type; typedef typename AABBTraits::Bounding_box Bounding_box; - typedef typename AABBTraits::Point_and_primitive Point_and_primitive; - typedef typename AABBTraits::Object_and_primitive Object_and_primitive; + typedef typename AABBTraits::Point_and_primitive_id Point_and_primitive_id; + typedef typename AABBTraits::Object_and_primitive_id Object_and_primitive_id; private: // internal KD-tree used to accelerate the distance queries @@ -118,19 +118,17 @@ namespace CGAL { // any intersection template - boost::optional any_intersected_primitive(const Query& query) const; + boost::optional any_intersected_primitive(const Query& query) const; template - boost::optional any_intersection(const Query& query) const; + boost::optional any_intersection(const Query& query) const; // distance queries FT squared_distance(const Point& query) const; FT squared_distance(const Point& query, const Point& hint) const; Point closest_point(const Point& query); Point closest_point(const Point& query, const Point& hint); - Primitive closest_primitive(const Point& query) const; - Primitive closest_primitive(const Point& query, const Point& hint) const; - Point_and_primitive closest_point_and_primitive(const Point& query) const; - Point_and_primitive closest_point_and_primitive(const Point& query, const Point& hint) const; + Point_and_primitive_id closest_point_and_primitive(const Point& query) const; + Point_and_primitive_id closest_point_and_primitive(const Point& query, const Point_and_primitive_id& hint) const; private: @@ -168,7 +166,7 @@ namespace CGAL { class First_intersection_traits { public: - typedef typename boost::optional Result; + typedef typename boost::optional Result; public: First_intersection_traits() : m_is_found(false) @@ -178,7 +176,7 @@ namespace CGAL { void intersection(const Query& query, const Primitive& primitive) { - Object_and_primitive op; + Object_and_primitive_id op; m_is_found = AABBTraits().intersection(query, primitive, op); if(m_is_found) m_result = Result(op); @@ -240,14 +238,13 @@ namespace CGAL { { public: Listing_intersection_traits(Output_iterator out_it) - : m_intersection() - , m_out_it(out_it) {} + : m_out_it(out_it) {} bool go_further() const { return true; } void intersection(const Query& query, const Primitive& primitive) { - Object_and_primitive intersection; + Object_and_primitive_id intersection; if( AABBTraits().intersection(query, primitive, intersection) ) { *m_out_it++ = intersection; @@ -280,7 +277,7 @@ namespace CGAL { { if( AABBTraits().do_intersect(query, primitive) ) { - *m_out_it++ = primitive; + *m_out_it++ = primitive.id(); } } @@ -311,7 +308,7 @@ namespace CGAL { { if( AABBTraits().do_intersect(query, primitive) ) { - m_result = boost::optional(primitive); + m_result = boost::optional(primitive.id()); m_is_found = true; } } @@ -321,12 +318,12 @@ namespace CGAL { return AABBTraits().do_intersect(query, node.bbox()); } - boost::optional result() const { return m_result; } + boost::optional result() const { return m_result; } bool is_intersection_found() const { return m_is_found; } private: bool m_is_found; - boost::optional m_result; + boost::optional m_result; }; /** @@ -337,7 +334,7 @@ namespace CGAL { public: Distance_traits(const Point& query, const Point& hint, - const Primitive& hint_primitive) + const typename Primitive::Id& hint_primitive) : m_closest_point(hint), m_closest_primitive(hint_primitive), m_sphere(AABBTraits().sphere(query,hint)) @@ -353,7 +350,7 @@ namespace CGAL { AABBTraits().closest_point(query, primitive, m_closest_point); if(new_closest_point != m_closest_point) { - m_closest_primitive = primitive; + m_closest_primitive = primitive.id(); m_closest_point = new_closest_point; } m_sphere = AABBTraits().sphere(query, m_closest_point); @@ -365,29 +362,29 @@ namespace CGAL { } Point closest_point() const { return m_closest_point; } - Primitive closest_primitive() const { return m_closest_primitive; } + typename Primitive::Id closest_primitive() const { return m_closest_primitive; } private: Sphere m_sphere; Point m_closest_point; - Primitive m_closest_primitive; + typename Primitive::Id m_closest_primitive; }; private: // returns a point guaranteed to be on one primitive - Point any_reference_point() + Point_and_primitive_id any_reference_point_and_id() { CGAL_assertion(!empty()); - return m_data[0].reference_point(); + return Point_and_primitive_id(m_data[0].reference_point(), m_data[0].id()); } public: - Point best_hint(const Point& query) + Point_and_primitive_id best_hint(const Point& query) { if(m_search_tree_constructed) return m_p_search_tree->closest_point(query); else - return this->any_reference_point(); + return this->any_reference_point_and_id(); } private: @@ -494,10 +491,10 @@ namespace CGAL { CGAL_assertion(!m_data.empty()); // iterate over primitives to get reference points on them - std::vector points; + std::vector points; typename std::vector::const_iterator it; for(it = m_data.begin(); it != m_data.end(); ++it) - points.push_back(it->reference_point()); + points.push_back(Point_and_primitive_id(it->reference_point(), it->id())); return accelerate_distance_queries(points.begin(), points.end()); } @@ -546,7 +543,7 @@ namespace CGAL { template template - boost::optional + boost::optional::Object_and_primitive_id> AABB_tree::any_intersection(const Query& query) const { First_intersection_traits traversal_traits; @@ -556,7 +553,7 @@ namespace CGAL { template template - boost::optional + boost::optional::Primitive::Id> AABB_tree::any_intersected_primitive(const Query& query) const { First_primitive_traits traversal_traits; @@ -570,7 +567,7 @@ namespace CGAL { AABB_tree::closest_point(const Point& query, const Point& hint) { - Primitive hint_primitive = m_data[0]; + typename Primitive::Id hint_primitive = m_data[0].id(); Distance_traits distance_traits(query,hint,hint_primitive); this->traversal(query, distance_traits); return distance_traits.closest_point(); @@ -582,8 +579,8 @@ namespace CGAL { typename AABB_tree::Point AABB_tree::closest_point(const Point& query) { - const Point hint = best_hint(query); - return closest_point(query,hint); + const Point_and_primitive_id hint = best_hint(query); + return closest_point(query,hint.first); } // squared distance with user-specified hint @@ -607,20 +604,20 @@ namespace CGAL { // closest point with user-specified hint template - typename AABB_tree::Primitive - AABB_tree::closest_primitive(const Point& query) const + typename AABB_tree::Point_and_primitive_id + AABB_tree::closest_point_and_primitive(const Point& query) const { return closest_primitive(query,best_hint(query)); } // closest point with user-specified hint template - typename AABB_tree::Primitive - AABB_tree::closest_primitive(const Point& query, - const Point& hint) const + typename AABB_tree::Point_and_primitive_id + AABB_tree::closest_point_and_primitive(const Point& query, + const Point_and_primitive_id& hint) const { - const Point hint = best_hint(query); - Distance_traits distance_traits(query,hint,any_primitive()); +// const Point hint = best_hint(query); + Distance_traits distance_traits(query,hint.first,hint.second); this->traversal(query, distance_traits); return distance_traits.closest_primitive(); }