diff --git a/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h b/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h index f2932e465e7..edc25b130f2 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h +++ b/Mesh_3/include/CGAL/Mesh_3/Mesh_complex_3_in_triangulation_3_base.h @@ -233,7 +233,11 @@ public: //test incident edges for REGULARITY and count BOUNDARY edges typename std::vector edges; edges.reserve(64); - tr_.incident_edges(v, std::back_inserter(edges)); + if(tr_.is_parallel()) { + tr_.incident_edges_threadsafe(v, std::back_inserter(edges)); + } else { + tr_.incident_edges(v, std::back_inserter(edges)); + } int number_of_boundary_incident_edges = 0; // could be a bool for (typename std::vector::iterator eit=edges.begin(), end = edges.end(); @@ -546,7 +550,11 @@ private: Union_find facets; { // fill the union find std::vector non_filtered_facets; - tr_.incident_facets(v, std::back_inserter(non_filtered_facets)); + if(tr_.is_parallel()) { + tr_.incident_facets_threadsafe(v, std::back_inserter(non_filtered_facets)); + } else { + tr_.incident_facets(v, std::back_inserter(non_filtered_facets)); + } for(typename std::vector::iterator fit = non_filtered_facets.begin(), diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h index 197890dc76b..59d7dd95de8 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_3.h @@ -483,7 +483,7 @@ protected: bool is_encroached_facet_refinable(Facet& facet) const; /// Insert facet into refinement queue - void insert_bad_facet(Facet& facet, const Quality& quality) + void insert_bad_facet(Facet facet, const Quality& quality) { // Insert the facet and its mirror this->add_bad_element( diff --git a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h index 4cfe6baef12..4364aa96253 100644 --- a/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h +++ b/Mesh_3/include/CGAL/Mesh_3/Refine_facets_manifold_base.h @@ -196,7 +196,10 @@ private: #endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS std::vector facets; facets.reserve(64); - this->r_tr_.incident_facets(v, std::back_inserter(facets)); + if(this->r_tr_.is_parallel()) + this->r_tr_.incident_facets_threadsafe(v, std::back_inserter(facets)); + else + this->r_tr_.incident_facets(v, std::back_inserter(facets)); typename std::vector::iterator fit = facets.begin(); while(fit != facets.end() && !this->r_c3t3_.is_in_complex(*fit)) ++fit; @@ -357,7 +360,7 @@ public: private: // Initialization function - void initialize_manifold_info() const { + void initialize_manifold_info() { #ifdef CGAL_MESH_3_VERBOSE std::cerr << "\nscanning edges "; if(m_with_boundary) @@ -373,9 +376,19 @@ private: ( (!m_with_boundary) && (this->r_c3t3_.face_status(*eit) == C3t3::BOUNDARY) ) ) { - m_bad_edges.insert(Bad_edge(edge_to_edgevv(*eit), - (this->r_c3t3_.face_status(*eit) == - C3t3::SINGULAR ? 0 : 1))); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->insert_bad_facet(biggest_incident_facet_in_complex(*eit), + typename Base::Quality()); + } else +#endif // CGAL_LINKED_WITH_TBB + { // Sequential + m_bad_edges.insert(Bad_edge(edge_to_edgevv(*eit), + (this->r_c3t3_.face_status(*eit) == + C3t3::SINGULAR ? 0 : 1))); + } #ifdef CGAL_MESH_3_VERBOSE ++n; #endif @@ -387,7 +400,7 @@ private: #endif } - void initialize_bad_vertices() const + void initialize_bad_vertices() { CGAL_assertion(m_bad_vertices_initialized == false); CGAL_assertion(m_bad_vertices.empty()); @@ -402,10 +415,20 @@ private: { if( this->r_c3t3_.face_status(vit) == C3t3::SINGULAR ) { #ifdef CGAL_MESHES_DEBUG_REFINEMENT_POINTS - std::cerr << "m_bad_edges.insert(" + std::cerr << "m_bad_vertices.insert(" << vit->point() << ")\n"; #endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - m_bad_vertices.insert( vit ); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->insert_bad_facet(biggest_incident_facet_in_complex(vit), + typename Base::Quality()); + } else +#endif // CGAL_LINKED_WITH_TBB + { // Sequential + m_bad_vertices.insert( vit ); + } #ifdef CGAL_MESH_3_VERBOSE ++n; #endif @@ -442,11 +465,13 @@ public: if( ! m_manifold_info_initialized ) initialize_manifold_info(); - if(m_bad_edges.left.empty()) + if(m_bad_edges.left.empty() && + Base::no_longer_element_to_refine_impl() /* for parallel */) { if( ! m_bad_vertices_initialized ) initialize_bad_vertices(); - return m_bad_vertices.empty(); + return m_bad_vertices.empty() && + Base::no_longer_element_to_refine_impl() /* for parallel */; } else // m_bad_vertices is not empty return false; @@ -551,12 +576,28 @@ public: (this->r_c3t3_.face_status(edge) == C3t3::BOUNDARY) ) ) { - m_bad_edges.insert(Bad_edge(edge_to_edgevv(edge), - (this->r_c3t3_.face_status(edge) == - C3t3::SINGULAR ? 0 : 1))); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->insert_bad_facet(biggest_incident_facet_in_complex(edge), + typename Base::Quality()); + } else +#endif // CGAL_LINKED_WITH_TBB + { // Sequential + m_bad_edges.insert(Bad_edge(edge_to_edgevv(edge), + (this->r_c3t3_.face_status(edge) == + C3t3::SINGULAR ? 0 : 1))); + } } else { - m_bad_edges.left.erase( edge_to_edgevv(edge) ); // @TODO: pourquoi?! +#ifdef CGAL_LINKED_WITH_TBB + // Sequential only + if (!boost::is_convertible::value) +#endif // CGAL_LINKED_WITH_TBB + { + m_bad_edges.left.erase( edge_to_edgevv(edge) ); // @TODO: pourquoi?! + } } } } @@ -587,7 +628,17 @@ public: std::cerr << "m_bad_vertices.insert(" << (*vit)->point() << ")\n"; #endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - m_bad_vertices.insert(*vit); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->insert_bad_facet(biggest_incident_facet_in_complex(*vit), + typename Base::Quality()); + } else +#endif // CGAL_LINKED_WITH_TBB + { // Sequential + m_bad_vertices.insert(*vit); + } } } @@ -600,7 +651,17 @@ public: std::cerr << "m_bad_vertices.insert(" << v->point() << ")\n"; #endif // CGAL_MESHES_DEBUG_REFINEMENT_POINTS - m_bad_vertices.insert(v); +#ifdef CGAL_LINKED_WITH_TBB + // Parallel + if (boost::is_convertible::value) + { + this->insert_bad_facet(biggest_incident_facet_in_complex(v), + typename Base::Quality()); + } else +#endif // CGAL_LINKED_WITH_TBB + { // Sequential + m_bad_vertices.insert(v); + } } } diff --git a/TDS_3/include/CGAL/Triangulation_data_structure_3.h b/TDS_3/include/CGAL/Triangulation_data_structure_3.h index fb46d35be9e..255574af553 100644 --- a/TDS_3/include/CGAL/Triangulation_data_structure_3.h +++ b/TDS_3/include/CGAL/Triangulation_data_structure_3.h @@ -1077,6 +1077,25 @@ public: BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_member_visited,Has_visited_for_vertex_extractor,false) + template + OutputIterator + incident_edges_1d(Vertex_handle v, OutputIterator edges, Filter f = Filter()) const + { + CGAL_assertion (dimension() == 1); + CGAL_triangulation_assertion( number_of_vertices() >= 3); + Cell_handle n0 = v->cell(); + const int index_v_in_n0 = n0->index(v); + CGAL_assume(index_v_in_n0 <= 1); + Cell_handle n1 = n0->neighbor(1-index_v_in_n0); + const int index_v_in_n1 = n1->index(v); + CGAL_assume(index_v_in_n1 <= 1); + if(!f(n0->vertex(1-index_v_in_n0))) + *edges++ = Edge(n0, n0->index(v), 1-index_v_in_n0); + if(!f(n1->vertex(1-index_v_in_n1))) + *edges++ = Edge(n1, n1->index(v), 1-index_v_in_n1); + return edges; + } + template OutputIterator incident_edges(Vertex_handle v, OutputIterator edges, Filter f = Filter()) const @@ -1087,22 +1106,32 @@ public: CGAL_triangulation_expensive_precondition( is_valid() ); if (dimension() == 1) { - CGAL_triangulation_assertion( number_of_vertices() >= 3); - Cell_handle n0 = v->cell(); - const int index_v_in_n0 = n0->index(v); - CGAL_assume(index_v_in_n0 <= 1); - Cell_handle n1 = n0->neighbor(1-index_v_in_n0); - const int index_v_in_n1 = n1->index(v); - CGAL_assume(index_v_in_n1 <= 1); - if(!f(n0->vertex(1-index_v_in_n0))) *edges++ = Edge(n0, n0->index(v), 1-index_v_in_n0); - if(!f(n1->vertex(1-index_v_in_n1))) *edges++ = Edge(n1, n1->index(v), 1-index_v_in_n1); - return edges; + return incident_edges_1d(v, edges, f); } return visit_incident_cells, OutputIterator, Filter, Has_member_visited::value>, OutputIterator>(v, edges, f); } + template + OutputIterator + incident_edges_threadsafe(Vertex_handle v, OutputIterator edges, + Filter f = Filter()) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_precondition( dimension() >= 1 ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + CGAL_triangulation_expensive_precondition( is_valid() ); + + if (dimension() == 1) { + return incident_edges_1d(v, edges, f); + } + return visit_incident_cells_threadsafe< + Vertex_extractor, + OutputIterator, Filter, Has_member_visited::value>, + OutputIterator>(v, edges, f); + } + template OutputIterator incident_edges(Vertex_handle v, OutputIterator edges) const @@ -1110,6 +1139,13 @@ public: return incident_edges(v, edges); } + template + OutputIterator + incident_edges_threadsafe(Vertex_handle v, OutputIterator edges) const + { + return incident_edges_threadsafe(v, edges); + } + template OutputIterator adjacent_vertices(Vertex_handle v, OutputIterator vertices, Filter f = Filter()) const diff --git a/Triangulation_3/include/CGAL/Triangulation_3.h b/Triangulation_3/include/CGAL/Triangulation_3.h index d8d1897b6f7..93c8f252138 100644 --- a/Triangulation_3/include/CGAL/Triangulation_3.h +++ b/Triangulation_3/include/CGAL/Triangulation_3.h @@ -2083,6 +2083,20 @@ public: return _tds.incident_edges(v, edges, Finite_filter(this)); } + template + OutputIterator + incident_edges_threadsafe(Vertex_handle v, OutputIterator edges) const + { + return _tds.incident_edges_threadsafe(v, edges); + } + + template + OutputIterator + finite_incident_edges_threadsafe(Vertex_handle v, OutputIterator edges) const + { + return _tds.incident_edges_threadsafe(v, edges, Finite_filter(this)); + } + size_type degree(Vertex_handle v) const { return _tds.degree(v);