diff --git a/BGL/examples/BGL_surface_mesh/connected_components.cpp b/BGL/examples/BGL_surface_mesh/connected_components.cpp new file mode 100644 index 00000000000..9923c25a44a --- /dev/null +++ b/BGL/examples/BGL_surface_mesh/connected_components.cpp @@ -0,0 +1,31 @@ +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Simple_cartesian Kernel; +typedef Kernel::Point_3 Point; +typedef CGAL::Surface_mesh Mesh; + +typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + +int main(int argc, char* argv[]) +{ + Mesh sm; + std::ifstream in((argc>1)?argv[1]:"data/prim.off"); + in >> sm; + + Mesh::Property_map ccmap; + ccmap = sm.add_property_map("v:CC").first; + + int num = connected_components(sm, ccmap); + std::cout << num << " connected components" << std::endl; + BOOST_FOREACH(vertex_descriptor v, vertices(sm)){ + std::cout << v << " is in component " << ccmap[v] << std::endl; + } + + return 0; +} diff --git a/BGL/examples/BGL_surface_mesh/data/prim.off b/BGL/examples/BGL_surface_mesh/data/prim.off index 7476f26cc46..da9ee71038c 100644 --- a/BGL/examples/BGL_surface_mesh/data/prim.off +++ b/BGL/examples/BGL_surface_mesh/data/prim.off @@ -1,5 +1,5 @@ OFF -8 7 0 +11 7 0 # vertices -1 -1 1 -1 1 1 @@ -9,6 +9,10 @@ OFF -1 1 -1 1 1 -1 1 -1 -1 + 2 2 2 + 3 2 2 + 3 3 3 + # facets 3 3 2 1 3 3 1 0 @@ -17,3 +21,4 @@ OFF 4 3 7 6 2 4 4 7 3 0 4 4 5 6 7 + 3 8 9 10 diff --git a/BGL/include/CGAL/boost/graph/iterator.h b/BGL/include/CGAL/boost/graph/iterator.h index 302ea6ca50a..d933ee9d070 100644 --- a/BGL/include/CGAL/boost/graph/iterator.h +++ b/BGL/include/CGAL/boost/graph/iterator.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include #include @@ -478,11 +478,18 @@ class Halfedge_around_target_circulator; template class Halfedge_around_source_circulator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_target_circulator > + : public boost::iterator_adaptor< + Halfedge_around_source_circulator // Derived + , Halfedge_around_target_circulator // Base + , typename boost::graph_traits::halfedge_descriptor // Value + , Bidirectional_circulator_tag // CategoryOrTraversal + , typename boost::graph_traits::halfedge_descriptor // Reference + > #endif { +private: + internal::OppositeHalfedge opp; #ifndef DOXYGEN_RUNNING - typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; typedef typename boost::graph_traits::vertex_descriptor vertex_descriptor; #endif @@ -490,7 +497,6 @@ class Halfedge_around_source_circulator public: #ifndef DOXYGEN_RUNNING - typedef Bidirectional_circulator_tag iterator_category; typedef std::size_t size_type; #endif @@ -498,12 +504,32 @@ public: {} Halfedge_around_source_circulator(halfedge_descriptor hd, const Graph& g) - : Base(Halfedge_around_target_circulator(hd,g), internal::OppositeHalfedge(g)) + : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator(hd,g)), opp(g) {} Halfedge_around_source_circulator(vertex_descriptor vd, const Graph& g) - : Base(Halfedge_around_target_circulator(halfedge(vd,g),g), internal::OppositeHalfedge(g)) + : Halfedge_around_source_circulator::iterator_adaptor_(Halfedge_around_target_circulator(halfedge(vd,g),g)), opp(g) {} + // design patter: "safe bool" + // will be replaced by explicit operator bool with C++11 + typedef void (Halfedge_around_source_circulator::*bool_type)() const; + + void this_type_does_not_support_comparisons() const {} + + operator bool_type() const + { + return (! (this->base_reference() == NULL)) ? + &Halfedge_around_source_circulator::this_type_does_not_support_comparisons : 0; + } + + bool operator== (void*) const + { + return this->base_reference() == NULL; + } + +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::halfedge_descriptor dereference() const { return opp(*this->base_reference()); } }; @@ -519,11 +545,17 @@ public: template class Face_around_target_circulator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_target_circulator > + : public boost::iterator_adaptor< + Face_around_target_circulator // Derived + , Halfedge_around_target_circulator // Base + , typename boost::graph_traits::face_descriptor // Value + , Bidirectional_circulator_tag // CategoryOrTraversal + , typename boost::graph_traits::face_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + internal::Face fct; public: @@ -531,10 +563,9 @@ public: {} Face_around_target_circulator(halfedge_descriptor hd, const Graph& g) - : Base(Halfedge_around_target_circulator(hd,g), internal::Face(g)) + : Face_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator(hd,g)), fct(g) {} #ifndef DOXYGEN_RUNNING - typedef Bidirectional_circulator_tag iterator_category; typedef std::size_t size_type; // design patter: "safe bool" @@ -545,14 +576,19 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Face_around_target_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { - return this->base() == NULL; + return this->base_reference() == NULL; } + + +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; @@ -712,7 +748,7 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (g == NULL)) ? &Halfedge_around_face_circulator::this_type_does_not_support_comparisons : 0; } @@ -820,23 +856,28 @@ halfedges_around_face(typename boost::graph_traits::halfedge_descriptor h template class Face_around_face_iterator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_face_iterator > + : public boost::iterator_adaptor< + Face_around_face_iterator // Derived + , Halfedge_around_face_iterator // Base + , typename boost::graph_traits::face_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::face_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_face_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - + internal::Face fct; public: -#ifndef DOXYGEN_RUNNING - typedef std::bidirectional_iterator_tag iterator_category; -#endif Face_around_face_iterator() {} Face_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Face(g)) + : Face_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } }; @@ -860,24 +901,32 @@ class Face_around_face_circulator template class Face_around_target_iterator -#ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_target_iterator > +#ifndef DOXYGEN_RUNNING + : public boost::iterator_adaptor< + Face_around_target_iterator // Derived + , Halfedge_around_target_iterator // Base + , typename boost::graph_traits::face_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::face_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + internal::Face fct; + public: -#ifndef DOXYGEN_RUNNING - typedef std::bidirectional_iterator_tag iterator_category; -#endif Face_around_target_iterator() {} Face_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Face(g)) + : Face_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} + +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::face_descriptor dereference() const { return fct(*this->base_reference()); } }; /** @@ -906,16 +955,21 @@ faces_around_face(typename boost::graph_traits::halfedge_descriptor h, co template class Vertex_around_face_circulator -#ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_face_circulator > +#ifndef DOXYGEN_RUNNING + : public boost::iterator_adaptor< + Vertex_around_face_circulator // Derived + , Halfedge_around_face_circulator // Base + , typename boost::graph_traits::vertex_descriptor // Value + , Bidirectional_circulator_tag // CategoryOrTraversal + , typename boost::graph_traits::vertex_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_face_circulator > Base; + internal::Target fct; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; public: #ifndef DOXYGEN_RUNNING - typedef Bidirectional_circulator_tag iterator_category; typedef std::size_t size_type; #endif @@ -923,7 +977,7 @@ public: {} Vertex_around_face_circulator(halfedge_descriptor h, const Graph& g) - : Base(Halfedge_around_face_circulator(h,g), internal::Target(g)) + : Vertex_around_face_circulator::iterator_adaptor_(Halfedge_around_face_circulator(h,g)), fct(g) {} #ifndef DOXYGEN_RUNNING @@ -935,36 +989,42 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Vertex_around_face_circulator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { - return this->base()== NULL; + return this->base_reference()== NULL; } +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; template class Vertex_around_face_iterator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_face_iterator > + : public boost::iterator_adaptor< + Vertex_around_face_iterator // Derived + , Halfedge_around_face_iterator // Base + , typename boost::graph_traits::vertex_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::vertex_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_face_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + internal::Target fct; public: -#ifndef DOXYGEN_RUNNING - typedef std::bidirectional_iterator_tag iterator_category; -#endif Vertex_around_face_iterator() {} Vertex_around_face_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Target(g)) + : Vertex_around_face_iterator::iterator_adaptor_(Halfedge_around_face_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} #ifndef DOXYGEN_RUNNING @@ -976,14 +1036,17 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Vertex_around_face_iterator::this_type_does_not_support_comparisons : 0; } bool operator== (void*) const { - return this->base()== NULL; + return this->base_reference()== NULL; } +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; @@ -1000,15 +1063,19 @@ public: template class Vertex_around_target_circulator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_target_circulator > + : public boost::iterator_adaptor< + Vertex_around_target_circulator // Derived + , Halfedge_around_target_circulator // Base + , typename boost::graph_traits::vertex_descriptor // Value + , Bidirectional_circulator_tag // CategoryOrTraversal + , typename boost::graph_traits::vertex_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_target_circulator > Base; - + internal::Source fct; public: #ifndef DOXYGEN_RUNNING typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - typedef Bidirectional_circulator_tag iterator_category; typedef std::size_t size_type; #endif @@ -1016,7 +1083,7 @@ public: {} Vertex_around_target_circulator(halfedge_descriptor h, const Graph& g) - : Base(Halfedge_around_target_circulator(h,g), internal::Source(g)) + : Vertex_around_target_circulator::iterator_adaptor_(Halfedge_around_target_circulator(h,g)), fct(g) {} #ifndef DOXYGEN_RUNNING @@ -1028,9 +1095,18 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Vertex_around_target_circulator::this_type_does_not_support_comparisons : 0; } + + bool operator== (void*) const + { + return this->base_reference()== NULL; + } + +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; @@ -1040,20 +1116,25 @@ public: template class Vertex_around_target_iterator #ifndef DOXYGEN_RUNNING - : public boost::transform_iterator, Halfedge_around_target_iterator > + : public boost::iterator_adaptor< + Vertex_around_target_iterator // Derived + , Halfedge_around_target_iterator // Base + , typename boost::graph_traits::vertex_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::vertex_descriptor // Reference + > #endif { - typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; + internal::Source fct; public: - typedef std::bidirectional_iterator_tag iterator_category; Vertex_around_target_iterator() {} Vertex_around_target_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Source(g)) + : Vertex_around_target_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} #ifndef DOXYGEN_RUNNING @@ -1065,9 +1146,12 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Vertex_around_target_iterator::this_type_does_not_support_comparisons : 0; } +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::vertex_descriptor dereference() const { return fct(*this->base_reference()); } #endif }; @@ -1120,57 +1204,69 @@ vertices_around_face(typename boost::graph_traits::halfedge_descriptor h, return make_range(I(h,g), I(h,g,1)); } -template + +template class Out_edge_iterator - : public boost::transform_iterator, Halfedge_around_target_iterator > + : public boost::iterator_adaptor< + Out_edge_iterator // Derived + , Halfedge_around_target_iterator // Base + , typename boost::graph_traits::edge_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::edge_descriptor // Reference + > { - typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - +private: + internal::OppositeEdge opp; public: - typedef std::bidirectional_iterator_tag iterator_category; - Out_edge_iterator() {} - + Out_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::OppositeEdge(g)) - {} - - + : Out_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), opp(g) {} + // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (Out_edge_iterator::*bool_type)() const; - + void this_type_does_not_support_comparisons() const {} - + operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &Out_edge_iterator::this_type_does_not_support_comparisons : 0; } - -}; + + +private: + friend class boost::iterator_core_access; + typename boost::graph_traits::edge_descriptor dereference() const { return opp(*this->base_reference()); } +}; -template + + +template class In_edge_iterator - : public boost::transform_iterator, Halfedge_around_target_iterator > + : public boost::iterator_adaptor< + In_edge_iterator // Derived + , Halfedge_around_target_iterator // Base + , typename boost::graph_traits::edge_descriptor // Value + , std::bidirectional_iterator_tag // CategoryOrTraversal + , typename boost::graph_traits::edge_descriptor // Reference + > { - typedef boost::transform_iterator, Halfedge_around_target_iterator > Base; typedef typename boost::graph_traits::halfedge_descriptor halfedge_descriptor; - +private: + internal::Edge fct; public: - typedef std::bidirectional_iterator_tag iterator_category; - In_edge_iterator() {} - + In_edge_iterator(halfedge_descriptor h, const Graph& g, int n = 0) - : Base(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n), internal::Edge(g)) + : In_edge_iterator::iterator_adaptor_(Halfedge_around_target_iterator(h,g,(h==halfedge_descriptor())?1:n)), fct(g) {} - // design patter: "safe bool" // will be replaced by explicit operator bool with C++11 typedef void (In_edge_iterator::*bool_type)() const; @@ -1179,11 +1275,17 @@ public: operator bool_type() const { - return (! (this->base() == NULL)) ? + return (! (this->base_reference() == NULL)) ? &In_edge_iterator::this_type_does_not_support_comparisons : 0; } -}; + private: + friend class boost::iterator_core_access; + typename boost::graph_traits::edge_descriptor dereference() const { return fct(*this->base_reference()); } +}; + + + diff --git a/BGL/test/BGL/test_circulator.cpp b/BGL/test/BGL/test_circulator.cpp index 1614444c984..b0ba2375fe8 100644 --- a/BGL/test/BGL/test_circulator.cpp +++ b/BGL/test/BGL/test_circulator.cpp @@ -5,6 +5,8 @@ #include #include +#include +#include #include #include @@ -17,6 +19,7 @@ typedef GraphTraits::vertex_descriptor vertex_descriptor; typedef GraphTraits::halfedge_descriptor halfedge_descriptor; typedef GraphTraits::edge_descriptor edge_descriptor; typedef GraphTraits::out_edge_iterator out_edge_iterator; +typedef GraphTraits::in_edge_iterator in_edge_iterator; typedef CGAL::Halfedge_around_face_circulator halfedge_around_face_circulator; typedef CGAL::Halfedge_around_target_circulator halfedge_around_target_circulator; @@ -27,9 +30,27 @@ typedef CGAL::Halfedge_around_source_circulator halfedge_around_sour typedef CGAL::Halfedge_around_target_iterator halfedge_around_target_iterator; typedef CGAL::Halfedge_around_face_iterator halfedge_around_face_iterator; - +typedef CGAL::Face_around_face_iterator face_around_face_iterator; +typedef CGAL::Vertex_around_target_iterator vertex_around_target_iterator; int main(int, char* argv[]) { + + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + + BOOST_CONCEPT_ASSERT((CGAL::Concepts::BidirectionalCirculator)) CGAL_UNUSED; + + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + BOOST_CONCEPT_ASSERT((boost::BidirectionalIterator)); + std::ifstream in(argv[1]); Polyhedron P; in >> P;