From a1bdd02f36024df0f82f8d158f6c2956b76b8b1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 14 May 2012 17:22:07 +0000 Subject: [PATCH] The traits now has a base class that is used to access the reference_point and datum of a primitive. The base class is the one that will store additional data. --- .gitattributes | 1 + AABB_tree/TODO | 7 + AABB_tree/include/CGAL/AABB_primitive.h | 16 +- AABB_tree/include/CGAL/AABB_traits.h | 236 +++++++++++++++--------- AABB_tree/include/CGAL/AABB_tree.h | 4 +- 5 files changed, 165 insertions(+), 99 deletions(-) create mode 100644 AABB_tree/TODO diff --git a/.gitattributes b/.gitattributes index 82cf57c06a2..794ac8cd026 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,4 +1,5 @@ * text=auto !eol +AABB_tree/TODO -text AABB_tree/demo/AABB_tree/AABB_demo.pdf -text svneol=unset#application/pdf AABB_tree/demo/AABB_tree/AABB_demo.ppt -text svneol=unset#application/vnd.ms-powerpoint AABB_tree/demo/AABB_tree/AABB_demo.qrc -text diff --git a/AABB_tree/TODO b/AABB_tree/TODO new file mode 100644 index 00000000000..ba916944c75 --- /dev/null +++ b/AABB_tree/TODO @@ -0,0 +1,7 @@ +*DOC: + - AABB_traits: + get_datum, get_reference_point, Extra_data + - AABB_primitive: ExternalPropertyMaps tag + -AABBPrimitive: Extra_data, Datum_reference, Point_reference + - On the Wiki: Traversal_traits must know the traits! + \ No newline at end of file diff --git a/AABB_tree/include/CGAL/AABB_primitive.h b/AABB_tree/include/CGAL/AABB_primitive.h index 76d8f769661..0823d52eda7 100644 --- a/AABB_tree/include/CGAL/AABB_primitive.h +++ b/AABB_tree/include/CGAL/AABB_primitive.h @@ -39,8 +39,8 @@ struct AABB_primitive_base { typedef typename boost::property_traits< ObjectPropertyMap >::value_type Datum; //datum type typedef typename boost::property_traits< PointPropertyMap >::value_type Point; //point type - typedef typename boost::property_traits< ObjectPropertyMap >::reference Datum_ref; //reference datum type - typedef typename boost::property_traits< PointPropertyMap >::reference Point_ref; //reference point type + typedef typename boost::property_traits< ObjectPropertyMap >::reference Datum_reference; //reference datum type + typedef typename boost::property_traits< PointPropertyMap >::reference Point_reference; //reference point type typedef Id_ Id; // Id type protected: @@ -76,10 +76,10 @@ public: AABB_primitive(Id id, ObjectPropertyMap obj_pmap=ObjectPropertyMap(), PointPropertyMap pt_pmap=PointPropertyMap()) : Base(id), m_obj_pmap(obj_pmap), m_pt_pmap(pt_pmap) {} - typename Base::Datum_ref + typename Base::Datum_reference datum() const { return get(m_obj_pmap,this->m_id); } - typename Base::Point_ref + typename Base::Point_reference reference_point() const { return get(m_pt_pmap,this->m_id); } }; @@ -100,7 +100,7 @@ public: const typename Base::Datum& datum() const { return m_datum; } - typename Base::Point_ref + typename Base::Point_reference reference_point() const { return get(m_pt_pmap,this->m_id); } }; @@ -118,10 +118,10 @@ public: AABB_primitive(Id id, ObjectPropertyMap=ObjectPropertyMap(), PointPropertyMap=PointPropertyMap()) : Base(id) {} - typename Base::Datum_ref + typename Base::Datum_reference datum(const Extra_data& data) const { return get(data.first,this->m_id); } - typename Base::Point_ref + typename Base::Point_reference reference_point(const Extra_data& data) const { return get(data.second,this->m_id); } }; @@ -144,7 +144,7 @@ public: const typename Base::Datum& datum(Extra_data) const { return m_datum; } - typename Base::Point_ref + typename Base::Point_reference reference_point(Extra_data data) const { return get(data,this->m_id); } }; diff --git a/AABB_tree/include/CGAL/AABB_traits.h b/AABB_tree/include/CGAL/AABB_traits.h index 4ee6f62d955..eedac57ed66 100644 --- a/AABB_tree/include/CGAL/AABB_traits.h +++ b/AABB_tree/include/CGAL/AABB_traits.h @@ -30,25 +30,61 @@ #include #include +#include +#include namespace CGAL { + +namespace internal{ + +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Extra_data,Extra_data,false) + +//for backward compatibility (if auto is available, use it) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Datum_reference,Datum_reference,false) +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_nested_type_Point_reference,Point_reference,false) + +template::value> +struct Datum_result_type{ typedef typename Primitive::Datum_reference type; }; + +template +struct Datum_result_type{ typedef typename Primitive::Datum type; }; + +template::value> +struct Point_result_type{ typedef typename Primitive::Point_reference type; }; + +template +struct Point_result_type{ typedef typename Primitive::Point type; }; + +//helper controlling whether extra data should be stored in the AABB_tree traits class +template ::value> +struct Primitive_helper; + +template +struct Primitive_helper{ + typename Datum_result_type::type get_datum(const Primitive& p) const {return p.datum();} + typename Point_result_type::type get_reference_point(const Primitive& p) const {return p.reference_point();} +}; + +} + /** * @class AABB_traits * * */ -template -class AABB_traits +template +class AABB_traits: + public internal::Primitive_helper { public: - typedef AABB_traits AT; + typedef AABB_traits AT; /// AABBTraits concept types typedef typename CGAL::Bbox_3 Bounding_box; typedef typename CGAL::Object Object; - typedef AABB_primitive Primitive; - typedef typename AABB_primitive::Datum Datum; + typedef AABBPrimitive Primitive; + typedef typename AABBPrimitive::Datum Datum; typedef typename GeomTraits::Point_3 Point; @@ -88,33 +124,37 @@ public: * axis, using the comparison function _less_than (dim in {x,y,z}) */ -class Sort_primitives -{ -public: -template -void operator()(PrimitiveIterator first, - PrimitiveIterator beyond, - const typename AT::Bounding_box& bbox) const + class Sort_primitives { - PrimitiveIterator middle = first + (beyond - first)/2; - switch(longest_axis(bbox)) - { - case AT::CGAL_AXIS_X: // sort along x - std::nth_element(first, middle, beyond, less_x); - break; - case AT::CGAL_AXIS_Y: // sort along y - std::nth_element(first, middle, beyond, less_y); - break; - case AT::CGAL_AXIS_Z: // sort along z - std::nth_element(first, middle, beyond, less_z); - break; - default: - CGAL_error(); - } - } -}; + const AABB_traits& m_traits; + public: + Sort_primitives(const AABB_traits& traits) + : m_traits(traits) {} + + template + void operator()(PrimitiveIterator first, + PrimitiveIterator beyond, + const typename AT::Bounding_box& bbox) const + { + PrimitiveIterator middle = first + (beyond - first)/2; + switch(longest_axis(bbox)) + { + case AT::CGAL_AXIS_X: // sort along x + std::nth_element(first, middle, beyond, boost::bind(less_x,_1,_2,m_traits)); + break; + case AT::CGAL_AXIS_Y: // sort along y + std::nth_element(first, middle, beyond, boost::bind(less_y,_1,_2,m_traits)); + break; + case AT::CGAL_AXIS_Z: // sort along z + std::nth_element(first, middle, beyond, boost::bind(less_z,_1,_2,m_traits)); + break; + default: + CGAL_error(); + } + } + }; -Sort_primitives sort_primitives_object() const {return Sort_primitives();} + Sort_primitives sort_primitives_object() const {return Sort_primitives(*this);} /** @@ -124,69 +164,86 @@ Sort_primitives sort_primitives_object() const {return Sort_primitives();} * @return the bounding box of the primitives of the iterator range */ - class Compute_bbox { -public: -template -typename AT::Bounding_box operator()(ConstPrimitiveIterator first, - ConstPrimitiveIterator beyond) const - { - typename AT::Bounding_box bbox = compute_bbox(*first); - for(++first; first != beyond; ++first) + class Compute_bbox { + const AABB_traits& m_traits; + public: + Compute_bbox(const AABB_traits& traits) + :m_traits (traits) {} + + template + typename AT::Bounding_box operator()(ConstPrimitiveIterator first, + ConstPrimitiveIterator beyond) const + { + typename AT::Bounding_box bbox = compute_bbox(*first,m_traits); + for(++first; first != beyond; ++first) + { + bbox = bbox + compute_bbox(*first,m_traits); + } + return bbox; + } + }; + + Compute_bbox compute_bbox_object() const {return Compute_bbox(*this);} + + + class Do_intersect { + const AABB_traits& m_traits; + public: + Do_intersect(const AABB_traits& traits) + :m_traits(traits) {} + + template + bool operator()(const Query& q, const Bounding_box& bbox) const { - bbox = bbox + compute_bbox(*first); + return CGAL::do_intersect(q, bbox); } - return bbox; - } -}; -Compute_bbox compute_bbox_object() const {return Compute_bbox();} + template + bool operator()(const Query& q, const Primitive& pr) const + { + return GeomTraits().do_intersect_3_object()(q, m_traits.get_datum(pr)); + } + }; + Do_intersect do_intersect_object() const {return Do_intersect(*this);} -class Do_intersect { -public: - template - bool operator()(const Query& q, const Bounding_box& bbox) const - { - return CGAL::do_intersect(q, bbox); - } + class Intersection { + const AABB_traits& m_traits; + public: + Intersection(const AABB_traits& traits) + :m_traits(traits) {} - template - bool operator()(const Query& q, const Primitive& pr) const - { - return GeomTraits().do_intersect_3_object()(q, pr.datum()); - } -}; + template + boost::optional + operator()(const Query& query, const typename AT::Primitive& primitive) const + { + typedef boost::optional Intersection; -Do_intersect do_intersect_object() const {return Do_intersect();} + CGAL::Object object = GeomTraits().intersect_3_object()(m_traits.get_datum(primitive),query); + if ( object.empty() ) + return Intersection(); + else + return Intersection(Object_and_primitive_id(object,primitive.id())); + } + }; -class Intersection { -public: -template -boost::optional -operator()(const Query& query, const typename AT::Primitive& primitive) const -{ - typedef boost::optional Intersection; - - CGAL::Object object = GeomTraits().intersect_3_object()(primitive.datum(),query); - if ( object.empty() ) - return Intersection(); - else - return Intersection(Object_and_primitive_id(object,primitive.id())); -} -}; - -Intersection intersection_object() const {return Intersection();} + Intersection intersection_object() const {return Intersection(*this);} // This should go down to the GeomTraits, i.e. the kernel class Closest_point { - typedef typename AT::Point Point; - typedef typename AT::Primitive Primitive; + typedef typename AT::Point Point; + typedef typename AT::Primitive Primitive; + const AABB_traits& m_traits; public: - Point operator()(const Point& p, const Primitive& pr, const Point& bound) const - { - return CGAL::nearest_point_3(p, pr.datum(), bound); - } + Closest_point(const AABB_traits& traits) + : m_traits(traits) {} + + + Point operator()(const Point& p, const Primitive& pr, const Point& bound) const + { + return CGAL::nearest_point_3(p, m_traits.get_datum(pr), bound); + } }; // This should go down to the GeomTraits, i.e. the kernel @@ -218,7 +275,7 @@ Intersection intersection_object() const {return Intersection();} } }; - Closest_point closest_point_object() const {return Closest_point();} + Closest_point closest_point_object() const {return Closest_point(*this);} Compare_distance compare_distance_object() const {return Compare_distance();} @@ -228,9 +285,10 @@ private: * @param pr the primitive * @return the bounding box of the primitive \c pr */ - static Bounding_box compute_bbox(const Primitive& pr) + static Bounding_box compute_bbox (const Primitive& pr, + const AABB_traits& traits) { - return pr.datum().bbox(); + return traits.get_datum(pr).bbox(); } typedef enum { CGAL_AXIS_X = 0, @@ -239,12 +297,12 @@ private: static Axis longest_axis(const Bounding_box& bbox); /// Comparison functions - static bool less_x(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().x() < pr2.reference_point().x(); } - static bool less_y(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().y() < pr2.reference_point().y(); } - static bool less_z(const Primitive& pr1, const Primitive& pr2) - { return pr1.reference_point().z() < pr2.reference_point().z(); } + static bool less_x(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + { return traits.get_reference_point(pr1).x() < traits.get_reference_point(pr2).x(); } + static bool less_y(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + { return traits.get_reference_point(pr1).y() < traits.get_reference_point(pr2).y(); } + static bool less_z(const Primitive& pr1, const Primitive& pr2,const AABB_traits& traits) + { return traits.get_reference_point(pr1).z() < traits.get_reference_point(pr2).z(); } }; // end class AABB_traits diff --git a/AABB_tree/include/CGAL/AABB_tree.h b/AABB_tree/include/CGAL/AABB_tree.h index 2ecb8ed6fd7..76711341984 100644 --- a/AABB_tree/include/CGAL/AABB_tree.h +++ b/AABB_tree/include/CGAL/AABB_tree.h @@ -223,7 +223,7 @@ public: Point_and_primitive_id any_reference_point_and_id() const { CGAL_assertion(!empty()); - return Point_and_primitive_id(m_primitives[0].reference_point(), m_primitives[0].id()); + return Point_and_primitive_id(m_traits.get_reference_point(m_primitives[0]), m_primitives[0].id()); } public: @@ -405,7 +405,7 @@ public: points.reserve(m_primitives.size()); typename Primitives::const_iterator it; for(it = m_primitives.begin(); it != m_primitives.end(); ++it) - points.push_back(Point_and_primitive_id(it->reference_point(), it->id())); + points.push_back(Point_and_primitive_id(m_traits.get_reference_point(*it), it->id())); // clears current KD tree clear_search_tree();