From a09ed46810b7bd1bb02fb21c9129f36a85f8e392 Mon Sep 17 00:00:00 2001 From: Clement Jamin Date: Mon, 23 Jun 2014 10:45:26 +0200 Subject: [PATCH] Thread-safe version of incident_cells and incident_facets --- Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h | 17 ++- .../CGAL/Mesh_3/Mesh_global_optimizer.h | 4 +- .../include/CGAL/Triangulation_3.h | 27 +++- .../CGAL/Triangulation_data_structure_3.h | 126 +++++++++++++----- 4 files changed, 126 insertions(+), 48 deletions(-) diff --git a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h index f1b1a57847a..e27bc1b4c55 100644 --- a/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h +++ b/Mesh_3/include/CGAL/Mesh_3/C3T3_helpers.h @@ -3247,7 +3247,18 @@ get_least_square_surface_plane(const Vertex_handle& v, { // Get incident facets Facet_vector facets; - tr_.finite_incident_facets(v,std::back_inserter(facets)); +# ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + tr_.finite_incident_facets_threadsafe(v, std::back_inserter(facets)); + } + // Sequential + else +# endif // CGAL_LINKED_WITH_TBB + { + tr_.finite_incident_facets(v,std::back_inserter(facets)); + } // Get adjacent surface points std::vector surface_point_vector; @@ -3373,10 +3384,10 @@ get_incident_slivers_without_using_tds_data(const Vertex_handle& v, Cell_vector &slivers) const { Is_sliver i_s(c3t3_, criterion, sliver_bound); - tr_.incident_cells_threadsafe(v, slivers, i_s); + tr_.incident_cells_threadsafe(v, std::back_inserter(slivers), i_s); } - +// CJTODO: call tr_.try_lock_and_get_incident_cells instead? template bool C3T3_helpers:: diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h b/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h index a9d0961b166..5c4b33af44c 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesh_global_optimizer.h @@ -851,7 +851,7 @@ compute_move(const Vertex_handle& v) // Parallel if (boost::is_convertible::value) { - tr_.incident_cells_threadsafe(v, incident_cells); + tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells)); } else #endif //CGAL_LINKED_WITH_TBB @@ -1066,7 +1066,7 @@ average_circumradius_length(const Vertex_handle& v) const // Parallel if (boost::is_convertible::value) { - tr_.incident_cells_threadsafe(v, incident_cells); + tr_.incident_cells_threadsafe(v, std::back_inserter(incident_cells)); } else #endif //CGAL_LINKED_WITH_TBB diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index 9d260de0170..c5cc2afadb7 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -1844,25 +1844,26 @@ public: } }; - template + template OutputIterator incident_cells(Vertex_handle v, OutputIterator cells) const { return _tds.incident_cells(v, cells); } + template void incident_cells_threadsafe(Vertex_handle v, - std::vector &cells) const + OutputIterator cells) const { - return _tds.incident_cells_threadsafe(v, cells); + _tds.incident_cells_threadsafe(v, cells); } - template + template void incident_cells_threadsafe(Vertex_handle v, - std::vector &cells, + OutputIterator cells, const Filter &filter) const { - return _tds.incident_cells_threadsafe(v, cells, filter); + _tds.incident_cells_threadsafe(v, cells, filter); } bool @@ -2002,6 +2003,20 @@ public: return _tds.incident_facets(v, facets, Finite_filter(this)); } + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets_threadsafe(v, facets); + } + + template + OutputIterator + finite_incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets_threadsafe(v, facets, Finite_filter(this)); + } + // old name (up to CGAL 3.4) // kept for backwards compatibility but not documented template diff --git a/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h b/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h index 55792d300c3..06937a9f473 100644 --- a/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_data_structure_3.h @@ -711,6 +711,36 @@ private: return it; } + + template + void + incident_cells_3_threadsafe(Vertex_handle v, Cell_handle d, + std::vector &cells, + IncidentFacetIterator facet_it) const + { + boost::unordered_set found_cells; + + cells.push_back(d); + found_cells.insert(d); + int head=0; + int tail=1; + do { + Cell_handle c = cells[head]; + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + if (c < next) + *facet_it++ = Facet(c, i); // Incident facet + if (! found_cells.insert(next).second ) + continue; + cells.push_back(next); + ++tail; + } + ++head; + } while(head != tail); + } void just_incident_cells_3(Vertex_handle v, std::vector& cells) const @@ -999,47 +1029,19 @@ public: } } - void incident_cells_threadsafe(Vertex_handle v, - std::vector &cells) const + template + OutputIterator + incident_cells_threadsafe(Vertex_handle v, OutputIterator cells, Filter f = Filter()) const { - boost::unordered_set found_cells; - Cell_handle d = v->cell(); - - cells.push_back(d); - found_cells.insert(d); - int head=0; - int tail=1; - do { - Cell_handle c = cells[head]; - - for (int i=0; i<4; ++i) { - if (c->vertex(i) == v) - continue; - Cell_handle next = c->neighbor(i); - if (! found_cells.insert(next).second ) - continue; - cells.push_back(next); - ++tail; - } - ++head; - } while(head != tail); + return visit_incident_cells_threadsafe, + OutputIterator>(v, cells, f); } - template - void incident_cells_threadsafe(Vertex_handle v, - std::vector &cells, - const Filter &filter) const + template + OutputIterator + incident_cells_threadsafe(Vertex_handle v, OutputIterator cells) const { - std::vector tmp_cells; - tmp_cells.reserve(64); - incident_cells_threadsafe(v, tmp_cells); - - BOOST_FOREACH(Cell_handle& ch, - std::make_pair(tmp_cells.begin(), tmp_cells.end())) - { - if (filter(ch)) - cells.push_back(ch); - } + return incident_cells_threadsafe(v, cells); } template @@ -1059,6 +1061,24 @@ public: { return incident_facets(v, facets); } + + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets, Filter f = Filter()) const + { + CGAL_triangulation_precondition( dimension() > 1 ); + if(dimension() == 3) + return visit_incident_cells_threadsafe, OutputIterator>(v, facets, f); + else + return visit_incident_cells_threadsafe, OutputIterator>(v, facets, f); + } + + template + OutputIterator + incident_facets_threadsafe(Vertex_handle v, OutputIterator facets) const + { + return incident_facets(v, facets); + } BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_member_visited,Has_visited_for_vertex_extractor,false) @@ -1178,6 +1198,38 @@ public: return visit.result(); } + template + OutputIterator + visit_incident_cells_threadsafe( + Vertex_handle v, OutputIterator output, Filter f) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + + if ( dimension() < 2 ) + return output; + + Visitor visit(v, output, this, f); + + std::vector tmp_cells; + tmp_cells.reserve(64); + if ( dimension() == 3 ) + incident_cells_3_threadsafe( + v, v->cell(), tmp_cells, visit.facet_it()); + else + incident_cells_2(v, v->cell(), std::back_inserter(tmp_cells)); + + typename std::vector::iterator cit; + for(cit = tmp_cells.begin(); + cit != tmp_cells.end(); + ++cit) + { + visit(*cit); + } + + return visit.result(); + } + template OutputIterator visit_incident_cells(Vertex_handle v, OutputIterator output,