diff --git a/Triangulation_3/benchmark/Triangulation_3/incident_edges.cpp b/Triangulation_3/benchmark/Triangulation_3/incident_edges.cpp new file mode 100644 index 00000000000..380f16415fa --- /dev/null +++ b/Triangulation_3/benchmark/Triangulation_3/incident_edges.cpp @@ -0,0 +1,40 @@ + + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Delaunay_triangulation_3 DT; +typedef K::Point_3 Point_3; +typedef CGAL::Timer Timer; + +int main() +{ + + std::vector points; + Point_3 p; + + while(std::cin >> p){ + points.push_back(p); + } + DT dt; + dt.insert(points.begin(), points.end()); + + Timer timer; + timer.start(); + int N = 0; + for(int i = 0; i < 5; i++){ + for(DT::Vertex_iterator vit = dt.vertices_begin(); vit!= dt.vertices_end(); ++vit){ + std::vector E; + E.reserve(64); + dt.incident_edges(vit,std::back_inserter(E)); + N += E.size(); + } + } + timer.stop(); + + std::cerr << N << std::endl << timer.time() << " sec" << std::endl; + return 0; +} diff --git a/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h b/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h index 29520c89443..c0299a16fbc 100644 --- a/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -814,37 +815,97 @@ public: } }; + template + class Vertex_extractor; // Visitor for visit_incident_cells: // outputs the result of Treatment applied to the vertices template - class Vertex_extractor { + class Vertex_extractor { Vertex_handle v; - std::set tmp_vertices; + + boost::unordered_set tmp_vertices; + Treatment treat; const Tds* t; Filter filter; public: Vertex_extractor(Vertex_handle _v, OutputIterator _output, const Tds* _t, Filter _filter): - v(_v), treat(_output), t(_t), filter(_filter) {} + v(_v), treat(_output), t(_t), filter(_filter) + { +#if ( BOOST_VERSION >= 105000 ) + tmp_vertices.reserve(64); +#endif + } + void operator()(Cell_handle c) { for (int j=0; j<= t->dimension(); ++j) { Vertex_handle w = c->vertex(j); if(filter(w)) continue; - if (w != v) + if (w != v){ + if(tmp_vertices.insert(w).second) { treat(c, v, j); } + + } } } + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} OutputIterator result() { return treat.result(); } }; + template + class Vertex_extractor { + Vertex_handle v; + std::vector tmp_vertices; + + Treatment treat; + const Tds* t; + Filter filter; + public: + Vertex_extractor(Vertex_handle _v, OutputIterator _output, const Tds* _t, Filter _filter): + v(_v), treat(_output), t(_t), filter(_filter) { + tmp_vertices.reserve(64); + } + + void operator()(Cell_handle c) { + for (int j=0; j<= t->dimension(); ++j) { + Vertex_handle w = c->vertex(j); + if(filter(w)) + continue; + if (w != v){ + + if(! w->visited_for_vertex_extractor){ + w->visited_for_vertex_extractor = true; + tmp_vertices.push_back(w); + treat(c, v, j); + } + } + } + } + + ~Vertex_extractor() + { + for(std::size_t i=0; i < tmp_vertices.size(); ++i){ + tmp_vertices[i]->visited_for_vertex_extractor = false; + } + } + + + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} + OutputIterator result() { + return treat.result(); + } + }; + + + // Treatment for Vertex_extractor: // outputs the vertices template @@ -922,6 +983,8 @@ public: return incident_facets(v, facets); } + BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_member_visited,Has_visited_for_vertex_extractor,false) + template OutputIterator incident_edges(Vertex_handle v, OutputIterator edges, Filter f = Filter()) const @@ -944,7 +1007,7 @@ public: return edges; } return visit_incident_cells, - OutputIterator, Filter>, + OutputIterator, Filter, Has_member_visited::value>, OutputIterator>(v, edges, f); } @@ -987,7 +1050,7 @@ public: return vertices; } return visit_incident_cells, - OutputIterator, Filter>, + OutputIterator, Filter, Has_member_visited::value>, OutputIterator>(v, vertices, f); } @@ -1033,7 +1096,8 @@ public: { (*cit)->tds_data().clear(); visit(*cit); - } + } + return visit.result(); } diff --git a/Triangulation_3/include/CGAL/Triangulation_ds_vertex_base_3.h b/Triangulation_3/include/CGAL/Triangulation_ds_vertex_base_3.h index 27f62fb3c0d..b60eb717c14 100644 --- a/Triangulation_3/include/CGAL/Triangulation_ds_vertex_base_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_ds_vertex_base_3.h @@ -37,10 +37,12 @@ public: struct Rebind_TDS { typedef Triangulation_ds_vertex_base_3 Other; }; Triangulation_ds_vertex_base_3() - : _c() {} + : _c(), visited_for_vertex_extractor(false) + {} Triangulation_ds_vertex_base_3(Cell_handle c) - : _c(c) {} + : _c(c), visited_for_vertex_extractor(false) + {} Cell_handle cell() const { return _c; } @@ -64,6 +66,13 @@ public: private: Cell_handle _c; + + // The typedef and the bool are used by Triangulation_data_structure::Vertex_extractor + // The names are chooses complicated so that we do not have to document them + // (privacy by obfuscation) + public: + typedef bool Has_visited_for_vertex_extractor; + bool visited_for_vertex_extractor; }; template < class TDS >