From be1de01b22d79e8dd72b34cf2ba30b7f97b1fdc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 10 May 2012 15:51:45 +0000 Subject: [PATCH] *update AABB_primitive: the property maps must operate on Id! *correct and complete implementation for HalfhedgeGraph models --- .gitattributes | 1 + .../AABB_HalfedgeGraph_edge_example.cpp | 63 +++++++++++ .../AABB_tree/AABB_segment_3_example.cpp | 2 +- .../AABB_tree/AABB_triangle_3_example.cpp | 2 +- .../CGAL/AABB_FaceGraph_triangle_primitive.h | 12 +- .../AABB_HalfedgeGraph_segment_primitive.h | 15 +-- AABB_tree/include/CGAL/AABB_primitive.h | 12 +- .../include/CGAL/AABB_segment_primitive.h | 33 +++--- .../include/CGAL/AABB_triangle_primitive.h | 30 ++--- .../internal/AABB_tree/Primitive_caching.h | 6 +- .../include/CGAL/property_map.h | 25 +++++ .../include/CGAL/Polyhedron_3_property_map.h | 103 +++++++++--------- 12 files changed, 198 insertions(+), 106 deletions(-) create mode 100644 AABB_tree/examples/AABB_tree/AABB_HalfedgeGraph_edge_example.cpp diff --git a/.gitattributes b/.gitattributes index ab5ae9e5ffb..90dd85099a9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -34,6 +34,7 @@ AABB_tree/doc_tex/AABB_tree_ref/AABB_tree.tex -text AABB_tree/doc_tex/AABB_tree_ref/introduction.tex -text AABB_tree/doc_tex/AABB_tree_ref/main.tex -text AABB_tree/dont_submit -text +AABB_tree/examples/AABB_tree/AABB_HalfedgeGraph_edge_example.cpp -text AABB_tree/examples/AABB_tree/cleanup.bat -text AABB_tree/include/CGAL/AABB_FaceGraph_triangle_primitive.h -text AABB_tree/include/CGAL/AABB_HalfedgeGraph_segment_primitive.h -text diff --git a/AABB_tree/examples/AABB_tree/AABB_HalfedgeGraph_edge_example.cpp b/AABB_tree/examples/AABB_tree/AABB_HalfedgeGraph_edge_example.cpp new file mode 100644 index 00000000000..5c25f1f3e48 --- /dev/null +++ b/AABB_tree/examples/AABB_tree/AABB_HalfedgeGraph_edge_example.cpp @@ -0,0 +1,63 @@ +// Author(s) : Pierre Alliez + +#include + +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K; +typedef K::FT FT; +typedef K::Point_3 Point; +typedef K::Triangle_3 Triangle; +typedef CGAL::Polyhedron_3 Polyhedron; +typedef CGAL::AABB_HalfedgeGraph_segment_primitive Primitive; +typedef CGAL::AABB_traits Traits; +typedef CGAL::AABB_tree Tree; + +template +void run(const HalfedgeGraph& graph){ + typename Kernel::Point_3 p(1.0, 0.0, 0.0); + typename Kernel::Point_3 q(0.0, 1.0, 0.0); + typename Kernel::Point_3 r(0.0, 0.0, 1.0); + + typedef typename boost::graph_traits::edge_descriptor edge_descriptor; + + // constructs the AABB tree and the internal search tree for + // efficient distance queries. + Tree tree(boost::make_transform_iterator(boost::edges(graph).first, + boost::bind(&std::make_pair, + &graph, _1)), + boost::make_transform_iterator(boost::edges(graph).second, + boost::bind(&std::make_pair, + &graph, _1))); + tree.accelerate_distance_queries(); + + // counts #intersections with a triangle query + Triangle triangle_query(p,q,r); + std::cout << tree.number_of_intersected_primitives(triangle_query) + << " intersections(s) with triangle" << std::endl; + + // computes the closest point from a query point + typename Kernel::Point_3 point_query(2.0, 2.0, 2.0); + typename Kernel::Point_3 closest = tree.closest_point(point_query); + + std::cerr << "closest point is: " << closest << std::endl; +} + +int main() +{ + Point p(1.0, 0.0, 0.0); + Point q(0.0, 1.0, 0.0); + Point r(0.0, 0.0, 1.0); + Point s(0.0, 0.0, 0.0); + Polyhedron polyhedron; + polyhedron.make_tetrahedron(p, q, r, s); + + run(polyhedron); + return EXIT_SUCCESS; +} diff --git a/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp b/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp index 99b66639d2a..93288489863 100644 --- a/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_segment_3_example.cpp @@ -17,7 +17,7 @@ typedef K::Segment_3 Segment; typedef K::Triangle_3 Triangle; typedef std::list::iterator Iterator; -typedef CGAL::AABB_segment_primitive Primitive; +typedef CGAL::AABB_segment_primitive Primitive; typedef CGAL::AABB_traits Traits; typedef CGAL::AABB_tree Tree; diff --git a/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp b/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp index 0a10dedd2eb..3d21f70b0cb 100644 --- a/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp +++ b/AABB_tree/examples/AABB_tree/AABB_triangle_3_example.cpp @@ -17,7 +17,7 @@ typedef K::Point_3 Point; typedef K::Triangle_3 Triangle; typedef std::list::iterator Iterator; -typedef CGAL::AABB_triangle_primitive Primitive; +typedef CGAL::AABB_triangle_primitive Primitive; typedef CGAL::AABB_traits AABB_triangle_traits; typedef CGAL::AABB_tree Tree; diff --git a/AABB_tree/include/CGAL/AABB_FaceGraph_triangle_primitive.h b/AABB_tree/include/CGAL/AABB_FaceGraph_triangle_primitive.h index 753fc2ea93e..c1c8e5bda18 100644 --- a/AABB_tree/include/CGAL/AABB_FaceGraph_triangle_primitive.h +++ b/AABB_tree/include/CGAL/AABB_FaceGraph_triangle_primitive.h @@ -12,8 +12,8 @@ // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // -// $URL: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/features/AABB_tree-one_primitive_per_object-sloriot/AABB_tree/include/CGAL/AABB_triangle_primitive.h $ -// $Id: AABB_triangle_primitive.h 68959 2012-05-04 12:24:50Z sloriot $ +// $URL$ +// $Id$ // // // Author(s) : Sebastien Loriot @@ -39,12 +39,12 @@ template < class FaceGraph, > class AABB_FaceGraph_triangle_primitive : public AABB_primitive< Id_, - Triangle_from_facet_property_map, - One_point_from_facet_property_map, + Triangle_from_facet_handle_property_map, + One_point_from_facet_handle_property_map, cache_primitive > { - typedef Triangle_from_facet_property_map Triangle_property_map; - typedef One_point_from_facet_property_map Point_property_map; + typedef Triangle_from_facet_handle_property_map Triangle_property_map; + typedef One_point_from_facet_handle_property_map Point_property_map; typedef AABB_primitive< Id_, Triangle_property_map, diff --git a/AABB_tree/include/CGAL/AABB_HalfedgeGraph_segment_primitive.h b/AABB_tree/include/CGAL/AABB_HalfedgeGraph_segment_primitive.h index 36e44f7a972..d704c43ee82 100644 --- a/AABB_tree/include/CGAL/AABB_HalfedgeGraph_segment_primitive.h +++ b/AABB_tree/include/CGAL/AABB_HalfedgeGraph_segment_primitive.h @@ -12,8 +12,8 @@ // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // -// $URL: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/features/AABB_tree-one_primitive_per_object-sloriot/AABB_tree/include/CGAL/AABB_triangle_primitive.h $ -// $Id: AABB_triangle_primitive.h 68959 2012-05-04 12:24:50Z sloriot $ +// $URL$ +// $Id$ // // // Author(s) : Sebastien Loriot @@ -35,6 +35,7 @@ #include #include #include +#include namespace CGAL { @@ -52,15 +53,15 @@ namespace internal{ template < class HalfedgeGraph, class cache_primitive=Tag_false, - class Id_=typename HalfedgeGraph::Halfedge_handle //this one should be autodetected using edge_descriptor + class Id_=typename boost::graph_traits::edge_descriptor > class AABB_HalfedgeGraph_segment_primitive : public AABB_primitive< Id_, - Segment_from_halfedge_property_map, - One_point_from_halfedge_property_map, + Segment_from_edge_descriptor_property_map, + Source_point_from_edge_descriptor, cache_primitive > { - typedef Segment_from_halfedge_property_map Triangle_property_map; - typedef One_point_from_halfedge_property_map Point_property_map; + typedef Segment_from_edge_descriptor_property_map Triangle_property_map; + typedef Source_point_from_edge_descriptor Point_property_map; typedef AABB_primitive< Id_, Triangle_property_map, diff --git a/AABB_tree/include/CGAL/AABB_primitive.h b/AABB_tree/include/CGAL/AABB_primitive.h index 150fc9af897..7accf69a617 100644 --- a/AABB_tree/include/CGAL/AABB_primitive.h +++ b/AABB_tree/include/CGAL/AABB_primitive.h @@ -12,8 +12,8 @@ // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // -// $URL: svn+ssh://sloriot@scm.gforge.inria.fr/svn/cgal/branches/features/AABB_tree-one_primitive_per_object-sloriot/AABB_tree/include/CGAL/AABB_triangle_primitive.h $ -// $Id: AABB_triangle_primitive.h 68970 2012-05-04 14:59:14Z sloriot $ +// $URL$ +// $Id$ // // // Author(s) : Sebastien Loriot @@ -53,10 +53,8 @@ public: // constructors AABB_primitive() {} AABB_primitive(Id it,ObjectPropertyMap t_pmap=ObjectPropertyMap(), PointPropertyMap p_pmap=PointPropertyMap()) - : m_ppmap(p_pmap), m_it(it) - { - this->set_primitive(it,t_pmap); - } + : Primitive_base(it,t_pmap),m_ppmap(p_pmap), m_it(it) + {} public: Id& id() { return m_it; } const Id& id() const { return m_it; } @@ -68,7 +66,7 @@ public: /// Returns a point on the primitive typename boost::property_traits< PointPropertyMap >::reference reference_point() const { - return get(m_ppmap,*m_it); + return get(m_ppmap, m_it); } }; diff --git a/AABB_tree/include/CGAL/AABB_segment_primitive.h b/AABB_tree/include/CGAL/AABB_segment_primitive.h index 0525bc481e9..b4028f2da84 100644 --- a/AABB_tree/include/CGAL/AABB_segment_primitive.h +++ b/AABB_tree/include/CGAL/AABB_segment_primitive.h @@ -27,42 +27,43 @@ #define CGAL_AABB_SEGMENT_PRIMITIVE_H_ #include +#include +#include namespace CGAL { namespace internal { - template - struct First_point_of_segment_3_property_map{ + template + struct Source_of_segment_3_iterator_property_map{ //classical typedefs - typedef const typename GeomTraits::Segment_3& key_type; + typedef typename CGAL::Kernel_traits< typename std::iterator_traits::value_type >::Kernel GeomTraits; + typedef Iterator key_type; typedef typename GeomTraits::Point_3 value_type; typedef const typename GeomTraits::Point_3& reference; typedef boost::readable_property_map_tag category; }; //get function for property map - template + template inline - const typename GeomTraits::Point_3& - get(First_point_of_segment_3_property_map, - const typename GeomTraits::Segment_3& s) + typename Source_of_segment_3_iterator_property_map::reference + get(Source_of_segment_3_iterator_property_map, Iterator it) { - return s.source(); + return it->source(); } }//namespace internal -template +template < class Iterator, + class cache_primitive=Tag_false> class AABB_segment_primitive : public AABB_primitive< Iterator, - boost::typed_identity_property_map, - internal::First_point_of_segment_3_property_map, - cache_primitive > + Input_iterator_property_map, + internal::Source_of_segment_3_iterator_property_map, + cache_primitive > { typedef AABB_primitive< Iterator, - boost::typed_identity_property_map, - internal::First_point_of_segment_3_property_map, + Input_iterator_property_map, + internal::Source_of_segment_3_iterator_property_map, cache_primitive > Base; public: // constructors diff --git a/AABB_tree/include/CGAL/AABB_triangle_primitive.h b/AABB_tree/include/CGAL/AABB_triangle_primitive.h index 253f8ae9651..934176ef423 100644 --- a/AABB_tree/include/CGAL/AABB_triangle_primitive.h +++ b/AABB_tree/include/CGAL/AABB_triangle_primitive.h @@ -27,42 +27,42 @@ #define CGAL_AABB_TRIANGLE_PRIMITIVE_H_ #include +#include namespace CGAL { namespace internal { - template - struct First_point_of_triangle_3_property_map{ + template + struct Point_from_triangle_3_iterator_property_map{ //classical typedefs - typedef const typename GeomTraits::Triangle_3& key_type; + typedef typename CGAL::Kernel_traits< typename std::iterator_traits::value_type >::Kernel GeomTraits; + typedef Iterator key_type; typedef typename GeomTraits::Point_3 value_type; typedef const typename GeomTraits::Point_3& reference; typedef boost::readable_property_map_tag category; }; //get function for property map - template + template inline - const typename GeomTraits::Point_3& - get(First_point_of_triangle_3_property_map, - const typename GeomTraits::Triangle_3& t) + typename Point_from_triangle_3_iterator_property_map::reference + get(Point_from_triangle_3_iterator_property_map,Iterator it) { - return t.vertex(0); + return it->vertex(0); } }//namespace internal -template +template < class Iterator, + class cache_primitive=Tag_false> class AABB_triangle_primitive : public AABB_primitive< Iterator, - boost::typed_identity_property_map, - internal::First_point_of_triangle_3_property_map, + Input_iterator_property_map, + internal::Point_from_triangle_3_iterator_property_map, cache_primitive > { typedef AABB_primitive< Iterator, - boost::typed_identity_property_map, - internal::First_point_of_triangle_3_property_map, + Input_iterator_property_map, + internal::Point_from_triangle_3_iterator_property_map, cache_primitive > Base; public: // constructors diff --git a/AABB_tree/include/CGAL/internal/AABB_tree/Primitive_caching.h b/AABB_tree/include/CGAL/internal/AABB_tree/Primitive_caching.h index df0c796ca62..f4a5a39116d 100644 --- a/AABB_tree/include/CGAL/internal/AABB_tree/Primitive_caching.h +++ b/AABB_tree/include/CGAL/internal/AABB_tree/Primitive_caching.h @@ -43,7 +43,7 @@ namespace internal{ typedef const Primitive& result_type; Primitive datum; - void set_primitive(Id id,PropertyMap pmap){datum=get(pmap,*id);} + Primitive_caching(Id id,PropertyMap pmap) {datum=get(pmap,id);} result_type get_primitive(Id) const{ return datum; } @@ -55,9 +55,9 @@ namespace internal{ typedef typename boost::property_traits< PropertyMap >::reference result_type; PropertyMap pmap_; - void set_primitive(Id,PropertyMap pmap){pmap_=pmap;} + Primitive_caching(Id,PropertyMap pmap){pmap_=pmap;} result_type get_primitive(Id id) const{ - return get(pmap_,*id); + return get(pmap_,id); } }; diff --git a/Point_set_processing_3/include/CGAL/property_map.h b/Point_set_processing_3/include/CGAL/property_map.h index 163ba31bca9..75887d8f98d 100644 --- a/Point_set_processing_3/include/CGAL/property_map.h +++ b/Point_set_processing_3/include/CGAL/property_map.h @@ -195,6 +195,31 @@ make_nth_of_tuple_property_map(Iter) return Nth_of_tuple_property_map::type>(); } +//========================================================================= + +/// Property map that accesses a value from an iterator +/// +/// @heading Is Model for the Concepts: +/// Model of boost::ReadablePropertyMap concept. +/// +/// @heading Parameters: +/// @param InputIterator an input iterator +template +struct Input_iterator_property_map{ + typedef InputIterator key_type; + typedef typename std::iterator_traits::value_type value_type; + typedef typename std::iterator_traits::reference reference; + typedef boost::readable_property_map_tag category; +}; + +/// Free function to use a get the value from an iterator using Input_iterator_property_map. +/// +/// @relates Input_iterator_property_map +template +inline +typename std::iterator_traits::reference +get(Input_iterator_property_map,InputIterator it){ return *it; } + } // namespace CGAL diff --git a/Polyhedron/include/CGAL/Polyhedron_3_property_map.h b/Polyhedron/include/CGAL/Polyhedron_3_property_map.h index 62464d8c937..2bdbaf2f62e 100644 --- a/Polyhedron/include/CGAL/Polyhedron_3_property_map.h +++ b/Polyhedron/include/CGAL/Polyhedron_3_property_map.h @@ -24,18 +24,20 @@ #include #include #include +#include +#include namespace CGAL{ //property map template -struct Triangle_from_facet_property_map{ - Triangle_from_facet_property_map(Polyhedron* = NULL){} +struct Triangle_from_facet_handle_property_map{ + Triangle_from_facet_handle_property_map(Polyhedron* = NULL){} //classical typedefs typedef typename boost::mpl::if_< typename boost::is_const::type, - const typename Polyhedron::Facet, - typename Polyhedron::Facet >::type key_type; + typename Polyhedron::Facet_const_handle, + typename Polyhedron::Facet_handle >::type key_type; typedef typename Polyhedron::Traits::Kernel::Triangle_3 value_type; typedef value_type reference; typedef boost::readable_property_map_tag category; @@ -44,53 +46,55 @@ struct Triangle_from_facet_property_map{ template inline typename Polyhedron::Traits::Kernel::Triangle_3 -get(const Triangle_from_facet_property_map&, - typename Triangle_from_facet_property_map::key_type& f) +get(Triangle_from_facet_handle_property_map, + typename Triangle_from_facet_handle_property_map::key_type f) { typedef typename Polyhedron::Traits::Kernel Kernel; - CGAL_precondition(f.halfedge() == f.halfedge()->next()->next()->next()); - const typename Kernel::Point_3& a = f.halfedge()->vertex()->point(); - const typename Kernel::Point_3& b = f.halfedge()->next()->vertex()->point(); - const typename Kernel::Point_3& c = f.halfedge()->next()->next()->vertex()->point(); + CGAL_precondition(f->halfedge() == f->halfedge()->next()->next()->next()); + const typename Kernel::Point_3& a = f->halfedge()->vertex()->point(); + const typename Kernel::Point_3& b = f->halfedge()->next()->vertex()->point(); + const typename Kernel::Point_3& c = f->halfedge()->next()->next()->vertex()->point(); return typename Kernel::Triangle_3(a,b,c); } -template -struct Segment_from_halfedge_property_map{ - Segment_from_halfedge_property_map(Polyhedron* = NULL){} +template +struct Segment_from_edge_descriptor_property_map{ + Segment_from_edge_descriptor_property_map(const HalfedgeGraph* g= NULL):m_graph( const_cast(g) ){} //classical typedefs - typedef typename boost::mpl::if_< - typename boost::is_const::type, - const typename Polyhedron::Halfedge, - typename Polyhedron::Halfedge >::type key_type; - typedef typename Polyhedron::Traits::Kernel::Segment_3 value_type; + typedef typename boost::property_traits< typename boost::property_map< HalfedgeGraph, vertex_point_t>::type >::value_type Point; + typedef typename boost::graph_traits::edge_descriptor key_type; + typedef typename Kernel_traits::Kernel::Segment_3 value_type; + typedef value_type reference; typedef boost::readable_property_map_tag category; + //data + HalfedgeGraph* m_graph; }; //get function for property map -template +template inline -typename Polyhedron::Traits::Kernel::Segment_3 -get(const Segment_from_halfedge_property_map&, - typename Segment_from_halfedge_property_map::key_type& h) +typename Segment_from_edge_descriptor_property_map::value_type +get(Segment_from_edge_descriptor_property_map pmap, + typename Segment_from_edge_descriptor_property_map::key_type h) { - typedef typename Polyhedron::Traits::Kernel Kernel; - const typename Kernel::Point_3& a = h.vertex()->point(); - const typename Kernel::Point_3& b = h.opposite()->vertex()->point(); + typedef typename boost::property_traits< typename boost::property_map< HalfedgeGraph, vertex_point_t>::type >::value_type Point; + typedef typename Kernel_traits::Kernel Kernel; + const Point& a = boost::source(h,*pmap.m_graph)->point(); + const Point& b = boost::target(h,*pmap.m_graph)->point(); return typename Kernel::Segment_3(a,b); } -//property map to access a point from a Facet +//property map to access a point from a facet handle template -struct One_point_from_facet_property_map{ - One_point_from_facet_property_map(Polyhedron* = NULL){} +struct One_point_from_facet_handle_property_map{ + One_point_from_facet_handle_property_map(Polyhedron* = NULL){} //classical typedefs typedef typename boost::mpl::if_< typename boost::is_const::type, - const typename Polyhedron::Facet, - typename Polyhedron::Facet >::type key_type; + typename Polyhedron::Facet_const_handle, + typename Polyhedron::Facet_handle >::type key_type; typedef typename Polyhedron::Traits::Kernel::Point_3 value_type; typedef const value_type& reference; typedef boost::lvalue_property_map_tag category; @@ -98,34 +102,33 @@ struct One_point_from_facet_property_map{ //get function for property map template inline -typename One_point_from_facet_property_map::reference -get(const One_point_from_facet_property_map&, - typename One_point_from_facet_property_map::key_type& f) +typename One_point_from_facet_handle_property_map::reference +get(One_point_from_facet_handle_property_map, + typename One_point_from_facet_handle_property_map::key_type f) { - return f.halfedge()->vertex()->point(); + return f->halfedge()->vertex()->point(); } -//property map to access a point from a Halfedge -template -struct One_point_from_halfedge_property_map{ - One_point_from_halfedge_property_map(Polyhedron* = NULL){} +//property map to access a point from an edge +template +struct Source_point_from_edge_descriptor{ + Source_point_from_edge_descriptor(const HalfedgeGraph* g= NULL):m_graph( const_cast(g) ){} //classical typedefs - typedef typename boost::mpl::if_< - typename boost::is_const::type, - const typename Polyhedron::Halfedge, - typename Polyhedron::Halfedge >::type key_type; - typedef typename Polyhedron::Traits::Kernel::Point_3 value_type; - typedef const value_type& reference; - typedef boost::lvalue_property_map_tag category; + typedef typename boost::property_traits< typename boost::property_map< HalfedgeGraph, vertex_point_t>::type >::value_type value_type; + typedef typename boost::property_traits< typename boost::property_map< HalfedgeGraph, vertex_point_t>::type >::reference reference; + typedef typename boost::graph_traits::edge_descriptor key_type; + typedef boost::readable_property_map_tag category; + //data + HalfedgeGraph* m_graph; }; //get function for property map -template +template inline -typename One_point_from_halfedge_property_map::reference -get(const One_point_from_halfedge_property_map&, - typename One_point_from_halfedge_property_map::key_type& h) +typename Source_point_from_edge_descriptor::reference +get(Source_point_from_edge_descriptor pmap, + typename boost::graph_traits::edge_descriptor h) { - return h.vertex()->point(); + return boost::source(h,*pmap.m_graph)->point(); } } //namespace CGAL